Added Platformio support

- firmware can now be built in Platformio too
- minor bug fixes
- added LED board picture
This commit is contained in:
EmanuelFeru 2020-02-13 18:18:02 +01:00
parent b69942e80e
commit 882d4b0115
31 changed files with 801 additions and 3602 deletions

5
.gitignore vendored
View File

@ -3,12 +3,11 @@
.vscode/ .vscode/
MDK-ARM/Listing/ MDK-ARM/Listing/
MDK-ARM/Objects/ MDK-ARM/Objects/
MDK-ARM/*.uvgui MDK-ARM/*.uvgui.*
build/
!build/VARIANT_DEBUG/firmware.hex !build/VARIANT_DEBUG/firmware.hex
!build/VARIANT_DEBUG/firmware.bin !build/VARIANT_DEBUG/firmware.bin
!build/VARIANT_DEBUG/firmware.elf !build/VARIANT_DEBUG/firmware.elf
!build/VARIANT_DEBUG/firmware.axf
!build/VARIANT_HOVERBOARD/firmware.hex !build/VARIANT_HOVERBOARD/firmware.hex
!build/VARIANT_HOVERBOARD/firmware.bin !build/VARIANT_HOVERBOARD/firmware.bin
!build/VARIANT_HOVERBOARD/firmware.elf !build/VARIANT_HOVERBOARD/firmware.elf
!build/VARIANT_HOVERBOARD/firmware.axf

View File

@ -45,3 +45,14 @@ jobs:
- export PATH=$HOME/arm-gcc-toolchain/bin:$PATH - export PATH=$HOME/arm-gcc-toolchain/bin:$PATH
before_script: arm-none-eabi-gcc --version before_script: arm-none-eabi-gcc --version
# # Not yet supportted, see https://community.platformio.org/t/build-gd32-project-with-platformio/11944
# - name: platformio
# script: platformio run
# language: python
# python:
# - "2.7"
# install:
# - pip install -U platformio
# - platformio update
# cache:
# - directories: "~/.platformio"

View File

@ -1,19 +1,24 @@
/*
*
* Automatically generated file
* PlatformIO default linker script template for STM32 F1/F2/F3/F4/F7/L0/L1/L4
*
*/
/* Entry Point */ /* Entry Point */
ENTRY(Reset_Handler) ENTRY(Reset_Handler)
/* Highest address of the user mode stack */ /* Highest address of the user mode stack */
_estack = 0x20000400; _estack = 0x20001000; /* end of RAM */
/* Generate a link error if heap and stack don't fit into RAM */ /* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0x400; /* required amount of heap */ _Min_Heap_Size = 0x200; /* required amount of heap */
_Min_Stack_Size = 0x400; /* required amount of stack */ _Min_Stack_Size = 0x400; /* required amount of stack */
/* Specify the memory areas */ /* Specify the memory areas */
MEMORY MEMORY
{ {
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 32K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 4K RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 4K
MEMORY_B1 (rx) : ORIGIN = 0x60000000, LENGTH = 0K FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 32K
} }
/* Define output sections */ /* Define output sections */
@ -33,10 +38,9 @@ SECTIONS
. = ALIGN(4); . = ALIGN(4);
*(.text) /* .text sections (code) */ *(.text) /* .text sections (code) */
*(.text*) /* .text* sections (code) */ *(.text*) /* .text* sections (code) */
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
*(.glue_7) /* glue arm to thumb code */ *(.glue_7) /* glue arm to thumb code */
*(.glue_7t) /* glue thumb to arm code */ *(.glue_7t) /* glue thumb to arm code */
*(.eh_frame)
KEEP (*(.init)) KEEP (*(.init))
KEEP (*(.fini)) KEEP (*(.fini))
@ -45,6 +49,14 @@ SECTIONS
_etext = .; /* define a global symbols at end of code */ _etext = .; /* define a global symbols at end of code */
} >FLASH } >FLASH
/* Constant data goes into FLASH */
.rodata :
{
. = ALIGN(4);
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
. = ALIGN(4);
} >FLASH
.ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH
.ARM : { .ARM : {
@ -53,8 +65,6 @@ SECTIONS
__exidx_end = .; __exidx_end = .;
} >FLASH } >FLASH
.ARM.attributes 0 : { *(.ARM.attributes) }
.preinit_array : .preinit_array :
{ {
PROVIDE_HIDDEN (__preinit_array_start = .); PROVIDE_HIDDEN (__preinit_array_start = .);
@ -71,16 +81,16 @@ SECTIONS
.fini_array : .fini_array :
{ {
PROVIDE_HIDDEN (__fini_array_start = .); PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(.fini_array*))
KEEP (*(SORT(.fini_array.*))) KEEP (*(SORT(.fini_array.*)))
KEEP (*(.fini_array*))
PROVIDE_HIDDEN (__fini_array_end = .); PROVIDE_HIDDEN (__fini_array_end = .);
} >FLASH } >FLASH
/* used by the startup to initialize data */ /* used by the startup to initialize data */
_sidata = .; _sidata = LOADADDR(.data);
/* Initialized data sections goes into RAM, load LMA copy after code */ /* Initialized data sections goes into RAM, load LMA copy after code */
.data : AT ( _sidata ) .data :
{ {
. = ALIGN(4); . = ALIGN(4);
_sdata = .; /* create a global symbol at data start */ _sdata = .; /* create a global symbol at data start */
@ -89,7 +99,7 @@ SECTIONS
. = ALIGN(4); . = ALIGN(4);
_edata = .; /* define a global symbol at data end */ _edata = .; /* define a global symbol at data end */
} >RAM } >RAM AT> FLASH
/* Uninitialized data section */ /* Uninitialized data section */
. = ALIGN(4); . = ALIGN(4);
@ -107,27 +117,18 @@ SECTIONS
__bss_end__ = _ebss; __bss_end__ = _ebss;
} >RAM } >RAM
PROVIDE ( end = _ebss );
PROVIDE ( _end = _ebss );
/* User_heap_stack section, used to check that there is enough RAM left */ /* User_heap_stack section, used to check that there is enough RAM left */
._user_heap_stack : ._user_heap_stack :
{ {
. = ALIGN(4); . = ALIGN(4);
PROVIDE ( end = . );
PROVIDE ( _end = . );
. = . + _Min_Heap_Size; . = . + _Min_Heap_Size;
. = . + _Min_Stack_Size; . = . + _Min_Stack_Size;
. = ALIGN(4); . = ALIGN(4);
} >RAM } >RAM
/* MEMORY_bank1 section, code must be located here explicitly */
/* Example: extern int foo(void) __attribute__ ((section (".mb1text"))); */
.memory_b1_text :
{
*(.mb1text) /* .mb1text sections (code) */
*(.mb1text*) /* .mb1text* sections (code) */
*(.mb1rodata) /* read-only data (constants) */
*(.mb1rodata*)
} >MEMORY_B1
/* Remove information from the standard libraries */ /* Remove information from the standard libraries */
/DISCARD/ : /DISCARD/ :
@ -136,4 +137,8 @@ SECTIONS
libm.a ( * ) libm.a ( * )
libgcc.a ( * ) libgcc.a ( * )
} }
.ARM.attributes 0 : { *(.ARM.attributes) }
} }

