--- /dev/null
+/*
+ * cmd_motor_example.c
+ *
+ * Created on: 16.5.2013
+ * Author: Michal Horn
+ *
+ * Example commands for motor controlling over FlexRay. First board has connected control panel
+ * with two buttons and variable resistor, second board has DC motor connected to H-bridge. Both
+ * boards are connected by FlexRay and user can drive motor by the control pannel (speed, direction
+ * and enabling).
+ */
+
+#include "cmd_motor_example.h"
+#include "cmdproc_io_tisci.h"
+#include "hal_port_def.h"
+#include "drv_din.h"
+#include "drv_fray.h"
+#include "drv_hbridge.h"
+
+#define ADC_MAX_VALUE 0x1000
+#define RX_ERROR_MAX 100
+
+/**
+ * Fill data structure with global configuration parameters.
+ * @param Fr_ConfigPtr Pointer to data structure to be filled
+ */
+void configure_fray_global_parameters(cfg *Fr_ConfigPtr) {
+ // GTUs (Global Time Unit ), PRTC configuration
+ Fr_ConfigPtr->gtu1 = 0x00036B00; // pMicroPerCycle = 224000d = 36B00h (has to be x40 of MacroPerCyle)
+ // [19:0]: These bits configure the duration of the communication cycle in microticks
+ Fr_ConfigPtr->gtu2 = 0x000F15E0; // gSyncodeMax = Fh, gMacroPerCycle = 5600d = 15E0h (cycle period, 5.6us)
+ //[13:0]: Macrotick per cycle (in macroticks). These bits configure the duration of one communication cycle
+ // in macroticks. The cycle length must be identical in all nodes of a cluster.
+ //[19:16]: Sync node max (in frames). These bits configure the maximum number of frames within a cluster
+ // with sync frame indicator bit SYN set. The number of frames must be identical in all nodes of a cluster.
+ Fr_ConfigPtr->gtu3 = 0x00061818; // gMacroInitialOffset = 6h, pMicroInitialOffset = 24d = 18h
+ Fr_ConfigPtr->gtu4 = 0x0AE40AE3; // gOffsetCorrectionStart - 1 = 2788d = AE4h, gMacroPerCycle - gdNIT - 1 = 2787d = AE3h
+ Fr_ConfigPtr->gtu5 = 0x33010303; // pDecodingCorrection = 51d = 33h, pClusterDriftDamping = 1h, pDelayCompensation = 3h
+ Fr_ConfigPtr->gtu6 = 0x01510081; // pdMaxDrift = 337d = 151h, pdAcceptedStartupRange = 129d = 81h
+
+ Fr_ConfigPtr->gtu7 = 0x00080056; // gNumberOfStaticSlots = 8h, gdStaticSlot = 86d = 56h
+ // [25:16]: These bits configure the number of static slots in a cycle.
+ // [9:0]: These bits configure the duration of a static slot (macroticks).
+
+ Fr_ConfigPtr->gtu8 = 0x015A0004; // gNumberOfMinislots = 346d = 15Ah, gdMinislot = 4h
+ // [28:16]:These bits configure the number of minislots in the dynamic segment of a cycle
+ // [5:0]: These bits configure the duration of a minislot
+
+ Fr_ConfigPtr->gtu9 = 0x00010204; // gdDynamicSlotIdlePhase = 1, gdMinislotActionPointOffset = 2, gdActionPointOffset = 4h
+ Fr_ConfigPtr->gtu10 = 0x015100CD; // pRateCorrectionOut = 337d = 151h, pOffsetCorrectionOut = 205d = CDh
+ Fr_ConfigPtr->gtu11 = 0x00000000; // pExternRateCorrection = 0, pExternOffsetCorrection = 0, no ext. clk. corr.
+
+
+ Fr_ConfigPtr->succ2 = 0x0F036DA2; // gListenNoise = Fh, pdListenTimeout = 224674d = 36DA2h
+ //LTN [27:24]: Listen timeout noise. Configures the upper limit for the startup and wakeup listen timeout in the
+ //presence of noise. Must be identical in all nodes of a cluster.
+ //The wakeup / startup noise timeout is calculated as follows: LT[20:0] � (LTN[3:0] + 1)
+ // LT[20:0]: Listen timeout. Configures the upper limit of the startup and wakeup listen timeout.
+
+ Fr_ConfigPtr->succ3 = 0x000000FF; // gMaxWithoutClockCorrectionFatal = Fh , passive = Fh
+ //WCF[7:4]: Maximum without clock correction fatal. These bits define the number of consecutive even/odd
+ //cycle pairs with missing clock correction terms that will cause a transition from
+ //NORMAL_ACTIVE or NORMAL_PASSIVE state.
+
+ //WCP[3:0]: Maximum without clock correction passive. These bits define the number of consecutive
+ //even/odd cycle pairs with missing clock correction terms that will cause a transition from
+ //NORMAL_ACTIVE to NORMAL_PASSIVE to HALT state.
+
+ Fr_ConfigPtr->prtc1 = 0x084C000A; // pWakeupPattern = 2h, gdWakeupSymbolRxWindow = 76d, BRP = 0, gdTSSTransmitter = Ah
+ //BRP[15:14]; Baud rate prescaler. These bits configure the baud rate on the FlexRay bus. The baud rates
+ //listed below are valid with a sample clock of 80 MHz. One bit time always consists of 8 samples
+ //independent of the configured baud rate. =0 ->10Mb/s
+
+ Fr_ConfigPtr->prtc2 = 0x3CB41212; // gdWakeupSymbolTxLow = 60d, gdWakeupSymbolTxIdle = 180d, gdWakeupSymbolRxLow = 18d, gdWakeupSymbolRxIdle = 18d
+
+ Fr_ConfigPtr->mhdc = 0x010D0009; // pLatestTransmit = 269d = 010Dh, gPayloadLengthStatic = 9h
+ //Start of latest transmit (in minislots). These bits configure the maximum minislot value allowed
+ //minislots before inhibiting new frame transmissions in the Dynamic Segment of the cycle.
+ //[7:0]: Static frame data length.
+
+ Fr_ConfigPtr->mrc = 0x00174004; // LCB=23d, FFB=64d, FDB=4d (0..3 static, 4..23 dyn., 0 fifo)
+}
+
+
+/**
+ * Configure FlexRay as control node.
+ * - Clear message RAMS
+ * - Configure global parameters
+ * - Initialize buffers
+ * - Go to ready state
+ * - Enable interrupts
+ * This function prepares FlexRay to send data in Frame 1.
+ * Frame 1 is synchronization frame.
+ * @return SUCCESS or FAILURE when error
+ */
+int config_init_fray_control() {
+ cfg Fr_Config;
+
+ if (fray_clear_msg_ram() != SUCCESS) {
+ return FAILURE;
+ }
+
+ fray_wait_for_POC_ready();
+ configure_fray_global_parameters(&Fr_Config);
+ fray_init(&Fr_Config);
+ fray_config_buffer(0, FRAY_BUF_MBI_EN|FRAY_BUF_CHB_EN|FRAY_BUF_CHA_EN|FRAY_BUF_TX|FRAY_BUF_SYNC_EN|FRAY_BUF_SFI_EN, 0, 1, 2, 0x80);
+ fray_config_buffer(1, FRAY_BUF_MBI_EN|FRAY_BUF_CHB_EN|FRAY_BUF_CHA_EN|FRAY_BUF_RX, 0, 2, 2, 0x85);
+
+ if (fray_controler_init() != SUCCESS) {
+ return FAILURE;
+ }
+
+ fray_init_irq();
+ return SUCCESS;
+}
+
+/**
+ * Configure FlexRay as control node.
+ * - Clear message RAMS
+ * - Configure global parameters
+ * - Initialize buffers
+ * - Go to ready state
+ * - Enable interrupts
+ * This function prepares FlexRay to send data in Frame 1.
+ * Frame 1 is synchronization frame.
+ * @return SUCCESS or FAILURE when error
+ */
+int config_init_fray_motor() {
+ cfg Fr_Config;
+
+ if (fray_clear_msg_ram() != SUCCESS) {
+ return FAILURE;
+ }
+
+ fray_wait_for_POC_ready();
+ configure_fray_global_parameters(&Fr_Config);
+ fray_init(&Fr_Config);
+ fray_config_buffer(0, FRAY_BUF_MBI_EN|FRAY_BUF_CHB_EN|FRAY_BUF_CHA_EN|FRAY_BUF_TX|FRAY_BUF_SYNC_EN|FRAY_BUF_SFI_EN, 0, 2, 2, 0x85);
+ fray_config_buffer(2, FRAY_BUF_MBI_EN|FRAY_BUF_CHB_EN|FRAY_BUF_CHA_EN|FRAY_BUF_RX, 0, 1, 2, 0x80);
+
+ if (fray_controler_init() != SUCCESS) {
+ return FAILURE;
+ }
+
+ fray_init_irq();
+ return SUCCESS;
+}
+
+/**
+ * Loads data into TX buffers for FlexRay node A.
+ * @param enable enable flag to be send
+ * @param direction direction flag to be send
+ * @param duty duty cycle value to be send
+ */
+void transmit_control_data(int enable, int direction, int duty) {
+ uint32_t data[1];
+
+ // write payload for buffers
+ // buffer #1
+ data[0] = 0 | duty | direction << 8 | enable << 16;
+ fray_buffer_set_data(0, data, 1);
+}
+
+/**
+ * Check if some message was received on message buffer 2 of FlexRay motor controller node.
+ * @param enable pointer to variable, where received enable flag will be stored
+ * @param direction pointer to variable, where received direction flag will be stored
+ * @param duty pointer to variable, where received duty cycle value will be stored
+ * @return 0 if message was received and is correct
+ * 1 if message no message was received
+ */
+int receive_control_data(int* enable, int* direction, int* duty) {
+ uint32_t data[1];
+ int error = 1; // No message received
+
+ // check if a message is received in buffer 2 from node B
+ if (fray_buffer_message_received(2)) {
+ fray_buffer_get_data(2, data, 1);
+ error = 0;
+ *duty = data[0] & 0xFF;
+ *direction = data[0]&0xFF00 >> 8;
+ *enable = data[0]&0xFF0000 >> 16;
+ }
+ return error;
+}
+
+
+/**
+ * @brief Read data from control panel and send them to motor controller through FlexRay
+ *
+ * Command syntax: control
+ *
+ * @param[in] cmd_io Pointer to IO stack
+ * @param[in] des Pointer to command descriptor
+ * @param[in] param Parameters of command
+ * @return 0 when OK or error code
+ */
+int cmd_do_control(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[]) {
+ port_desc_t* adc_desc;
+ uint32_t adc_values[PORT_ADC_CHANNEL_NUM*2];
+ int ret;
+ int duty = 0;
+ int enable = 0;
+ int direction = 1;
+
+ adc_desc = hal_port_get_dsc(PORT_NAME_ADC, -1);
+
+ din_reset();
+ din_set_pr(0x2); // Set DIN0 to switch to ground and DIN1 to switch do battery
+ din_set_int(0,0); // Disable interrupt and wake-up function
+ din_set_stat(0xFFFC, 0xFFFF); // Set DIN0 and DIN1 as active
+ din_switch_st(); // Prepare for input state read
+
+ if (config_init_fray_control() != SUCCESS) {
+ print((uint8_t*)"Fray control node initialization failed.\r\n");
+ return 0;
+ }
+ print((uint8_t*)"Fray control node initialized.\r\n");
+ print((uint8_t*)"Waiting for network connection...\r\n");
+
+ if (fray_startup_procedure(1) != SUCCESS) {
+ print((uint8_t*)"Integration to the network failed.\r\n");
+ return 0;
+ }
+
+ print((uint8_t*)"Connected.\r\n");
+
+ while(1) {
+ // wait for cycle start interrupt flag
+ fray_wait_for_new_cycle();
+ ret = adc_desc->port_getfnc_ptr(adc_desc->config, PORT_ADC_CHANNEL_NUM, adc_values);
+ if (ret < 0) {
+ print((uint8_t*)"ADC read failed!");
+ break;
+ }
+ duty = (100*adc_values[0])/ADC_MAX_VALUE;
+ din_spi_transfer();
+ enable = din_get_pin_val(0);
+ direction = din_get_pin_val(1);
+ transmit_control_data(enable, direction, duty);
+ }
+
+ if (fray_halt() != SUCCESS) {
+ print((uint8_t*)"FlexRay HALT command failed, please reset the board to stop transmission.\r\n");
+ }
+ else {
+ print((uint8_t*)"FlexRay halted\r\n");
+ }
+ return 0;
+}
+
+/**
+ * @brief Receive data from FlexRay and control motor on HBR
+ *
+ * Command syntax: motor
+ *
+ * @param[in] cmd_io Pointer to IO stack
+ * @param[in] des Pointer to command descriptor
+ * @param[in] param Parameters of command
+ * @return 0 when OK or error code
+ */
+int cmd_do_motor(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[]) {
+ double hbr_period = 1000;
+ int hbr_duty = 0;
+ int direction = 1;
+ int enable = 0;
+ uint32_t rx_error = 0;
+ int ret;
+
+ hbr_pwm_set_signal(hbr_period, hbr_duty);
+ hbr_set_en(enable);
+ hbr_set_dir(direction);
+ hbr_spi_wdg_transfer();
+
+ if (config_init_fray_motor() != SUCCESS) {
+ print((uint8_t*)"Fray motor node initialization failed.\r\n");
+ return 0;
+ }
+ print((uint8_t*)"Fray motor node initialized.\r\n");
+ print((uint8_t*)"Waiting for network connection...\r\n");
+
+ if (fray_startup_procedure(1) != SUCCESS) {
+ print((uint8_t*)"Integration to the network failed.\r\n");
+ return 0;
+ }
+
+ print((uint8_t*)"Connected.\r\n");
+
+ while (1) {
+ fray_wait_for_new_cycle();
+ ret = receive_control_data(&enable, &direction, &hbr_duty);
+ if (ret == 1) {
+ rx_error++;
+ if (rx_error > RX_ERROR_MAX) {
+ hbr_set_en(0);
+ print((uint8_t*)"Maximum RX errors reached!");
+ break;
+ }
+ }
+ }
+ if (fray_halt() != SUCCESS) {
+ print((uint8_t*)"FlexRay HALT command failed, please reset the board to stop transmission.\r\n");
+ }
+ else {
+ print((uint8_t*)"FlexRay halted\r\n");
+ }
+ return 0;
+}
+
+/** Command descriptor for control */
+cmd_des_t const cmd_des_control={
+ 0, 0,
+ "control","Run example - control panel",
+ cmd_do_control, (void *)&cmd_list_motor_example
+ };
+
+/** Command descriptor for motor */
+cmd_des_t const cmd_des_motor={
+ 0, 0,
+ "motor","Run example - motor controller",
+ cmd_do_motor, (void *)&cmd_list_motor_example
+ };
+
+/** List of commands for example, defined as external */
+cmd_des_t const *cmd_list_motor_example[]={
+ &cmd_des_control,
+ &cmd_des_motor,
+ NULL
+};