Skip to content

Commit

Permalink
Major UART communication improvement
Browse files Browse the repository at this point in the history
- the UART communication is improved based on UART Idle line detection interrupt
- both Tx and Rx are efficiently handled using DMA

Other:
- minor visual improvements
  • Loading branch information
EFeru committed Jun 21, 2020
1 parent e9d74be commit 1e7bf7c
Show file tree
Hide file tree
Showing 11 changed files with 312 additions and 183 deletions.
69 changes: 37 additions & 32 deletions Inc/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,60 +27,61 @@
// 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_HOVERBOARD // Variant for using the side-boards connected to the Hoverboard mainboard
#endif

/* ==================================== DO NOT TOUCH SETTINGS ==================================== */
#define MPU6050 // [-] Define IMU sensor type
#define MPU_GYRO_FSR 2000 // [deg/s] Set Gyroscope Full Scale Range: 250 deg/s, 500 deg/s, 1000 deg/s, 2000 deg/s. !! DMP sensor fusion works only with 2000 deg/s !!
#define MPU_ACCEL_FSR 2 // [g] Set Acceleromenter Full Scale Range: 2g, 4g, 8g, 16g. !! DMP sensor fusion works only with 2g !!
#define MPU_I2C_SPEED 400000 // [bit/s] Define I2C speed for communicating with the MPU6050
#define DELAY_IN_MAIN_LOOP 1 // [ms] Delay in the main loop
// #define PRINTF_FLOAT_SUPPORT // [-] Uncomment this for printf to support float on Serial Debug. It will increase code size! Better to avoid it!
#define MPU6050 // [-] Define IMU sensor type
#define MPU_GYRO_FSR 2000 // [deg/s] Set Gyroscope Full Scale Range: 250 deg/s, 500 deg/s, 1000 deg/s, 2000 deg/s. !! DMP sensor fusion works only with 2000 deg/s !!
#define MPU_ACCEL_FSR 2 // [g] Set Acceleromenter Full Scale Range: 2g, 4g, 8g, 16g. !! DMP sensor fusion works only with 2g !!
#define MPU_I2C_SPEED 400000 // [bit/s] Define I2C speed for communicating with the MPU6050
#define DELAY_IN_MAIN_LOOP 1 // [ms] Delay in the main loop
// #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.
#define MPU_DEFAULT_HZ 20 // [Hz] Default MPU frequecy: must be between 1Hz and 200Hz.
#define TEMP_READ_MS 500 // [ms] Temperature read time interval
#define PEDO_READ_MS 1000 // [ms] Pedometer read time interval
// #define USE_CAL_HW_REGISTERS // [-] Uncommnent this to SAVE the sensor calibration to the MPU-6050 registers after the Self-test was run
#define MPU_DMP_ENABLE // [-] Enable flag for MPU-6050 DMP (Digital Motion Processing) functionality.
#define MPU_DEFAULT_HZ 20 // [Hz] Default MPU frequecy: must be between 1Hz and 200Hz.
#define TEMP_READ_MS 500 // [ms] Temperature read time interval
#define PEDO_READ_MS 1000 // [ms] Pedometer read time interval
// #define USE_CAL_HW_REGISTERS // [-] Uncommnent this to SAVE the sensor calibration to the MPU-6050 registers after the Self-test was run