View File

@ -33,6 +33,7 @@
#define MPU_ACCEL_FSR 2 // [g] Set Acceleromenter Full Scale Range: 2g, 4g, 8g, 16g. !! DMP sensor fusion works only with 2g !! #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 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 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!
/* =============================================================================================== */ /* =============================================================================================== */

View File

@ -26,6 +26,10 @@
#include "gd32f1x0.h" #include "gd32f1x0.h"
#include "config.h" #include "config.h"
#if defined(PRINTF_FLOAT_SUPPORT) && defined(SERIAL_DEBUG) && defined(__GNUC__)
asm(".global _printf_float"); // this is the magic trick for printf to support float. Warning: It will increase code considerably! Better to avoid!
#endif
/* =========================== Defines General =========================== */ /* =========================== Defines General =========================== */
// #define _BV(bit) (1 << (bit)) // #define _BV(bit) (1 << (bit))
// #define ARRAYNUM(arr_nanme) (uint32_t)(sizeof(arr_nanme) / sizeof(*(arr_nanme))) // #define ARRAYNUM(arr_nanme) (uint32_t)(sizeof(arr_nanme) / sizeof(*(arr_nanme)))
@ -49,6 +53,12 @@
#define LED5_GPIO_Port GPIOB #define LED5_GPIO_Port GPIOB
#define LED5_Pin GPIO_PIN_4 // BLUE2 #define LED5_Pin GPIO_PIN_4 // BLUE2
#define LED1_SET (0x01)
#define LED2_SET (0x02)
#define LED3_SET (0x04)
#define LED4_SET (0x08)
#define LED5_SET (0x10)
/* =========================== Defines SENSORS =========================== */ /* =========================== Defines SENSORS =========================== */
#define SENSOR1_GPIO_Port GPIOA #define SENSOR1_GPIO_Port GPIOA

View File

@ -48,7 +48,8 @@ extern volatile int8_t i2c_aux_nRABytes;
/* general functions */ /* general functions */
void consoleLog(char *message); void consoleLog(char *message);
void introDemoLED(uint32_t tDelay); void toggle_led(uint32_t gpio_periph, uint32_t pin);
void intro_demo_led(uint32_t tDelay);
/* i2c write/read functions */ /* i2c write/read functions */
int8_t i2c_writeBytes(uint8_t slaveAddr, uint8_t regAddr, uint8_t length, uint8_t *data); int8_t i2c_writeBytes(uint8_t slaveAddr, uint8_t regAddr, uint8_t length, uint8_t *data);

View File

