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