]> rtime.felk.cvut.cz Git - pes-rpp/rpp-test-sw.git/blob - rpp-test-sw/commands/cmd_fray.c
Change license to MIT
[pes-rpp/rpp-test-sw.git] / rpp-test-sw / commands / cmd_fray.c
1 /*
2  * Copyright (C) 2012-2013, 2015 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_fray.c
31  *
32  * Abstract:
33  *  Commands for control FlexRay
34  *  - Getting status of FlexRay from chips on SPI
35  *  - Sending test data on FRAY
36  *  - Receiving test data on FRAY
37  *
38  *  There are FlexRay test commands, to test the connection between two FlexRay nodes A and B
39  *  The node A is sending a message 100 times with some period.
40  *  The node B is receiving this message and check if it fits the pattern.
41  *  Commands are counting the number of errors, which is printed at the end of the test.
42  *  After 100 transmissions both nodes are halted.
43  */
44
45 #include "cmd_fray.h"
46 #include "stdio.h"
47
48 #ifndef DOCGEN
49
50 #include "drv/port_def.h"
51 #include "rpp/rpp.h"
52 #include "cmdproc_utils.h"
53 #include "cmdproc.h"
54 #include "spi_resp_transl.h"
55
56 /**
57  * This structure contains global FlexRay configuration.
58  * All nodes in the network have to use the same values for
59  * all parameters of this structure.
60  */
61 static Fr_TMS570LS_ClusterConfigType Fr_cluster_config = {
62         .gColdStartAttempts = 0x2,
63         .gListenNoise = 0xF,
64         .gMacroPerCycle = 0x15E0,   // Macrotick = 1us
65         .gMaxWithoutClockCorrectionFatal = 0xF,
66         .gMaxWithoutClockCorrectionPassive = 0xF,
67         .gNetworkManagementVectorLength = 12,
68         .gNumberOfMinislots = 0x15A,
69         .gNumberOfStaticSlots = 0x8,
70         .gOffsetCorrectionStart = 0xAE4,
71         .gPayloadLengthStatic = 0x9,
72         .gSyncNodeMax = 0xF,
73         .gdActionPointOffset = 0x4,
74         .gdCASRxLowMax = 0x43,
75         .gdDynamicSlotIdlePhase = 0x1,
76         .gdMinislot = 0x4,
77         .gdMinislotActionPointOffset = 0x2,
78         .gdNIT = 0xAE3,
79         .gdSampleClockPeriod = 0,       // 10mbit/sec
80         .gdStaticSlot = 0x56,
81         .gdTSSTransmitter = 0xA,
82         .gdWakeupSymbolRxIdle = 18,
83         .gdWakeupSymbolRxLow = 18,
84         .gdWakeupSymbolRxWindow = 76,
85         .gdWakeupSymbolTxIdle = 180,
86         .gdWakeupSymbolTxLow = 60
87 };
88
89
90 /**
91  * This structure contains local configuration of the FlexRay node A.
92  * That is the node that transmits messages to the node B.
93  */
94 static Fr_TMS570LS_NodeConfigType Fr_node_A_config = {
95         .pAllowHaltDueToClock = 0,
96         .pAllowPassiveToActive = 0xF,
97         .pChannels = FR_CHANNEL_AB,
98         .pClusterDriftDamping = 0x1,
99         .pDelayCompensationA = 0x3,
100         .pDelayCompensationB = 0x3,
101         .pExternOffsetCorrection = 0,
102         .pExternRateCorrection = 0,
103         .pKeySlotUsedForStartup = TRUE,
104         .pKeySlotUsedForSync = TRUE,
105         .pLatestTx = 0x10D,
106         .pMacroInitialOffsetA = 0x6,
107         .pMacroInitialOffsetB = 0x6,
108         .pMicroInitialOffsetA = 0x18,
109         .pMicroInitialOffsetB = 0x18,
110         .pMicroPerCycle = 0x36B00,      // (cycle period, 5.6ms), uT = 25ns@10Mbit/sec,  25ns@5Mbit/sec, 50ns@2.5Mbit/sec
111         .pRateCorrectionOut = 0xCD,
112         .pOffsetCorrectionOut = 0x151,
113         .pSamplesPerMicrotick = 0,      // 10 mbit/sec
114         .pSingleSlotEnabled = TRUE,
115         .pWakeupChannel = FR_CHANNEL_A,
116         .pWakeupPattern = 2,
117         .pdAcceptedStartupRange = 0x81,
118         .pdListenTimeout = 0x36DA2,
119         .pdMaxDrift = 0x151,
120         .pDecodingCorrection = 0x33
121 };
122
123 /**
124  * This structure contains local configuration of the FlexRay node B.
125  * That is the node that receives messages from the node A.
126  */
127 static Fr_TMS570LS_NodeConfigType Fr_node_B_config = {
128         .pAllowHaltDueToClock = 0,
129         .pAllowPassiveToActive = 0xF,
130         .pChannels = FR_CHANNEL_AB,
131         .pClusterDriftDamping = 0x1,
132         .pDelayCompensationA = 0x3,
133         .pDelayCompensationB = 0x3,
134         .pExternOffsetCorrection = 0,
135         .pExternRateCorrection = 0,
136         .pKeySlotUsedForStartup = TRUE,
137         .pKeySlotUsedForSync = TRUE,
138         .pLatestTx = 0x10D,
139         .pMacroInitialOffsetA = 0x6,
140         .pMacroInitialOffsetB = 0x6,
141         .pMicroInitialOffsetA = 0x18,
142         .pMicroInitialOffsetB = 0x18,
143         .pMicroPerCycle = 0x36B00,
144         .pRateCorrectionOut = 0xCD,
145         .pOffsetCorrectionOut = 0x151,
146         .pSamplesPerMicrotick = 0,          // 10 mbit/sec
147         .pSingleSlotEnabled = TRUE,
148         .pWakeupChannel = FR_CHANNEL_A,
149         .pWakeupPattern = 2,
150         .pdAcceptedStartupRange = 0x81,
151         .pdListenTimeout = 0x36DA2,
152         .pdMaxDrift = 0x151,
153         .pDecodingCorrection = 0x33
154 };
155
156 /**
157  * FlexRay node A message RAM configuration.
158  * Reconfiguration is disabled, 2 static buffers are configured.
159  */
160 static Fr_TMS570LS_MsgRAMConfig Fr_node_A_msgRAM_config = {
161         .dynSegmentBufferCount = 0,
162         .fifoBufferCount = 0,
163         .secureBuffers = FR_SB_ALL_REC_DISABLED,
164         .statSegmentBufferCount = 2,
165         .syncFramePayloadMultiplexEnabled = 0
166 };
167
168 /**
169  * FlexRay node B message RAM configuration.
170  * Reconfiguration is disabled, 2 static buffers are configured.
171  */
172 static Fr_TMS570LS_MsgRAMConfig Fr_node_B_msgRAM_config = {
173         .dynSegmentBufferCount = 0,
174         .fifoBufferCount = 0,
175         .secureBuffers = FR_SB_ALL_REC_DISABLED,
176         .statSegmentBufferCount = 2,
177         .syncFramePayloadMultiplexEnabled = 0
178 };
179
180 /**
181  * The FlexRay node A is a sync node and coldstarter. That is why the first buffer
182  * (buffer 0) is configured as TX. All coldstarters and sync nodes must have the
183  * first buffer configured as TX. The FlexRay network has to contain at least two
184  * sync nodes and coldstarters.
185  * The second buffer is used for messages transmission. It is TX and configured as
186  * single-shot to send only one message after some period.
187  */
188 static Fr_TMS570LS_BufferConfigType Fr_node_A_static_buffers_config[] = {
189         {
190                 .channel = FR_CHANNEL_AB,
191                 .cycleCounterFiltering = 0,
192                 .isTx = TRUE,
193                 .fidMask = 0,
194                 .maxPayload = 9,
195                 .msgBufferInterrupt = TRUE,
196                 .payloadPreambleIndicatorTr = FALSE,
197                 .rejectNullFrames = FALSE,
198                 .rejectStaticSegment = FALSE,
199                 .singleTransmit = FALSE,
200                 .slotId = 1
201         },
202         {
203                 .channel = FR_CHANNEL_AB,
204                 .cycleCounterFiltering = 0,
205                 .isTx = TRUE,
206                 .fidMask = 0,
207                 .maxPayload = 9,
208                 .msgBufferInterrupt = TRUE,
209                 .payloadPreambleIndicatorTr = FALSE,
210                 .rejectNullFrames = FALSE,
211                 .rejectStaticSegment = FALSE,
212                 .singleTransmit = TRUE,
213                 .slotId = 3
214         }
215 };
216
217 /**
218  * The FlexRay node B is a sync node and coldstarter. That is why the first buffer
219  * (buffer 0) is configured as TX. All coldstarters and sync nodes must have the
220  * first buffer configured as TX. The FlexRay network has to contain at least two
221  * sync nodes and coldstarters.
222  * The second buffer is used for messages receiving.
223  */
224 static Fr_TMS570LS_BufferConfigType Fr_node_B_static_buffers_config[] = {
225         {
226                 .channel = FR_CHANNEL_AB,
227                 .cycleCounterFiltering = 0,
228                 .isTx = TRUE,
229                 .fidMask = 0,
230                 .maxPayload = 9,
231                 .msgBufferInterrupt = TRUE,
232                 .payloadPreambleIndicatorTr = FALSE,
233                 .rejectNullFrames = FALSE,
234                 .rejectStaticSegment = FALSE,
235                 .singleTransmit = FALSE,
236                 .slotId = 2
237         },
238         {
239                 .channel = FR_CHANNEL_AB,
240                 .cycleCounterFiltering = 0,
241                 .isTx = FALSE,
242                 .fidMask = 0,
243                 .maxPayload = 9,
244                 .msgBufferInterrupt = TRUE,
245                 .payloadPreambleIndicatorTr = FALSE,
246                 .rejectNullFrames = FALSE,
247                 .rejectStaticSegment = FALSE,
248                 .singleTransmit = TRUE,
249                 .slotId = 3
250         }
251 };
252
253 /**
254  * Unifying configuration structure for the node A.
255  */
256 static Fr_ConfigType Fr_config_node_A = {
257         .clusterConfiguration = &Fr_cluster_config,
258         .dynamicBufferConfigs = NULL,
259         .fifoBufferConfigs = NULL,
260         .msgRAMConfig = &Fr_node_A_msgRAM_config,
261         .nodeConfiguration = &Fr_node_A_config,
262         .staticBufferConfigs = Fr_node_A_static_buffers_config
263 };
264
265 /**
266  * Unifying configuration structure for the node B.
267  */
268 static Fr_ConfigType Fr_config_node_B = {
269         .clusterConfiguration = &Fr_cluster_config,
270         .dynamicBufferConfigs = NULL,
271         .fifoBufferConfigs = NULL,
272         .msgRAMConfig = &Fr_node_B_msgRAM_config,
273         .nodeConfiguration = &Fr_node_B_config,
274         .staticBufferConfigs = Fr_node_B_static_buffers_config
275 };
276
277 /**
278  *  Loads data into TX buffer for FlexRay node A.
279  *  Set TX Request for the buffer to start the transmission.
280  */
281 int8_t transmit_node_a()
282 {
283         uint8_t data[18];
284         int i;
285
286         // Write payload for the buffer
287         for (i = 0; i < 18; i++) {
288                 data[i] = i;
289         }
290         return rpp_fr_transmit_lpdu(0, 1, data, 18);
291 }
292
293 /**
294  *      Check data of the received message for correctness.
295  *      @return  0 if message was received and is correct
296  *                       1 if message was received and is incorrect
297  */
298 int check_message(const uint8_t *data)
299 {
300         int i;
301
302         for (i = 0; i < 18; i++) {
303                 if (data[i] != i)
304                         return 1;
305         }
306         return 0;
307 }
308
309
310 /**
311  *  @brief      Get FlexRay status in human readable form
312  *
313  *  Command sends some data on SPI (data do not matters, chips are read only) and retreives a response.
314  *  The response is translated and displayed as readable text.
315  *
316  * @param[in]   cmd_io  Pointer to IO stack
317  * @param[in]   des             Pointer to command descriptor
318  * @param[in]   param   Parameters of command
319  * @return      0 when OK or error code
320  */
321 int cmd_do_fray_status(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
322 {
323         char *p;
324         int pin;
325
326         p = param[1];
327         if (sscanf(p, "%d", &pin) != 1)
328                 return -CMDERR_BADPAR;
329         pin--; // Highlevel command has pin number mapped according the board scheme, this switches to internal representation
330         if (pin > FRAY_NUM_PORTS || pin < 0) return -CMDERR_BADPAR;
331
332         if (Fr_spi_transfer(pin) != 0) return -CMDERR_BADDIO;
333
334         const spitr_cmd_desc_t *cmd_desc = get_spi_cmd_desc(&spitr_port_cmds[PORT_ID_FRAY1],
335                                                                                                                 Fr_spi_get_cmd(pin));
336         if (cmd_desc == NULL)
337                 return -CMDERR_BADPAR;
338         uint32_t fr_spi_response = Fr_spi_response(pin);
339         uint32_t lsbResponse = 0 | ((fr_spi_response & 0xFF) << 8) | ((fr_spi_response & 0xFF00) >> 8);
340
341         spitr_print_resp(cmd_desc, lsbResponse);
342         return 0;
343 }
344
345 /**
346  *  @brief      Start sending data on the FlexRay as node A
347  *
348  * @param[in]   cmd_io  Pointer to IO stack
349  * @param[in]   des             Pointer to command descriptor
350  * @param[in]   param   Parameters of command
351  * @return      0 when OK or error code
352  */
353 int cmd_do_test_frayA(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
354 {
355         uint32_t i;
356         uint32_t error = 0;
357         uint32_t msg_cnt = 0;
358         uint32_t count = 100;
359         Fr_TxLPduStatusType status;
360         Fr_POCStatusType poc_status;
361
362         if (param[1] && sscanf(param[1], "%d", &count) != 1)
363                 return -CMDERR_BADPAR;
364
365         if (rpp_fr_init_driver(&Fr_config_node_A, &error) == FAILURE) {
366                 rpp_sci_printf("Fray driver initialization failed: %#x.\n", error);
367                 return -CMDERR_BADCFG;
368         }
369         if (rpp_fr_init_controller(0, &error) == FAILURE) {
370                 rpp_sci_printf("Fray control node initialization failed: %#x.\n", error);
371                 return -CMDERR_BADCFG;
372         }
373         rpp_sci_printf("Fray control node initialized.\r\n");
374         rpp_sci_printf("Waiting for network connection...\r\n");
375
376         if (rpp_fr_start_communication(0, &error) == FAILURE) {
377                 rpp_sci_printf("Integration to the network failed: %#x.\n", error);
378                 return -CMDERR_BADCFG;
379         }
380         if (rpp_fr_all_slots(0) == FAILURE) {
381                 rpp_sci_printf("All slots mode selection failed.\n");
382                 return -CMDERR_BADCFG;
383         }
384
385         rpp_sci_printf("Connected. Frames transmission is starting. O means OK, X means Error\r\n");
386         if (rpp_fr_clear_timer_irq(0,0) == FAILURE ||
387                 rpp_fr_set_timer(0,0,10,1) == FAILURE
388                 ) {
389                 rpp_sci_printf("Absolute timer setting failed.\n");
390                 return -CMDERR_BADCFG;
391         }
392         for (i = 0; i < count; i++) {
393                 if (transmit_node_a() == FAILURE) {
394                         rpp_sci_printf("X");
395                         error++;
396                 }
397                 else
398                         rpp_sci_printf("O");
399                 msg_cnt++;
400
401                 do {
402                         rpp_fr_check_tx_lpdu_status(0, 1, &status);
403                         rpp_fr_get_poc_status(0, &poc_status);
404                 } while (status == FR_NOT_TRANSMITTED && poc_status.ErrorMode == FR_ERRORMODE_ACTIVE);
405
406                 if (poc_status.ErrorMode != FR_ERRORMODE_ACTIVE) {
407                         rpp_sci_printf("\nFlexRay exited active mode (see command frbtgetpocst)!\n");
408                         break;
409                 }
410
411         }
412         rpp_sci_printf("\r\nTransmitted %d messages with %d errors.\r\n", msg_cnt, error);
413         if (rpp_fr_halt_communication(0) != SUCCESS)
414                 rpp_sci_printf("FlexRay HALT command failed, please reset the board to stop transmission.\r\n");
415         else
416                 rpp_sci_printf("FlexRay halted, reset the board to make FlexRay usable again.\r\n");
417         return 0;
418 }
419
420 /**
421  *  @brief      Start receiving data on the FlexRay as node B
422  *
423  * @param[in]   cmd_io  Pointer to IO stack
424  * @param[in]   des             Pointer to command descriptor
425  * @param[in]   param   Parameters of command
426  * @return      0 when OK or error code
427  */
428 int cmd_do_test_frayB(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
429 {
430         uint32_t i;
431         uint32_t error = 0;
432         uint32_t msg_cnt = 0;
433         uint32_t count = 100;
434
435         if (param[1] && sscanf(param[1], "%d", &count) != 1)
436                 return -CMDERR_BADPAR;
437
438         if (rpp_fr_init_driver(&Fr_config_node_B, &error) == FAILURE) {
439                 rpp_sci_printf("Fray driver initialization failed: %#x.\n", error);
440                 return -CMDERR_BADCFG;
441         }
442         if (rpp_fr_init_controller(0, &error) == FAILURE) {
443                 rpp_sci_printf("Fray control node initialization failed: %#x.\n", error);
444                 return -CMDERR_BADCFG;
445         }
446         rpp_sci_printf("Fray control node initialized.\r\n");
447         rpp_sci_printf("Waiting for network connection...\r\n");
448
449         if (rpp_fr_start_communication(0, &error) == FAILURE) {
450                 rpp_sci_printf("Integration to the network failed: %#x.\n", error);
451                 return -CMDERR_BADCFG;
452         }
453         if (rpp_fr_all_slots(0) == FAILURE) {
454                 rpp_sci_printf("All slots mode selection failed.\n");
455                 return -CMDERR_BADCFG;
456         }
457
458         rpp_sci_printf("Connected. Frames transmission is starting. O means OK, X means Error, T means timeout.\r\n");
459         for (i = 0; i < count; i++) {
460                 uint8_t data[18];
461                 Fr_RxLPduStatusType status;
462                 uint8_t size;
463                 uint8_t cycle1, cycle2;
464                 uint16_t mtick;
465
466                 rpp_fr_get_global_time(0, &cycle1, &mtick);
467                 do {
468                         if (rpp_fr_receive_lpdu(0, 1, data, &status, &size) == FAILURE) {
469                                 rpp_sci_printf("\nMessage receiving failed!\n");
470                                 break;
471                         }
472                         rpp_fr_get_global_time(0, &cycle2, &mtick);
473                 } while (status == FR_NOT_RECEIVED && (cycle2 != ((cycle1-1) & 0x3F)));
474
475                 if (status == FR_NOT_RECEIVED)
476                         rpp_sci_printf("T");
477                 else if (check_message(data) == 0) {
478                         rpp_sci_printf("O");
479                         msg_cnt++;
480                 }
481                 else {
482                         rpp_sci_printf("X");
483                         error++;
484                         msg_cnt++;
485                 }
486         }
487         rpp_sci_printf("\r\nReceived %d messages with %d errors.\r\n", msg_cnt, error);
488         if (rpp_fr_halt_communication(0) != SUCCESS)
489                 rpp_sci_printf("FlexRay HALT command failed, please reset the board to stop transmission.\r\n");
490         else
491                 rpp_sci_printf("FlexRay halted\r\n");
492         return 0;
493 }
494
495 #endif  /* DOCGEN */
496
497 /** Command descriptor for FlexRay status command */
498 cmd_des_t const cmd_des_fray_stat = {
499         0, 0,
500         "frayxcvrstat#","Get the status of a FlexRay transceiver in a human readable form",
501         "### Command syntax ###\n"
502         "\n"
503         "    frayxcvrstat<CHN>\n"
504         "where CHN is a number in range 1-2\n"
505         "\n"
506         "### Description ###\n"
507         "\n"
508         "The command receives response from a FlexRay transceiver via SPI, and\n"
509         "prints in the form of attribute-value table.\n"
510         "\n"
511         "### Example ###\n"
512         "\n"
513         "    --> frayxcvrstat1\n"
514         "\n"
515         "Prints the status of FRAY1 transceiver.\n",
516         CMD_HANDLER(cmd_do_fray_status), (void *)&cmd_list_fray
517 };
518
519 /** Command descriptor for FlexRay 1 test node A */
520 cmd_des_t const cmd_des_test_fray_a = {
521         0, 0,
522         "fraytestA","Run the FlexRay test as A node",
523         "### Command syntax ###\n"
524         "\n"
525         "    fraytestA [<COUNT>]\n"
526         "\n"
527         "where `<COUNT>` is an optional number of messages to send. The default\n"
528         "is 100.\n"
529         "\n"
530         "### Description ###\n"
531         "\n"
532         "The commands creates FlexRay node A and starts sending a message\n"
533         "approximately every communication cycle. COUNT messages are sent for the\n"
534         "test of the connection. The command should be run with two devices\n"
535         "connected by a FlexRay bus and the second device should be running the\n"
536         "fraytestB command (it is necessary to run both commands shortly after\n"
537         "each other).\n"
538         "\n"
539         "When the command transmits a message a character is printed. O means\n"
540         "that the message was transmitted correctly, X signals a transmission\n"
541         "error. The number of TX errors and successfully transmitted messages\n"
542         "is maintained during the test and printed at the end.\n",
543         CMD_HANDLER(cmd_do_test_frayA), (void *)&cmd_list_fray
544 };
545
546 /** Command descriptor for FlexRay 1 test node B */
547 cmd_des_t const cmd_des_test_fray_b = {
548         0, 0,
549         "fraytestB","Run the FlexRay test as B node",
550         "### Command syntax ###\n"
551         "\n"
552         "    fraytestB [<COUNT>]\n"
553         "\n"
554         "where `<COUNT>` is an optional number of messages to receive. The default\n"
555         "is 100.\n"
556         "\n"
557         "### Description ###\n"
558         "\n"
559         "The commands creates FlexRay node B and starts receiving a messages.\n"
560         "100 messages should be received. The command should be run with two\n"
561         "devices connected by a FlexRay bus and the second device should be\n"
562         "running the fraytestA command (it is necessary to run both commands\n"
563         "shortly after each other).\n"
564         "\n"
565         "When the command receives a message a character is printed. O means\n"
566         "that the message was received correctly, X signals an error in data, T\n"
567         "means timeout (i.e. no message was received within 63 cycles). The\n"
568         "number of RX errors and successfully received messages is maintained\n"
569         "during the test and printed at the end.\n",
570         CMD_HANDLER(cmd_do_test_frayB), (void *)&cmd_list_fray
571 };
572
573 /** List of commands for din, defined as external */
574 cmd_des_t const *cmd_list_fray[] = {
575         &cmd_des_fray_stat,
576         &cmd_des_test_fray_a,
577         &cmd_des_test_fray_b,
578         NULL
579 };