From 46ee23e97538f99fee55bb36c67e3320c94b7cbf Mon Sep 17 00:00:00 2001 From: EmanuelFeru Date: Mon, 30 Nov 2020 19:23:30 +0100 Subject: [PATCH] Added iBUS on AUX Serial - iBUS implementation - changed default baud rate to 115200 - updated platformio.ini, the chip is now supported by Platformio --- Inc/config.h | 52 ++++++--- Inc/defines.h | 32 +++--- Inc/gd32f1x0_it.h | 2 + Inc/mpu6050.h | 15 +-- Inc/util.h | 32 +++++- Src/gd32f1x0_it.c | 16 ++- Src/main.c | 273 +++++++++++++++++++++++++++------------------- Src/setup.c | 105 ++++++++++++------ Src/util.c | 115 ++++++++++++++++--- add_nanolib.py | 3 +- platformio.ini | 40 +++++-- 11 files changed, 464 insertions(+), 221 deletions(-) diff --git a/Inc/config.h b/Inc/config.h index f8d66c1..93033c9 100644 --- a/Inc/config.h +++ b/Inc/config.h @@ -27,8 +27,9 @@ // Ubuntu: define the desired build variant here if you want to use make in console // or use VARIANT environment variable for example like "make -e VARIANT=VARIANT_DEBUG". Select only one at a time. #if !defined(PLATFORMIO) - // #define VARIANT_DEBUG // Variant for debugging and checking the capabilities of the side-board - // #define VARIANT_HOVERBOARD // Variant for using the side-boards connected to the Hoverboard mainboard + // #define VARIANT_DEBUG // Variant for debugging and checking the capabilities of the side-board + // #define VARIANT_HOVERCAR // Variant for using the side-boards connected to the Hoverboard mainboard + // #define VARIANT_HOVERBOARD // Variant for using the side-boards connected to the Hoverboard mainboard #endif /* ==================================== DO NOT TOUCH SETTINGS ==================================== */ @@ -40,7 +41,6 @@ // #define PRINTF_FLOAT_SUPPORT // [-] Uncomment this for printf to support float on Serial Debug. It will increase code size! Better to avoid it! /* =============================================================================================== */ - /* ==================================== SETTINGS MPU-6050 ==================================== */ #define MPU_SENSOR_ENABLE // [-] Enable flag for MPU-6050 sensor. Comment-out this flag to Disable the MPU sensor and reduce code size. #define MPU_DMP_ENABLE // [-] Enable flag for MPU-6050 DMP (Digital Motion Processing) functionality. @@ -59,32 +59,50 @@ #define DMP_SHAKE_REJECT_TIME 40 // [ms] Set shake rejection time. Sets the length of time that the gyro must be outside of the DMP_SHAKE_REJECT_THRESH before taps are rejected. A mandatory 60 ms is added to this parameter. #define DMP_SHAKE_REJECT_TIMEOUT 10 // [ms] Set shake rejection timeout. Sets the length of time after a shake rejection that the gyro must stay inside of the threshold before taps can be detected again. A mandatory 60 ms is added to this parameter. - /* ==================================== SETTINGS USART ==================================== */ -#if defined(VARIANT_DEBUG) - #define SERIAL_DEBUG // [-] Define for Serial Debug via the serial port -#elif defined(VARIANT_HOVERBOARD) - #define SERIAL_CONTROL // [-] Define for Serial Control via the serial port - #define SERIAL_FEEDBACK // [-] Define for Serial Feedback via the serial port -#endif -#define USART_MAIN_BAUD 38400 // [bit/s] MAIN Serial Tx/Rx baud rate #define SERIAL_START_FRAME 0xABCD // [-] Start frame definition for reliable serial communication #define SERIAL_BUFFER_SIZE 64 // [bytes] Size of Serial Rx buffer. Make sure it is always larger than the 'Feedback' structure size #define SERIAL_TIMEOUT 600 // [-] Number of wrong received data for Serial timeout detection. Depends on DELAY_IN_MAIN_LOOP - +#define USART_MAIN_BAUD 115200 // [bit/s] MAIN Serial Tx/Rx baud rate +#define USART_AUX_BAUD 115200 // [bit/s] AUX Serial Tx/Rx baud rate /* ==================================== SETTINGS AUX ==================================== */ // #define AUX45_USE_GPIO // [-] Use AUX4, AUX5 as GPIO ports // #define AUX45_USE_I2C // [-] Use AUX4, AUX5 as I2C port -#define AUX45_USE_USART // [-] Use AUX4, AUX5 as USART port -#ifdef AUX45_USE_USART - #define USART_AUX_BAUD 38400 // [bit/s] AUX Serial Tx/Rx baud rate -#endif #ifdef AUX45_USE_I2C #define AUX_I2C_SPEED 100000 // [bit/s] Define I2C speed for communicating via AUX45 wires #endif + +/* ==================================== VARIANT DEBUG ==================================== */ +#ifdef VARIANT_DEBUG + #define SERIAL_DEBUG // [-] Define for Serial Debug via the serial port +#endif + + +/* ==================================== VARIANT HOVERCAR ==================================== */ +#ifdef VARIANT_HOVERCAR + #define SERIAL_CONTROL // [-] Define for Serial Control via the serial port + #define SERIAL_FEEDBACK // [-] Define for Serial Feedback via the serial port + #define SERIAL_AUX_TX // [-] Use AUX4, AUX5 as USART port + #define SERIAL_AUX_RX // [-] Use AUX4, AUX5 as USART port + + #define CONTROL_IBUS + #define IBUS_NUM_CHANNELS 14 // total number of IBUS channels to receive, even if they are not used. + #define IBUS_LENGTH 0x20 + #define IBUS_COMMAND 0x40 +#endif + + +/* ==================================== VARIANT HOVERBOARD ==================================== */ +#ifdef VARIANT_HOVERBOARD + #define SERIAL_CONTROL // [-] Define for Serial Control via the serial port + #define SERIAL_FEEDBACK // [-] Define for Serial Feedback via the serial port +#endif + + + /* ==================================== VALIDATE SETTINGS ==================================== */ #if defined(SERIAL_DEBUG) && defined(SERIAL_CONTROL) #error SERIAL_DEBUG and SERIAL_CONTROL not allowed. It is on the same cable. @@ -94,7 +112,7 @@ #error SERIAL_DEBUG and SERIAL_FEEDBACK not allowed. It is on the same cable. #endif -#if defined(AUX45_USE_GPIO) && (defined(AUX45_USE_USART) || defined(AUX45_USE_I2C)) || (defined(AUX45_USE_USART) && defined(AUX45_USE_I2C)) +#if defined(AUX45_USE_GPIO) && (defined(SERIAL_AUX_RX) || defined(AUX45_USE_I2C)) || (defined(SERIAL_AUX_RX) && defined(AUX45_USE_I2C)) #error AUX45_USE_(GPIO,USART,I2C) not allowed in the same time. It is on the same cable. #endif diff --git a/Inc/defines.h b/Inc/defines.h index 203ed0b..0914584 100644 --- a/Inc/defines.h +++ b/Inc/defines.h @@ -77,24 +77,24 @@ // USART ports number #define USARTn 2 - -// USART to Auxiliary, connected to USART0 +// USART AUX, connected to USART0 #define USART_AUX USART0 -#define USART_AUX_CLK RCU_USART0 -#define USART_AUX_TX_PIN GPIO_PIN_9 -#define USART_AUX_RX_PIN GPIO_PIN_10 - - -// USART to Mainboard, connected to USART1 -#define USART_MAIN USART1 -#define USART_MAIN_CLK RCU_USART1 -#define USART_MAIN_TX_PIN GPIO_PIN_2 -#define USART_MAIN_RX_PIN GPIO_PIN_3 - -// USART address for DMA defines -#define USART0_TDATA_ADDRESS ((uint32_t)0x40013828) // USART0: 0x4001 3800 - 0x4001 3BFF +#define USART0_CLK RCU_USART0 +#define USART0_TX_PIN GPIO_PIN_9 +#define USART0_RX_PIN GPIO_PIN_10 +#define USART0_TX_DMA_CH DMA_CH1 +#define USART0_RX_DMA_CH DMA_CH2 +#define USART0_TDATA_ADDRESS ((uint32_t)0x40013828) // USART0: 0x4001 3800 - 0x4001 3BFF, Rx offset: 0x28, Tx offset: 0x24 #define USART0_RDATA_ADDRESS ((uint32_t)0x40013824) -#define USART1_TDATA_ADDRESS ((uint32_t)0x40004428) // USART1: 0x4000 4400 - 0x4000 47FF + +// USART MAIN, connected to USART1 +#define USART_MAIN USART1 +#define USART1_CLK RCU_USART1 +#define USART1_TX_PIN GPIO_PIN_2 +#define USART1_RX_PIN GPIO_PIN_3 +#define USART1_TX_DMA_CH DMA_CH3 +#define USART1_RX_DMA_CH DMA_CH4 +#define USART1_TDATA_ADDRESS ((uint32_t)0x40004428) // USART1: 0x4000 4400 - 0x4000 47FF, Rx offset: 0x28, Tx offset: 0x24 #define USART1_RDATA_ADDRESS ((uint32_t)0x40004424) diff --git a/Inc/gd32f1x0_it.h b/Inc/gd32f1x0_it.h index 92f0da3..ee82add 100644 --- a/Inc/gd32f1x0_it.h +++ b/Inc/gd32f1x0_it.h @@ -38,6 +38,8 @@ void PendSV_Handler(void); /* SysTick handle function */ void SysTick_Handler(void); /* USART0 handle function */ +void USART0_IRQHandler(void); +/* USART1 handle function */ void USART1_IRQHandler(void); /* I2C0 event handle function */ void I2C0_EV_IRQHandler(void); diff --git a/Inc/mpu6050.h b/Inc/mpu6050.h index 7faaa10..12c63ee 100644 --- a/Inc/mpu6050.h +++ b/Inc/mpu6050.h @@ -104,18 +104,13 @@ int mpu_get_compass_reg(short *data, unsigned long *timestamp); int mpu_get_temperature(long *data, unsigned long *timestamp); int mpu_get_int_status(short *status); -int mpu_read_fifo(short *gyro, short *accel, unsigned long *timestamp, - unsigned char *sensors, unsigned char *more); -int mpu_read_fifo_stream(unsigned short length, unsigned char *data, - unsigned char *more); +int mpu_read_fifo(short *gyro, short *accel, unsigned long *timestamp, unsigned char *sensors, unsigned char *more); +int mpu_read_fifo_stream(unsigned short length, unsigned char *data, unsigned char *more); int mpu_reset_fifo(void); -int mpu_write_mem(unsigned short mem_addr, unsigned short length, - unsigned char *data); -int mpu_read_mem(unsigned short mem_addr, unsigned short length, - unsigned char *data); -int mpu_load_firmware(unsigned short length, const unsigned char *firmware, - unsigned short start_addr, unsigned short sample_rate); +int mpu_write_mem(unsigned short mem_addr, unsigned short length, unsigned char *data); +int mpu_read_mem(unsigned short mem_addr, unsigned short length, unsigned char *data); +int mpu_load_firmware(unsigned short length, const unsigned char *firmware, unsigned short start_addr, unsigned short sample_rate); int mpu_reg_dump(void); int mpu_read_reg(unsigned char reg, unsigned char *data); diff --git a/Inc/util.h b/Inc/util.h index 0bdea4f..3b5ea61 100644 --- a/Inc/util.h +++ b/Inc/util.h @@ -23,8 +23,7 @@ #include - -/* Rx Structures USART */ +/* Tx structure USART MAIN */ #ifdef SERIAL_CONTROL typedef struct{ uint16_t start; @@ -35,6 +34,7 @@ typedef struct{ uint16_t checksum; } SerialSideboard; #endif +/* Rx structure USART MAIN */ #ifdef SERIAL_FEEDBACK typedef struct{ uint16_t start; @@ -49,6 +49,28 @@ typedef struct{ } SerialFeedback; #endif +/* Tx structure USART AUX */ +#ifdef SERIAL_AUX_TX +typedef struct{ + uint16_t start; + int16_t signal1; + int16_t signal2; + uint16_t checksum; +} SerialAuxTx; +#endif +/* Rx structure USART AUX */ +#ifdef SERIAL_AUX_RX + #ifdef CONTROL_IBUS + typedef struct{ + uint8_t start; + uint8_t type; + uint8_t channels[IBUS_NUM_CHANNELS*2]; + uint8_t checksuml; + uint8_t checksumh; + } SerialCommand; + #endif +#endif + /* general functions */ void consoleLog(char *message); void toggle_led(uint32_t gpio_periph, uint32_t pin); @@ -58,13 +80,17 @@ void intro_demo_led(uint32_t tDelay); void input_init(void); /* usart read functions */ -void usart_rx_check(void); +void usart0_rx_check(void); +void usart1_rx_check(void); #ifdef SERIAL_DEBUG void usart_process_debug(uint8_t *userCommand, uint32_t len); #endif #ifdef SERIAL_FEEDBACK void usart_process_data(SerialFeedback *Feedback_in, SerialFeedback *Feedback_out); #endif +#ifdef SERIAL_AUX_RX +void usart_process_command(SerialCommand *command_in, SerialCommand *command_out); +#endif /* i2c write/read functions */ int8_t i2c_writeBytes(uint8_t slaveAddr, uint8_t regAddr, uint8_t length, uint8_t *data); diff --git a/Src/gd32f1x0_it.c b/Src/gd32f1x0_it.c index 5ce9e3c..ea756ab 100644 --- a/Src/gd32f1x0_it.c +++ b/Src/gd32f1x0_it.c @@ -122,6 +122,20 @@ void SysTick_Handler(void) delay_decrement(); } +/*! + \brief this function handles the USART0 interrupt request + \param[in] none + \param[out] none + \retval none +*/ +void USART0_IRQHandler(void) +{ + if(RESET != usart_interrupt_flag_get(USART0, USART_INT_FLAG_IDLE)) { // Check for IDLE line interrupt + usart_flag_clear(USART0, USART_FLAG_IDLE); // Clear IDLE line flag (otherwise it will continue to enter interrupt) + usart0_rx_check(); // Check for data to process + } +} + /*! \brief this function handles the USART1 interrupt request \param[in] none @@ -132,7 +146,7 @@ void USART1_IRQHandler(void) { if(RESET != usart_interrupt_flag_get(USART1, USART_INT_FLAG_IDLE)) { // Check for IDLE line interrupt usart_flag_clear(USART1, USART_FLAG_IDLE); // Clear IDLE line flag (otherwise it will continue to enter interrupt) - usart_rx_check(); // Check for data to process + usart1_rx_check(); // Check for data to process } } diff --git a/Src/main.c b/Src/main.c index 8810e25..6be65a1 100644 --- a/Src/main.c +++ b/Src/main.c @@ -35,130 +35,179 @@ extern SerialSideboard Sideboard; #ifdef SERIAL_FEEDBACK extern SerialFeedback Feedback; -extern uint16_t timeoutCntSerial; // Timeout counter for Rx Serial command -extern uint8_t timeoutFlagSerial; // Timeout Flag for Rx Serial command: 0 = OK, 1 = Problem detected (line disconnected or wrong Rx data) +extern uint16_t timeoutCntSerial; // Timeout counter for UART1 Rx Serial +extern uint8_t timeoutFlagSerial; // Timeout Flag for UART1 Rx Serial: 0 = OK, 1 = Problem detected (line disconnected or wrong Rx data) #endif -extern MPU_Data mpu; // holds the MPU-6050 data -extern ErrStatus mpuStatus; // holds the MPU-6050 status: SUCCESS or ERROR +#ifdef SERIAL_AUX_TX +extern SerialAuxTx AuxTx; +#endif -FlagStatus sensor1, sensor2; // holds the sensor1 and sensor 2 values -FlagStatus sensor1_read, sensor2_read; // holds the instantaneous Read for sensor1 and sensor 2 +#ifdef SERIAL_AUX_RX +extern SerialCommand command; +extern uint16_t timeoutCntSerial0; // Timeout counter for UART0 Rx Serial +extern uint8_t timeoutFlagSerial0; // Timeout Flag for UART0Rx Serial: 0 = OK, 1 = Problem detected (line disconnected or wrong Rx data) + #ifdef CONTROL_IBUS + uint16_t ibus_captured_value[IBUS_NUM_CHANNELS]; + #endif +#endif -static uint32_t main_loop_counter; // main loop counter to perform task squeduling inside main() +extern MPU_Data mpu; // holds the MPU-6050 data +extern ErrStatus mpuStatus; // holds the MPU-6050 status: SUCCESS or ERROR + +FlagStatus sensor1, sensor2; // holds the sensor1 and sensor 2 values +FlagStatus sensor1_read, sensor2_read; // holds the instantaneous Read for sensor1 and sensor 2 + +static uint32_t main_loop_counter; // main loop counter to perform task squeduling inside main() int main(void) -{ - systick_config(); // SysTick config - gpio_config(); // GPIO config - usart_nvic_config(); // USART interrupt configuration - usart_config(USART_MAIN, USART_MAIN_BAUD); // USART config - i2c_config(); // I2C config - i2c_nvic_config(); // I2C interrupt configuration - input_init(); // Input initialization +{ + systick_config(); // SysTick config + gpio_config(); // GPIO config + usart_nvic_config(); // USART interrupt configuration + usart_config(USART_MAIN, USART_MAIN_BAUD); // USART MAIN config + #if defined(SERIAL_AUX_RX) || defined(SERIAL_AUX_TX) + usart_config(USART_AUX, USART_AUX_BAUD); // USART AUX config + #endif + i2c_config(); // I2C config + i2c_nvic_config(); // I2C interrupt configuration + input_init(); // Input initialization - while(1) { - - delay_1ms(DELAY_IN_MAIN_LOOP); - - // ==================================== LEDs Handling ==================================== - // toggle_led(LED4_GPIO_Port, LED4_Pin); // Toggle BLUE1 LED - #ifdef SERIAL_FEEDBACK - if (!timeoutFlagSerial) { - if (Feedback.cmdLed & LED1_SET) { gpio_bit_set(LED1_GPIO_Port, LED1_Pin); } else { gpio_bit_reset(LED1_GPIO_Port, LED1_Pin); } - if (Feedback.cmdLed & LED2_SET) { gpio_bit_set(LED2_GPIO_Port, LED2_Pin); } else { gpio_bit_reset(LED2_GPIO_Port, LED2_Pin); } - if (Feedback.cmdLed & LED3_SET) { gpio_bit_set(LED3_GPIO_Port, LED3_Pin); } else { gpio_bit_reset(LED3_GPIO_Port, LED3_Pin); } - if (Feedback.cmdLed & LED4_SET) { gpio_bit_set(LED4_GPIO_Port, LED4_Pin); } else { gpio_bit_reset(LED4_GPIO_Port, LED4_Pin); } - if (Feedback.cmdLed & LED5_SET) { gpio_bit_set(LED5_GPIO_Port, LED5_Pin); } else { gpio_bit_reset(LED5_GPIO_Port, LED5_Pin); } - if (Feedback.cmdLed & LED4_SET) { gpio_bit_set(AUX3_GPIO_Port, AUX3_Pin); } else { gpio_bit_reset(AUX3_GPIO_Port, AUX3_Pin); } - } - #endif - + while(1) { - // ==================================== MPU-6050 Handling ==================================== - #ifdef MPU_SENSOR_ENABLE - // Get MPU data. Because the MPU-6050 interrupt pin is not wired we have to check DMP data by pooling periodically - if (SUCCESS == mpuStatus) { - mpu_get_data(); - } else if (ERROR == mpuStatus && main_loop_counter % 100 == 0) { - toggle_led(LED1_GPIO_Port, LED1_Pin); // Toggle the Red LED every 100 ms - } - // Print MPU data to Console - if (main_loop_counter % 50 == 0) { - mpu_print_to_console(); - } - #endif + delay_1ms(DELAY_IN_MAIN_LOOP); + + // ==================================== LEDs Handling ==================================== + // toggle_led(LED4_GPIO_Port, LED4_Pin); // Toggle BLUE1 LED + #ifdef SERIAL_FEEDBACK + if (!timeoutFlagSerial) { + if (Feedback.cmdLed & LED1_SET) { gpio_bit_set(LED1_GPIO_Port, LED1_Pin); } else { gpio_bit_reset(LED1_GPIO_Port, LED1_Pin); } + if (Feedback.cmdLed & LED2_SET) { gpio_bit_set(LED2_GPIO_Port, LED2_Pin); } else { gpio_bit_reset(LED2_GPIO_Port, LED2_Pin); } + if (Feedback.cmdLed & LED3_SET) { gpio_bit_set(LED3_GPIO_Port, LED3_Pin); } else { gpio_bit_reset(LED3_GPIO_Port, LED3_Pin); } + if (Feedback.cmdLed & LED4_SET) { gpio_bit_set(LED4_GPIO_Port, LED4_Pin); } else { gpio_bit_reset(LED4_GPIO_Port, LED4_Pin); } + if (Feedback.cmdLed & LED5_SET) { gpio_bit_set(LED5_GPIO_Port, LED5_Pin); } else { gpio_bit_reset(LED5_GPIO_Port, LED5_Pin); } + if (Feedback.cmdLed & LED4_SET) { gpio_bit_set(AUX3_GPIO_Port, AUX3_Pin); } else { gpio_bit_reset(AUX3_GPIO_Port, AUX3_Pin); } + } + #endif - // ==================================== SENSORS Handling ==================================== - sensor1_read = gpio_input_bit_get(SENSOR1_GPIO_Port, SENSOR1_Pin); - sensor2_read = gpio_input_bit_get(SENSOR2_GPIO_Port, SENSOR2_Pin); - // SENSOR1 - if (sensor1 == RESET && sensor1_read == SET) { - // Sensor ACTIVE: Do something here (one time task on activation) - sensor1 = SET; - gpio_bit_set(LED4_GPIO_Port, LED4_Pin); - consoleLog("-- SENSOR 1 Active --\n"); - } else if(sensor1 == SET && sensor1_read == RESET) { - // Sensor DEACTIVE: Do something here (one time task on deactivation) - sensor1 = RESET; - gpio_bit_reset(LED4_GPIO_Port, LED4_Pin); - consoleLog("-- SENSOR 1 Deactive --\n"); - } - - // SENSOR2 - if (sensor2 == RESET && sensor2_read == SET) { - // Sensor ACTIVE: Do something here (one time task on activation) - sensor2 = SET; - gpio_bit_set(LED5_GPIO_Port, LED5_Pin); - consoleLog("-- SENSOR 2 Active --\n"); - } else if (sensor2 == SET && sensor2_read == RESET) { - // Sensor DEACTIVE: Do something here (one time task on deactivation) - sensor2 = RESET; - gpio_bit_reset(LED5_GPIO_Port, LED5_Pin); - consoleLog("-- SENSOR 2 Deactive --\n"); - } + // ==================================== MPU-6050 Handling ==================================== + #ifdef MPU_SENSOR_ENABLE + // Get MPU data. Because the MPU-6050 interrupt pin is not wired we have to check DMP data by pooling periodically + if (SUCCESS == mpuStatus) { + mpu_get_data(); + } else if (ERROR == mpuStatus && main_loop_counter % 100 == 0) { + toggle_led(LED1_GPIO_Port, LED1_Pin); // Toggle the Red LED every 100 ms + } + // Print MPU data to Console + if (main_loop_counter % 50 == 0) { + mpu_print_to_console(); + } + #endif - if (sensor1 == SET) { - // Sensor ACTIVE: Do something here (continuous task) - } - if (sensor2 == SET) { - // Sensor ACTIVE: Do something here (continuous task) - } - - - // ==================================== SERIAL Tx/Rx Handling ==================================== - #ifdef SERIAL_CONTROL - // To transmit on USART - if (main_loop_counter % 5 == 0 && dma_transfer_number_get(DMA_CH3) == 0) { // Check if DMA channel counter is 0 (meaning all data has been transferred) - Sideboard.start = (uint16_t)SERIAL_START_FRAME; - Sideboard.roll = (int16_t)mpu.euler.roll; - Sideboard.pitch = (int16_t)mpu.euler.pitch; - Sideboard.yaw = (int16_t)mpu.euler.yaw; - Sideboard.sensors = (uint16_t)(sensor1 | (sensor2 << 1) | (mpuStatus << 2)); - Sideboard.checksum = (uint16_t)(Sideboard.start ^ Sideboard.roll ^ Sideboard.pitch ^ Sideboard.yaw ^ Sideboard.sensors); - - dma_channel_disable(DMA_CH3); - DMA_CHCNT(DMA_CH3) = sizeof(Sideboard); - DMA_CHMADDR(DMA_CH3) = (uint32_t)&Sideboard; - dma_channel_enable(DMA_CH3); - } - #endif - - #ifdef SERIAL_FEEDBACK - if (timeoutCntSerial++ >= SERIAL_TIMEOUT) { // Timeout qualification - timeoutFlagSerial = 1; // Timeout detected - timeoutCntSerial = SERIAL_TIMEOUT; // Limit timout counter value - } - if (timeoutFlagSerial && main_loop_counter % 100 == 0) { // In case of timeout bring the system to a Safe State and indicate error if desired - toggle_led(LED3_GPIO_Port, LED3_Pin); // Toggle the Yellow LED every 100 ms - } - #endif - - main_loop_counter++; - - } + // ==================================== SENSORS Handling ==================================== + sensor1_read = gpio_input_bit_get(SENSOR1_GPIO_Port, SENSOR1_Pin); + sensor2_read = gpio_input_bit_get(SENSOR2_GPIO_Port, SENSOR2_Pin); + + // SENSOR1 + if (sensor1 == RESET && sensor1_read == SET) { + // Sensor ACTIVE: Do something here (one time task on activation) + sensor1 = SET; + gpio_bit_set(LED4_GPIO_Port, LED4_Pin); + consoleLog("-- SENSOR 1 Active --\n"); + } else if(sensor1 == SET && sensor1_read == RESET) { + // Sensor DEACTIVE: Do something here (one time task on deactivation) + sensor1 = RESET; + gpio_bit_reset(LED4_GPIO_Port, LED4_Pin); + consoleLog("-- SENSOR 1 Deactive --\n"); + } + + // SENSOR2 + if (sensor2 == RESET && sensor2_read == SET) { + // Sensor ACTIVE: Do something here (one time task on activation) + sensor2 = SET; + gpio_bit_set(LED5_GPIO_Port, LED5_Pin); + consoleLog("-- SENSOR 2 Active --\n"); + } else if (sensor2 == SET && sensor2_read == RESET) { + // Sensor DEACTIVE: Do something here (one time task on deactivation) + sensor2 = RESET; + gpio_bit_reset(LED5_GPIO_Port, LED5_Pin); + consoleLog("-- SENSOR 2 Deactive --\n"); + } + + if (sensor1 == SET) { + // Sensor ACTIVE: Do something here (continuous task) + } + if (sensor2 == SET) { + // Sensor ACTIVE: Do something here (continuous task) + } + + + // ==================================== SERIAL Tx/Rx Handling ==================================== + // Tx USART MAIN + #ifdef SERIAL_CONTROL + if (main_loop_counter % 5 == 0 && dma_transfer_number_get(USART1_TX_DMA_CH) == 0) { // Check if DMA channel counter is 0 (meaning all data has been transferred) + Sideboard.start = (uint16_t)SERIAL_START_FRAME; + Sideboard.roll = (int16_t)mpu.euler.roll; + Sideboard.pitch = (int16_t)mpu.euler.pitch; + Sideboard.yaw = (int16_t)mpu.euler.yaw; + Sideboard.sensors = (uint16_t)(sensor1 | (sensor2 << 1) | (mpuStatus << 2)); + Sideboard.checksum = (uint16_t)(Sideboard.start ^ Sideboard.roll ^ Sideboard.pitch ^ Sideboard.yaw ^ Sideboard.sensors); + + dma_channel_disable(USART1_TX_DMA_CH); + DMA_CHCNT(USART1_TX_DMA_CH) = sizeof(Sideboard); + DMA_CHMADDR(USART1_TX_DMA_CH) = (uint32_t)&Sideboard; + dma_channel_enable(USART1_TX_DMA_CH); + } + #endif + // Rx USART MAIN + #ifdef SERIAL_FEEDBACK + if (timeoutCntSerial++ >= SERIAL_TIMEOUT) { // Timeout qualification + timeoutFlagSerial = 1; // Timeout detected + timeoutCntSerial = SERIAL_TIMEOUT; // Limit timout counter value + } + if (timeoutFlagSerial && main_loop_counter % 100 == 0) { // In case of timeout bring the system to a Safe State and indicate error if desired + toggle_led(LED3_GPIO_Port, LED3_Pin); // Toggle the Yellow LED every 100 ms + } + #endif + + // Tx USART AUX + #ifdef SERIAL_AUX_TX + if (main_loop_counter % 5 == 0 && dma_transfer_number_get(USART0_TX_DMA_CH) == 0) { // Check if DMA channel counter is 0 (meaning all data has been transferred) + AuxTx.start = (uint16_t)SERIAL_START_FRAME; + AuxTx.signal1 = (int16_t)sensor1; + AuxTx.signal2 = (int16_t)sensor2; + AuxTx.checksum = (uint16_t)(AuxTx.start ^ AuxTx.signal1 ^ AuxTx.signal2); + + dma_channel_disable(USART0_TX_DMA_CH); + DMA_CHCNT(USART0_TX_DMA_CH) = sizeof(AuxTx); + DMA_CHMADDR(USART0_TX_DMA_CH) = (uint32_t)&AuxTx; + dma_channel_enable(USART0_TX_DMA_CH); + } + #endif + // Rx USART AUX + #ifdef SERIAL_AUX_RX + #ifdef CONTROL_IBUS + for (uint8_t i = 0; i < (IBUS_NUM_CHANNELS * 2); i+=2) { + ibus_captured_value[(i/2)] = command.channels[i] + (command.channels[i+1] << 8) - 1000; // 1000-2000 -> 0-1000 + } + //ch1 = (ibus_captured_value[0] - 500) * 2; + //ch2 = (ibus_captured_value[1] - 500) * 2; + log_i( "CH1: %d \t CH2: %d\n", (ibus_captured_value[0] - 500) * 2, (ibus_captured_value[1] - 500) * 2); + #endif + if (timeoutCntSerial0++ >= SERIAL_TIMEOUT) { // Timeout qualification + timeoutFlagSerial0 = 1; // Timeout detected + timeoutCntSerial0 = SERIAL_TIMEOUT; // Limit timout counter value + } + if (timeoutFlagSerial0 && main_loop_counter % 100 == 0) { // In case of timeout bring the system to a Safe State and indicate error if desired + //toggle_led(LED2_GPIO_Port, LED2_Pin); // Toggle the Green LED every 100 ms + } + #endif + + main_loop_counter++; + + } } diff --git a/Src/setup.c b/Src/setup.c index 4a62826..f142524 100644 --- a/Src/setup.c +++ b/Src/setup.c @@ -29,37 +29,53 @@ // Private variables -static rcu_periph_enum USART_CLK[USARTn] = { USART_AUX_CLK, - USART_MAIN_CLK +static rcu_periph_enum USART_CLK[USARTn] = { USART0_CLK, + USART1_CLK }; -static uint32_t USART_TX_PIN[USARTn] = { USART_AUX_TX_PIN, - USART_MAIN_TX_PIN +static uint32_t USART_TX_PIN[USARTn] = { USART0_TX_PIN, + USART1_TX_PIN }; -static uint32_t USART_RX_PIN[USARTn] = { USART_AUX_RX_PIN, - USART_MAIN_RX_PIN +static uint32_t USART_RX_PIN[USARTn] = { USART0_RX_PIN, + USART1_RX_PIN }; - +static dma_channel_enum USART_TX_DMA_CH[USARTn] = { USART0_TX_DMA_CH, + USART1_TX_DMA_CH + }; + +static dma_channel_enum USART_RX_DMA_CH[USARTn] = { USART0_RX_DMA_CH, + USART1_RX_DMA_CH + }; + +static uint32_t USART_TDATA_ADDRESS[USARTn] = { USART0_TDATA_ADDRESS, + USART1_TDATA_ADDRESS + }; + +static uint32_t USART_RDATA_ADDRESS[USARTn] = { USART0_RDATA_ADDRESS, + USART1_RDATA_ADDRESS + }; + + void gpio_config(void) { /* =========================== Configure LEDs GPIOs =========================== */ /* enable the GPIO clock */ rcu_periph_clock_enable(RCU_GPIOA); - rcu_periph_clock_enable(RCU_GPIOB); + rcu_periph_clock_enable(RCU_GPIOB); /* configure GPIO port */ - gpio_mode_set(LED1_GPIO_Port, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED1_Pin); + gpio_mode_set(LED1_GPIO_Port, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED1_Pin); gpio_mode_set(LED2_GPIO_Port, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED2_Pin); - gpio_mode_set(LED3_GPIO_Port, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED3_Pin); - gpio_mode_set(LED4_GPIO_Port, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED4_Pin); - gpio_mode_set(LED5_GPIO_Port, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED5_Pin); + gpio_mode_set(LED3_GPIO_Port, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED3_Pin); + gpio_mode_set(LED4_GPIO_Port, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED4_Pin); + gpio_mode_set(LED5_GPIO_Port, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED5_Pin); gpio_output_options_set(LED1_GPIO_Port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, LED1_Pin); gpio_output_options_set(LED2_GPIO_Port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, LED2_Pin); gpio_output_options_set(LED3_GPIO_Port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, LED3_Pin); gpio_output_options_set(LED4_GPIO_Port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, LED4_Pin); - gpio_output_options_set(LED5_GPIO_Port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, LED5_Pin); + gpio_output_options_set(LED5_GPIO_Port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, LED5_Pin); /* reset GPIO pin */ gpio_bit_reset(LED1_GPIO_Port, LED1_Pin); @@ -69,7 +85,7 @@ void gpio_config(void) { gpio_bit_reset(LED5_GPIO_Port, LED5_Pin); - /* =========================== Configure Sensors GPIOs =========================== */ + /* =========================== Configure Sensors GPIOs =========================== */ /* enable the GPIO clock */ rcu_periph_clock_enable(RCU_GPIOA); rcu_periph_clock_enable(RCU_GPIOC); @@ -79,7 +95,7 @@ void gpio_config(void) { gpio_mode_set(SENSOR2_GPIO_Port, GPIO_MODE_INPUT, GPIO_PUPD_NONE, SENSOR2_Pin); - /* =========================== Configure I2C GPIOs =========================== */ + /* =========================== Configure I2C GPIOs =========================== */ /* enable I2C clock */ rcu_periph_clock_enable(RCU_GPIOB); rcu_periph_clock_enable(MPU_RCU_I2C); @@ -145,16 +161,17 @@ void gpio_config(void) { } -void usart_config(uint32_t selUSART, uint32_t selBaudRate) { +void usart_config(uint32_t selUSART, uint32_t selBaudRate) { - /* enable GPIO clock */ - uint32_t USART_ID = 0U; + uint8_t USART_ID = 0U; if(selUSART == USART0){ USART_ID = 0U; } if(selUSART == USART1){ USART_ID = 1U; - } + } + + /* enable GPIO clock */ rcu_periph_clock_enable(USART_GPIO_CLK); /* enable USART clock */ @@ -193,40 +210,48 @@ void usart_config(uint32_t selUSART, uint32_t selBaudRate) { // DMA_CH3 = USART1_TX // DMA_CH4 = USART1_RX -void usart_Tx_DMA_config(uint32_t selUSART, uint8_t *pData, uint32_t dSize) { +void usart_Tx_DMA_config(uint32_t selUSART, uint8_t *pData, uint32_t dSize) { - dma_parameter_struct dma_init_struct; + dma_parameter_struct dma_init_struct; - // --------------------------- TX Channel --------------------------- + // --------------------------- TX Channel --------------------------- + + uint8_t USART_ID = 0U; + if(selUSART == USART0){ + USART_ID = 0U; + } + if(selUSART == USART1){ + USART_ID = 1U; + } /* enable DMA clock */ rcu_periph_clock_enable(RCU_DMA); /* deinitialize DMA channel2 */ - dma_deinit(DMA_CH3); + dma_deinit(USART_TX_DMA_CH[USART_ID]); dma_init_struct.direction = DMA_MEMORY_TO_PERIPHERAL; dma_init_struct.memory_addr = (uint32_t)pData; dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE; dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT; dma_init_struct.number = dSize; - dma_init_struct.periph_addr = USART1_TDATA_ADDRESS; + dma_init_struct.periph_addr = USART_TDATA_ADDRESS[USART_ID]; dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE; dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT; dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH; // Priorities: *_LOW, *_MEDIUM, *_HIGH, *_ULTRA_HIGH, - dma_init(DMA_CH3, dma_init_struct); + dma_init(USART_TX_DMA_CH[USART_ID], dma_init_struct); /* configure DMA mode */ - dma_circulation_disable(DMA_CH3); - dma_memory_to_memory_disable(DMA_CH3); + dma_circulation_disable(USART_TX_DMA_CH[USART_ID]); + dma_memory_to_memory_disable(USART_TX_DMA_CH[USART_ID]); /* USART DMA enable for transmission */ usart_dma_transmit_config(selUSART, USART_DENT_ENABLE); /* enable DMA channel1 */ - dma_channel_enable(DMA_CH3); + dma_channel_enable(USART_TX_DMA_CH[USART_ID]); /* wait DMA channel transfer complete */ - // while (RESET == dma_flag_get(DMA_CH3, DMA_FLAG_FTF)); + // while (RESET == dma_flag_get(USART_TX_DMA[USART_ID], DMA_FLAG_FTF)); } @@ -236,34 +261,42 @@ void usart_Rx_DMA_config(uint32_t selUSART, uint8_t *pData, uint32_t dSize) { // --------------------------- RX Channel --------------------------- + uint8_t USART_ID = 0U; + if(selUSART == USART0){ + USART_ID = 0U; + } + if(selUSART == USART1){ + USART_ID = 1U; + } + /* enable DMA clock */ rcu_periph_clock_enable(RCU_DMA); /* deinitialize DMA channel4 */ - dma_deinit(DMA_CH4); + dma_deinit(USART_RX_DMA_CH[USART_ID]); dma_init_struct.direction = DMA_PERIPHERAL_TO_MEMORY; dma_init_struct.memory_addr = (uint32_t)pData; dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE; dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT; dma_init_struct.number = dSize; - dma_init_struct.periph_addr = USART1_RDATA_ADDRESS; + dma_init_struct.periph_addr = USART_RDATA_ADDRESS[USART_ID]; dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE; dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT; dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH; // Priorities: *_LOW, *_MEDIUM, *_HIGH, *_ULTRA_HIGH, - dma_init(DMA_CH4, dma_init_struct); + dma_init(USART_RX_DMA_CH[USART_ID], dma_init_struct); /* configure DMA mode */ - dma_circulation_enable(DMA_CH4); // dma_circulation_disable(DMA_CH4); - dma_memory_to_memory_disable(DMA_CH4); + dma_circulation_enable(USART_RX_DMA_CH[USART_ID]); // dma_circulation_disable(USART_RX_DMA[USART_ID]); + dma_memory_to_memory_disable(USART_RX_DMA_CH[USART_ID]); /* USART DMA enable for reception */ usart_dma_receive_config(selUSART, USART_DENR_ENABLE); /* enable DMA channel */ - dma_channel_enable(DMA_CH4); + dma_channel_enable(USART_RX_DMA_CH[USART_ID]); /* wait DMA channel transfer complete */ - // while (RESET == dma_flag_get(DMA_CH4, DMA_FLAG_FTF)); + // while (RESET == dma_flag_get(USART_RX_DMA[USART_ID], DMA_FLAG_FTF)); } diff --git a/Src/util.c b/Src/util.c index 34ee147..3fca171 100644 --- a/Src/util.c +++ b/Src/util.c @@ -34,18 +34,39 @@ SerialSideboard Sideboard; #endif #if defined(SERIAL_DEBUG) || defined(SERIAL_FEEDBACK) -static uint8_t rx_buffer[SERIAL_BUFFER_SIZE]; // USART Rx DMA circular buffer -static uint32_t rx_buffer_len = ARRAY_LEN(rx_buffer); +static uint8_t rx1_buffer[SERIAL_BUFFER_SIZE]; // USART Rx DMA circular buffer +static uint32_t rx1_buffer_len = ARRAY_LEN(rx1_buffer); #endif #ifdef SERIAL_FEEDBACK SerialFeedback Feedback; SerialFeedback FeedbackRaw; -uint16_t timeoutCntSerial = 0; // Timeout counter for Rx Serial command -uint8_t timeoutFlagSerial = 0; // Timeout Flag for Rx Serial command: 0 = OK, 1 = Problem detected (line disconnected or wrong Rx data) +uint16_t timeoutCntSerial = 0; // Timeout counter for UART1 Rx Serial +uint8_t timeoutFlagSerial = 0; // Timeout Flag for UART1 Rx Serial: 0 = OK, 1 = Problem detected (line disconnected or wrong Rx data) static uint32_t Feedback_len = sizeof(Feedback); #endif +#ifdef SERIAL_AUX_TX +SerialAuxTx AuxTx; +#endif + +#ifdef SERIAL_AUX_RX +static uint8_t rx0_buffer[SERIAL_BUFFER_SIZE]; // USART Rx DMA circular buffer +static uint32_t rx0_buffer_len = ARRAY_LEN(rx0_buffer); +#endif + +#ifdef SERIAL_AUX_RX +SerialCommand command; +SerialCommand command_raw; +uint16_t timeoutCntSerial0 = 0; // Timeout counter for UART0 Rx Serial +uint8_t timeoutFlagSerial0 = 0; // Timeout Flag for UART0 Rx Serial: 0 = OK, 1 = Problem detected (line disconnected or wrong Rx data) +static uint32_t command_len = sizeof(command); + #ifdef CONTROL_IBUS + static uint16_t ibus_chksum; + uint16_t ibus_captured_value[IBUS_NUM_CHANNELS]; + #endif +#endif + // MPU variables ErrStatus mpuStatus; // holds the MPU-6050 status: SUCCESS or ERROR @@ -149,7 +170,13 @@ void input_init(void) { usart_Tx_DMA_config(USART_MAIN, (uint8_t *)&Sideboard, sizeof(Sideboard)); #endif #if defined(SERIAL_DEBUG) || defined(SERIAL_FEEDBACK) - usart_Rx_DMA_config(USART_MAIN, (uint8_t *)rx_buffer, sizeof(rx_buffer)); + usart_Rx_DMA_config(USART_MAIN, (uint8_t *)rx1_buffer, sizeof(rx1_buffer)); + #endif + #ifdef SERIAL_AUX_TX + usart_Tx_DMA_config(USART_AUX, (uint8_t *)&AuxTx, sizeof(AuxTx)); + #endif + #ifdef SERIAL_AUX_RX + usart_Rx_DMA_config(USART_AUX, (uint8_t *)rx0_buffer, sizeof(rx0_buffer)); #endif intro_demo_led(100); // Short LEDs intro demo with 100 ms delay. This also gives some time for the MPU-6050 to power-up. @@ -175,25 +202,54 @@ void input_init(void) { * Check for new data received on USART with DMA: refactored function from https://github.com/MaJerle/stm32-usart-uart-dma-rx-tx * - this function is called for every USART IDLE line detection, in the USART interrupt handler */ -void usart_rx_check(void) +void usart0_rx_check(void) +{ + #ifdef SERIAL_AUX_RX + static uint32_t old_pos; + uint32_t pos; + uint8_t *ptr; + + pos = rx0_buffer_len - dma_transfer_number_get(USART0_RX_DMA_CH); // Calculate current position in buffer + if (pos != old_pos) { // Check change in received data + ptr = (uint8_t *)&command_raw; // Initialize the pointer with structure address + if (pos > old_pos && (pos - old_pos) == command_len) { // "Linear" buffer mode: check if current position is over previous one AND data length equals expected length + memcpy(ptr, &rx0_buffer[old_pos], command_len); // Copy data. This is possible only if structure is contiguous! (meaning all the structure members have the same size) + usart_process_command(&command_raw, &command); // Process data + } else if ((rx0_buffer_len - old_pos + pos) == command_len) { // "Overflow" buffer mode: check if data length equals expected length + memcpy(ptr, &rx0_buffer[old_pos], rx0_buffer_len - old_pos); // First copy data from the end of buffer + if (pos > 0) { // Check and continue with beginning of buffer + ptr += rx0_buffer_len - old_pos; // Update position + memcpy(ptr, &rx0_buffer[0], pos); // Copy remaining data + } + usart_process_command(&command_raw, &command); // Process data + } + } + old_pos = pos; // Updated old position + if (old_pos == rx0_buffer_len) { // Check and manually update if we reached end of buffer + old_pos = 0; + } + #endif // SERIAL_AUX_RX +} + +void usart1_rx_check(void) { #ifdef SERIAL_DEBUG static uint32_t old_pos; uint32_t pos; - pos = rx_buffer_len - dma_transfer_number_get(DMA_CH4); // Calculate current position in buffer + pos = rx1_buffer_len - dma_transfer_number_get(USART1_RX_DMA_CH); // Calculate current position in buffer if (pos != old_pos) { // Check change in received data if (pos > old_pos) { // "Linear" buffer mode: check if current position is over previous one - usart_process_debug(&rx_buffer[old_pos], pos - old_pos); // Process data + usart_process_debug(&rx1_buffer[old_pos], pos - old_pos); // Process data } else { // "Overflow" buffer mode - usart_process_debug(&rx_buffer[old_pos], rx_buffer_len - old_pos); // First Process data from the end of buffer + usart_process_debug(&rx1_buffer[old_pos], rx1_buffer_len - old_pos); // First Process data from the end of buffer if (pos > 0) { // Check and continue with beginning of buffer - usart_process_debug(&rx_buffer[0], pos); // Process remaining data + usart_process_debug(&rx1_buffer[0], pos); // Process remaining data } } } old_pos = pos; // Update old position - if (old_pos == rx_buffer_len) { // Check and manually update if we reached end of buffer + if (old_pos == rx1_buffer_len) { // Check and manually update if we reached end of buffer old_pos = 0; } #endif // SERIAL_DEBUG @@ -203,23 +259,23 @@ void usart_rx_check(void) uint32_t pos; uint8_t *ptr; - pos = rx_buffer_len - dma_transfer_number_get(DMA_CH4); // Calculate current position in buffer + pos = rx1_buffer_len - dma_transfer_number_get(USART1_RX_DMA_CH); // Calculate current position in buffer if (pos != old_pos) { // Check change in received data ptr = (uint8_t *)&FeedbackRaw; // Initialize the pointer with FeedbackRaw address if (pos > old_pos && (pos - old_pos) == Feedback_len) { // "Linear" buffer mode: check if current position is over previous one AND data length equals expected length - memcpy(ptr, &rx_buffer[old_pos], Feedback_len); // Copy data. This is possible only if FeedbackRaw is contiguous! (meaning all the structure members have the same size) + memcpy(ptr, &rx1_buffer[old_pos], Feedback_len); // Copy data. This is possible only if FeedbackRaw is contiguous! (meaning all the structure members have the same size) usart_process_data(&FeedbackRaw, &Feedback); // Process data - } else if ((rx_buffer_len - old_pos + pos) == Feedback_len) { // "Overflow" buffer mode: check if data length equals expected length - memcpy(ptr, &rx_buffer[old_pos], rx_buffer_len - old_pos); // First copy data from the end of buffer + } else if ((rx1_buffer_len - old_pos + pos) == Feedback_len) { // "Overflow" buffer mode: check if data length equals expected length + memcpy(ptr, &rx1_buffer[old_pos], rx1_buffer_len - old_pos); // First copy data from the end of buffer if (pos > 0) { // Check and continue with beginning of buffer - ptr += rx_buffer_len - old_pos; // Move to correct position in FeedbackRaw - memcpy(ptr, &rx_buffer[0], pos); // Copy remaining data + ptr += rx1_buffer_len - old_pos; // Move to correct position in FeedbackRaw + memcpy(ptr, &rx1_buffer[0], pos); // Copy remaining data } usart_process_data(&FeedbackRaw, &Feedback); // Process data } } old_pos = pos; // Updated old position - if (old_pos == rx_buffer_len) { // Check and manually update if we reached end of buffer + if (old_pos == rx1_buffer_len) { // Check and manually update if we reached end of buffer old_pos = 0; } #endif // SERIAL_FEEDBACK @@ -262,6 +318,29 @@ void usart_process_data(SerialFeedback *Feedback_in, SerialFeedback *Feedback_ou } #endif // SERIAL_FEEDBACK +/* + * Process command UART0 Rx data + * - if the command_in data is valid (correct START_FRAME and checksum) copy the command_in to command_out + */ +#ifdef SERIAL_AUX_RX +void usart_process_command(SerialCommand *command_in, SerialCommand *command_out) +{ + #ifdef CONTROL_IBUS + if (command_in->start == IBUS_LENGTH && command_in->type == IBUS_COMMAND) { + ibus_chksum = 0xFFFF - IBUS_LENGTH - IBUS_COMMAND; + for (uint8_t i = 0; i < (IBUS_NUM_CHANNELS * 2); i++) { + ibus_chksum -= command_in->channels[i]; + } + if (ibus_chksum == (uint16_t)((command_in->checksumh << 8) + command_in->checksuml)) { + *command_out = *command_in; + timeoutCntSerial0 = 0; // Reset timeout counter + timeoutFlagSerial0 = 0; // Clear timeout flag + } + } + #endif +} +#endif + /* =========================== I2C WRITE Functions =========================== */ /* diff --git a/add_nanolib.py b/add_nanolib.py index 85055b9..a8ff2a0 100644 --- a/add_nanolib.py +++ b/add_nanolib.py @@ -1,2 +1,3 @@ Import("env") -env.Append(LINKFLAGS=["--specs=nano.specs"]) \ No newline at end of file +#env.Append(LINKFLAGS=["--specs=nano.specs"]) +env.Append(LINKFLAGS=["--specs=nosys.specs", "--specs=nano.specs"]) \ No newline at end of file diff --git a/platformio.ini b/platformio.ini index 0ef487f..a9aed61 100644 --- a/platformio.ini +++ b/platformio.ini @@ -15,9 +15,13 @@ src_dir = Src ;=================== VARIANT SELECTION ========================== ;default_envs = VARIANT_DEBUG ; DEFAULT Variant +;default_envs = VARIANT_HOVERCAR ; HOVERCAR Variant ;default_envs = VARIANT_HOVERBOARD ; HOVERBOARD Variant ;================================================================ +[env] +platform_packages = maxgerhardt/framework-spl@2.10300.0 ; Add GD32 support package: globally override framework-spl for all environments + ;================================================================ [env:VARIANT_DEBUG] @@ -31,19 +35,41 @@ extra_scripts = add_nanolib.py ; adds nanolib to reduce printf memory f ; Serial Port settings (make sure the COM port is correct) monitor_port = COM5 -monitor_speed = 38400 +monitor_speed = 115200 build_flags = -IInc -ISrc -DUSE_STDPERIPH_DRIVER -DGD32F130_150 - -Wl,-T./GD32F130C6T_FLASH.ld - -Wl,-lc - -Wl,-lm + -T./GD32F130C6T_FLASH.ld + -lc + -lm -g -ggdb -D VARIANT_DEBUG + +;================================================================ + +[env:VARIANT_HOVERCAR] +platform = ststm32 +board = gd32f130c6 +debug_tool = stlink +upload_protocol = stlink +framework = spl +extra_scripts = add_nanolib.py + +build_flags = + -IInc + -ISrc + -DUSE_STDPERIPH_DRIVER + -DGD32F130_150 + -T./GD32F130C6T_FLASH.ld + -lc + -lm + -g -ggdb + -D VARIANT_HOVERCAR + ;================================================================ [env:VARIANT_HOVERBOARD] @@ -59,9 +85,9 @@ build_flags = -ISrc -DUSE_STDPERIPH_DRIVER -DGD32F130_150 - -Wl,-T./GD32F130C6T_FLASH.ld - -Wl,-lc - -Wl,-lm + -T./GD32F130C6T_FLASH.ld + -lc + -lm -g -ggdb -D VARIANT_HOVERBOARD