]> rtime.felk.cvut.cz Git - pes-rpp/rpp-test-sw.git/blob - rpp-test-sw/commands/cmd_can.c
CAN baudrate setting fixed, manual CAN timing parameters specification implemented
[pes-rpp/rpp-test-sw.git] / rpp-test-sw / commands / cmd_can.c
1 /*
2  * Copyright (C) 2012-2013 Czech Technical University in Prague
3  *
4  * Created on: 28.2.2013
5  *
6  * Authors:
7  *     - Michal Horn
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
21  *
22  * File : cmd_can.c
23  *
24  * Abstract:
25  *      This file contains commands for CAN test
26  *
27  */
28
29 #include "cmd_can.h"
30
31 #ifndef DOCGEN
32
33 #include "rpp/rpp.h"
34 #include "sys/sys.h"
35 #include <stdio.h>
36
37 /** Semaphore used for blocking task until message is received */
38 extern xSemaphoreHandle canMsgReceived;
39 /** Semaphore used for blocking task until message is sent */
40 extern xSemaphoreHandle canMsgSent;
41 /** Pointer to Destination CAN registers */
42 extern canBASE_t* canDst;
43 /** Pointer to Source CAN registers */
44 extern canBASE_t* canSrc;
45 /** Can message box for received messages */
46 extern uint32_t canMsgBox;
47 /** Error counter for errors in sending */
48 extern uint32_t canSendError;
49 /** Error counter for errors in receiving */
50 extern uint32_t canRecError;
51
52 static void canPrintStatus(int can_num, uint32_t es)
53 {
54         uint32_t errorLevel = es & 0xE0U;
55         char* levText;
56
57         switch (errorLevel) {
58         case canLEVEL_BUS_OFF:
59                 levText = "Bus-Off";
60                 break;
61         case canLEVEL_PASSIVE:
62                 levText = "Error Passive";
63                 break;
64         case canLEVEL_WARNING:
65                 levText = "Warning";
66                 break;
67         case canLEVEL_ACTIVE:
68                 levText = "Bus-On";
69                 break;
70         default:
71                 levText = "Unknown";
72         }
73
74         rpp_sci_printf("CAN%d status: %s, ES: %#x\n", can_num, levText, es);
75 }
76
77 uint32_t canCheckForError(int can_num, uint32_t es)
78 {
79         uint32_t errorLevel = es & 0xE0U;
80
81         if (errorLevel != 0) {
82                 canPrintStatus(can_num, es);
83         }
84
85         return errorLevel;
86 }
87
88 /**
89  *      @brief  Command for external CAN loopback testing.
90  *
91  * @param[in]   cmd_io  Pointer to IO stack
92  * @param[in]   des             Pointer to command descriptor
93  * @param[in]   param   Parameters of command
94  * @return      0 when OK or error code
95  */
96 int cmd_do_test_can_loopback(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
97 {
98         uint32_t can_src, can_dst;
99         canBASE_t *canBases[3] = {canREG1, canREG2, canREG3};
100         uint32_t canMailBoxes[3] = {canMESSAGE_BOX1, canMESSAGE_BOX2, canMESSAGE_BOX3};
101         uint32_t txTimeOutCnt = 0;
102         uint32_t rxTimeOutCnt = 0;
103         uint32_t messagesTransmitted = 0;
104         uint32_t messagesReceived = 0;
105         uint32_t i;
106         uint8_t tx_data[8] = {'T', 'E', 'S', 'T', ' ', 'C', 'A', 'N'};
107         uint8_t rx_data[8] = {0, 0, 0, 0, 0, 0, 0, 0 };
108         char *p=param[1];
109         char spareParams;
110
111
112         dmmREG->PC4 = (1<<(13)); // set CAN_NSTB
113         vTaskDelay(50/portTICK_RATE_MS);
114         dmmREG->PC5 = (1<<(15)); // clr CAN_EN
115         vTaskDelay(50/portTICK_RATE_MS);
116         dmmREG->PC5 = (1<<(13)); // clr CAN_NSTB
117         vTaskDelay(50/portTICK_RATE_MS);
118         dmmREG->PC4 = (1<<(13)); // set CAN_NSTB
119         vTaskDelay(50/portTICK_RATE_MS);
120         dmmREG->PC4 = (1<<(15)); // set CAN_EN
121         vTaskDelay(50/portTICK_RATE_MS);
122
123
124         if (sscanf(p, "%d %d %1s", &can_src, &can_dst, &spareParams) != 2) {
125                 return -CMDERR_BADPAR;
126         }
127
128         if (can_src == can_dst) {
129                 rpp_sci_printf("ERROR: Destination equals source!\n");
130                 return 1;
131         }
132         if (can_src < 1 | can_dst > 3) {
133                 rpp_sci_printf("Parameter out of range <1;3>!\n");
134                 return 1;
135         }
136         canSrc = canBases[can_src-1];
137         canDst = canBases[can_dst-1];
138         canMsgBox = canMailBoxes[can_src-1];
139         canMsgReceived = xSemaphoreCreateCounting(1, 0);
140         canMsgSent = xSemaphoreCreateCounting(1, 0);
141
142         rpp_sci_printf("Testing CAN loopback\r\n");
143         canREG1->CTL |= 1|(1<<9);
144         canREG2->CTL |= 1|(1<<9);
145         canREG3->CTL |= 1|(1<<9);
146         canRecError = 0;
147         canDst->CTL |= 1<<15;           // Reset
148         while (canDst->CTL & (1<<15)) ; // Wait for reset
149         canSendError = 0;
150         canSrc->CTL |= 1<<15;
151         while (canSrc->CTL & (1<<15)) ;
152         canInit();
153         canDst->CTL |= 1<<9;
154         canSrc->CTL |= 1<<9;
155         vTaskDelay(50/portTICK_RATE_MS);
156
157         i = canSrc->ES; // Reset error flag
158         i = canDst->ES; // Reset error flag
159         canEnableErrorNotification(canDst);
160         canEnableErrorNotification(canSrc);
161
162         for (i = 0; i < 100; i++) {             // Send 100 times the message
163                 if (canCheckForError(can_src, canSendError) != canLEVEL_ACTIVE) {
164                         break;
165                 }
166                 canTransmit(canSrc, canMsgBox, tx_data);
167                 if (xSemaphoreTake(canMsgSent, 100/portTICK_RATE_MS) == pdFALSE) {
168                         txTimeOutCnt++;
169                 }
170                 else {
171                         if (canCheckForError(can_src, canSendError) & canLEVEL_BUS_OFF) {
172                                 break;
173                         }
174                         else {
175                                 messagesTransmitted++;
176                                 if (xSemaphoreTake(canMsgReceived, 100/portTICK_RATE_MS) == pdFALSE) {
177                                         rxTimeOutCnt++;
178                                 }
179                                 else {
180                                         if (canGetData(canDst, canMsgBox, rx_data))
181                                                 messagesReceived++;
182
183                                         if (canCheckForError(can_dst, canRecError) & canLEVEL_BUS_OFF) {
184                                                 break;
185                                         }
186                                 }
187                         }
188                 }
189
190                 rpp_sci_printf("Messages transmitted: %d/100\r\n", messagesTransmitted);
191                 rpp_sci_printf("Messages received: %d/100\r\n", messagesReceived);
192                 rpp_sci_printf("TX timeouts: %d\r\n", txTimeOutCnt);
193                 rpp_sci_printf("RX timeouts: %d\r\n", rxTimeOutCnt);
194                 rpp_sci_printf("Src TX error counter: %d\r\n", canSrc->EERC & 0xFFU);
195                 rpp_sci_printf("Src RX error counter: %d\r\n", (canSrc->EERC & 0xFF00U) >> 8);
196                 rpp_sci_printf("Dst TX error counter: %d\r\n", canDst->EERC & 0xFFU);
197                 rpp_sci_printf("Dst RX error counter: %d\r\n", (canDst->EERC & 0xFF00U) >> 8);
198                 canPrintStatus(can_src, canSendError);
199                 canPrintStatus(can_dst, canRecError);
200
201                 canDisableErrorNotification(canDst);
202                 canDisableErrorNotification(canSrc);
203                 vSemaphoreDelete(canMsgReceived);
204                 vSemaphoreDelete(canMsgSent);
205                 return 0;
206         }
207         return 0;
208 }
209
210
211 static int can_inited = 0;
212
213 /* Default CAN timing set to 500kb */
214 static struct rpp_can_timing_cfg can_timing[] = {
215         {
216                 .brp = 10,
217                 .error = 0,
218                 .phase_seg1 = 5,
219                 .phase_seg2 = 2,
220                 .prop_seg = 8,
221                 .sampl_pt = 875,
222                 .sjw = 1,
223                 .tq = 125
224         },
225         {
226                 .brp = 10,
227                 .error = 0,
228                 .phase_seg1 = 5,
229                 .phase_seg2 = 2,
230                 .prop_seg = 8,
231                 .sampl_pt = 875,
232                 .sjw = 1,
233                 .tq = 125
234         },
235         {
236                 .brp = 10,
237                 .error = 0,
238                 .phase_seg1 = 5,
239                 .phase_seg2 = 2,
240                 .prop_seg = 8,
241                 .sampl_pt = 875,
242                 .sjw = 1,
243                 .tq = 125
244         },
245 };
246
247
248 static struct rpp_can_ctrl_config ctrl_config[] = {
249         {
250                 .baudrate = 500000,
251                 .clk = 80000000,
252                 .prop_delay = 700,
253                 .timing_calc_method = RPP_CAN_TIMING_CALC_AUTO,
254                 .timing_config = NULL
255         },
256         {
257                 .baudrate = 500000,
258                 .clk = 80000000,
259                 .prop_delay = 700,
260                 .timing_calc_method = RPP_CAN_TIMING_CALC_AUTO,
261                 .timing_config = NULL
262         },
263         {
264                 .baudrate = 500000,
265                 .clk = 80000000,
266                 .prop_delay = 700,
267                 .timing_calc_method = RPP_CAN_TIMING_CALC_AUTO,
268                 .timing_config = NULL
269         }
270 };
271
272 static struct rpp_can_tx_config tx_config[] = {
273         {
274                 .type = RPP_CAN_EXTENDED,
275                 .controller = 1,
276                 .msg_obj = 2,
277         },
278         {
279                 .type = RPP_CAN_EXTENDED,
280                 .controller = 2,
281                 .msg_obj = 2,
282         },
283         {
284                 .type = RPP_CAN_EXTENDED,
285                 .controller = 3,
286                 .msg_obj = 2,
287         }
288 };
289
290 static struct rpp_can_rx_config rx_config[] = {
291         {
292                 .type = RPP_CAN_MIXED,
293                 .controller = 1,
294                 .msg_obj = 1,
295                 .id = 1,
296                 .mask = 0,
297         },
298         {
299                 .type = RPP_CAN_MIXED,
300                 .controller = 2,
301                 .msg_obj = 1,
302                 .id = 1,
303                 .mask = 0,
304         },
305         {
306                 .type = RPP_CAN_MIXED,
307                 .controller = 3,
308                 .msg_obj = 1,
309                 .id = 1,
310                 .mask = 0,
311         }
312 };
313
314 static struct rpp_can_config can_config = {
315         .num_tx_obj = 3,
316         .num_rx_obj = 3,
317         .tx_config = tx_config,
318         .rx_config = rx_config,
319         .ctrl = ctrl_config,
320 };
321
322
323 int cmd_do_can_init(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
324 {
325     dmmREG->PC4 = (1<<(13)); // set CAN_NSTB
326     dmmREG->PC5 = (1<<(15)); // clr CAN_EN
327     dmmREG->PC5 = (1<<(13)); // clr CAN_NSTB
328     dmmREG->PC4 = (1<<(13)); // set CAN_NSTB
329     dmmREG->PC4 = (1<<(15)); // set CAN_EN
330
331
332
333     can_inited = (rpp_can_init(&can_config) == SUCCESS ? 1 : 0);
334     return (can_inited ? 0 : 1);
335 }
336
337
338 int cmd_do_can_send(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
339 {
340         uint32_t controller_id;
341         uint32_t i, l = 0;
342         int ret;
343         struct rpp_can_pdu pdu;
344         char *p;
345
346         if (!can_inited)
347         {
348                 rpp_sci_printf("CAN is not initialized\n");
349                 return -CMDERR_NODEV;
350         }
351
352         p = param[1];
353         ret = sscanf(p, "%i %i%n", &controller_id, &pdu.id, &l);
354         if (ret < 2)
355         {
356                 rpp_sci_printf("Cannot parse parameter %d\n", ret+1);
357                 return -CMDERR_BADPAR;
358         }
359         p += l;
360
361         i = 0;
362         do {
363                 uint16_t data;
364                 ret = sscanf(p, "%2hx%n", &data, &l);
365                 if (ret < 1) break;
366                 pdu.data[i] = data & 0xff;
367                 i++;
368                 p += l;
369         } while (1);
370
371         pdu.dlc = i;
372
373
374         if (rpp_can_write(controller_id-1, &pdu) == SUCCESS)
375         {
376                 rpp_sci_printf("Sent: can%u\t%X\t[%u]\t", controller_id, pdu.id, pdu.dlc);
377                 for (i=0; i<pdu.dlc; i++)
378                 {
379                         rpp_sci_printf("%X ", pdu.data[i]);
380                 }
381         }
382         else
383         {
384                 rpp_sci_printf("Error: rpp_can_write");
385         }
386         rpp_sci_printf("\n");
387
388
389         return 0;
390 }
391
392
393 int cmd_do_can_dump(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
394 {
395         uint32_t controller_id = 0;
396         bool rx_ind;
397         struct rpp_can_pdu pdu;
398
399         uint32_t i;
400
401         if (!can_inited)
402         {
403                 rpp_sci_printf("CAN is not initialized\n");
404                 return -CMDERR_NODEV;
405         }
406
407         if (!(sscanf(param[1], "%u", &controller_id) == 1))
408         {
409                 rpp_sci_printf("Unable to parse controller ID\n");
410                 return 1;
411         }
412
413         rpp_can_init(&can_config);
414
415         while(cmd_io->getc(cmd_io) < 0)
416         {
417                 rpp_can_check_rx_ind(controller_id-1, &rx_ind);
418                 if (rx_ind)
419                 {
420                         if (rpp_can_read(controller_id-1, &pdu) == SUCCESS)
421                         {
422                                 if (pdu.id & CAN_EFF_FLAG)
423                                 {
424                                         rpp_sci_printf("can%u  %08X  [%u]  ", controller_id & (~CAN_EFF_FLAG), pdu.id, pdu.dlc);
425                                 }
426                                 else
427                                 {
428                                         rpp_sci_printf("can%u  %03X  [%u]  ", controller_id, pdu.id, pdu.dlc);
429                                 }
430
431                                 for (i=0; i<pdu.dlc; i++)
432                                 {
433                                             rpp_sci_printf("%X ", pdu.data[i]);
434                                 }
435                                 rpp_sci_printf("\n");
436                         }
437                         else
438                         {
439                                 rpp_sci_printf("Error rpp_can_read\n");
440                         }
441                 }
442         }
443
444         return 0;
445 }
446
447
448 int cmd_do_can_change_baudrate(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
449 {
450         int opchar;
451         uint32_t controller_id, baudrate;
452
453         if ((opchar = cmd_opchar_check(cmd_io, des, param)) < 0)
454                 return opchar;
455
456         if (opchar == ':')
457         {
458                 if (!(sscanf(param[1], "%u:%u", &controller_id, &baudrate) == 2))
459                 {
460                         rpp_sci_printf("Unable to parse arguments\n");
461                         return 1;
462                 }
463
464                 if (controller_id < 1 || controller_id > 3)
465                         return -CMDERR_BADPAR;
466
467                 can_config.ctrl[controller_id-1].baudrate = baudrate;
468                 can_config.ctrl[controller_id-1].timing_config = NULL;
469                 can_config.ctrl[controller_id-1].timing_calc_method = RPP_CAN_TIMING_CALC_AUTO;
470         }
471         else
472         {
473                 if (!(sscanf(param[1], "%u", &controller_id) == 1))
474
475                 if (controller_id < 1 || controller_id > 3)
476                         return -CMDERR_BADPAR;
477
478                 cmd_opchar_replong(cmd_io, param, can_config.ctrl[controller_id-1].baudrate, 0, 10);
479         }
480
481         return 0;
482 }
483
484 int cmd_do_can_change_timing(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
485 {
486         int opchar;
487         uint32_t controller_id, brp, prop_seg, phase_seg1, phase_seg2, sjw;
488
489         if ((opchar = cmd_opchar_check(cmd_io, des, param)) < 0)
490                 return opchar;
491
492         if (opchar == ':')
493         {
494                 if (!(sscanf(param[1], "%u:%u %u %u %u %u", &controller_id, &brp, &prop_seg, &phase_seg1, &phase_seg2, &sjw) == 6))
495                 {
496                         rpp_sci_printf("Unable to parse arguments\n");
497                         return 1;
498                 }
499
500                 if (controller_id < 1 || controller_id > 3)
501                         return -CMDERR_BADPAR;
502
503                 can_config.ctrl[controller_id-1].baudrate = 0;
504                 can_config.ctrl[controller_id-1].timing_config = &can_timing[controller_id-1];
505                 can_config.ctrl[controller_id-1].timing_config->brp = brp;
506                 can_config.ctrl[controller_id-1].timing_config->phase_seg1 = phase_seg1;
507                 can_config.ctrl[controller_id-1].timing_config->phase_seg2 = phase_seg2;
508                 can_config.ctrl[controller_id-1].timing_config->prop_seg = prop_seg;
509                 can_config.ctrl[controller_id-1].timing_config->sjw = sjw;
510                 can_config.ctrl[controller_id-1].timing_calc_method = RPP_CAN_TIMING_CALC_MANUAL;
511         }
512         else
513         {
514                 if (!(sscanf(param[1], "%u", &controller_id) == 1))
515
516                 if (controller_id < 1 || controller_id > 3)
517                         return -CMDERR_BADPAR;
518
519                 if (can_config.ctrl[controller_id-1].timing_config != NULL) {
520                         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\nsample_pt: %u ns\r\nerror: %u\r\n tQ: %u ns\r\n",
521                                         can_config.ctrl[controller_id-1].timing_config->brp,
522                                         can_config.ctrl[controller_id-1].timing_config->prop_seg,
523                                         can_config.ctrl[controller_id-1].timing_config->phase_seg1,
524                                         can_config.ctrl[controller_id-1].timing_config->phase_seg2,
525                                         can_config.ctrl[controller_id-1].timing_config->sjw,
526                                         can_config.ctrl[controller_id-1].timing_config->sampl_pt,
527                                         can_config.ctrl[controller_id-1].timing_config->error,
528                                         can_config.ctrl[controller_id-1].timing_config->tq
529                         );
530
531                 }
532                 else {
533                         rpp_sci_printf("CAN timing has not yet been manualy specified.\r\n");
534                 }
535         }
536
537         return 0;
538 }
539
540
541
542
543 #endif  /* DOCGEN */
544
545 /** @brief command descriptor for test CAN loopback command */
546 cmd_des_t const cmd_des_test_can_loopback={
547     0, 0,
548     "cantest*", "Test CAN loopback between two CAN interfaces",
549     "### Command syntax ###\n"
550     "\n"
551     "    cantest<SRC> <DST>\n"
552     "\n"
553     "where `<SRC>` and `<DST>` are different numbers in range 1-3.\n"
554     "\n"
555     "### Description ###\n"
556     "\n"
557     "This command tests CAN communication by sending and receiving messages\n"
558     "through external loopback. At the beginning, the involved CAN\n"
559     "controller are initialized to the Bus-On state.\n"
560     "\n"
561     "The command sends 100 messages and measures the numbers of TX errors,\n"
562     "RX errors and detected timeouts. At the end, these statistics are\n"
563     "printed as well as the status of the involved CAN controllers.\n"
564     "\n"
565     "When an error is detected during the test, the status of faulty CAN\n"
566     "controller is printed immediately.\n"
567     "\n"
568     "### Example ###\n"
569     "\n"
570     "    --> cantest1 2\n"
571     "    Testing CAN loopback\n"
572     "    Messages transmitted: 100/100\n"
573     "    Messages received: 100/100\n"
574     "    TX timeouts: 0\n"
575     "    RX timeouts: 0\n"
576     "    Src TX error counter: 0\n"
577     "    Src RX error counter: 0\n"
578     "    Dst TX error counter: 0\n"
579     "    Dst RX error counter: 0\n"
580     "    CAN1 status: Bus-On, ES: 0x8\n"
581     "    CAN2 status: Bus-On, ES: 0x10\n",
582     CMD_HANDLER(cmd_do_test_can_loopback), (void *)&cmd_list_can
583 };
584
585
586 cmd_des_t const cmd_des_can_init={
587     0, 0,
588     "caninit", "Initialize CAN controllers",
589     "### Command syntax ###\n"
590     "\n"
591     "    caninit\n"
592     "\n"
593     "### Description ###\n"
594     "\n"
595     "This command (re-)initializes all CAN controllers using current\n"
596     "CAN configuration. This configuration can be changed using\n"
597     "canbaudrate command.\n"
598     "\n"
599     "In the default configuration the baudrate of all CAN controllers i set\n"
600     "to 500 kbit/s.\n"
601     "\n"
602     "### Example ###\n"
603     "  --> caninit\n",
604     CMD_HANDLER(cmd_do_can_init), (void *)&cmd_list_can
605 };
606
607 cmd_des_t const cmd_des_can_baudrate={
608     0, CDESM_OPCHR|CDESM_RW,
609     "canbaudrate#", "Change baudrate of CAN controller",
610     "### Command syntax ###\n"
611     "\n"
612     "    canbaudrate<CONTROLLER>?\n"
613     "    canbaudrate<CONTROLLER>:<BAUDRATE>\n"
614     "\n"
615     "where `<CONTROLLER>` is number in range 1-3 and BAUDRATE is number in\n"
616     "range 1000-10000000 specifying the baudrate in bits per second.\n"
617     "\n"
618     "### Description ###\n"
619     "\n"
620     "This command is used to set or show the baudrate of a CAN controller.\n"
621     "The baudrate shown is the one which will be used by next invocation of\n"
622     "the caninit command.\n"
623     "The baudrate specified by the command is used to automatic calculation of\n"
624     "the CAN controller timing. If you want to specify the timing manually,\n"
625     "please use the command cantiming.\n"
626     "The automatic calculation might not work properly for some baudrates. In\n"
627     "this case you should calculate the timing manually and specify it by the\n"
628     "command cantiming."
629     "\n"
630     "### Examples ###\n"
631     "\n"
632     "    --> canbaudrate2?\n"
633     "    canbaudrate2=500000\n"
634     "\n"
635     "    --> canbaudrate2:100000\n",
636     CMD_HANDLER(cmd_do_can_change_baudrate), (void *)&cmd_list_can
637 };
638
639 cmd_des_t const cmd_des_can_timing={
640     0, CDESM_OPCHR|CDESM_RW,
641     "cantiming#", "Change timing of CAN controller manually",
642     "### Command syntax ###\n"
643     "\n"
644     "    cantiming<CONTROLLER>?\n"
645     "    cantiming<CONTROLLER>:<BRP> <PROP_SEG> <PHASE_SEG1> <PHASE_SEG2> <SJW>\n"
646     "\n"
647     "where:"
648     " - `<CONTROLLER>` is number in range 1-3\n"
649     " - `<BRP>` (baudrate prescaler) is number in range 1-65\n"
650     " - `<PROP_SEG>` (length of propagation segment in tQ) is a number in range 1-8\n"
651     " - `<PHASE_SEG1>` (phase buffer segment 1 in tQ) is a number in range 1-8\n"
652     " - `<PHASE_SEG2>` (phase buffer segment 2 in tQ) is a number in range 1-8\n"
653     " - `<SJW>` (synchronization jump width in tQ) is a number in range 1-4\n"
654     "\n"
655     "### Description ###\n"
656     "\n"
657     "This command is used to set or show the timing of a CAN controller.\n"
658     "The timing shown is the one which will be used by next invocation of\n"
659     "the caninit command.\n"
660     "The timing configured by this command defines manually the baudrate of\n"
661     "the CAN controller. If you want to calculate the timing automaticaly from\n"
662     "a baudrate, please use the command canbaudrate.\n"
663     "\n"
664     "### Examples ###\n"
665     "\n"
666     "    --> cantiming2?\n"
667     "    brp: 17\n"
668     "    prop_seg: 4 tQ\n"
669     "    phase_seg1: 5 tQ\n"
670     "    phase_seg2: 5 tQ\n"
671     "    sjw: 4 tQ\n"
672     "    sample_pt: 875 ns\n"
673     "    error: 0\n"
674     "    tQ: 125 ns\n"
675     "\n"
676     "    --> cantiming2:5 8 7 4 1\n",
677     CMD_HANDLER(cmd_do_can_change_timing), (void *)&cmd_list_can
678 };
679
680
681 cmd_des_t const cmd_des_can_send={
682     0, 0,
683     "cansend", "Test sending message over CAN",
684     "### Command syntax ###\n"
685     "\n"
686     "    cansend <CONTROLLER> <ID> <DATA>\n"
687     "\n"
688     "where `<CONTROLLER>` is number in range 1-3, `<ID>` is a valid CAN ID\n"
689     "and `<DATA>` is 0-8 bytes of data in hexadecimal representation.\n"
690     "There may be any number of spaces between the data bytes.\n"
691     "`<ID>` may be given in octal, decimal or hexadecimal base.\n"
692     "\n"
693     "### Description ###\n"
694     "\n"
695     "This command sends a CAN frame using specified CAN controller.\n"
696     "\n"
697     "The caninit command must be called before using this command.\n"
698     "\n"
699     "### Example ###\n"
700     "    --> cansend 2 0x123 DEAD BEEF\n"
701     "    Sent: can2      123     [4]     DE AD BE EF\n",
702     CMD_HANDLER(cmd_do_can_send), (void *)&cmd_list_can
703 };
704
705
706 cmd_des_t const cmd_des_can_dump={
707     0, 0,
708     "candump", "Dump all messages received over CAN",
709     "### Command syntax ###\n"
710     "\n"
711     "    candump <CONTROLLER>\n"
712     "\n"
713     "where `<CONTROLLER>` is a number in range 1-3.\n"
714     "\n"
715     "### Description ###\n"
716     "\n"
717     "This command prints out all CAN messages received via the specified\n"
718     "controller.\n"
719     "\n"
720     "IDs are zero-filled to length 3 if a message in the standard frame\n"
721     "format is received and to 8 for extended frame format messages.\n"
722     "\n"
723     "caninit must be called before using this command.\n"
724     "\n"
725     "### Example ###\n"
726     "\n"
727     "    --> candump 2\n"
728     "can2  0000FADE  [2]  12 34\n",
729     CMD_HANDLER(cmd_do_can_dump), (void *)&cmd_list_can
730 };
731
732
733
734 cmd_des_t const *cmd_list_can[]={
735   &cmd_des_test_can_loopback,
736   &cmd_des_can_init,
737   &cmd_des_can_baudrate,
738   &cmd_des_can_timing,
739   &cmd_des_can_send,
740   &cmd_des_can_dump,
741   NULL
742 };