]> rtime.felk.cvut.cz Git - pes-rpp/rpp-test-sw.git/blob - rpp-test-sw/commands/cmd_can.c
Remove excessive CAN command
[pes-rpp/rpp-test-sw.git] / rpp-test-sw / commands / cmd_can.c
1 /*
2  * Copyright (C) 2012-2013 Czech Technical University in Prague
3  *
4  * Created on: 28.2.2013
5  *
6  * Authors:
7  *     - Michal Horn
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
21  *
22  * File : cmd_can.c
23  *
24  * Abstract:
25  *      This file contains commands for CAN test
26  *
27  */
28
29 #include "cmd_can.h"
30
31 #ifndef DOCGEN
32
33 #include "rpp/rpp.h"
34 #include "sys/sys.h"
35 #include <stdio.h>
36
37 /*
38  * Error codes definitions for RPP CAN functions tests.
39  */
40 #define ERR_CCT_HW_OBJ                  0x0001  /**< Wrong HW object passed to the RPP CAN function. */
41 #define ERR_CCT_MSG_MISMATCH            0x0010  /**< Received message does not match to the sent message. */
42 #define ERR_CCT_RX_IND_NOT_CLEARED      0x0020  /**< Message received indicator was not cleared by the rpp_can_read function.  */
43 #define ERR_CCT_RX_IND_SET_NO_MSG_REC   0x0040  /**< Message received indicator is set, but no message could be retrieved by the rpp_can_read function. */
44 #define ERR_CCT_RECV_TIMEOUT            0x0100  /**< Message receive timeout reached. */
45 #define ERR_CCT_CLEAR_TX_PEND_TO        0x0200  /**< Timeout reached for waiting for the clearance of the transmission request flag. */
46 #define ERR_CCT_SET_TX_PEND_TO          0x0400  /**< Timeout reached for waiting until the transmission request flag is set after the request is posted. */
47 #define ERR_CCT_INIT                    0x1000  /**< Error while initializing the CAN bus. */
48 #define ERR_CCT_SEND                    0x2000  /**< Error while sending a CAN message. */
49 #define ERR_CCT_RCV                     0x4000  /**< Error while receiving a CAN message */
50 #define ERR_CCT_UNEXPECTED_RETVAL       0x0008  /**< Unexpected return value has been returned from some RPP CAN function. */
51
52 #define CCT_TIMEOUT                     100000  /**< Timeout for RPP CAN test steps. */
53
54 static int can_inited = 0;
55
56 /* Default CAN timing set to 500kb */
57 static struct rpp_can_timing_cfg can_timing[] = {
58         {
59                 .brp = 10,
60                 .phase_seg1 = 5,
61                 .phase_seg2 = 2,
62                 .prop_seg = 8,
63                 .sjw = 1
64         },
65         {
66                 .brp = 10,
67                 .phase_seg1 = 5,
68                 .phase_seg2 = 2,
69                 .prop_seg = 8,
70                 .sjw = 1
71         },
72         {
73                 .brp = 10,
74                 .phase_seg1 = 5,
75                 .phase_seg2 = 2,
76                 .prop_seg = 8,
77                 .sjw = 1
78         },
79 };
80
81
82 static struct rpp_can_ctrl_config ctrl_config[] = {
83         {
84                 .baudrate = 500000,
85                 .clk = 80000000,
86                 .timing_calc_method = RPP_CAN_TIMING_CALC_AUTO,
87                 .timing_config = NULL
88         },
89         {
90                 .baudrate = 500000,
91                 .clk = 80000000,
92                 .timing_calc_method = RPP_CAN_TIMING_CALC_AUTO,
93                 .timing_config = NULL
94         },
95         {
96                 .baudrate = 500000,
97                 .clk = 80000000,
98                 .timing_calc_method = RPP_CAN_TIMING_CALC_AUTO,
99                 .timing_config = NULL
100         }
101 };
102
103 static struct rpp_can_tx_config tx_config[] = {
104         {
105                 .type = RPP_CAN_EXTENDED,
106                 .controller = 1,
107                 .msg_obj = 2,
108         },
109         {
110                 .type = RPP_CAN_EXTENDED,
111                 .controller = 2,
112                 .msg_obj = 2,
113         },
114         {
115                 .type = RPP_CAN_EXTENDED,
116                 .controller = 3,
117                 .msg_obj = 2,
118         }
119 };
120
121 static struct rpp_can_rx_config rx_config[] = {
122         {
123                 .type = RPP_CAN_MIXED,
124                 .controller = 1,
125                 .msg_obj = 1,
126                 .id = 1,
127                 .mask = 0x7fffff,
128         },
129         {
130                 .type = RPP_CAN_MIXED,
131                 .controller = 2,
132                 .msg_obj = 1,
133                 .id = 1,
134                 .mask = 0x7fffff,
135         },
136         {
137                 .type = RPP_CAN_MIXED,
138                 .controller = 3,
139                 .msg_obj = 1,
140                 .id = 1,
141                 .mask = 0x7fffff,
142         }
143 };
144
145 struct rpp_can_config can_config = {
146         .num_tx_obj = 3,
147         .num_rx_obj = 3,
148         .tx_config = tx_config,
149         .rx_config = rx_config,
150         .ctrl = ctrl_config,
151 };
152
153 /*
154  * Structures for RPP CAN functions tests.
155  */
156
157 /**
158  * CAN test bit timings configurations.
159  */
160 struct rpp_can_timing_cfg can_test_timing[] = {
161                 {
162                         .brp = 10,
163                         .prop_seg = 8,
164                         .phase_seg1 = 5,
165                         .phase_seg2 = 2,
166                         .sjw = 1
167                 },
168                 {
169                         .brp = 10,
170                         .prop_seg = 8,
171                         .phase_seg1 = 5,
172                         .phase_seg2 = 2,
173                         .sjw = 1
174                 },
175                 {
176                         .brp = 10,
177                         .prop_seg = 8,
178                         .phase_seg1 = 5,
179                         .phase_seg2 = 2,
180                         .sjw = 1
181                 },
182 };
183
184 /**
185  * CAN test controllers configurations.
186  */
187 struct rpp_can_ctrl_config can_test_ctrl_cfg[] = {
188                 {
189                         .baudrate = 500000,
190                         .clk = 80000000,
191                         .timing_calc_method = RPP_CAN_TIMING_CALC_MANUAL,
192                         .timing_config = &can_test_timing[0]
193                 },
194                 {
195                         .baudrate = 500000,
196                         .clk = 80000000,
197                         .timing_calc_method = RPP_CAN_TIMING_CALC_MANUAL,
198                         .timing_config = &can_test_timing[1]
199                 },
200                 {
201                         .baudrate = 500000,
202                         .clk = 80000000,
203                         .timing_calc_method = RPP_CAN_TIMING_CALC_MANUAL,
204                         .timing_config = &can_test_timing[2]
205                 },
206 };
207
208 /**
209  * CAN test TX configuration.
210  */
211 struct rpp_can_tx_config can_test_tx_cfg[] = {
212                 {
213                                 .type = RPP_CAN_STANDARD,
214                                 .controller = 1,
215                                 .msg_obj = 1
216                 }
217 };
218
219 /**
220  * CAN test RX configuration.
221  */
222 struct rpp_can_rx_config can_test_rx_cfg[] = {
223                 {
224                                 .type = RPP_CAN_STANDARD,
225                                 .controller = 2,
226                                 .id = 0x1,
227                                 .mask = 1,
228                                 .msg_obj = 1
229                 }
230 };
231
232 /**
233  * Root CAN test configuration structure
234  */
235 struct rpp_can_config can_test_cfg = {
236                 .num_tx_obj = 1,
237                 .num_rx_obj = 1,
238                 .tx_config = can_test_tx_cfg,
239                 .rx_config = can_test_rx_cfg,
240                 .ctrl = can_test_ctrl_cfg
241 };
242
243 /**
244  * Compare two CAN messages.
245  *
246  * @param[in] pdu1 CAN message 1
247  * @param[in] pdu2 CAN message 2
248  * @return TRUE, if the two CAN messages are equal.
249  */
250 boolean_t cmd_can_messages_equal(const struct rpp_can_pdu *pdu1, const struct rpp_can_pdu *pdu2)
251 {
252         boolean_t pdus_equal = TRUE;
253         if (pdu1->id != pdu2->id ||
254                 pdu1->dlc != pdu2->dlc) {
255                 pdus_equal = FALSE;
256         }
257         else {
258                 uint8_t i = 0;
259                 for (i = 0; i < pdu1->dlc; i++) {
260                         if (pdu1->data[i] != pdu1->data[i]) {
261                                 pdus_equal = FALSE;
262                                 break;
263                         }
264                 }
265         }
266         return pdus_equal;
267 }
268
269 /**
270  * Initialize the CAN bus driver for tests.
271  *
272  * @param[in] timing_calc Select RPP_CAN_TIMING_CALC_AUTO for automatic CAN bit timing calculation
273  * for a baudrate specified by desired_baudrate. Select RPP_CAN_TIMING_CALC_MANUAL for configuring the
274  * CAN bus to 500kbits/sec with verified bit timing parameters generated by HALCoGen.
275  *
276  * @return SUCCESS if the test passed, FAILURE otherwise.
277  */
278 int cmd_can_test_init(enum rpp_can_timing_calculation timing_calc, uint32_t desired_baudrate)
279 {
280         can_test_cfg.ctrl[0].baudrate = desired_baudrate;
281         can_test_cfg.ctrl[0].timing_calc_method = timing_calc;
282         can_test_cfg.ctrl[1].baudrate = desired_baudrate;
283         can_test_cfg.ctrl[1].timing_calc_method = timing_calc;
284         can_test_cfg.ctrl[2].baudrate = desired_baudrate;
285         can_test_cfg.ctrl[2].timing_calc_method = timing_calc;
286
287         if (rpp_can_init(&can_test_cfg) == SUCCESS) {
288                 return SUCCESS;
289         }
290         else {
291                 return FAILURE;
292         }
293 }
294
295 /**
296  * General test for receiving of message.
297  *
298  * This function verifies that the rpp_can_read() function is working
299  * properly and that the CAN driver behaves as expected.
300  *
301  * This is a blocking function that tries to receive a CAN message. The reception
302  * has to finish until specified timeout is reached.
303  * The received message is compared with the transmitted one.
304  *
305  * @param[in] can_tx_pdu A message pattern, which should be received. Used for RX
306  * and TX equality verification.
307  * @param[in] timeout How long should the test wait for the message.
308  * @return SUCCESS if the test passed, error code otherwise.
309  */
310 int cmd_can_test_recv(const struct rpp_can_pdu* can_tx_pdu, uint32_t timeout)
311 {
312         boolean_t msg_received = FALSE;
313         volatile uint32_t rec_time = 0;
314         struct rpp_can_pdu can_rx_pdu;
315
316         while (!msg_received) {
317                 int ret = rpp_can_read(0, &can_rx_pdu);
318                 switch (ret) {
319                 case -RPP_EINVAL:
320                         return ERR_CCT_HW_OBJ;
321                 case -RPP_ENODATA:
322                         if (++rec_time >= CCT_TIMEOUT) {
323                                 return ERR_CCT_RECV_TIMEOUT;
324                         }
325                         break;
326                 case SUCCESS:
327                         if (!cmd_can_messages_equal(&can_rx_pdu, can_tx_pdu)) {
328                                 return ERR_CCT_MSG_MISMATCH;
329                         }
330                         else {
331                                 msg_received = TRUE;
332                         }
333                         break;
334                 default:
335                         return ERR_CCT_UNEXPECTED_RETVAL;
336                 }
337         }
338         return SUCCESS;
339 }
340
341 /**
342  * General test of sending a message.
343  *
344  * This function verifies that the rpp_can_write() function is working
345  * properly and that the CAN driver behaves as expected.
346  *
347  * @param[in] can_tx_msg A message for transmission.
348  * @return SUCCESS if the test passed, error code otherwise.
349  */
350 int cmd_can_test_send(const struct rpp_can_pdu* can_tx_msg)
351 {
352         if (rpp_can_write(0, can_tx_msg) != SUCCESS) {
353                 return ERR_CCT_HW_OBJ;
354         }
355         return SUCCESS;
356 }
357
358 /**
359  * General test of sending and receiving mechanism.
360  *
361  * This function verifies that the rpp_can_write() and rpp_can_read() functions
362  * are working properly and that the CAN driver behaves as expected.
363  *
364  * The message specified as a parameter is sent on the CAN bus and received to
365  * another mailbox. The received message is compared with the sent one.
366  *
367  * @param[in] can_tx_msg A message used to testing
368  * @return SUCCESS if the test passed, error code otherwise.
369  */
370 int cmd_can_test_simple_send_recv(const struct rpp_can_pdu* can_tx_msg)
371 {
372         int ret_val = 0;
373         if ((ret_val = cmd_can_test_send(can_tx_msg)) != SUCCESS) {
374                 return ERR_CCT_SEND|ret_val;
375         }
376         else {
377                 if ((ret_val = cmd_can_test_recv(can_tx_msg, CCT_TIMEOUT)) != SUCCESS) {
378                         return ERR_CCT_RCV|ret_val;
379                 }
380         }
381         return SUCCESS;
382 }
383
384 /**
385  * Test automatic CAN bit timing calculation for the specified baudrate.
386  *
387  * @param[in] tested_baudrate Desired baudrate.
388  * @param[in] can_tx_msg A message used to testing.
389  * @return SUCCESS if the test passed, error code otherwise.
390  *
391  */
392 int cmd_can_test_baudrate_calc(uint32_t tested_baudrate,const struct rpp_can_pdu* can_tx_msg)
393 {
394         int ret_val = 0;
395         if ((ret_val = cmd_can_test_init(RPP_CAN_TIMING_CALC_AUTO, 125000)) != SUCCESS) {
396                 return ERR_CCT_INIT|ret_val;
397         }
398         else {
399                 if ((ret_val = cmd_can_test_simple_send_recv(can_tx_msg)) != SUCCESS) {
400                         return ret_val;
401                 }
402         }
403         return SUCCESS;
404 }
405
406 /**
407  * Test behavioral of two consecutive TX requests posting.
408  *
409  * This function verifies that the rpp_can_write() function is working properly and
410  * that the CAN driver behaves as expected.
411  *
412  * According to the behavioral defined by tha Autosar, the rpp_can_write() should not fail when
413  * new transmission request comes before the previous one has been processed. The function should
414  * overwrite the old request and only the new one should be transmitted.
415  *
416  * @param[in] can_tx_msg1 A message which transmission is requested foremost.
417  * @param[in] can_tx_msg2 A message, which transmission is requested right after the can_tx_msg1
418  * @return SUCCESS if the test passed, error code otherwise.
419  */
420 int cmd_can_test_tx_request_replace(const struct rpp_can_pdu* can_tx_msg1, const struct rpp_can_pdu* can_tx_msg2)
421 {
422         int ret_val = 0;
423         if ((ret_val = cmd_can_test_send(can_tx_msg1)) != SUCCESS) {
424                 return ret_val;
425         }
426         else {
427                 if ((ret_val = cmd_can_test_simple_send_recv(can_tx_msg2)) != SUCCESS) {
428                         return ret_val;
429                 }
430         }
431         return SUCCESS;
432 }
433
434 /**
435  * Test the TX request flag.
436  *
437  * This function verifies that the rpp_can_check_tx_pend() function is working properly and
438  * that the CAN driver behaves as expected.
439  *
440  * The TX request flag should be clear if no transmission request is pending. Once a rpp_can_write()
441  * is called a new transmission requst is posted and the TX request flag should be set, until the CAN
442  * bus driver sends the message. After the transmission is finished, the flag should be cleared.
443  *
444  * @param[in] rpp_can_pdu A message which used to testing.
445  * @param[out] time Measured time between posting the transmission request and setting the TX request flag.
446  * @return SUCCESS if the test passed, error code otherwise.
447  */
448 int cmd_can_test_tx_request_flag(const struct rpp_can_pdu* can_tx_msg, uint32_t* time)
449 {
450         *time = 0;
451         uint32_t timeout = 0;
452         boolean_t tx_pend = FALSE;
453         int ret_val = 0;
454         if ((ret_val = cmd_can_test_send(can_tx_msg)) != SUCCESS) {
455                 return ret_val;
456         }
457         else {
458                 /* Wait for the flag to be set */
459                 while (!tx_pend) {
460                         if (++timeout > CCT_TIMEOUT) {
461                                 return ERR_CCT_SET_TX_PEND_TO;
462                         }
463                         if (rpp_can_check_tx_pend(0, &tx_pend) == FAILURE) {
464                                 return ERR_CCT_HW_OBJ;
465                         }
466                 }
467                 timeout = 0;
468                 while (tx_pend) {
469                         if (rpp_can_check_tx_pend(0, &tx_pend) == FAILURE) {
470                                 return ERR_CCT_HW_OBJ;
471                         }
472                         (*time)++;
473                         if (++timeout > CCT_TIMEOUT) {
474                                 return ERR_CCT_CLEAR_TX_PEND_TO;
475                         }
476                 }
477                 if ((ret_val = cmd_can_test_recv(can_tx_msg, CCT_TIMEOUT)) != SUCCESS) {
478                         return ERR_CCT_RCV|ret_val;
479                 }
480         }
481
482         return SUCCESS;
483 }
484
485 /**
486  * Test the RX indicator.
487  *
488  * This function verifies that the rpp_can_check_rx_ind() function is working properly and
489  * that the CAN driver behaves as expected.
490  *
491  * The RX indicator should be set whenever new CAN message is received and remains set, until
492  * rpp_can_read() is called in order to retrieve the message.
493  *
494  * @param[in] rpp_can_pdu A message which used to testing.
495  * @param[out] time Measured time between posting the transmission request and setting the RX flag.
496  * @return SUCCESS if the test passed, error code otherwise.
497  */
498 int cmd_can_test_rx_indicator(const struct rpp_can_pdu* can_tx_msg, uint32_t* time)
499 {
500         *time = 0;
501         volatile uint32_t timeout = 0;
502         boolean_t rx_ind = FALSE;
503         int ret_val = 0;
504         struct rpp_can_pdu can_rx_pdu;
505
506         if ((ret_val = cmd_can_test_send(can_tx_msg)) != SUCCESS) {
507                 return ret_val;
508         }
509         else {
510                 /* Wait for the flag to be set */
511                 while (!rx_ind) {
512                         if (rpp_can_check_rx_ind(0, &rx_ind) == FAILURE) {
513                                 return ERR_CCT_HW_OBJ;
514                         }
515                         (*time)++;
516                         if (++timeout > CCT_TIMEOUT) {
517                                 return ERR_CCT_SET_TX_PEND_TO;
518                         }
519                 }
520
521                 if ((ret_val = rpp_can_read(0, &can_rx_pdu)) != SUCCESS) {
522                         switch(ret_val) {
523                         case -RPP_ENODATA:
524                                 return ERR_CCT_RX_IND_SET_NO_MSG_REC;
525                         case -RPP_EINVAL:
526                                 return ERR_CCT_HW_OBJ;
527                         default:
528                                 return ERR_CCT_UNEXPECTED_RETVAL;
529                         }
530                 }
531                 else {
532                         if (!cmd_can_messages_equal(&can_rx_pdu, can_tx_msg)) {
533                                 return ERR_CCT_MSG_MISMATCH;
534                         }
535                         else {
536                                 if (rpp_can_check_rx_ind(0, &rx_ind) == FAILURE) {
537                                         return ERR_CCT_HW_OBJ;
538                                 }
539                                 if (rx_ind == TRUE) {
540                                         return ERR_CCT_RX_IND_NOT_CLEARED;
541                                 }
542                         }
543                 }
544         }
545
546         return SUCCESS;
547 }
548
549 /**
550  * Test CAN functions from RPP library.
551  *
552  * This is a complex test command for verification of automatic CAN bit timing
553  * calculation for baudrates 125k, 250k and 500kbits/sec and for checking RPP
554  * CAN functions:
555  * - rpp_can_init()
556  * - rpp_can_write()
557  * - rpp_can_read()
558  * - rpp_can_check_rx_ind()
559  * - rpp_can_check_tx_pend()
560  *
561  * @return always SUCCESS
562  */
563 int cmd_do_can_test_functions(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
564 {
565         struct rpp_can_pdu can_tx_msg1 = {
566                         .id = 0x1,
567                         .dlc = 8,
568                         .data = {'H', 'E', 'L', 'L', 'O', '0', '0', '1'}
569         };
570
571         struct rpp_can_pdu can_tx_msg2 = {
572                         .id = 0x1,
573                         .dlc = 8,
574                         .data = {'H', 'E', 'L', 'L', 'O', '0', '0', '2'}
575         };
576
577         rpp_sci_printf("This is a test for RPP CAN library functions:\n");
578         /*
579          * Simple send and receive a message with CAN bit time parameters for 500 kb/sec, picked
580          * from HALCoGen, which are proven to be functional.
581          */
582         rpp_sci_printf("Test of simple message transmission and reception.\n");
583         int ret_val = 0;
584         rpp_sci_printf("\tCAN bus Initialization: ");
585         if ((ret_val = cmd_can_test_init(RPP_CAN_TIMING_CALC_MANUAL, 500000)) != SUCCESS) {
586                 rpp_sci_printf("failed: error: 0x%X.\n", ret_val);
587         }
588         else {
589                 rpp_sci_printf("OK\n");
590                 rpp_sci_printf("\tTransmission and reception...");
591                 if ((ret_val = cmd_can_test_simple_send_recv(&can_tx_msg1)) != SUCCESS) {
592                         rpp_sci_printf("failed: error: 0x%X.\n", ret_val);
593                 }
594                 else {
595                         rpp_sci_printf("OK\n");
596                 }
597         }
598         rpp_sci_printf("---\n");
599         /* Baudrate calculation testing
600          *
601          * Based on EATON requirements for baudrates: 125k, 250k, 500k
602          *  - calculate bit timing parameters,
603          *  - initialize the CAN bus,
604          *  - send a message
605          *  - receive a message
606          *  - test if the received message is OK.
607          */
608         uint32_t baudrates[] = {125000, 250000, 500000};
609         uint8_t num_baudrates = 3;
610         uint8_t i;
611         rpp_sci_printf("Test of automatic CAN bit timing calculation.\n");
612
613         for (i = 0; i < num_baudrates; i++) {
614                 rpp_sci_printf("\tBaudrate: %d: ", baudrates[i]);
615                 if ((ret_val = cmd_can_test_baudrate_calc(baudrates[i], &can_tx_msg1)) != SUCCESS) {
616                         rpp_sci_printf("failed: error: 0x%X.\n", ret_val);
617                 }
618                 else {
619                         rpp_sci_printf("OK\n");
620                 }
621         }
622         rpp_sci_printf("---\n");
623
624         /*
625          * Test the behavioral when a new message replaces the actually pending message.
626          *
627          *  - Send a request for message A transmission,
628          *  - right after that, send a request for another message B transmission,
629          *  - receive a message, which should be the message B.
630          */
631         rpp_sci_printf("Test of transmission request rewritting.\n");
632         rpp_sci_printf("\tCAN bus Initialization: ");
633         if ((ret_val = cmd_can_test_init(RPP_CAN_TIMING_CALC_MANUAL, 500000)) != SUCCESS) {
634                 rpp_sci_printf("failed: error: 0x%X.\n", ret_val);
635         }
636         else {
637                 rpp_sci_printf("OK\n");
638                 rpp_sci_printf("\tTX request rewritting...");
639                 if ((ret_val = cmd_can_test_tx_request_replace(&can_tx_msg1, &can_tx_msg2)) != SUCCESS) {
640                         rpp_sci_printf("failed: error: 0x%X.\n", ret_val);
641                 }
642                 else {
643                         rpp_sci_printf("OK\n");
644                 }
645         }
646         rpp_sci_printf("---\n");
647
648         /*
649          * Test the tx_pending flag detection
650          *  - Send a request for a message transmission request,
651          *  - Wait while the flag is reset, which means that the message has been received
652          *    by another node, while measuring the time between the sending the request and
653          *    resetting the flag.
654          *  - Read the message to check that it has been already received.
655          *
656          */
657         rpp_sci_printf("Test of TX request pending flag detection.\n");
658         rpp_sci_printf("\tCAN bus Initialization: ");
659         if ((ret_val = cmd_can_test_init(RPP_CAN_TIMING_CALC_MANUAL, 500000)) != SUCCESS) {
660                 rpp_sci_printf("failed: error: 0x%X.\n", ret_val);
661         }
662         else {
663                 rpp_sci_printf("OK\n");
664                 uint32_t time = 0;
665                 rpp_sci_printf("\tTX request pending flag behavioral: ");
666                 if ((ret_val = cmd_can_test_tx_request_flag(&can_tx_msg1, &time)) != SUCCESS) {
667                         rpp_sci_printf("failed: error: 0x%X.\n", ret_val);
668                 }
669                 else {
670                         rpp_sci_printf("OK, time: %d cycles.\n", time);
671                 }
672         }
673         rpp_sci_printf("---\n");
674
675         /*
676          * Test the rx_ind flag
677          *  - Send a message
678          *  - Wait for setting the rx_ind flag
679          *  - Try to read the message.
680          */
681         rpp_sci_printf("Test of RX indicator.\n");
682         rpp_sci_printf("\tCAN bus Initialization: ");
683         if ((ret_val = cmd_can_test_init(RPP_CAN_TIMING_CALC_MANUAL, 500000)) != SUCCESS) {
684                 rpp_sci_printf("failed: error: 0x%X.\n", ret_val);
685         }
686         else {
687                 rpp_sci_printf("OK\n");
688                 uint32_t time = 0;
689                 rpp_sci_printf("\tRX indicator behavioral: ");
690                 if ((ret_val = cmd_can_test_rx_indicator(&can_tx_msg1, &time)) != SUCCESS) {
691                         rpp_sci_printf("failed: error: 0x%X.\n", ret_val);
692                 }
693                 else {
694                         rpp_sci_printf("OK, time: %d cycles.\n", time);
695                 }
696         }
697         rpp_sci_printf("---\n");
698
699         /*
700          * Reset the CAN bus to a determined state
701          * Baudrate: 500kb
702          */
703         rpp_sci_printf("Reset the CAN bus.\n");
704         rpp_sci_printf("\tCAN bus Initialization: ");
705         if ((ret_val = cmd_can_test_init(RPP_CAN_TIMING_CALC_MANUAL, 500000)) != SUCCESS) {
706                 rpp_sci_printf("failed: error: 0x%X.\n", ret_val);
707         }
708         else {
709                 rpp_sci_printf("OK\n");
710         }
711         return SUCCESS;
712 }
713
714 int cmd_do_can_init(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
715 {
716     can_inited = (rpp_can_init(&can_config) == SUCCESS ? 1 : 0);
717     return (can_inited ? 0 : 1);
718 }
719
720
721 int cmd_do_can_send(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
722 {
723         uint32_t controller_id;
724         uint32_t i, l = 0;
725         int ret;
726         struct rpp_can_pdu pdu;
727         char *p;
728
729         if (!can_inited)
730         {
731                 rpp_sci_printf("CAN is not initialized\n");
732                 return -CMDERR_NODEV;
733         }
734
735         p = param[1];
736         ret = sscanf(p, "%i %i%n", &controller_id, &pdu.id, &l);
737         if (ret < 2)
738         {
739                 rpp_sci_printf("Cannot parse parameter %d\n", ret+1);
740                 return -CMDERR_BADPAR;
741         }
742         p += l;
743
744         i = 0;
745         do {
746                 uint16_t data;
747                 ret = sscanf(p, "%2hx%n", &data, &l);
748                 if (ret < 1) break;
749                 pdu.data[i] = data & 0xff;
750                 i++;
751                 p += l;
752         } while (1);
753
754         pdu.dlc = i;
755
756
757         if (rpp_can_write(controller_id-1, &pdu) == SUCCESS)
758         {
759                 rpp_sci_printf("Sent: can%u\t%X\t[%u]\t", controller_id, pdu.id, pdu.dlc);
760                 for (i=0; i<pdu.dlc; i++)
761                 {
762                         rpp_sci_printf("%X ", pdu.data[i]);
763                 }
764         }
765         else
766         {
767                 rpp_sci_printf("Error: rpp_can_write");
768         }
769         rpp_sci_printf("\n");
770
771
772         return 0;
773 }
774
775
776 int cmd_do_can_dump(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
777 {
778         uint32_t controller_id = 0;
779         bool rx_ind;
780         struct rpp_can_pdu pdu;
781
782         uint32_t i;
783
784         if (!can_inited)
785         {
786                 rpp_sci_printf("CAN is not initialized\n");
787                 return -CMDERR_NODEV;
788         }
789
790         if (!(sscanf(param[1], "%u", &controller_id) == 1))
791         {
792                 rpp_sci_printf("Unable to parse controller ID\n");
793                 return 1;
794         }
795
796         rpp_can_init(&can_config);
797
798         while(cmd_io->getc(cmd_io) < 0)
799         {
800                 rpp_can_check_rx_ind(controller_id-1, &rx_ind);
801                 if (rx_ind)
802                 {
803                         if (rpp_can_read(controller_id-1, &pdu) == SUCCESS)
804                         {
805                                 if (pdu.id & CAN_EFF_FLAG)
806                                 {
807                                         rpp_sci_printf("can%u  %08X  [%u]  ", controller_id & (~CAN_EFF_FLAG), pdu.id, pdu.dlc);
808                                 }
809                                 else
810                                 {
811                                         rpp_sci_printf("can%u  %03X  [%u]  ", controller_id, pdu.id, pdu.dlc);
812                                 }
813
814                                 for (i=0; i<pdu.dlc; i++)
815                                 {
816                                             rpp_sci_printf("%X ", pdu.data[i]);
817                                 }
818                                 rpp_sci_printf("\n");
819                         }
820                         else
821                         {
822                                 rpp_sci_printf("Error rpp_can_read\n");
823                         }
824                 }
825         }
826
827         return 0;
828 }
829
830
831 int cmd_do_can_change_baudrate(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
832 {
833         int opchar;
834         uint32_t controller_id, baudrate;
835
836         if ((opchar = cmd_opchar_check(cmd_io, des, param)) < 0)
837                 return opchar;
838
839         if (opchar == ':')
840         {
841                 if (!(sscanf(param[1], "%u:%u", &controller_id, &baudrate) == 2))
842                 {
843                         rpp_sci_printf("Unable to parse arguments\n");
844                         return 1;
845                 }
846
847                 if (controller_id < 1 || controller_id > 3)
848                         return -CMDERR_BADPAR;
849
850                 can_config.ctrl[controller_id-1].baudrate = baudrate;
851                 can_config.ctrl[controller_id-1].timing_config = NULL;
852                 can_config.ctrl[controller_id-1].timing_calc_method = RPP_CAN_TIMING_CALC_AUTO;
853         }
854         else
855         {
856                 if (!(sscanf(param[1], "%u", &controller_id) == 1))
857
858                 if (controller_id < 1 || controller_id > 3)
859                         return -CMDERR_BADPAR;
860
861                 cmd_opchar_replong(cmd_io, param, can_config.ctrl[controller_id-1].baudrate, 0, 10);
862         }
863
864         return 0;
865 }
866
867 int cmd_do_can_change_timing(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
868 {
869         int opchar;
870         uint32_t controller_id, brp, prop_seg, phase_seg1, phase_seg2, sjw;
871
872         if ((opchar = cmd_opchar_check(cmd_io, des, param)) < 0)
873                 return opchar;
874
875         if (opchar == ':')
876         {
877                 if (!(sscanf(param[1], "%u:%u %u %u %u %u", &controller_id, &brp, &prop_seg, &phase_seg1, &phase_seg2, &sjw) == 6))
878                 {
879                         rpp_sci_printf("Unable to parse arguments\n");
880                         return 1;
881                 }
882
883                 if (controller_id < 1 || controller_id > 3)
884                         return -CMDERR_BADPAR;
885
886                 can_config.ctrl[controller_id-1].baudrate = 0;
887                 can_config.ctrl[controller_id-1].timing_config = &can_timing[controller_id-1];
888                 can_config.ctrl[controller_id-1].timing_config->brp = brp;
889                 can_config.ctrl[controller_id-1].timing_config->phase_seg1 = phase_seg1;
890                 can_config.ctrl[controller_id-1].timing_config->phase_seg2 = phase_seg2;
891                 can_config.ctrl[controller_id-1].timing_config->prop_seg = prop_seg;
892                 can_config.ctrl[controller_id-1].timing_config->sjw = sjw;
893                 can_config.ctrl[controller_id-1].timing_calc_method = RPP_CAN_TIMING_CALC_MANUAL;
894         }
895         else
896         {
897                 if (!(sscanf(param[1], "%u", &controller_id) == 1))
898
899                 if (controller_id < 1 || controller_id > 3)
900                         return -CMDERR_BADPAR;
901
902                 if (can_config.ctrl[controller_id-1].timing_config != NULL) {
903                         rpp_sci_printf("brp: %u\r\nprop_seg: %u tQ\r\nphase_seg1: %u tQ\r\nphase_seg2: %u tQ\r\nsjw: %u tQ\r\n",
904                                         can_config.ctrl[controller_id-1].timing_config->brp,
905                                         can_config.ctrl[controller_id-1].timing_config->prop_seg,
906                                         can_config.ctrl[controller_id-1].timing_config->phase_seg1,
907                                         can_config.ctrl[controller_id-1].timing_config->phase_seg2,
908                                         can_config.ctrl[controller_id-1].timing_config->sjw
909                         );
910
911                 }
912                 else {
913                         rpp_sci_printf("CAN timing has not yet been manually specified.\r\n");
914                 }
915         }
916
917         return 0;
918 }
919
920
921
922
923 #endif  /* DOCGEN */
924
925 cmd_des_t const cmd_des_can_init={
926     0, 0,
927     "caninit", "Initialize CAN controllers",
928     "### Command syntax ###\n"
929     "\n"
930     "    caninit\n"
931     "\n"
932     "### Description ###\n"
933     "\n"
934     "This command (re-)initializes all CAN controllers using current\n"
935     "CAN configuration. This configuration can be changed using\n"
936     "canbaudrate command.\n"
937     "\n"
938     "In the default configuration the baudrate of all CAN controllers i set\n"
939     "to 500 kbit/s.\n"
940     "\n"
941     "### Example ###\n"
942     "  --> caninit\n",
943     CMD_HANDLER(cmd_do_can_init), (void *)&cmd_list_can
944 };
945
946 cmd_des_t const cmd_des_can_baudrate={
947     0, CDESM_OPCHR|CDESM_RW,
948     "canbaudrate#", "Change baudrate of CAN controller",
949     "### Command syntax ###\n"
950     "\n"
951     "    canbaudrate<CONTROLLER>?\n"
952     "    canbaudrate<CONTROLLER>:<BAUDRATE>\n"
953     "\n"
954     "where `<CONTROLLER>` is number in range 1-3 and BAUDRATE is number in\n"
955     "range 1000-10000000 specifying the baudrate in bits per second.\n"
956     "\n"
957     "### Description ###\n"
958     "\n"
959     "This command is used to set or show the baudrate of a CAN controller.\n"
960     "The baudrate shown is the one which will be used by next invocation of\n"
961     "the caninit command.\n"
962     "The baudrate specified by the command is used to automatic calculation of\n"
963     "the CAN controller timing. If you want to specify the timing manually,\n"
964     "please use the command cantiming.\n"
965     "The automatic calculation might not work properly for some baudrates. In\n"
966     "this case you should calculate the timing manually and specify it by the\n"
967     "command cantiming."
968     "\n"
969     "### Examples ###\n"
970     "\n"
971     "    --> canbaudrate2?\n"
972     "    canbaudrate2=500000\n"
973     "\n"
974     "    --> canbaudrate2:100000\n",
975     CMD_HANDLER(cmd_do_can_change_baudrate), (void *)&cmd_list_can
976 };
977
978 cmd_des_t const cmd_des_can_timing={
979     0, CDESM_OPCHR|CDESM_RW,
980     "cantiming#", "Change timing of CAN controller manually",
981     "### Command syntax ###\n"
982     "\n"
983     "    cantiming<CONTROLLER>?\n"
984     "    cantiming<CONTROLLER>:<BRP> <PROP_SEG> <PHASE_SEG1> <PHASE_SEG2> <SJW>\n"
985     "\n"
986     "where:"
987     " - `<CONTROLLER>` is number in range 1-3\n"
988     " - `<BRP>` (baudrate prescaler) is number in range 1-65\n"
989     " - `<PROP_SEG>` (length of propagation segment in tQ) is a number in range 1-8\n"
990     " - `<PHASE_SEG1>` (phase buffer segment 1 in tQ) is a number in range 1-8\n"
991     " - `<PHASE_SEG2>` (phase buffer segment 2 in tQ) is a number in range 1-8\n"
992     " - `<SJW>` (synchronization jump width in tQ) is a number in range 1-4\n"
993     "\n"
994     "### Description ###\n"
995     "\n"
996     "This command is used to set or show the timing of a CAN controller.\n"
997     "The timing shown is the one which will be used by next invocation of\n"
998     "the caninit command.\n"
999     "The timing configured by this command defines manually the baudrate of\n"
1000     "the CAN controller. If you want to calculate the timing automaticaly from\n"
1001     "a baudrate, please use the command canbaudrate.\n"
1002     "\n"
1003     "### Examples ###\n"
1004     "\n"
1005     "    --> cantiming2?\n"
1006     "    brp: 17\n"
1007     "    prop_seg: 4 tQ\n"
1008     "    phase_seg1: 5 tQ\n"
1009     "    phase_seg2: 5 tQ\n"
1010     "    sjw: 4 tQ\n"
1011     "    sample_pt: 875 ns\n"
1012     "    error: 0\n"
1013     "    tQ: 125 ns\n"
1014     "\n"
1015     "    --> cantiming2:5 8 7 4 1\n",
1016     CMD_HANDLER(cmd_do_can_change_timing), (void *)&cmd_list_can
1017 };
1018
1019
1020 cmd_des_t const cmd_des_can_send={
1021     0, 0,
1022     "cansend", "Test sending message over CAN",
1023     "### Command syntax ###\n"
1024     "\n"
1025     "    cansend <CONTROLLER> <ID> <DATA>\n"
1026     "\n"
1027     "where `<CONTROLLER>` is number in range 1-3, `<ID>` is a valid CAN ID\n"
1028     "and `<DATA>` is 0-8 bytes of data in hexadecimal representation.\n"
1029     "There may be any number of spaces between the data bytes.\n"
1030     "`<ID>` may be given in octal, decimal or hexadecimal base.\n"
1031     "\n"
1032     "### Description ###\n"
1033     "\n"
1034     "This command sends a CAN frame using specified CAN controller.\n"
1035     "\n"
1036     "The caninit command must be called before using this command.\n"
1037     "\n"
1038     "### Example ###\n"
1039     "    --> cansend 2 0x123 DEAD BEEF\n"
1040     "    Sent: can2      123     [4]     DE AD BE EF\n",
1041     CMD_HANDLER(cmd_do_can_send), (void *)&cmd_list_can
1042 };
1043
1044
1045 cmd_des_t const cmd_des_can_dump={
1046     0, 0,
1047     "candump", "Dump all messages received over CAN",
1048     "### Command syntax ###\n"
1049     "\n"
1050     "    candump <CONTROLLER>\n"
1051     "\n"
1052     "where `<CONTROLLER>` is a number in range 1-3.\n"
1053     "\n"
1054     "### Description ###\n"
1055     "\n"
1056     "This command prints out all CAN messages received via the specified\n"
1057     "controller.\n"
1058     "\n"
1059     "IDs are zero-filled to length 3 if a message in the standard frame\n"
1060     "format is received and to 8 for extended frame format messages.\n"
1061     "\n"
1062     "caninit must be called before using this command.\n"
1063     "\n"
1064     "### Example ###\n"
1065     "\n"
1066     "    --> candump 2\n"
1067     "can2  0000FADE  [2]  12 34\n",
1068     CMD_HANDLER(cmd_do_can_dump), (void *)&cmd_list_can
1069 };
1070
1071 cmd_des_t const cmd_des_can_test={
1072     0, 0,
1073     "canrpptest", "Test the CAN functions from the RPP library",
1074     "### Command syntax ###\n"
1075     "\n"
1076     "    canrpptest\n"
1077     "\n"
1078     "### Description ###\n"
1079     "\n"
1080     "This command tests all CAN functions in the RPP library. It does those\n"
1081     "particular tests:\n"
1082     "\n"
1083     "1) Test of the rpp_can_init(), rpp_can_write() and rpp_can_read() functions.\n"
1084     "   At the beginning, the CAN bus is initialized with manually specified and\n"
1085     "   verified CAN bit timing parameters. Then a message is sent on the CAN1 and is\n"
1086     "   received on the CAN2. Finally the received message is compared with the sent one.\n"
1087     "   If the transmissions fails, reception exceeds a timeout or the sent and\n"
1088     "   received messages do not match, the command prints the appropriate error\n"
1089     "   code."
1090     "2) Test of the CAN bit timing parameters calculation.\n"
1091     "   This test subsequently initializes the CAN bus to a baudrates 125k, 250k\n"
1092     "   and 500k. For each one of them a message is sent on CAN1 and received on CAN2.\n"
1093     "   Finally the received message is compared with the sent one like in a test (1).\n"
1094     "   If the initialization, transmission, reception or comparison fails or\n"
1095     "   if the reception timeout is reached, an appropriate error code is printed.\n"
1096     "3) Test of the behavior of transmission request overwriting.\n"
1097     "   The CAN bus is initialized like in the test (1). A message A transmission\n"
1098     "   request is posted on CAN1 by calling rpp_can_write() and right after that\n"
1099     "   another message B transmission request is posted on CAN1 by another call of\n"
1100     "   the rpp_can_write(). A message B is received on CAN2, because the second request\n"
1101     "   came so quickly, that it overwrote the first one. The sent and received messages\n"
1102     "   are compared to verify that the transmission was correct.\n"
1103     "   If the initialization, transmission, reception or comparison fails or\n"
1104     "   if the reception timeout is reached, an appropriate error code is printed.\n"
1105     "4) Test of the TX request pending flag detection.\n"
1106     "   The CAN bus is initialized like in the test (1). A message is transmitted\n"
1107     "   on the CAN1 and the test waits for the TX pending flag to be set, which\n"
1108     "   signalizes that there is a message transmission request pending. After the\n"
1109     "   flag has been set, the test waits for its clearance, which means that the\n"
1110     "   message has been sent. The test measures, how many flag test cycles passed,\n"
1111     "   until the flag has been cleared. This value is then presented as a time.\n"
1112     "   At the end, the message is received on the CAN2 and is compared with the\n"
1113     "   sent message for verification.\n"
1114     "   If the initialization, transmission, reception or comparison fails or if\n"
1115     "   timeout is reached while waiting for the flag set/clear or receive timeout\n"
1116     "   is reached, an appropriate error code is printed.\n"
1117     "5) Test of the message received (RX) indicator.\n"
1118     "   The CAN bus is initialized like in the test (1). A message is transmitted\n"
1119     "   on the CAN1. The test then waits for the RX indicator to be set, which\n"
1120     "   indicates that a message has been received. The message is picked up by\n"
1121     "   the rpp_can_read(). This should clear the indicator, which is tested. Finally\n"
1122     "   the received messages is compared with the sent one.\n"
1123     "   If the initialization, transmission, reception, message comparison or indicator\n"
1124     "   test fails or if timeout is reached while waiting for the flag set, the\n"
1125     "   appropriate error code is printed.\n"
1126     "\n"
1127     "At the end the CAN bus is reset and left with the configuration from test (1).\n"
1128     "Those tests assumes the CAN1 and CAN2 to be connected in HW loopback.\n"
1129     "Any previous configuration is canceled, but is not deleted, so any following\n"
1130     "call of caninit command will restore the CAN bus to previous configuration.\n"
1131     "\n"
1132     "For error codes description refer please the API documentation for the rpp-test-sw.\n"
1133     "\n"
1134     "### Example ###\n"
1135     "\n"
1136     "    --> canrpptest\n"
1137     "This is a test for RPP CAN library functions:"
1138     "Test of simple message transmission and reception."
1139     "   CAN bus Initialization...OK"
1140     "   Transmission and reception...OK"
1141     "---"
1142     "Test od automatic CAN bit timing calculation."
1143     "   Baudrate: 125000: OK"
1144     "   Baudrate: 250000: OK"
1145     "   Baudrate: 500000: OK"
1146     "---"
1147     "Test of transmission request rewritting."
1148     "   CAN bus Initialization...OK"
1149     "   TX request rewritting...OK"
1150     "---"
1151     "Test of TX request pending flag detection."
1152     "   CAN bus Initialization...OK"
1153     "   TX request pending flag behavioral: OK, time: 256 cycles."
1154     "---"
1155     "Test of RX indicator."
1156     "   CAN bus Initialization...OK"
1157     "   RX indicator behavioral:"
1158     "OK, time: 0 cycles."
1159     "---"
1160     "Reset the CAN bus."
1161     "   CAN bus Initialization...OK",
1162     CMD_HANDLER(cmd_do_can_test_functions), (void *)&cmd_list_can
1163 };
1164
1165
1166
1167
1168 cmd_des_t const *cmd_list_can[]={
1169   &cmd_des_can_init,
1170   &cmd_des_can_baudrate,
1171   &cmd_des_can_timing,
1172   &cmd_des_can_send,
1173   &cmd_des_can_dump,
1174   &cmd_des_can_test,
1175   NULL
1176 };