@ -29,7 +29,7 @@
<CLKADS>8000000</CLKADS> <CLKADS>8000000</CLKADS>
<OPTTT> <OPTTT>
<gFlags>1</gFlags> <gFlags>1</gFlags>
<BeepAtEnd>1</BeepAtEnd> <BeepAtEnd>0</BeepAtEnd>
<RunSim>1</RunSim> <RunSim>1</RunSim>
<RunTarget>0</RunTarget> <RunTarget>0</RunTarget>
<RunAbUc>0</RunAbUc> <RunAbUc>0</RunAbUc>
@ -115,6 +115,11 @@
<pMon>STLink\ST-LINKIII-KEIL_SWO.dll</pMon> <pMon>STLink\ST-LINKIII-KEIL_SWO.dll</pMon>
</DebugOpt> </DebugOpt>
<TargetDriverDllRegistry> <TargetDriverDllRegistry>
<SetRegEntry>
<Number>0</Number>
<Key>ST-LINKIII-KEIL_SWO</Key>
<Name>-U -O207 -S0 -C0 -A0 -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO15 -FD20000000 -FC800 -FN1 -FF0GD32F1x0_32 -FS08000000 -FL08000</Name>
</SetRegEntry>
<SetRegEntry> <SetRegEntry>
<Number>0</Number> <Number>0</Number>
<Key>UL2CM3</Key> <Key>UL2CM3</Key>

View File

@ -77,9 +77,9 @@
<nStopB2X>0</nStopB2X> <nStopB2X>0</nStopB2X>
</BeforeMake> </BeforeMake>
<AfterMake> <AfterMake>
<RunUserProg1>0</RunUserProg1> <RunUserProg1>1</RunUserProg1>
<RunUserProg2>0</RunUserProg2> <RunUserProg2>0</RunUserProg2>
<UserProg1Name></UserProg1Name> <UserProg1Name>$K\ARM\ARMCC\bin\fromelf.exe --bin --output=.\Objects\@L.bin !L</UserProg1Name>
<UserProg2Name></UserProg2Name> <UserProg2Name></UserProg2Name>
<UserProg1Dos16Mode>0</UserProg1Dos16Mode> <UserProg1Dos16Mode>0</UserProg1Dos16Mode>
<UserProg2Dos16Mode>0</UserProg2Dos16Mode> <UserProg2Dos16Mode>0</UserProg2Dos16Mode>

View File

@ -150,7 +150,7 @@ CFLAGS += -MMD -MP -MF"$(@:%.o=%.d)"
# LDFLAGS # LDFLAGS
####################################### #######################################
# link script # link script
LDSCRIPT = GD32F130C6_FLASH.ld LDSCRIPT = GD32F130C6T_FLASH.ld
# libraries # libraries
LIBS = -lc -lm -lnosys LIBS = -lc -lm -lnosys

View File

