2 * Copyright (C) 2012-2013 Czech Technical University in Prague
4 * Created on: 16.5.2013
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.
17 * Example commands for motor controlling over FlexRay. The first board has connected a control panel
18 * with two buttons and variable resistor, the second board has a DC motor connected to the H-bridge.
19 * Both boards are connected by the FlexRay bus and user can drive the motor by the control panel
20 * (speed, direction and enabling).
23 #include "cmd_motor_example.h"
32 #define ADC_MAX_VALUE 0x0983
33 #define RX_ERROR_MAX 100
34 #define ENABLE_DEBOUNCE_TIME 2
35 #define DIRECTION_DEBOUNCE_TIME 2
38 * This structure contains global FlexRay configuration.
39 * All nodes in the network have to use the same values for
40 * all parameters of this structure.
42 static Fr_TMS570LS_ClusterConfigType Fr_cluster_config = {
43 .gColdStartAttempts = 0x2,
45 .gMacroPerCycle = 0x15E0, // (cycle period, 5.6us)
46 .gMaxWithoutClockCorrectionFatal = 0xF,
47 .gMaxWithoutClockCorrectionPassive = 0xF,
48 .gNetworkManagementVectorLength = 12,
49 .gNumberOfMinislots = 0x15A,
50 .gNumberOfStaticSlots = 0x8,
51 .gOffsetCorrectionStart = 0xAE4,
52 .gPayloadLengthStatic = 0x2,
54 .gdActionPointOffset = 0x4,
55 .gdCASRxLowMax = 0x43,
56 .gdDynamicSlotIdlePhase = 0x1,
58 .gdMinislotActionPointOffset = 0x2,
60 .gdSampleClockPeriod = 0, // 10mbit/sec
62 .gdTSSTransmitter = 0xA,
63 .gdWakeupSymbolRxIdle = 18,
64 .gdWakeupSymbolRxLow = 18,
65 .gdWakeupSymbolRxWindow = 76,
66 .gdWakeupSymbolTxIdle = 180,
67 .gdWakeupSymbolTxLow = 60
71 * This structure contains local configuration of the FlexRay node for
72 * the control panel reading and sending the data.
74 static Fr_TMS570LS_NodeConfigType Fr_node_control_config = {
75 .pAllowHaltDueToClock = 0,
76 .pAllowPassiveToActive = 0xF,
77 .pChannels = FR_CHANNEL_AB,
78 .pClusterDriftDamping = 0x1,
79 .pDelayCompensationA = 0x3,
80 .pDelayCompensationB = 0x3,
81 .pExternOffsetCorrection = 0,
82 .pExternRateCorrection = 0,
83 .pKeySlotUsedForStartup = TRUE,
84 .pKeySlotUsedForSync = TRUE,
86 .pMacroInitialOffsetA = 0x6,
87 .pMacroInitialOffsetB = 0x6,
88 .pMicroInitialOffsetA = 0x18,
89 .pMicroInitialOffsetB = 0x18,
90 .pMicroPerCycle = 0x36B00,
91 .pRateCorrectionOut = 0xCD,
92 .pOffsetCorrectionOut = 0x151,
93 .pSamplesPerMicrotick = 0, // 10 mbit/sec
94 .pSingleSlotEnabled = TRUE,
95 .pWakeupChannel = FR_CHANNEL_A,
97 .pdAcceptedStartupRange = 0x81,
98 .pdListenTimeout = 0x36DA2,
100 .pDecodingCorrection = 0x33
104 * This structure contains local configuration of the FlexRay node for
105 * the motor driving. This node receives control data from the FlexRay
106 * and configures the H-bridge.
108 static Fr_TMS570LS_NodeConfigType Fr_node_motor_config = {
109 .pAllowHaltDueToClock = 0,
110 .pAllowPassiveToActive = 0xF,
111 .pChannels = FR_CHANNEL_AB,
112 .pClusterDriftDamping = 0x1,
113 .pDelayCompensationA = 0x3,
114 .pDelayCompensationB = 0x3,
115 .pExternOffsetCorrection = 0,
116 .pExternRateCorrection = 0,
117 .pKeySlotUsedForStartup = TRUE,
118 .pKeySlotUsedForSync = TRUE,
120 .pMacroInitialOffsetA = 0x6,
121 .pMacroInitialOffsetB = 0x6,
122 .pMicroInitialOffsetA = 0x18,
123 .pMicroInitialOffsetB = 0x18,
124 .pMicroPerCycle = 0x36B00,
125 .pRateCorrectionOut = 0xCD,
126 .pOffsetCorrectionOut = 0x151,
127 .pSamplesPerMicrotick = 0, // 10 mbit/sec
128 .pSingleSlotEnabled = TRUE,
129 .pWakeupChannel = FR_CHANNEL_A,
131 .pdAcceptedStartupRange = 0x81,
132 .pdListenTimeout = 0x36DA2,
134 .pDecodingCorrection = 0x33
138 * Message RAM configuration for the node reading the control panel.
140 static Fr_TMS570LS_MsgRAMConfig Fr_node_control_msgRAM_config = {
141 .dynSegmentBufferCount = 0,
142 .fifoBufferCount = 0,
143 .secureBuffers = FR_SB_ALL_REC_DISABLED,
144 .statSegmentBufferCount = 2,
145 .syncFramePayloadMultiplexEnabled = 0
149 * Message RAM configuration for the node receiving the control data and driving the H=bridge.
151 static Fr_TMS570LS_MsgRAMConfig Fr_node_motor_msgRAM_config = {
152 .dynSegmentBufferCount = 0,
153 .fifoBufferCount = 0,
154 .secureBuffers = FR_SB_ALL_REC_DISABLED,
155 .statSegmentBufferCount = 2,
156 .syncFramePayloadMultiplexEnabled = 0
160 * Static buffers configuration for the node reading the control panel.
161 * The node is configured as coldstarter and sync node. This is why the first buffer
162 * is configured as TX.
163 * The second buffer is configured as TX in single-shot mode. The buffer is used to
164 * transfer the control data.
166 static Fr_TMS570LS_BufferConfigType Fr_node_control_static_buffers_config[] = {
168 .channel = FR_CHANNEL_AB,
169 .cycleCounterFiltering = 0,
172 .msgBufferInterrupt = TRUE,
173 .payloadPreambleIndicatorTr = FALSE,
174 .rejectNullFrames = FALSE,
175 .rejectStaticSegment = FALSE,
176 .singleTransmit = FALSE,
180 .channel = FR_CHANNEL_AB,
181 .cycleCounterFiltering = 0,
184 .msgBufferInterrupt = TRUE,
185 .payloadPreambleIndicatorTr = FALSE,
186 .rejectNullFrames = FALSE,
187 .rejectStaticSegment = FALSE,
188 .singleTransmit = FALSE,
194 * Static buffers configuration for the node driving the motor.
195 * The node is configured as coldstarter and sync node. This is why the first buffer
196 * is configured as TX.
197 * The second buffer is configured as RX and is receiving the control data.
199 static Fr_TMS570LS_BufferConfigType Fr_node_motor_static_buffers_config[] = {
201 .channel = FR_CHANNEL_AB,
202 .cycleCounterFiltering = 0,
205 .msgBufferInterrupt = TRUE,
206 .payloadPreambleIndicatorTr = FALSE,
207 .rejectNullFrames = FALSE,
208 .rejectStaticSegment = FALSE,
209 .singleTransmit = FALSE,
213 .channel = FR_CHANNEL_AB,
214 .cycleCounterFiltering = 0,
217 .msgBufferInterrupt = TRUE,
218 .payloadPreambleIndicatorTr = FALSE,
219 .rejectNullFrames = FALSE,
220 .rejectStaticSegment = FALSE,
221 .singleTransmit = FALSE,
227 * Unifying configuration structure for the node reading the control panel.
229 static Fr_ConfigType Fr_config_node_control = {
230 .clusterConfiguration = &Fr_cluster_config,
231 .dynamicBufferConfigs = NULL,
232 .fifoBufferConfigs = NULL,
233 .msgRAMConfig = &Fr_node_control_msgRAM_config,
234 .nodeConfiguration = &Fr_node_control_config,
235 .staticBufferConfigs = Fr_node_control_static_buffers_config
239 * Unifying configuration structure for the node driving the motor.
241 static Fr_ConfigType Fr_config_node_motor = {
242 .clusterConfiguration = &Fr_cluster_config,
243 .dynamicBufferConfigs = NULL,
244 .fifoBufferConfigs = NULL,
245 .msgRAMConfig = &Fr_node_motor_msgRAM_config,
246 .nodeConfiguration = &Fr_node_motor_config,
247 .staticBufferConfigs = Fr_node_motor_static_buffers_config
251 * Loads data into TX buffers for FlexRay node sending the control data.
253 * After data are copied into TX buffer, the TX request is enabled, which
254 * means that message will be transmitted as soon as the frame occures in the
255 * communication cycle.
257 * @param enable enable flag to be send
258 * @param direction direction flag to be send
259 * @param duty duty cycle value to be send
261 * @return SUCCESS when data were succesfully sent
262 * FAILURE when some error occured.
264 int8_t transmit_control_data(int enable, int direction, int duty)
268 // Write payload for buffer associated with frame 1
272 return rpp_fr_transmit_lpdu(0, 3, data, 3);
276 * Checks if some message was received on message buffer 2 of the FlexRay motor controller node.
278 * If new message was received, the function copies the data from the buffer.
280 * @param enable pointer to variable, where received enable flag will be stored
281 * @param direction pointer to variable, where received direction flag will be stored
282 * @param duty pointer to variable, where received duty cycle value will be stored
283 * @return 0 if message was received and is correct
284 * 1 if message no message was received
285 * 2 if receiving failed
287 int receive_control_data(int *enable, int *direction, int *duty)
290 Fr_RxLPduStatusType status;
293 if (rpp_fr_receive_lpdu(0, 3, data, &status, &size) == FAILURE)
295 if (status == FR_NOT_RECEIVED)
299 *direction = data[1];
306 * @brief Read data from control panel and send them to motor controller through FlexRay
308 * This node reads periodically each 10ms the ADC1 channel and computes
309 * the duty cycle. Then reads DIN0, which is connected to the red
310 * button on the control panel (connected as switch to battery) and then
311 * it reads the DIN1, which is connected to the black button (connected as
313 * Finally all data are sent on the Frame 3.
316 * @param[in] cmd_io Pointer to IO stack
317 * @param[in] des Pointer to command descriptor
318 * @param[in] param Parameters of command
319 * @return 0 when OK or error code
321 int cmd_do_control(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
323 port_desc_t *adc_desc;
324 uint32_t adc_values[PORT_ADC_CHANNEL_NUM*2];
330 int enable_cnt = 0; // Debounce counter for enable button
331 int dir_cnt = 0; // Debounce counter for direction button
334 adc_desc = hal_port_get_dsc(PORT_NAME_ADC, -1);
336 if (rpp_din_setup(0, FALSE, TRUE, FALSE) == FAILURE) { // For the red button, which is switch to battery
337 rpp_sci_printf("Din 0 setup failed.\n");
338 return -CMDERR_BADCFG;
340 if (rpp_din_setup(1, FALSE, TRUE, FALSE) == FAILURE) { // For the black button, which is switch to ground
341 rpp_sci_printf("Din 1 setup failed.\n");
342 return -CMDERR_BADCFG;
344 if (rpp_din_update() == FAILURE) {
345 rpp_sci_printf("Din update failed.\n");
346 return -CMDERR_BADCFG;
349 if (rpp_fr_init_driver(&Fr_config_node_control, &error) == FAILURE) {
350 rpp_sci_printf("Fray driver initialization failed: %#x.\n", error);
351 return -CMDERR_BADCFG;
353 if (rpp_fr_init_controller(0, &error) == FAILURE) {
354 rpp_sci_printf("Fray control node initialization failed: %#x.\n", error);
355 return -CMDERR_BADCFG;
357 rpp_sci_printf("Fray control node initialized.\r\n");
358 rpp_sci_printf("Waiting for network connection...\r\n");
360 if (rpp_fr_start_communication(0, &error) == FAILURE) {
361 rpp_sci_printf("Integration to the network failed: %#x.\n", error);
362 return -CMDERR_BADCFG;
364 if (rpp_fr_all_slots(0) == FAILURE) {
365 rpp_sci_printf("All slots mode selection failed.\n");
366 return -CMDERR_BADCFG;
369 rpp_sci_printf("Connected.\r\n");
372 vTaskDelay(10/portTICK_RATE_MS);
373 ret = adc_desc->port_getfnc_ptr(adc_desc->config, PORT_ADC_CHANNEL_NUM, adc_values);
375 rpp_sci_printf("ADC read failed!\n");
378 duty = (100*adc_values[0])/ADC_MAX_VALUE;
379 if (rpp_din_update() == FAILURE) {
380 rpp_sci_printf("Din update failed.\n");
383 button = !rpp_din_get(0);
385 if (enable_cnt++ == ENABLE_DEBOUNCE_TIME)
392 button = rpp_din_get(1);
394 if (dir_cnt++ == DIRECTION_DEBOUNCE_TIME)
395 direction = !direction;
402 if (transmit_control_data(enable, direction, duty) == FAILURE) {
403 rpp_sci_printf("Data transmission failed!\n");
406 rpp_sci_printf("Enable: %d, Direction: %s, Duty: %d%%\r", enable, (direction == 1) ? "L" : "R", duty);
409 if (rpp_fr_halt_communication(0) == FAILURE)
410 rpp_sci_printf("FlexRay HALT command failed, please reset the board to stop transmission.\n");
412 rpp_sci_printf("FlexRay halted, reset the board to make FlexRay usable again.\r\n");
417 * @brief Receive data from FlexRay and control motor on HBR
419 * This FlexRay node receives the control data from the FlexRay network
420 * and configures the H-bridge to drive the DC motor according the
421 * parameters from the received message.
423 * @param[in] cmd_io Pointer to IO stack
424 * @param[in] des Pointer to command descriptor
425 * @param[in] param Parameters of command
426 * @return 0 when OK or error code
428 int cmd_do_motor(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
430 double hbr_period = 50; // us
431 double control = 0.0;
435 uint32_t rx_error = 0;
439 if (rpp_hbr_enable(hbr_period) == FAILURE ||
440 rpp_hbr_control(0) == FAILURE
442 rpp_sci_printf("H-bridge initialization failed.\n");
443 return -CMDERR_BADCFG;
446 if (rpp_fr_init_driver(&Fr_config_node_motor, &error) == FAILURE) {
447 rpp_sci_printf("Fray driver initialization failed: %#x.\n", error);
448 return -CMDERR_BADCFG;
450 if (rpp_fr_init_controller(0, &error) == FAILURE) {
451 rpp_sci_printf("Fray motor node initialization failed: %#x.\n", error);
452 return -CMDERR_BADCFG;
454 rpp_sci_printf("Fray motor node initialized.\r\n");
455 rpp_sci_printf("Waiting for network connection...\r\n");
457 if (rpp_fr_start_communication(0, &error) == FAILURE) {
458 rpp_sci_printf("Integration to the network failed: %#x.\n", error);
459 return -CMDERR_BADCFG;
461 if (rpp_fr_all_slots(0) == FAILURE) {
462 rpp_sci_printf("All slots mode selection failed.\n");
463 return -CMDERR_BADCFG;
466 rpp_sci_printf("Connected.\r\n");
469 ret = receive_control_data(&enable, &direction, &hbr_duty);
470 if (ret == 2) { // receiving failed
472 if (rx_error > RX_ERROR_MAX) {
473 rpp_sci_printf("Maximum RX errors reached!\n");
477 else if (ret == 0) { // message received
478 control = hbr_duty/((double)100) * ((direction == 1) ? -1 : 1) * enable;
479 rpp_sci_printf("Enable: %d, Direction: %s, Duty: %d%%\r", enable, (direction == 1) ? "L" : "R", hbr_duty);
480 if (rpp_hbr_control(control) == FAILURE) {
481 rpp_sci_printf("H-bridge control failed!\n");
486 if (rpp_hbr_disable() == FAILURE)
487 rpp_sci_printf("H-bridge disabling failed!\n");
489 rpp_sci_printf("H-bridge disabled.\n");
490 if (rpp_fr_halt_communication(0) == FAILURE)
491 rpp_sci_printf("FlexRay HALT command failed, please reset the board to stop transmission.\n");
493 rpp_sci_printf("FlexRay halted, reset the board to make FlexRay usable again.\r\n");
499 /** Command descriptor for control */
500 cmd_des_t const cmd_des_control = {
502 "demomotctrl","Run motor control demo - reads input and sends it",
503 "### Command syntax ###\n"
507 "### Description ###\n"
509 "This command creates a FlexRay node and starts to read buttons\n"
510 "(connected to DIN0 and DIN1) and a potentiometer (ADC1) from a control\n"
511 "panel. The read data are sent via FlexRay to the second node, created\n"
512 "by running demomotdrive command.\n"
514 "The purpose of this pair of commands is to demonstrate functionality\n"
515 "of the FlexRay, ADC, DIN and HBR peripherals.\n",
516 CMD_HANDLER(cmd_do_control), (void *)&cmd_list_motor_example
519 /** Command descriptor for motor */
520 cmd_des_t const cmd_des_motor = {
522 "demomotdrive","Run motor control demo - drives the DC motor",
523 "### Command syntax ###\n"
527 "### Description ###\n"
529 "This command creates a FlexRay node and starts to receive the data\n"
530 "from another node created by command demomotctrl. The received data\n"
531 "are applied to HBR to control the DC motor.\n"
533 "The purpose of this pair of commands is to demonstrate functionality\n"
534 "of the FlexRay, ADC, DIN and HBR peripherals.\n",
535 CMD_HANDLER(cmd_do_motor), (void *)&cmd_list_motor_example
538 /** List of commands for example, defined as external */
539 cmd_des_t const *cmd_list_motor_example[] = {