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