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