@ -14,6 +14,9 @@ This repository implements the firmware for the hoveboard sideboards. The hovebo
The original sideboard hardware supports one 4-pin cable that originally was connected to the hoveboard mainboard. It breaks out GND, 12/15V and USART. Additionally, two ports are used to connect to the LED boards. On the back of the board, two Photo Interrupter Optical Switches can be found, originally used to detect if a human is standing on the hoverboard. The original sideboard hardware supports one 4-pin cable that originally was connected to the hoveboard mainboard. It breaks out GND, 12/15V and USART. Additionally, two ports are used to connect to the LED boards. On the back of the board, two Photo Interrupter Optical Switches can be found, originally used to detect if a human is standing on the hoverboard.
![sideboard](/docs/pictures/sideboard_pinout.png) ![sideboard](/docs/pictures/sideboard_pinout.png)
The LED boards consist of colored LEDs (blue, red, green, orange) used for design and to inform the user about the current hoverboard state.
![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 heart of the sideboard is a [GD32F130C6T6](/docs/GD32F130xx-Datasheet_Rev3.3.pdf) with the pinout shown in the follwing figure:
![MCU_pinout](/docs/pictures/MCU_pinout.png) ![MCU_pinout](/docs/pictures/MCU_pinout.png)
@ -40,13 +43,34 @@ If you have never flashed your sideboard before, the MCU is probably locked. To
To build and flash choose one of the following methods: To build and flash choose one of the following methods:
### Method 1: Using Keil uVision (recommended) ### Method 1: Using PlatformIO
Because this board is not yet supported by [PlatformIO](https://platformio.org/), we have to make two extra steps. These steps can be skipped once the board is supported (see [this thread](https://community.platformio.org/t/build-gd32-project-with-platformio/11944)).
- go to your PlatformIO home folder (Windows: `C:\Users\<user>\.platformio`, Unix/Max: `/home/<user>/.platformio`). Then go into `packages`. If the folder `framework-spl` exists, delete it.
- unpack the `framework-spl.zip` in the `packages` folder so that the directory structure is now:
```
packages/
| - framework-spl/
| |-- gd32/
| |-- platformio/
| |-- stm32/
| |-- package.json
```
(This folder contains the `GD32F1x0_Firmware_Library_v3.1.0` files)
- open the project folder in the IDE of choice (vscode or Atom)
- press the 'PlatformIO:Build' or the 'PlatformIO:Upload' button (bottom left in vscode).
### Method 2: Using Keil uVision
- in [Keil uVision](https://www.keil.com/download/product/), open the [sideboard-hack.uvproj](/MDK-ARM/) - in [Keil uVision](https://www.keil.com/download/product/), open the [sideboard-hack.uvproj](/MDK-ARM/)
- if you are asked to install missing package, click `Yes`
- click Build Target (or press F7) to build the firmware - click Build Target (or press F7) to build the firmware
- click Load Code (or press F8) to flash the firmware. - click Load Code (or press F8) to flash the firmware.
### Method 2: Using Ubuntu ### Method 3: Using Ubuntu
- prerequisites: install [ST-Flash utility](https://github.com/texane/stlink). - prerequisites: install [ST-Flash utility](https://github.com/texane/stlink).
@ -59,8 +83,6 @@ make
make flash make flash
``` ```
*Note: If someone finds a way to build and flash the GD32 MCU via [Platformio](https://platformio.org/) let me know.*
--- ---
## Example Variants ## Example Variants

View File

@ -24,6 +24,7 @@
#include "systick.h" #include "systick.h"
#include "config.h" #include "config.h"
void I2C0_EventIRQ_Handler(void) void I2C0_EventIRQ_Handler(void)
{ {
uint16_t k; uint16_t k;
@ -52,10 +53,18 @@ void I2C0_EventIRQ_Handler(void)
if (i2c_nDABytes > 0) { if (i2c_nDABytes > 0) {
i2c_data_transmit(I2C0, *i2c_txbuffer++); // the master sends a data byte i2c_data_transmit(I2C0, *i2c_txbuffer++); // the master sends a data byte
i2c_nDABytes--; i2c_nDABytes--;
for(k=0; k<500; k++); // make some clock cycles delay (otherwise DMP writing will fail!! Reason unknown yet.. could be that writing to MPU6050 memory takes a bit more time) if (0 == i2c_nDABytes) {
i2c_status = 0; // 0 = Success
}
for(k=0; k<500; k++) {
#ifdef __GNUC__
asm volatile ("nop"); // unoptimizable NOP loop, 500 times to make some clock cycles delay (otherwise DMP writing will fail!! Reason unknown yet.. could be that writing to MPU6050 memory takes a bit more time)
#else
__asm volatile ("nop");
#endif
}
} else { } else {
i2c_stop_on_bus(I2C0); // the master sends a stop condition to I2C bus i2c_stop_on_bus(I2C0); // the master sends a stop condition to I2C bus
i2c_status = 0; // 0 = Success
i2c_interrupt_disable(I2C0, I2C_INT_ERR | I2C_INT_BUF | I2C_INT_EV); // disable the I2C0 interrupt i2c_interrupt_disable(I2C0, I2C_INT_ERR | I2C_INT_BUF | I2C_INT_EV); // disable the I2C0 interrupt
} }
} }
@ -209,10 +218,17 @@ void I2C1_EventIRQ_Handler(void)
if (i2c_aux_nDABytes > 0) { if (i2c_aux_nDABytes > 0) {
i2c_data_transmit(I2C1, *i2c_aux_txbuffer++); // the master sends a data byte i2c_data_transmit(I2C1, *i2c_aux_txbuffer++); // the master sends a data byte
i2c_aux_nDABytes--; i2c_aux_nDABytes--;
for(k=0; k<500; k++); // make some clock cycles delay (otherwise DMP writing will fail!! Reason unknown yet.. could be that writing to MPU6050 memory takes a bit more time) for(k=0; k<500; k++);
if (0 == i2c_aux_nDABytes) {
i2c_aux_status = 0; // 0 = Success
}
#ifdef __GNUC__
asm volatile ("nop"); // unoptimizable NOP loop, 500 times to make some clock cycles delay (otherwise DMP writing will fail!! Reason unknown yet.. could be that writing to MPU6050 memory takes a bit more time)
#else
__asm volatile ("nop");
#endif
} else { } else {
i2c_stop_on_bus(I2C1); // the master sends a stop condition to I2C bus i2c_stop_on_bus(I2C1); // the master sends a stop condition to I2C bus
i2c_aux_status = 0; // 0 = Success
i2c_interrupt_disable(I2C1, I2C_INT_ERR | I2C_INT_BUF | I2C_INT_EV); // disable the I2C0 interrupt i2c_interrupt_disable(I2C1, I2C_INT_ERR | I2C_INT_BUF | I2C_INT_EV); // disable the I2C0 interrupt
} }
} }

View File

@ -52,7 +52,8 @@ typedef struct{
int16_t speedL_meas; int16_t speedL_meas;
int16_t batVoltage; int16_t batVoltage;
int16_t boardTemp; int16_t boardTemp;
int16_t checksum; uint16_t cmdLed;
uint16_t checksum;
} SerialFeedback; } SerialFeedback;
SerialFeedback Feedback; SerialFeedback Feedback;
SerialFeedback NewFeedback; SerialFeedback NewFeedback;
@ -65,7 +66,8 @@ extern MPU_Data mpu; // holds the MPU-6050 data
ErrStatus mpuStatus = SUCCESS; // holds the MPU-6050 status: SUCCESS or ERROR ErrStatus mpuStatus = SUCCESS; // holds the MPU-6050 status: SUCCESS or ERROR
uint8_t userCommand; // holds the user command input uint8_t userCommand; // holds the user command input
uint8_t sensor1, sensor2; // holds the sensor1 and sensor 2 values 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() static uint32_t main_loop_counter; // main loop counter to perform task squeduling inside main()
@ -85,9 +87,13 @@ int main(void)
usart_Rx_DMA_config(USART_MAIN, (uint8_t *)&NewFeedback, sizeof(NewFeedback)); usart_Rx_DMA_config(USART_MAIN, (uint8_t *)&NewFeedback, sizeof(NewFeedback));
#endif #endif
introDemoLED(100); // Short LEDs intro demo with 100 ms delay. This also gives some time for the MPU-6050 to initialize. intro_demo_led(100); // Short LEDs intro demo with 100 ms delay. This also gives some time for the MPU-6050 to power-up.
if(mpu_config()) { // IMU MPU-6050 config if(mpu_config()) { // IMU MPU-6050 config
mpuStatus = ERROR; mpuStatus = ERROR;
gpio_bit_set(LED1_GPIO_Port, LED1_Pin); // Turn on RED LED
}
else {
gpio_bit_set(LED2_GPIO_Port, LED2_Pin); // Turn on GREEN LED
} }
mpu_handle_input('h'); // Print the User Help commands to serial mpu_handle_input('h'); // Print the User Help commands to serial
@ -96,12 +102,17 @@ int main(void)
delay_1ms(DELAY_IN_MAIN_LOOP); delay_1ms(DELAY_IN_MAIN_LOOP);
// ==================================== LEDs Handling ==================================== // ==================================== LEDs Handling ====================================
// gpio_bit_write(LED4_GPIO_Port, LED4_Pin, (bit_status)(1-gpio_input_bit_get(LED4_GPIO_Port, LED4_Pin))); // Toggle BLUE1 LED // toggle_led(LED4_GPIO_Port, LED4_Pin); // Toggle BLUE1 LED
if (SUCCESS == mpuStatus) { #ifdef SERIAL_FEEDBACK
gpio_bit_set(LED2_GPIO_Port, LED2_Pin); // Turn on GREEN LED if (!timeoutFlagSerial) {
} else { if (Feedback.cmdLed & LED1_SET) { gpio_bit_set(LED1_GPIO_Port, LED1_Pin); } else { gpio_bit_reset(LED1_GPIO_Port, LED1_Pin); }
gpio_bit_set(LED1_GPIO_Port, LED1_Pin); // Turn on RED LED 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); }
} }
#endif
// ==================================== USER Handling ==================================== // ==================================== USER Handling ====================================
#ifdef SERIAL_DEBUG #ifdef SERIAL_DEBUG
@ -122,36 +133,43 @@ int main(void)
mpu_get_data(); mpu_get_data();
} }
// Print MPU data to Console // Print MPU data to Console
if (main_loop_counter % 50 == 0 && SUCCESS == mpuStatus) { if (main_loop_counter % 50 == 0) {
mpu_print_to_console(); mpu_print_to_console();
} }
// ==================================== SENSORS Handling ==================================== // ==================================== 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 // SENSOR1
if (gpio_input_bit_get(SENSOR1_GPIO_Port, SENSOR1_Pin)) { if (sensor1 == RESET && sensor1_read == SET) {
sensor1 = 1; sensor1 = SET;
// Sensor ACTIVE: Do something here // Sensor ACTIVE: Do something here (one time task on activation)
gpio_bit_set(LED4_GPIO_Port, LED4_Pin); gpio_bit_set(LED4_GPIO_Port, LED4_Pin);
consoleLog("-- SENSOR 1 Active --\n"); consoleLog("-- SENSOR 1 Active --\n");
delay_1ms(50); } else if(sensor1 == SET && sensor1_read == RESET) {
} else { sensor1 = RESET;
sensor1 = 0;
gpio_bit_reset(LED4_GPIO_Port, LED4_Pin); gpio_bit_reset(LED4_GPIO_Port, LED4_Pin);
} }
// SENSOR2 // SENSOR2
if (gpio_input_bit_get(SENSOR2_GPIO_Port, SENSOR2_Pin)) { if (sensor2 == RESET && sensor2_read == SET) {
sensor2 = 1; sensor2 = SET;
// Sensor ACTIVE: Do something here // Sensor ACTIVE: Do something here (one time task on activation)
gpio_bit_set(LED5_GPIO_Port, LED5_Pin); gpio_bit_set(LED5_GPIO_Port, LED5_Pin);
consoleLog("-- SENSOR 2 Active --\n"); } else if (sensor2 == SET && sensor2_read == RESET) {
delay_1ms(50); sensor2 = RESET;
} else {
sensor2 = 0;
gpio_bit_reset(LED5_GPIO_Port, LED5_Pin); gpio_bit_reset(LED5_GPIO_Port, LED5_Pin);
} }
if (sensor1 == SET) {
// Sensor ACTIVE: Do something here (continuous task)
}
if (sensor2 == SET) {
// Sensor ACTIVE: Do something here (continuous task)
}
// ==================================== SERIAL Tx/Rx Handling ==================================== // ==================================== SERIAL Tx/Rx Handling ====================================
#ifdef SERIAL_CONTROL #ifdef SERIAL_CONTROL
@ -175,7 +193,7 @@ int main(void)
#ifdef SERIAL_FEEDBACK #ifdef SERIAL_FEEDBACK
uint16_t checksum; uint16_t checksum;
checksum = (uint16_t)(NewFeedback.start ^ NewFeedback.cmd1 ^ NewFeedback.cmd2 ^ NewFeedback.speedR ^ NewFeedback.speedL checksum = (uint16_t)(NewFeedback.start ^ NewFeedback.cmd1 ^ NewFeedback.cmd2 ^ NewFeedback.speedR ^ NewFeedback.speedL
^ NewFeedback.speedR_meas ^ NewFeedback.speedL_meas ^ NewFeedback.batVoltage ^ NewFeedback.boardTemp); ^ NewFeedback.speedR_meas ^ NewFeedback.speedL_meas ^ NewFeedback.batVoltage ^ NewFeedback.boardTemp ^ NewFeedback.cmdLed);
if (NewFeedback.start == SERIAL_START_FRAME && NewFeedback.checksum == checksum) { if (NewFeedback.start == SERIAL_START_FRAME && NewFeedback.checksum == checksum) {
if (timeoutFlagSerial) { // Check for previous timeout flag if (timeoutFlagSerial) { // Check for previous timeout flag
if (timeoutCntSerial-- <= 0) // Timeout de-qualification if (timeoutCntSerial-- <= 0) // Timeout de-qualification

View File

@ -2183,17 +2183,17 @@ static int accel_6500_self_test(long *bias_regular, long *bias_st, int debug)
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
st_shift_cust[i] = bias_st[i] - bias_regular[i]; st_shift_cust[i] = bias_st[i] - bias_regular[i];
if(debug) { if(debug) {
log_i("Bias_Shift=%7.4f, Bias_Reg=%7.4f, Bias_HWST=%7.4f\r\n", log_i("Bias_Shift=%ld, Bias_Reg=%ld, Bias_HWST=%ld\r\n",
st_shift_cust[i]/1.f, bias_regular[i]/1.f, (long)st_shift_cust[i], bias_regular[i],
bias_st[i]/1.f); bias_st[i]);
log_i("OTP value: %7.4f\r\n", ct_shift_prod[i]/1.f); log_i("OTP value: %ld\r\n", (long)ct_shift_prod[i]);
} }
st_shift_ratio[i] = st_shift_cust[i] / ct_shift_prod[i] - 1.f; st_shift_ratio[i] = st_shift_cust[i] / ct_shift_prod[i] - 1.f;
if(debug) if(debug)
log_i("ratio=%7.4f, threshold=%7.4f\r\n", st_shift_ratio[i]/1.f, log_i("ratio=%ld, threshold=%ld\r\n", (long)st_shift_ratio[i],
test.max_accel_var/1.f); (long)test.max_accel_var);
if (fabs(st_shift_ratio[i]) > test.max_accel_var) { if (fabs(st_shift_ratio[i]) > test.max_accel_var) {
if(debug) if(debug)
@ -2209,15 +2209,15 @@ static int accel_6500_self_test(long *bias_regular, long *bias_st, int debug)
if(debug) { if(debug) {
log_i("ACCEL:CRITERIA B\r\n"); log_i("ACCEL:CRITERIA B\r\n");
log_i("Min MG: %7.4f\r\n", accel_st_al_min/1.f); log_i("Min MG: %ld\r\n", (long)accel_st_al_min);
log_i("Max MG: %7.4f\r\n", accel_st_al_max/1.f); log_i("Max MG: %ld\r\n", (long)accel_st_al_max);
} }
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
st_shift_cust[i] = bias_st[i] - bias_regular[i]; st_shift_cust[i] = bias_st[i] - bias_regular[i];
if(debug) if(debug)
log_i("Bias_shift=%7.4f, st=%7.4f, reg=%7.4f\n", st_shift_cust[i]/1.f, bias_st[i]/1.f, bias_regular[i]/1.f); log_i("Bias_shift=%ld, st=%ld, reg=%ld\n", (long)st_shift_cust[i], bias_st[i], bias_regular[i]);
if(st_shift_cust[i] < accel_st_al_min || st_shift_cust[i] > accel_st_al_max) { if(st_shift_cust[i] < accel_st_al_min || st_shift_cust[i] > accel_st_al_max) {
if(debug) if(debug)
log_i("Accel FAIL axis:%d <= 225mg or >= 675mg\n", i); log_i("Accel FAIL axis:%d <= 225mg or >= 675mg\n", i);
@ -2230,7 +2230,7 @@ static int accel_6500_self_test(long *bias_regular, long *bias_st, int debug)
/* Self Test Pass/Fail Criteria C */ /* Self Test Pass/Fail Criteria C */
accel_offset_max = test.max_g_offset * 65536.f; accel_offset_max = test.max_g_offset * 65536.f;
if(debug) if(debug)
log_i("Accel:CRITERIA C: bias less than %7.4f\n", accel_offset_max/1.f); log_i("Accel:CRITERIA C: bias less than %ld\n", (long)accel_offset_max);
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
if(fabs(bias_regular[i]) > accel_offset_max) { if(fabs(bias_regular[i]) > accel_offset_max) {
if(debug) if(debug)
@ -2279,17 +2279,17 @@ static int gyro_6500_self_test(long *bias_regular, long *bias_st, int debug)
st_shift_cust[i] = bias_st[i] - bias_regular[i]; st_shift_cust[i] = bias_st[i] - bias_regular[i];
if(debug) { if(debug) {
log_i("Bias_Shift=%7.4f, Bias_Reg=%7.4f, Bias_HWST=%7.4f\r\n", log_i("Bias_Shift=%ld, Bias_Reg=%ld, Bias_HWST=%ld\r\n",
st_shift_cust[i]/1.f, bias_regular[i]/1.f, (long)st_shift_cust[i], bias_regular[i],
bias_st[i]/1.f); bias_st[i]);
log_i("OTP value: %7.4f\r\n", ct_shift_prod[i]/1.f); log_i("OTP value: %ld\r\n", (long)ct_shift_prod[i]);
} }
st_shift_ratio[i] = st_shift_cust[i] / ct_shift_prod[i]; st_shift_ratio[i] = st_shift_cust[i] / ct_shift_prod[i];
if(debug) if(debug)
log_i("ratio=%7.4f, threshold=%7.4f\r\n", st_shift_ratio[i]/1.f, log_i("ratio=%ld, threshold=%ld\r\n", (long)st_shift_ratio[i],
test.max_gyro_var/1.f); (long)test.max_gyro_var);
if (fabs(st_shift_ratio[i]) < test.max_gyro_var) { if (fabs(st_shift_ratio[i]) < test.max_gyro_var) {
if(debug) if(debug)
@ -2304,14 +2304,14 @@ static int gyro_6500_self_test(long *bias_regular, long *bias_st, int debug)
if(debug) { if(debug) {
log_i("GYRO:CRITERIA B\r\n"); log_i("GYRO:CRITERIA B\r\n");
log_i("Max DPS: %7.4f\r\n", gyro_st_al_max/1.f); log_i("Max DPS: %ld\r\n", (long)gyro_st_al_max);
} }
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
st_shift_cust[i] = bias_st[i] - bias_regular[i]; st_shift_cust[i] = bias_st[i] - bias_regular[i];
if(debug) if(debug)
log_i("Bias_shift=%7.4f, st=%7.4f, reg=%7.4f\n", st_shift_cust[i]/1.f, bias_st[i]/1.f, bias_regular[i]/1.f); log_i("Bias_shift=%ld, st=%ld, reg=%ld\n", (long)st_shift_cust[i], bias_st[i], bias_regular[i]);
if(st_shift_cust[i] < gyro_st_al_max) { if(st_shift_cust[i] < gyro_st_al_max) {
if(debug) if(debug)
log_i("GYRO FAIL axis:%d greater than 60dps\n", i); log_i("GYRO FAIL axis:%d greater than 60dps\n", i);
@ -2324,7 +2324,7 @@ static int gyro_6500_self_test(long *bias_regular, long *bias_st, int debug)
/* Self Test Pass/Fail Criteria C */ /* Self Test Pass/Fail Criteria C */
gyro_offset_max = test.min_dps * 65536.f; gyro_offset_max = test.min_dps * 65536.f;
if(debug) if(debug)
log_i("Gyro:CRITERIA C: bias less than %7.4f\n", gyro_offset_max/1.f); log_i("Gyro:CRITERIA C: bias less than %ld\n", (long)gyro_offset_max);
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
if(fabs(bias_regular[i]) > gyro_offset_max) { if(fabs(bias_regular[i]) > gyro_offset_max) {
if(debug) if(debug)
@ -2456,8 +2456,8 @@ static int get_st_6500_biases(long *gyro, long *accel, unsigned char hw_test, in
if(debug) { if(debug) {
log_i("Accel offset data HWST bit=%d: %7.4f %7.4f %7.4f\r\n", hw_test, accel[0]/65536.f, accel[1]/65536.f, accel[2]/65536.f); log_i("Accel offset data HWST bit=%d: %ld %ld %ld\r\n", hw_test, accel[0], accel[1], accel[2]);
log_i("Gyro offset data HWST bit=%d: %7.4f %7.4f %7.4f\r\n", hw_test, gyro[0]/65536.f, gyro[1]/65536.f, gyro[2]/65536.f); log_i("Gyro offset data HWST bit=%d: %ld %ld %ld\r\n", hw_test, gyro[0], gyro[1], gyro[2]);
} }
return 0; return 0;
@ -3229,14 +3229,14 @@ void mpu_start_self_test(void)
if (result == 0x7) { if (result == 0x7) {
#ifdef SERIAL_DEBUG #ifdef SERIAL_DEBUG
consoleLog("Passed!\n"); consoleLog("Passed!\n");
log_i("accel: %7.4f %7.4f %7.4f\n", log_i("accel: %ld %ld %ld\n",
accel[0]/65536.f, accel[0],
accel[1]/65536.f, accel[1],
accel[2]/65536.f); accel[2]);
log_i("gyro: %7.4f %7.4f %7.4f\n", log_i("gyro: %ld %ld %ld\n",
gyro[0]/65536.f, gyro[0],
gyro[1]/65536.f, gyro[1],
gyro[2]/65536.f); gyro[2]);
/* Test passed. We can trust the gyro data here, so now we need to update calibrated data*/ /* Test passed. We can trust the gyro data here, so now we need to update calibrated data*/
#endif #endif

View File

@ -61,15 +61,34 @@ void consoleLog(char *message)
/* retarget the C library printf function to the USART */ /* retarget the C library printf function to the USART */
int fputc(int ch, FILE *f) #ifdef SERIAL_DEBUG
{ #ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif
PUTCHAR_PROTOTYPE {
usart_data_transmit(USART_MAIN, (uint8_t)ch); usart_data_transmit(USART_MAIN, (uint8_t)ch);
while(RESET == usart_flag_get(USART_MAIN, USART_FLAG_TBE)); while(RESET == usart_flag_get(USART_MAIN, USART_FLAG_TBE));
return ch; return ch;
} }
#ifdef __GNUC__
int _write(int file, char *data, int len) {
int i;
for (i = 0; i < len; i++) { __io_putchar( *data++ );}
return len;
}
#endif
#endif
void introDemoLED(uint32_t tDelay)
void toggle_led(uint32_t gpio_periph, uint32_t pin)
{
GPIO_OCTL(gpio_periph) ^= pin;
}
void intro_demo_led(uint32_t tDelay)
{ {
int i; int i;

2
add_nanolib.py Normal file
View File

@ -0,0 +1,2 @@
Import("env")
env.Append(LINKFLAGS=["--specs=nano.specs"])

40
boards/gd32f130c6.json Normal file
View File

@ -0,0 +1,40 @@
{
"build": {
"core": "gd32",
"cpu": "cortex-m3",
"extra_flags": "-DGD32F1x0 -DGD32F130_150 -D__GD32F130_SUBFAMILY -D__GD32F1x0_FAMILY",
"f_cpu": "72000000L",
"mcu": "gd32f130c6t6"
},
"connectivity": [
],
"debug": {
"default_tools": [
"stlink"
],
"jlink_device": "GD32F130C6",
"onboard_tools": [
"stlink"
],
"openocd_target": "stm32f1x",
"svd_path": "STM32F10x.svd"
},
"frameworks": [
"stm32cube",
"spl"
],
"name": "Generic GD32F130C6T6",
"upload": {
"maximum_ram_size": 4096,
"maximum_size": 32768,
"protocol": "stlink",
"protocols": [
"jlink",
"stlink",
"blackmagic",
"mbed"
]
},
"url": "https://www.gigadevice.com/microcontroller/gd32f130c6t6/",
"vendor": "GigaDevices"
}

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 361 KiB

BIN
framework-spl.zip Normal file

Binary file not shown.

69
platformio.ini Normal file
View File

@ -0,0 +1,69 @@
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[platformio]
include_dir = Inc
src_dir = Src
;=================== VARIANT SELECTION ==========================
;default_envs = VARIANT_DEBUG ; DEFAULT Variant
;default_envs = VARIANT_HOVERBOARD ; HOVERBOARD Variant
;================================================================
;================================================================
[env:VARIANT_DEBUG]
platform = ststm32
board = gd32f130c6
debug_tool = stlink
upload_protocol = stlink
framework = spl
extra_scripts = add_nanolib.py ; adds nanolib to reduce printf memory foot print
; Serial Port settings (make sure the COM port is correct)
monitor_port = COM5
monitor_speed = 38400
build_flags =
-IInc
-ISrc
-DUSE_STDPERIPH_DRIVER
-DGD32F130_150
-Wl,-T./GD32F130C6T_FLASH.ld
-Wl,-lc
-Wl,-lm
-g -ggdb
-D VARIANT_DEBUG
;================================================================
[env:VARIANT_HOVERBOARD]
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
-Wl,-T./GD32F130C6T_FLASH.ld
-Wl,-lc
-Wl,-lm
-g -ggdb
-D VARIANT_HOVERBOARD
;================================================================

View File

@ -77,7 +77,8 @@ LoopFillZerobss:
/* Call the clock system intitialization function.*/ /* Call the clock system intitialization function.*/
bl SystemInit bl SystemInit
/* Call static constructors */ /* Call static constructors */
bl __libc_init_array // nope no C++ code today
// bl __libc_init_array
/* Call the application's entry point.*/ /* Call the application's entry point.*/
bl main bl main
bx lr bx lr