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