// DMP Tap Detection Settings
#define DMP_TAP_AXES TAP_XYZ // [-] Set which axes will register a tap: TAP_XYZ, TAP_X, TAP_Y, TAP_Z
#define DMP_TAP_THRESH 250 // [mg/ms] Set tap threshold for the selected axis.
#define DMP_TAP_COUNT 1 // [-] Set minimum number of taps needed for an interrupt. Minimum consecutive taps: 1 to 4
#define DMP_TAP_TIME 100 // [ms] Set time length between valid taps.
#define DMP_TAP_TIME_MULTI 500 // [ms] Set max time between taps to register as a multi-tap.
#define DMP_SHAKE_REJECT_THRESH 200 // [deg/s] Set shake rejection threshold in degree per second (dps). If the DMP detects a gyro sample larger than the thresh, taps are rejected.
#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.
#define DMP_TAP_AXES TAP_XYZ // [-] Set which axes will register a tap: TAP_XYZ, TAP_X, TAP_Y, TAP_Z
#define DMP_TAP_THRESH 250 // [mg/ms] Set tap threshold for the selected axis.
#define DMP_TAP_COUNT 1 // [-] Set minimum number of taps needed for an interrupt. Minimum consecutive taps: 1 to 4
#define DMP_TAP_TIME 100 // [ms] Set time length between valid taps.
#define DMP_TAP_TIME_MULTI 500 // [ms] Set max time between taps to register as a multi-tap.
#define DMP_SHAKE_REJECT_THRESH 200 // [deg/s] Set shake rejection threshold in degree per second (dps). If the DMP detects a gyro sample larger than the thresh, taps are rejected.
#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
#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
#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_TIMEOUT 800 // [-] Numer of wrong received data for Serial timeout detection
#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_TIMEOUT 500 // [-] Number of wrong received data for Serial timeout detection. Depends on DELAY_IN_MAIN_LOOP
#define SERIAL_BUFFER_SIZE 64 // [bytes] Size of Serial Rx buffer. Make sure it is always larger than the 'Feedback' structure size


/* ==================================== 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
// #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
#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
#define AUX_I2C_SPEED 100000 // [bit/s] Define I2C speed for communicating via AUX45 wires
#endif


Expand All @@ -89,6 +90,10 @@
#error SERIAL_DEBUG and SERIAL_CONTROL not allowed. It is on the same cable.
#endif

#if defined(SERIAL_DEBUG) && defined(SERIAL_FEEDBACK)
#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))
#error AUX45_USE_(GPIO,USART,I2C) not allowed in the same time. It is on the same cable.
#endif
Expand Down
18 changes: 9 additions & 9 deletions Inc/defines.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,15 @@
#endif

/* =========================== Defines General =========================== */
// #define _BV(bit) (1 << (bit))
// #define ARRAYNUM(arr_nanme) (uint32_t)(sizeof(arr_nanme) / sizeof(*(arr_nanme)))
#define min(a, b) (((a) < (b)) ? (a) : (b))
#define max(a, b) (((a) > (b)) ? (a) : (b))
#define i2c_write i2c_writeBytes
#define i2c_read i2c_readBytes
#define delay_ms delay_1ms
#define get_ms get_tick_count_ms
// #define _BV(bit) (1 << (bit))
#define ARRAY_LEN(x) (uint32_t)(sizeof(x) / sizeof(*(x)))
#define min(a, b) (((a) < (b)) ? (a) : (b))
#define max(a, b) (((a) > (b)) ? (a) : (b))
#define i2c_write i2c_writeBytes
#define i2c_read i2c_readBytes
#define delay_ms delay_1ms
#define get_ms get_tick_count_ms
#define log_i printf // redirect the log_i debug function to printf


/* =========================== Defines LEDs =========================== */
Expand Down Expand Up @@ -132,7 +133,6 @@ typedef enum {READ = 0, WRITE = !READ} i2c_cmd;
#endif

/* =========================== Defines MPU-6050 =========================== */
#define log_i printf // redirect the log_i debug function to printf
#define RAD2DEG 57.295779513082323 // RAD2DEG = 180/pi. Example: angle[deg] = angle[rad] * RAD2DEG
#define q30 1073741824 // 1073741824 = 2^30
#define ACCEL_ON (0x01)
Expand Down
2 changes: 2 additions & 0 deletions Inc/gd32f1x0_it.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ void DebugMon_Handler(void);
void PendSV_Handler(void);
/* SysTick handle function */
void SysTick_Handler(void);
/* USART0 handle function */
void USART1_IRQHandler(void);
/* I2C0 event handle function */
void I2C0_EV_IRQHandler(void);
/* I2C0 error handle function */
Expand Down
5 changes: 3 additions & 2 deletions Inc/setup.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@
// Function declarations
void gpio_config(void);
void usart_config(uint32_t selUSART, uint32_t selBaudRate);
void usart_Tx_DMA_config(uint32_t selUSART, uint8_t *pData, uint32_t Size);
void usart_Rx_DMA_config(uint32_t selUSART, uint8_t *pData, uint32_t Size);
void usart_Tx_DMA_config(uint32_t selUSART, uint8_t *pData, uint32_t dSize);
void usart_Rx_DMA_config(uint32_t selUSART, uint8_t *pData, uint32_t dSize);
void usart_nvic_config(void);

