]> rtime.felk.cvut.cz Git - pes-rpp/rpp-test-sw.git/blob - rpp-test-sw/commands/cmd_can.c
Excessive record from rpp_can_ctrl_config structure removed
[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                 .timing_calc_method = RPP_CAN_TIMING_CALC_AUTO,
253                 .timing_config = NULL
254         },
255         {
256                 .baudrate = 500000,
257                 .clk = 80000000,
258                 .timing_calc_method = RPP_CAN_TIMING_CALC_AUTO,
259                 .timing_config = NULL
260         },
261         {
262                 .baudrate = 500000,
263                 .clk = 80000000,
264                 .timing_calc_method = RPP_CAN_TIMING_CALC_AUTO,
265                 .timing_config = NULL
266         }
267 };
268
269 static struct rpp_can_tx_config tx_config[] = {
270         {
271                 .type = RPP_CAN_EXTENDED,
272                 .controller = 1,
273                 .msg_obj = 2,
274         },
275         {
276                 .type = RPP_CAN_EXTENDED,
277                 .controller = 2,
278                 .msg_obj = 2,
279         },
280         {
281                 .type = RPP_CAN_EXTENDED,
282                 .controller = 3,
283                 .msg_obj = 2,
284         }
285 };
286
287 static struct rpp_can_rx_config rx_config[] = {
288         {
289                 .type = RPP_CAN_MIXED,
290                 .controller = 1,
291                 .msg_obj = 1,
292                 .id = 1,
293                 .mask = 0,
294         },
295         {
296                 .type = RPP_CAN_MIXED,
297                 .controller = 2,
298                 .msg_obj = 1,
299                 .id = 1,
300                 .mask = 0,
301         },
302         {
303                 .type = RPP_CAN_MIXED,
304                 .controller = 3,
305                 .msg_obj = 1,
306                 .id = 1,
307                 .mask = 0,
308         }
309 };
310
311 static struct rpp_can_config can_config = {
312         .num_tx_obj = 3,
313         .num_rx_obj = 3,
314         .tx_config = tx_config,
315         .rx_config = rx_config,
316         .ctrl = ctrl_config,
317 };
318
319
320 int cmd_do_can_init(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
321 {
322     dmmREG->PC4 = (1<<(13)); // set CAN_NSTB
323     dmmREG->PC5 = (1<<(15)); // clr CAN_EN
324     dmmREG->PC5 = (1<<(13)); // clr CAN_NSTB
325     dmmREG->PC4 = (1<<(13)); // set CAN_NSTB
326     dmmREG->PC4 = (1<<(15)); // set CAN_EN
327
328
329
330     can_inited = (rpp_can_init(&can_config) == SUCCESS ? 1 : 0);
331     return (can_inited ? 0 : 1);
332 }
333
334
335 int cmd_do_can_send(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
336 {
337         uint32_t controller_id;
338         uint32_t i, l = 0;
339         int ret;
340         struct rpp_can_pdu pdu;
341         char *p;
342
343         if (!can_inited)
344         {
345                 rpp_sci_printf("CAN is not initialized\n");
346                 return -CMDERR_NODEV;
347         }
348
349         p = param[1];
350         ret = sscanf(p, "%i %i%n", &controller_id, &pdu.id, &l);
351         if (ret < 2)
352         {
353                 rpp_sci_printf("Cannot parse parameter %d\n", ret+1);
354                 return -CMDERR_BADPAR;
355         }
356         p += l;
357
358         i = 0;
359         do {
360                 uint16_t data;
361                 ret = sscanf(p, "%2hx%n", &data, &l);
362                 if (ret < 1) break;
363                 pdu.data[i] = data & 0xff;
364                 i++;
365                 p += l;
366         } while (1);
367
368         pdu.dlc = i;
369
370
371         if (rpp_can_write(controller_id-1, &pdu) == SUCCESS)
372         {
373                 rpp_sci_printf("Sent: can%u\t%X\t[%u]\t", controller_id, pdu.id, pdu.dlc);
374                 for (i=0; i<pdu.dlc; i++)
375                 {
376                         rpp_sci_printf("%X ", pdu.data[i]);
377                 }
378         }
379         else
380         {
381                 rpp_sci_printf("Error: rpp_can_write");
382         }
383         rpp_sci_printf("\n");
384
385
386         return 0;
387 }
388
389
390 int cmd_do_can_dump(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
391 {
392         uint32_t controller_id = 0;
393         bool rx_ind;
394         struct rpp_can_pdu pdu;
395
396         uint32_t i;
397
398         if (!can_inited)
399         {
400                 rpp_sci_printf("CAN is not initialized\n");
401                 return -CMDERR_NODEV;
402         }
403
404         if (!(sscanf(param[1], "%u", &controller_id) == 1))
405         {
406                 rpp_sci_printf("Unable to parse controller ID\n");
407                 return 1;
408         }
409
410         rpp_can_init(&can_config);
411
412         while(cmd_io->getc(cmd_io) < 0)
413         {
414                 rpp_can_check_rx_ind(controller_id-1, &rx_ind);
415                 if (rx_ind)
416                 {
417                         if (rpp_can_read(controller_id-1, &pdu) == SUCCESS)
418                         {
419                                 if (pdu.id & CAN_EFF_FLAG)
420                                 {
421                                         rpp_sci_printf("can%u  %08X  [%u]  ", controller_id & (~CAN_EFF_FLAG), pdu.id, pdu.dlc);
422                                 }
423                                 else
424                                 {
425                                         rpp_sci_printf("can%u  %03X  [%u]  ", controller_id, pdu.id, pdu.dlc);
426                                 }
427
428                                 for (i=0; i<pdu.dlc; i++)
429                                 {
430                                             rpp_sci_printf("%X ", pdu.data[i]);
431                                 }
432                                 rpp_sci_printf("\n");
433                         }
434                         else
435                         {
436                                 rpp_sci_printf("Error rpp_can_read\n");
437                         }
438                 }
439         }
440
441         return 0;
442 }
443
444
445 int cmd_do_can_change_baudrate(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
446 {
447         int opchar;
448         uint32_t controller_id, baudrate;
449
450         if ((opchar = cmd_opchar_check(cmd_io, des, param)) < 0)
451                 return opchar;
452
453         if (opchar == ':')
454         {
455                 if (!(sscanf(param[1], "%u:%u", &controller_id, &baudrate) == 2))
456                 {
457                         rpp_sci_printf("Unable to parse arguments\n");
458                         return 1;
459                 }
460
461                 if (controller_id < 1 || controller_id > 3)
462                         return -CMDERR_BADPAR;
463
464                 can_config.ctrl[controller_id-1].baudrate = baudrate;
465                 can_config.ctrl[controller_id-1].timing_config = NULL;
466                 can_config.ctrl[controller_id-1].timing_calc_method = RPP_CAN_TIMING_CALC_AUTO;
467         }
468         else
469         {
470                 if (!(sscanf(param[1], "%u", &controller_id) == 1))
471
472                 if (controller_id < 1 || controller_id > 3)
473                         return -CMDERR_BADPAR;
474
475                 cmd_opchar_replong(cmd_io, param, can_config.ctrl[controller_id-1].baudrate, 0, 10);
476         }
477
478         return 0;
479 }
480
481 int cmd_do_can_change_timing(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
482 {
483         int opchar;
484         uint32_t controller_id, brp, prop_seg, phase_seg1, phase_seg2, sjw;
485
486         if ((opchar = cmd_opchar_check(cmd_io, des, param)) < 0)
487                 return opchar;
488
489         if (opchar == ':')
490         {
491                 if (!(sscanf(param[1], "%u:%u %u %u %u %u", &controller_id, &brp, &prop_seg, &phase_seg1, &phase_seg2, &sjw) == 6))
492                 {
493                         rpp_sci_printf("Unable to parse arguments\n");
494                         return 1;
495                 }
496
497                 if (controller_id < 1 || controller_id > 3)
498                         return -CMDERR_BADPAR;
499
500                 can_config.ctrl[controller_id-1].baudrate = 0;
501                 can_config.ctrl[controller_id-1].timing_config = &can_timing[controller_id-1];
502                 can_config.ctrl[controller_id-1].timing_config->brp = brp;
503                 can_config.ctrl[controller_id-1].timing_config->phase_seg1 = phase_seg1;
504                 can_config.ctrl[controller_id-1].timing_config->phase_seg2 = phase_seg2;
505                 can_config.ctrl[controller_id-1].timing_config->prop_seg = prop_seg;
506                 can_config.ctrl[controller_id-1].timing_config->sjw = sjw;
507                 can_config.ctrl[controller_id-1].timing_calc_method = RPP_CAN_TIMING_CALC_MANUAL;
508         }
509         else
510         {
511                 if (!(sscanf(param[1], "%u", &controller_id) == 1))
512
513                 if (controller_id < 1 || controller_id > 3)
514                         return -CMDERR_BADPAR;
515
516                 if (can_config.ctrl[controller_id-1].timing_config != NULL) {
517                         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",
518                                         can_config.ctrl[controller_id-1].timing_config->brp,
519                                         can_config.ctrl[controller_id-1].timing_config->prop_seg,
520                                         can_config.ctrl[controller_id-1].timing_config->phase_seg1,
521                                         can_config.ctrl[controller_id-1].timing_config->phase_seg2,
522                                         can_config.ctrl[controller_id-1].timing_config->sjw,
523                                         can_config.ctrl[controller_id-1].timing_config->sampl_pt,
524                                         can_config.ctrl[controller_id-1].timing_config->error,
525                                         can_config.ctrl[controller_id-1].timing_config->tq
526                         );
527
528                 }
529                 else {
530                         rpp_sci_printf("CAN timing has not yet been manualy specified.\r\n");
531                 }
532         }
533
534         return 0;
535 }
536
537
538
539
540 #endif  /* DOCGEN */
541
542 /** @brief command descriptor for test CAN loopback command */
543 cmd_des_t const cmd_des_test_can_loopback={
544     0, 0,
545     "cantest*", "Test CAN loopback between two CAN interfaces",
546     "### Command syntax ###\n"
547     "\n"
548     "    cantest<SRC> <DST>\n"
549     "\n"
550     "where `<SRC>` and `<DST>` are different numbers in range 1-3.\n"
551     "\n"
552     "### Description ###\n"
553     "\n"
554     "This command tests CAN communication by sending and receiving messages\n"
555     "through external loopback. At the beginning, the involved CAN\n"
556     "controller are initialized to the Bus-On state.\n"
557     "\n"
558     "The command sends 100 messages and measures the numbers of TX errors,\n"
559     "RX errors and detected timeouts. At the end, these statistics are\n"
560     "printed as well as the status of the involved CAN controllers.\n"
561     "\n"
562     "When an error is detected during the test, the status of faulty CAN\n"
563     "controller is printed immediately.\n"
564     "\n"
565     "### Example ###\n"
566     "\n"
567     "    --> cantest1 2\n"
568     "    Testing CAN loopback\n"
569     "    Messages transmitted: 100/100\n"
570     "    Messages received: 100/100\n"
571     "    TX timeouts: 0\n"
572     "    RX timeouts: 0\n"
573     "    Src TX error counter: 0\n"
574     "    Src RX error counter: 0\n"
575     "    Dst TX error counter: 0\n"
576     "    Dst RX error counter: 0\n"
577     "    CAN1 status: Bus-On, ES: 0x8\n"
578     "    CAN2 status: Bus-On, ES: 0x10\n",
579     CMD_HANDLER(cmd_do_test_can_loopback), (void *)&cmd_list_can
580 };
581
582
583 cmd_des_t const cmd_des_can_init={
584     0, 0,
585     "caninit", "Initialize CAN controllers",
586     "### Command syntax ###\n"
587     "\n"
588     "    caninit\n"
589     "\n"
590     "### Description ###\n"
591     "\n"
592     "This command (re-)initializes all CAN controllers using current\n"
593     "CAN configuration. This configuration can be changed using\n"
594     "canbaudrate command.\n"
595     "\n"
596     "In the default configuration the baudrate of all CAN controllers i set\n"
597     "to 500 kbit/s.\n"
598     "\n"
599     "### Example ###\n"
600     "  --> caninit\n",
601     CMD_HANDLER(cmd_do_can_init), (void *)&cmd_list_can
602 };
603
604 cmd_des_t const cmd_des_can_baudrate={
605     0, CDESM_OPCHR|CDESM_RW,
606     "canbaudrate#", "Change baudrate of CAN controller",
607     "### Command syntax ###\n"
608     "\n"
609     "    canbaudrate<CONTROLLER>?\n"
610     "    canbaudrate<CONTROLLER>:<BAUDRATE>\n"
611     "\n"
612     "where `<CONTROLLER>` is number in range 1-3 and BAUDRATE is number in\n"
613     "range 1000-10000000 specifying the baudrate in bits per second.\n"
614     "\n"
615     "### Description ###\n"
616     "\n"
617     "This command is used to set or show the baudrate of a CAN controller.\n"
618     "The baudrate shown is the one which will be used by next invocation of\n"
619     "the caninit command.\n"
620     "The baudrate specified by the command is used to automatic calculation of\n"
621     "the CAN controller timing. If you want to specify the timing manually,\n"
622     "please use the command cantiming.\n"
623     "The automatic calculation might not work properly for some baudrates. In\n"
624     "this case you should calculate the timing manually and specify it by the\n"
625     "command cantiming."
626     "\n"
627     "### Examples ###\n"
628     "\n"
629     "    --> canbaudrate2?\n"
630     "    canbaudrate2=500000\n"
631     "\n"
632     "    --> canbaudrate2:100000\n",
633     CMD_HANDLER(cmd_do_can_change_baudrate), (void *)&cmd_list_can
634 };
635
636 cmd_des_t const cmd_des_can_timing={
637     0, CDESM_OPCHR|CDESM_RW,
638     "cantiming#", "Change timing of CAN controller manually",
639     "### Command syntax ###\n"
640     "\n"
641     "    cantiming<CONTROLLER>?\n"
642     "    cantiming<CONTROLLER>:<BRP> <PROP_SEG> <PHASE_SEG1> <PHASE_SEG2> <SJW>\n"
643     "\n"
644     "where:"
645     " - `<CONTROLLER>` is number in range 1-3\n"
646     " - `<BRP>` (baudrate prescaler) is number in range 1-65\n"
647     " - `<PROP_SEG>` (length of propagation segment in tQ) is a number in range 1-8\n"
648     " - `<PHASE_SEG1>` (phase buffer segment 1 in tQ) is a number in range 1-8\n"
649     " - `<PHASE_SEG2>` (phase buffer segment 2 in tQ) is a number in range 1-8\n"
650     " - `<SJW>` (synchronization jump width in tQ) is a number in range 1-4\n"
651     "\n"
652     "### Description ###\n"
653     "\n"
654     "This command is used to set or show the timing of a CAN controller.\n"
655     "The timing shown is the one which will be used by next invocation of\n"
656     "the caninit command.\n"
657     "The timing configured by this command defines manually the baudrate of\n"
658     "the CAN controller. If you want to calculate the timing automaticaly from\n"
659     "a baudrate, please use the command canbaudrate.\n"
660     "\n"
661     "### Examples ###\n"
662     "\n"
663     "    --> cantiming2?\n"
664     "    brp: 17\n"
665     "    prop_seg: 4 tQ\n"
666     "    phase_seg1: 5 tQ\n"
667     "    phase_seg2: 5 tQ\n"
668     "    sjw: 4 tQ\n"
669     "    sample_pt: 875 ns\n"
670     "    error: 0\n"
671     "    tQ: 125 ns\n"
672     "\n"
673     "    --> cantiming2:5 8 7 4 1\n",
674     CMD_HANDLER(cmd_do_can_change_timing), (void *)&cmd_list_can
675 };
676
677
678 cmd_des_t const cmd_des_can_send={
679     0, 0,
680     "cansend", "Test sending message over CAN",
681     "### Command syntax ###\n"
682     "\n"
683     "    cansend <CONTROLLER> <ID> <DATA>\n"
684     "\n"
685     "where `<CONTROLLER>` is number in range 1-3, `<ID>` is a valid CAN ID\n"
686     "and `<DATA>` is 0-8 bytes of data in hexadecimal representation.\n"
687     "There may be any number of spaces between the data bytes.\n"
688     "`<ID>` may be given in octal, decimal or hexadecimal base.\n"
689     "\n"
690     "### Description ###\n"
691     "\n"
692     "This command sends a CAN frame using specified CAN controller.\n"
693     "\n"
694     "The caninit command must be called before using this command.\n"
695     "\n"
696     "### Example ###\n"
697     "    --> cansend 2 0x123 DEAD BEEF\n"
698     "    Sent: can2      123     [4]     DE AD BE EF\n",
699     CMD_HANDLER(cmd_do_can_send), (void *)&cmd_list_can
700 };
701
702
703 cmd_des_t const cmd_des_can_dump={
704     0, 0,
705     "candump", "Dump all messages received over CAN",
706     "### Command syntax ###\n"
707     "\n"
708     "    candump <CONTROLLER>\n"
709     "\n"
710     "where `<CONTROLLER>` is a number in range 1-3.\n"
711     "\n"
712     "### Description ###\n"
713     "\n"
714     "This command prints out all CAN messages received via the specified\n"
715     "controller.\n"
716     "\n"
717     "IDs are zero-filled to length 3 if a message in the standard frame\n"
718     "format is received and to 8 for extended frame format messages.\n"
719     "\n"
720     "caninit must be called before using this command.\n"
721     "\n"
722     "### Example ###\n"
723     "\n"
724     "    --> candump 2\n"
725     "can2  0000FADE  [2]  12 34\n",
726     CMD_HANDLER(cmd_do_can_dump), (void *)&cmd_list_can
727 };
728
729
730
731 cmd_des_t const *cmd_list_can[]={
732   &cmd_des_test_can_loopback,
733   &cmd_des_can_init,
734   &cmd_des_can_baudrate,
735   &cmd_des_can_timing,
736   &cmd_des_can_send,
737   &cmd_des_can_dump,
738   NULL
739 };