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