void i2c_config(void);
void i2c_nvic_config(void);
Expand Down
35 changes: 35 additions & 0 deletions Inc/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,41 @@ void consoleLog(char *message);
void toggle_led(uint32_t gpio_periph, uint32_t pin);
void intro_demo_led(uint32_t tDelay);

/* input initialization function */
void input_init(void);

/* usart read functions */
void usart_rx_check(void);

#ifdef SERIAL_DEBUG
void usart_process_debug(uint8_t *userCommand, uint32_t len);
#endif

#ifdef SERIAL_CONTROL
typedef struct{
uint16_t start;
int16_t roll;
int16_t pitch;
int16_t yaw;
uint16_t sensors;
uint16_t checksum;
} SerialSideboard;
#endif
#ifdef SERIAL_FEEDBACK
typedef struct{
uint16_t start;
int16_t cmd1;
int16_t cmd2;
int16_t speedR_meas;
int16_t speedL_meas;
int16_t batVoltage;
int16_t boardTemp;
uint16_t cmdLed;
uint16_t checksum;
} SerialFeedback;
void usart_process_data(SerialFeedback *Feedback_in, SerialFeedback *Feedback_out);
#endif

/* i2c write/read functions */
int8_t i2c_writeBytes(uint8_t slaveAddr, uint8_t regAddr, uint8_t length, uint8_t *data);
int8_t i2c_writeByte (uint8_t slaveAddr, uint8_t regAddr, uint8_t data);
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ The original sideboard hardware supports one 4-pin cable that originally was con
The LED boards consist of colored LEDs (blue, red, green, orange) used for design and to inform the user about the current hoverboard state. Below the pinout of the LED boards is shown.
![ledboard](/docs/pictures/ledboard_pinout.png)

The heart of the sideboard is a [GD32F130C6T6](/docs/GD32F130xx-Datasheet_Rev3.3.pdf) with the pinout shown in the follwing figure:
The sideboard brain is a [GD32F130C6T6](/docs/GD32F130xx-Datasheet_Rev3.3.pdf) with the pinout shown in the follwing figure:
![MCU_pinout](/docs/pictures/MCU_pinout.png)

A very important component of the sideboard is the IMU [MPU-6050](https://www.invensense.com/products/motion-tracking/6-axis/mpu-6050/) from Invensense. The [MPU-6050](https://www.invensense.com/products/motion-tracking/6-axis/mpu-6050/) determines the board orientation by combining a 3-axis gyroscope and a 3-axis accelerometer on the same silicon die, together with an onboard Digital Motion Processor™ (DMP™), which processes complex 6-axis MotionFusion algorithms. The DMP™ offers many features, such as:
Expand Down
15 changes: 15 additions & 0 deletions Src/gd32f1x0_it.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "systick.h"
#include "i2c_it.h"
#include "config.h"
#include "util.h"

/*!
\brief this function handles NMI exception
Expand Down Expand Up @@ -121,6 +122,20 @@ void SysTick_Handler(void)
delay_decrement();
}

/*!
\brief this function handles the USART1 interrupt request
\param[in] none
\param[out] none
\retval none
*/
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
}
}

/*!
\brief this function handles I2C0 event interrupt request exception
\param[in] none
Expand Down
Loading

0 comments on commit 1e7bf7c

Please sign in to comment.