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