├── CommunicationOverview.ods
├── GD32F130C8 Dokumentation
├── GD32F130.pdf
├── GD32F1x0_User_Manual.pdf
└── TUEV-Report-AKKU.pdf
├── Hardware_Overview_small.png
├── HoverBoardGigaDevice
├── EventRecorderStub.scvd
├── Hoverboard.uvguix.Florian
├── Hoverboard.uvoptx
├── Hoverboard.uvprojx
├── Inc
│ ├── bldc.h
│ ├── comms.h
│ ├── commsBluetooth.h
│ ├── commsMasterSlave.h
│ ├── commsSteering.h
│ ├── config.h
│ ├── defines.h
│ ├── it.h
│ ├── led.h
│ └── setup.h
├── Listings
│ ├── Hoverboard.map
│ └── startup_gd32f1x0.lst
├── RTE
│ ├── Device
│ │ └── GD32F130C8
│ │ │ ├── gd32f1x0_adc.c
│ │ │ ├── gd32f1x0_dbg.c
│ │ │ ├── gd32f1x0_dma.c
│ │ │ ├── gd32f1x0_fwdgt.c
│ │ │ ├── gd32f1x0_gpio.c
│ │ │ ├── gd32f1x0_i2c.c
│ │ │ ├── gd32f1x0_misc.c
│ │ │ ├── gd32f1x0_opa.c
│ │ │ ├── gd32f1x0_pmu.c
│ │ │ ├── gd32f1x0_rcu.c
│ │ │ ├── gd32f1x0_syscfg.c
│ │ │ ├── gd32f1x0_timer.c
│ │ │ ├── gd32f1x0_usart.c
│ │ │ ├── gd32f1x0_wwdgt.c
│ │ │ ├── startup_gd32f1x0.s
│ │ │ └── system_gd32f1x0.c
│ └── _Target_1
│ │ └── RTE_Components.h
└── Src
│ ├── bldc.c
│ ├── comms.c
│ ├── commsBluetooth.c
│ ├── commsMasterSlave.c
│ ├── commsSteering.c
│ ├── it.c
│ ├── led.c
│ ├── main.c
│ └── setup.c
├── LICENSE
├── PPMDeviceArduino_V1.0
└── PPMDevice
│ ├── PPMDevice.ino
│ ├── RCReceiver.cpp
│ ├── RCReceiver.h
│ ├── SteeringSerial.cpp
│ ├── SteeringSerial.h
│ └── utils.h
├── README.md
├── Raumzeigerdiagramm.png
└── Schematics
├── HoverBoard_CoolAndFun.pdf
└── HoverBoard_CoolAndFun.sch
/CommunicationOverview.ods:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flo199213/Hoverboard-Firmware-Hack-Gen2/e138b221aed944478d12e15d81fb858f44f4a289/CommunicationOverview.ods
--------------------------------------------------------------------------------
/GD32F130C8 Dokumentation/GD32F130.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flo199213/Hoverboard-Firmware-Hack-Gen2/e138b221aed944478d12e15d81fb858f44f4a289/GD32F130C8 Dokumentation/GD32F130.pdf
--------------------------------------------------------------------------------
/GD32F130C8 Dokumentation/GD32F1x0_User_Manual.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flo199213/Hoverboard-Firmware-Hack-Gen2/e138b221aed944478d12e15d81fb858f44f4a289/GD32F130C8 Dokumentation/GD32F1x0_User_Manual.pdf
--------------------------------------------------------------------------------
/GD32F130C8 Dokumentation/TUEV-Report-AKKU.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flo199213/Hoverboard-Firmware-Hack-Gen2/e138b221aed944478d12e15d81fb858f44f4a289/GD32F130C8 Dokumentation/TUEV-Report-AKKU.pdf
--------------------------------------------------------------------------------
/Hardware_Overview_small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flo199213/Hoverboard-Firmware-Hack-Gen2/e138b221aed944478d12e15d81fb858f44f4a289/Hardware_Overview_small.png
--------------------------------------------------------------------------------
/HoverBoardGigaDevice/EventRecorderStub.scvd:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/HoverBoardGigaDevice/Inc/bldc.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the hoverboard-firmware-hack-V2 project. The
3 | * firmware is used to hack the generation 2 board of the hoverboard.
4 | * These new hoverboards have no mainboard anymore. They consist of
5 | * two Sensorboards which have their own BLDC-Bridge per Motor and an
6 | * ARM Cortex-M3 processor GD32F130C8.
7 | *
8 | * Copyright (C) 2018 Florian Staeblein
9 | * Copyright (C) 2018 Jakob Broemauer
10 | * Copyright (C) 2018 Kai Liebich
11 | * Copyright (C) 2018 Christoph Lehnert
12 | *
13 | * The program is based on the hoverboard project by Niklas Fauth. The
14 | * structure was tried to be as similar as possible, so that everyone
15 | * could find a better way through the code.
16 | *
17 | * This program is free software: you can redistribute it and/or modify
18 | * it under the terms of the GNU General Public License as published by
19 | * the Free Software Foundation, either version 3 of the License, or
20 | * (at your option) any later version.
21 | *
22 | * This program is distributed in the hope that it will be useful,
23 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 | * GNU General Public License for more details.
26 | *
27 | * You should have received a copy of the GNU General Public License
28 | * along with this program. If not, see .
29 | */
30 |
31 | #ifndef BLDC_H
32 | #define BLDC_H
33 |
34 | #include "gd32f1x0.h"
35 | #include "../Inc/config.h"
36 |
37 | //----------------------------------------------------------------------------
38 | // Set motor enable
39 | //----------------------------------------------------------------------------
40 | void SetEnable(FlagStatus setEnable);
41 |
42 | //----------------------------------------------------------------------------
43 | // Set pwm -1000 to 1000
44 | //----------------------------------------------------------------------------
45 | void SetPWM(int16_t setPwm);
46 |
47 | //----------------------------------------------------------------------------
48 | // Calculation-Routine for BLDC => calculates with 16kHz
49 | //----------------------------------------------------------------------------
50 | void CalculateBLDC(void);
51 |
52 | #endif
53 |
--------------------------------------------------------------------------------
/HoverBoardGigaDevice/Inc/comms.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the hoverboard-firmware-hack-V2 project. The
3 | * firmware is used to hack the generation 2 board of the hoverboard.
4 | * These new hoverboards have no mainboard anymore. They consist of
5 | * two Sensorboards which have their own BLDC-Bridge per Motor and an
6 | * ARM Cortex-M3 processor GD32F130C8.
7 | *
8 | * Copyright (C) 2018 Florian Staeblein
9 | * Copyright (C) 2018 Jakob Broemauer
10 | * Copyright (C) 2018 Kai Liebich
11 | * Copyright (C) 2018 Christoph Lehnert
12 | *
13 | * The program is based on the hoverboard project by Niklas Fauth. The
14 | * structure was tried to be as similar as possible, so that everyone
15 | * could find a better way through the code.
16 | *
17 | * This program is free software: you can redistribute it and/or modify
18 | * it under the terms of the GNU General Public License as published by
19 | * the Free Software Foundation, either version 3 of the License, or
20 | * (at your option) any later version.
21 | *
22 | * This program is distributed in the hope that it will be useful,
23 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 | * GNU General Public License for more details.
26 | *
27 | * You should have received a copy of the GNU General Public License
28 | * along with this program. If not, see .
29 | */
30 |
31 | #ifndef COMMS_H
32 | #define COMMS_H
33 |
34 | #include "gd32f1x0.h"
35 | #include "../Inc/config.h"
36 |
37 | //----------------------------------------------------------------------------
38 | // Send buffer via USART
39 | //----------------------------------------------------------------------------
40 | void SendBuffer(uint32_t usart_periph, uint8_t buffer[], uint8_t length);
41 |
42 | //----------------------------------------------------------------------------
43 | // Calculate CRC
44 | //----------------------------------------------------------------------------
45 | uint16_t CalcCRC(uint8_t *ptr, int count);
46 |
47 | #endif
48 |
--------------------------------------------------------------------------------
/HoverBoardGigaDevice/Inc/commsBluetooth.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the hoverboard-firmware-hack-V2 project. The
3 | * firmware is used to hack the generation 2 board of the hoverboard.
4 | * These new hoverboards have no mainboard anymore. They consist of
5 | * two Sensorboards which have their own BLDC-Bridge per Motor and an
6 | * ARM Cortex-M3 processor GD32F130C8.
7 | *
8 | * Copyright (C) 2018 Florian Staeblein
9 | * Copyright (C) 2018 Jakob Broemauer
10 | * Copyright (C) 2018 Kai Liebich
11 | * Copyright (C) 2018 Christoph Lehnert
12 | *
13 | * The program is based on the hoverboard project by Niklas Fauth. The
14 | * structure was tried to be as similar as possible, so that everyone
15 | * could find a better way through the code.
16 | *
17 | * This program is free software: you can redistribute it and/or modify
18 | * it under the terms of the GNU General Public License as published by
19 | * the Free Software Foundation, either version 3 of the License, or
20 | * (at your option) any later version.
21 | *
22 | * This program is distributed in the hope that it will be useful,
23 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 | * GNU General Public License for more details.
26 | *
27 | * You should have received a copy of the GNU General Public License
28 | * along with this program. If not, see .
29 | */
30 |
31 | #ifndef COMMSBLUETOOTH_H
32 | #define COMMSBLUETOOTH_H
33 |
34 | #include "gd32f1x0.h"
35 | #include "../Inc/config.h"
36 |
37 | // Only slave communicates over bluetooth
38 | #ifdef SLAVE
39 |
40 | //----------------------------------------------------------------------------
41 | // Update USART bluetooth input
42 | //----------------------------------------------------------------------------
43 | void UpdateUSARTBluetoothInput(void);
44 |
45 | #endif
46 |
47 | #endif
48 |
--------------------------------------------------------------------------------
/HoverBoardGigaDevice/Inc/commsMasterSlave.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the hoverboard-firmware-hack-V2 project. The
3 | * firmware is used to hack the generation 2 board of the hoverboard.
4 | * These new hoverboards have no mainboard anymore. They consist of
5 | * two Sensorboards which have their own BLDC-Bridge per Motor and an
6 | * ARM Cortex-M3 processor GD32F130C8.
7 | *
8 | * Copyright (C) 2018 Florian Staeblein
9 | * Copyright (C) 2018 Jakob Broemauer
10 | * Copyright (C) 2018 Kai Liebich
11 | * Copyright (C) 2018 Christoph Lehnert
12 | *
13 | * The program is based on the hoverboard project by Niklas Fauth. The
14 | * structure was tried to be as similar as possible, so that everyone
15 | * could find a better way through the code.
16 | *
17 | * This program is free software: you can redistribute it and/or modify
18 | * it under the terms of the GNU General Public License as published by
19 | * the Free Software Foundation, either version 3 of the License, or
20 | * (at your option) any later version.
21 | *
22 | * This program is distributed in the hope that it will be useful,
23 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 | * GNU General Public License for more details.
26 | *
27 | * You should have received a copy of the GNU General Public License
28 | * along with this program. If not, see .
29 | */
30 |
31 | #ifndef COMMSMASTERSLAVE_H
32 | #define COMMSMASTERSLAVE_H
33 |
34 | #include "gd32f1x0.h"
35 | #include "../Inc/config.h"
36 |
37 | //----------------------------------------------------------------------------
38 | // Update USART master slave input
39 | //----------------------------------------------------------------------------
40 | void UpdateUSARTMasterSlaveInput(void);
41 |
42 | #ifdef MASTER
43 | //----------------------------------------------------------------------------
44 | // Send slave frame via USART
45 | //----------------------------------------------------------------------------
46 | void SendSlave(int16_t pwmSlave, FlagStatus enable, FlagStatus shutoff, FlagStatus chargeState, uint8_t identifier, int16_t value);
47 | #endif
48 | #ifdef SLAVE
49 | //----------------------------------------------------------------------------
50 | // Send master frame via USART
51 | //----------------------------------------------------------------------------
52 | void SendMaster(FlagStatus upperLEDMaster, FlagStatus lowerLEDMaster, FlagStatus mosfetOutMaster, FlagStatus beepsBackwards);
53 |
54 | //----------------------------------------------------------------------------
55 | // Returns current value sent by master
56 | //----------------------------------------------------------------------------
57 | int16_t GetCurrentDCMaster(void);
58 |
59 | //----------------------------------------------------------------------------
60 | // Returns battery value sent by master
61 | //----------------------------------------------------------------------------
62 | int16_t GetBatteryMaster(void);
63 |
64 | //----------------------------------------------------------------------------
65 | // Returns realspeed value sent by master
66 | //----------------------------------------------------------------------------
67 | int16_t GetRealSpeedMaster(void);
68 |
69 | //----------------------------------------------------------------------------
70 | // Sets upper LED value which will be send to master
71 | //----------------------------------------------------------------------------
72 | void SetUpperLEDMaster(FlagStatus value);
73 |
74 | //----------------------------------------------------------------------------
75 | // Returns upper LED value sent by master
76 | //----------------------------------------------------------------------------
77 | FlagStatus GetUpperLEDMaster(void);
78 |
79 | //----------------------------------------------------------------------------
80 | // Sets lower LED value which will be send to master
81 | //----------------------------------------------------------------------------
82 | void SetLowerLEDMaster(FlagStatus value);
83 |
84 | //----------------------------------------------------------------------------
85 | // Returns lower LED value sent by master
86 | //----------------------------------------------------------------------------
87 | FlagStatus GetLowerLEDMaster(void);
88 |
89 | //----------------------------------------------------------------------------
90 | // Sets mosfetOut value which will be send to master
91 | //----------------------------------------------------------------------------
92 | void SetMosfetOutMaster(FlagStatus value);
93 |
94 | //----------------------------------------------------------------------------
95 | // Returns MosfetOut value sent by master
96 | //----------------------------------------------------------------------------
97 | FlagStatus GetMosfetOutMaster(void);
98 |
99 | //----------------------------------------------------------------------------
100 | // Sets beepsBackwards value which will be send to master
101 | //----------------------------------------------------------------------------
102 | void SetBeepsBackwardsMaster(FlagStatus value);
103 |
104 | //----------------------------------------------------------------------------
105 | // Returns beepsBackwardsMaster value sent by master
106 | //----------------------------------------------------------------------------
107 | FlagStatus GetBeepsBackwardsMaster(void);
108 | #endif
109 |
110 | #endif
111 |
--------------------------------------------------------------------------------
/HoverBoardGigaDevice/Inc/commsSteering.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the hoverboard-firmware-hack-V2 project. The
3 | * firmware is used to hack the generation 2 board of the hoverboard.
4 | * These new hoverboards have no mainboard anymore. They consist of
5 | * two Sensorboards which have their own BLDC-Bridge per Motor and an
6 | * ARM Cortex-M3 processor GD32F130C8.
7 | *
8 | * Copyright (C) 2018 Florian Staeblein
9 | * Copyright (C) 2018 Jakob Broemauer
10 | * Copyright (C) 2018 Kai Liebich
11 | * Copyright (C) 2018 Christoph Lehnert
12 | *
13 | * The program is based on the hoverboard project by Niklas Fauth. The
14 | * structure was tried to be as similar as possible, so that everyone
15 | * could find a better way through the code.
16 | *
17 | * This program is free software: you can redistribute it and/or modify
18 | * it under the terms of the GNU General Public License as published by
19 | * the Free Software Foundation, either version 3 of the License, or
20 | * (at your option) any later version.
21 | *
22 | * This program is distributed in the hope that it will be useful,
23 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 | * GNU General Public License for more details.
26 | *
27 | * You should have received a copy of the GNU General Public License
28 | * along with this program. If not, see .
29 | */
30 |
31 | #ifndef COMMSSTEERING_H
32 | #define COMMSSTEERING_H
33 |
34 | #include "gd32f1x0.h"
35 | #include "../Inc/config.h"
36 |
37 | // Only master communicates with steering device
38 | #ifdef MASTER
39 | //----------------------------------------------------------------------------
40 | // Update USART steer input
41 | //----------------------------------------------------------------------------
42 | void UpdateUSARTSteerInput(void);
43 |
44 | //----------------------------------------------------------------------------
45 | // Send frame to steer device
46 | //----------------------------------------------------------------------------
47 | void SendSteerDevice(void);
48 | #endif
49 |
50 | #endif
51 |
--------------------------------------------------------------------------------
/HoverBoardGigaDevice/Inc/config.h:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flo199213/Hoverboard-Firmware-Hack-Gen2/e138b221aed944478d12e15d81fb858f44f4a289/HoverBoardGigaDevice/Inc/config.h
--------------------------------------------------------------------------------
/HoverBoardGigaDevice/Inc/defines.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the hoverboard-firmware-hack-V2 project. The
3 | * firmware is used to hack the generation 2 board of the hoverboard.
4 | * These new hoverboards have no mainboard anymore. They consist of
5 | * two Sensorboards which have their own BLDC-Bridge per Motor and an
6 | * ARM Cortex-M3 processor GD32F130C8.
7 | *
8 | * Copyright (C) 2018 Florian Staeblein
9 | * Copyright (C) 2018 Jakob Broemauer
10 | * Copyright (C) 2018 Kai Liebich
11 | * Copyright (C) 2018 Christoph Lehnert
12 | *
13 | * The program is based on the hoverboard project by Niklas Fauth. The
14 | * structure was tried to be as similar as possible, so that everyone
15 | * could find a better way through the code.
16 | *
17 | * This program is free software: you can redistribute it and/or modify
18 | * it under the terms of the GNU General Public License as published by
19 | * the Free Software Foundation, either version 3 of the License, or
20 | * (at your option) any later version.
21 | *
22 | * This program is distributed in the hope that it will be useful,
23 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 | * GNU General Public License for more details.
26 | *
27 | * You should have received a copy of the GNU General Public License
28 | * along with this program. If not, see .
29 | */
30 |
31 | #ifndef DEFINES_H
32 | #define DEFINES_H
33 |
34 | #include "gd32f1x0.h"
35 | #include "../Inc/config.h"
36 |
37 | // LED defines
38 | #define LED_GREEN GPIO_PIN_15
39 | #define LED_GREEN_PORT GPIOA
40 | #define LED_ORANGE GPIO_PIN_12
41 | #define LED_ORANGE_PORT GPIOA
42 | #define LED_RED GPIO_PIN_3
43 | #define LED_RED_PORT GPIOB
44 |
45 | #define UPPER_LED_PIN GPIO_PIN_1
46 | #define UPPER_LED_PORT GPIOA
47 | #define LOWER_LED_PIN GPIO_PIN_0
48 | #define LOWER_LED_PORT GPIOA
49 |
50 | // Mosfet output
51 | #define MOSFET_OUT_PIN GPIO_PIN_13
52 | #define MOSFET_OUT_PORT GPIOC
53 |
54 | // Brushless Control DC (BLDC) defines
55 | // Channel G
56 | #define RCU_TIMER_BLDC RCU_TIMER0
57 | #define TIMER_BLDC TIMER0
58 | #define TIMER_BLDC_CHANNEL_G TIMER_CH_2
59 | #define TIMER_BLDC_GH_PIN GPIO_PIN_10
60 | #define TIMER_BLDC_GH_PORT GPIOA
61 | #define TIMER_BLDC_GL_PIN GPIO_PIN_15
62 | #define TIMER_BLDC_GL_PORT GPIOB
63 | // Channel B
64 | #define TIMER_BLDC_CHANNEL_B TIMER_CH_1
65 | #define TIMER_BLDC_BH_PIN GPIO_PIN_9
66 | #define TIMER_BLDC_BH_PORT GPIOA
67 | #define TIMER_BLDC_BL_PIN GPIO_PIN_14
68 | #define TIMER_BLDC_BL_PORT GPIOB
69 | // Channel Y
70 | #define TIMER_BLDC_CHANNEL_Y TIMER_CH_0
71 | #define TIMER_BLDC_YH_PIN GPIO_PIN_8
72 | #define TIMER_BLDC_YH_PORT GPIOA
73 | #define TIMER_BLDC_YL_PIN GPIO_PIN_13
74 | #define TIMER_BLDC_YL_PORT GPIOB
75 |
76 | // Timer BLDC short circuit emergency shutoff define
77 | #define TIMER_BLDC_EMERGENCY_SHUTDOWN_PIN GPIO_PIN_12
78 | #define TIMER_BLDC_EMERGENCY_SHUTDOWN_PORT GPIOB
79 |
80 | // Hall sensor defines
81 | #define HALL_A_PIN GPIO_PIN_11
82 | #define HALL_A_PORT GPIOB
83 | #define HALL_B_PIN GPIO_PIN_1
84 | #define HALL_B_PORT GPIOF
85 | #define HALL_C_PIN GPIO_PIN_14
86 | #define HALL_C_PORT GPIOC
87 |
88 | // Usart master slave defines
89 | #define USART_MASTERSLAVE USART1
90 | #define USART_MASTERSLAVE_TX_PIN GPIO_PIN_2
91 | #define USART_MASTERSLAVE_TX_PORT GPIOA
92 | #define USART_MASTERSLAVE_RX_PIN GPIO_PIN_3
93 | #define USART_MASTERSLAVE_RX_PORT GPIOA
94 |
95 | // ADC defines
96 | #define VBATT_PIN GPIO_PIN_4
97 | #define VBATT_PORT GPIOA
98 | #define VBATT_CHANNEL ADC_CHANNEL_4
99 | #define CURRENT_DC_PIN GPIO_PIN_6
100 | #define CURRENT_DC_PORT GPIOA
101 | #define CURRENT_DC_CHANNEL ADC_CHANNEL_6
102 |
103 | // Self hold defines
104 | #define SELF_HOLD_PIN GPIO_PIN_2
105 | #define SELF_HOLD_PORT GPIOB
106 |
107 | // Button defines
108 | #define BUTTON_PIN GPIO_PIN_15
109 | #define BUTTON_PORT GPIOC
110 |
111 | // Usart steer defines
112 | #define USART_STEER_COM USART0
113 | #define USART_STEER_COM_TX_PIN GPIO_PIN_6
114 | #define USART_STEER_COM_TX_PORT GPIOB
115 | #define USART_STEER_COM_RX_PIN GPIO_PIN_7
116 | #define USART_STEER_COM_RX_PORT GPIOB
117 |
118 | #ifdef MASTER
119 | // Buzzer defins
120 | #define BUZZER_PIN GPIO_PIN_10
121 | #define BUZZER_PORT GPIOB
122 |
123 | // Charge state defines
124 | #define CHARGE_STATE_PIN GPIO_PIN_0
125 | #define CHARGE_STATE_PORT GPIOF
126 | #endif
127 |
128 | // Debug pin defines
129 | #define DEBUG_PIN GPIO_PIN_4
130 | #define DEBUG_PORT GPIOB
131 |
132 | // ADC value conversion defines
133 | #define MOTOR_AMP_CONV_DC_AMP 0.201465201465 // 3,3V * 1/3 - 0,004Ohm * IL(ampere) = (ADC-Data/4095) *3,3V
134 | #define ADC_BATTERY_VOLT 0.024169921875 // V_Batt to V_BattMeasure = factor 30: ( (ADC-Data/4095) *3,3V *30 )
135 |
136 | // Useful math function defines
137 | #define ABS(a) (((a) < 0.0) ? -(a) : (a))
138 | #define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
139 | #define MAX(x, high) (((x) > (high)) ? (high) : (x))
140 | #define MAP(x, xMin, xMax, yMin, yMax) ((x - xMin) * (yMax - yMin) / (xMax - xMin) + yMin)
141 |
142 | // ADC buffer struct
143 | typedef struct
144 | {
145 | uint16_t v_batt;
146 | uint16_t current_dc;
147 | } adc_buf_t;
148 |
149 | #endif
150 |
--------------------------------------------------------------------------------
/HoverBoardGigaDevice/Inc/it.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the hoverboard-firmware-hack-V2 project. The
3 | * firmware is used to hack the generation 2 board of the hoverboard.
4 | * These new hoverboards have no mainboard anymore. They consist of
5 | * two Sensorboards which have their own BLDC-Bridge per Motor and an
6 | * ARM Cortex-M3 processor GD32F130C8.
7 | *
8 | * Copyright (C) 2018 Florian Staeblein
9 | * Copyright (C) 2018 Jakob Broemauer
10 | * Copyright (C) 2018 Kai Liebich
11 | * Copyright (C) 2018 Christoph Lehnert
12 | *
13 | * The program is based on the hoverboard project by Niklas Fauth. The
14 | * structure was tried to be as similar as possible, so that everyone
15 | * could find a better way through the code.
16 | *
17 | * This program is free software: you can redistribute it and/or modify
18 | * it under the terms of the GNU General Public License as published by
19 | * the Free Software Foundation, either version 3 of the License, or
20 | * (at your option) any later version.
21 | *
22 | * This program is distributed in the hope that it will be useful,
23 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 | * GNU General Public License for more details.
26 | *
27 | * You should have received a copy of the GNU General Public License
28 | * along with this program. If not, see .
29 | */
30 |
31 | #ifndef IT_H
32 | #define IT_H
33 |
34 | #include "gd32f1x0.h"
35 | #include "../Inc/config.h"
36 |
37 | //----------------------------------------------------------------------------
38 | // Resets the timeout to zero
39 | //----------------------------------------------------------------------------
40 | void ResetTimeout(void);
41 |
42 | //----------------------------------------------------------------------------
43 | // Returns number of milliseconds since system start
44 | //----------------------------------------------------------------------------
45 | uint32_t millis( void );
46 |
47 | //----------------------------------------------------------------------------
48 | // Delays number of tick Systicks (happens every 10 ms)
49 | //----------------------------------------------------------------------------
50 | void Delay (uint32_t dlyTicks);
51 |
52 | #endif
53 |
--------------------------------------------------------------------------------
/HoverBoardGigaDevice/Inc/led.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the hoverboard-firmware-hack-V2 project. The
3 | * firmware is used to hack the generation 2 board of the hoverboard.
4 | * These new hoverboards have no mainboard anymore. They consist of
5 | * two Sensorboards which have their own BLDC-Bridge per Motor and an
6 | * ARM Cortex-M3 processor GD32F130C8.
7 | *
8 | * Copyright (C) 2018 Florian Staeblein
9 | * Copyright (C) 2018 Jakob Broemauer
10 | * Copyright (C) 2018 Kai Liebich
11 | * Copyright (C) 2018 Christoph Lehnert
12 | *
13 | * The program is based on the hoverboard project by Niklas Fauth. The
14 | * structure was tried to be as similar as possible, so that everyone
15 | * could find a better way through the code.
16 | *
17 | * This program is free software: you can redistribute it and/or modify
18 | * it under the terms of the GNU General Public License as published by
19 | * the Free Software Foundation, either version 3 of the License, or
20 | * (at your option) any later version.
21 | *
22 | * This program is distributed in the hope that it will be useful,
23 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 | * GNU General Public License for more details.
26 | *
27 | * You should have received a copy of the GNU General Public License
28 | * along with this program. If not, see .
29 | */
30 |
31 | #ifndef LED_H
32 | #define LED_H
33 |
34 | #include "gd32f1x0.h"
35 | #include "../Inc/config.h"
36 |
37 | // Only slave has LED mechanism
38 | #ifdef SLAVE
39 |
40 | // Modes for RGB-LED operation
41 | typedef enum
42 | {
43 | LED_OFF = 0,
44 | LED_HSB = 1,
45 | LED_HSB_BLINK = 2,
46 | LED_HSB_FADE = 3,
47 | LED_HSB_STROBE = 4
48 | } LED_PROGRAM;
49 |
50 | #define COUNT_PROGRAMS 6 // Count of LED programs!!
51 |
52 | //----------------------------------------------------------------------------
53 | // Update RGB LED output with 16kHz
54 | //----------------------------------------------------------------------------
55 | void CalculateLEDPWM(void);
56 |
57 | //----------------------------------------------------------------------------
58 | // Update RGB LED program every 1ms
59 | //----------------------------------------------------------------------------
60 | void CalculateLEDProgram(void);
61 |
62 | //----------------------------------------------------------------------------
63 | // Sets/Gets LED program
64 | //----------------------------------------------------------------------------
65 | void SetRGBProgram(LED_PROGRAM Program);
66 | LED_PROGRAM GetRGBProgram(void);
67 |
68 | //----------------------------------------------------------------------------
69 | // Sets/Gets hue from 0-764
70 | //----------------------------------------------------------------------------
71 | void SetHSBHue(uint16_t hue);
72 | uint16_t GetHSBHue(void);
73 |
74 | //----------------------------------------------------------------------------
75 | // Sets/Gets saturation from 0-128
76 | //----------------------------------------------------------------------------
77 | void SetHSBSaturation(uint8_t saturation);
78 | uint8_t GetHSBSaturation(void);
79 |
80 | //----------------------------------------------------------------------------
81 | // Sets/Gets brightness from 0-63
82 | //----------------------------------------------------------------------------
83 | void SetHSBBrightness(uint8_t brightnessVal);
84 | uint8_t GetHSBBrightness(void);
85 |
86 |
87 | //----------------------------------------------------------------------------
88 | // Sets/Gets fading speed from 200-1000
89 | //----------------------------------------------------------------------------
90 | void SetSpeedFading(uint16_t speed);
91 | uint16_t GetSpeedFading(void);
92 |
93 | //----------------------------------------------------------------------------
94 | // Sets/Gets blink speed from 700-2400
95 | //----------------------------------------------------------------------------
96 | void SetSpeedBlink(uint16_t speed);
97 | uint16_t GetSpeedBlink(void);
98 |
99 | //----------------------------------------------------------------------------
100 | // Sets/Gets strobe speed from 0-1000
101 | //----------------------------------------------------------------------------
102 | void SetSpeedStrobe(uint16_t speed);
103 | uint16_t GetSpeedStrobe(void);
104 |
105 | #endif
106 |
107 | #endif
108 |
--------------------------------------------------------------------------------
/HoverBoardGigaDevice/Inc/setup.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the hoverboard-firmware-hack-V2 project. The
3 | * firmware is used to hack the generation 2 board of the hoverboard.
4 | * These new hoverboards have no mainboard anymore. They consist of
5 | * two Sensorboards which have their own BLDC-Bridge per Motor and an
6 | * ARM Cortex-M3 processor GD32F130C8.
7 | *
8 | * Copyright (C) 2018 Florian Staeblein
9 | * Copyright (C) 2018 Jakob Broemauer
10 | * Copyright (C) 2018 Kai Liebich
11 | * Copyright (C) 2018 Christoph Lehnert
12 | *
13 | * The program is based on the hoverboard project by Niklas Fauth. The
14 | * structure was tried to be as similar as possible, so that everyone
15 | * could find a better way through the code.
16 | *
17 | * This program is free software: you can redistribute it and/or modify
18 | * it under the terms of the GNU General Public License as published by
19 | * the Free Software Foundation, either version 3 of the License, or
20 | * (at your option) any later version.
21 | *
22 | * This program is distributed in the hope that it will be useful,
23 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 | * GNU General Public License for more details.
26 | *
27 | * You should have received a copy of the GNU General Public License
28 | * along with this program. If not, see .
29 | */
30 |
31 | #ifndef SETUP_H
32 | #define SETUP_H
33 |
34 | #include "gd32f1x0.h"
35 | #include "../Inc/config.h"
36 |
37 |
38 | #define USART_MASTERSLAVE_RX_BUFFERSIZE 1
39 | #define USART_MASTERSLAVE_DATA_RX_ADDRESS ((uint32_t)0x40004424)
40 |
41 | #define USART_STEER_COM_RX_BUFFERSIZE 1
42 | #define USART_STEER_COM_DATA_RX_ADDRESS ((uint32_t)0x40013824)
43 |
44 | //----------------------------------------------------------------------------
45 | // Initializes the interrupts
46 | //----------------------------------------------------------------------------
47 | void Interrupt_init(void);
48 |
49 | //----------------------------------------------------------------------------
50 | // Initializes the watchdog
51 | //----------------------------------------------------------------------------
52 | ErrStatus Watchdog_init(void);
53 |
54 | //----------------------------------------------------------------------------
55 | // Initializes the timeout timer
56 | //----------------------------------------------------------------------------
57 | void TimeoutTimer_init(void);
58 |
59 | //----------------------------------------------------------------------------
60 | // Initializes the GPIOs
61 | //----------------------------------------------------------------------------
62 | void GPIO_init(void);
63 |
64 | //----------------------------------------------------------------------------
65 | // Initializes the PWM
66 | //----------------------------------------------------------------------------
67 | void PWM_init(void);
68 |
69 | //----------------------------------------------------------------------------
70 | // Initializes the ADC
71 | //----------------------------------------------------------------------------
72 | void ADC_init(void);
73 |
74 | //----------------------------------------------------------------------------
75 | // Initializes the usart master slave
76 | //----------------------------------------------------------------------------
77 | void USART_MasterSlave_init(void);
78 |
79 | //----------------------------------------------------------------------------
80 | // Initializes the steer/bluetooth usart
81 | //----------------------------------------------------------------------------
82 | void USART_Steer_COM_init(void);
83 |
84 | #endif
85 |
--------------------------------------------------------------------------------
/HoverBoardGigaDevice/RTE/Device/GD32F130C8/gd32f1x0_dbg.c:
--------------------------------------------------------------------------------
1 | /*!
2 | \file gd32f1x0_dbg.c
3 | \brief DBG driver
4 | */
5 |
6 | /*
7 | Copyright (C) 2017 GigaDevice
8 |
9 | 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5)
10 | 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9)
11 | 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9)
12 | 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9)
13 | */
14 |
15 | #include "gd32f1x0_dbg.h"
16 |
17 | #define DBG_RESET_VAL 0x00000000U
18 |
19 | /*!
20 | \brief deinitialize the DBG
21 | \param[in] none
22 | \param[out] none
23 | \retval none
24 | */
25 | void dbg_deinit(void)
26 | {
27 | DBG_CTL0 = DBG_RESET_VAL;
28 | DBG_CTL1 = DBG_RESET_VAL;
29 | }
30 |
31 | /*!
32 | \brief read DBG_ID code register
33 | \param[in] none
34 | \param[out] none
35 | \retval DBG_ID code
36 | */
37 | uint32_t dbg_id_get(void)
38 | {
39 | return DBG_ID;
40 | }
41 |
42 | /*!
43 | \brief enable low power behavior when the mcu is in debug mode
44 | \param[in] dbg_low_power:
45 | this parameter can be any combination of the following values:
46 | \arg DBG_LOW_POWER_SLEEP: keep debugger connection during sleep mode
47 | \arg DBG_LOW_POWER_DEEPSLEEP: keep debugger connection during deepsleep mode
48 | \arg DBG_LOW_POWER_STANDBY: keep debugger connection during standby mode
49 | \param[out] none
50 | \retval none
51 | */
52 | void dbg_low_power_enable(uint32_t dbg_low_power)
53 | {
54 | DBG_CTL0 |= dbg_low_power;
55 | }
56 |
57 | /*!
58 | \brief disable low power behavior when the mcu is in debug mode
59 | \param[in] dbg_low_power:
60 | this parameter can be any combination of the following values:
61 | \arg DBG_LOW_POWER_SLEEP: donot keep debugger connection during sleep mode
62 | \arg DBG_LOW_POWER_DEEPSLEEP: donot keep debugger connection during deepsleep mode
63 | \arg DBG_LOW_POWER_STANDBY: donot keep debugger connection during standby mode
64 | \param[out] none
65 | \retval none
66 | */
67 | void dbg_low_power_disable(uint32_t dbg_low_power)
68 | {
69 | DBG_CTL0 &= ~dbg_low_power;
70 | }
71 |
72 | /*!
73 | \brief enable peripheral behavior when the mcu is in debug mode
74 | \param[in] dbg_periph: refer to dbg_periph_enum
75 | only one parameter can be selected which is shown as below:
76 | \arg DBG_FWDGT_HOLD : debug FWDGT kept when core is halted
77 | \arg DBG_WWDGT_HOLD : debug WWDGT kept when core is halted
78 | \arg DBG_CANx_HOLD (x=0,1): hold CANx counter when core is halted(170_190 series only)
79 | \arg DBG_I2Cx_HOLD (x=0,1,2): hold I2Cx smbus when core is halted
80 | \arg DBG_TIMERx_HOLD (x=0,1,2,5,13,14,15,16): hold TIMERx counter when core is halted
81 | \arg DBG_RTC_HOLD : hold RTC calendar and wakeup counter when core is halted
82 | \param[out] none
83 | \retval none
84 | */
85 | void dbg_periph_enable(dbg_periph_enum dbg_periph)
86 | {
87 | DBG_REG_VAL(dbg_periph) |= BIT(DBG_BIT_POS(dbg_periph));
88 | }
89 |
90 | /*!
91 | \brief disable peripheral behavior when the mcu is in debug mode
92 | \param[in] dbg_periph: refer to dbg_periph_enum
93 | only one parameter can be selected which is shown as below:
94 | \arg DBG_FWDGT_HOLD : debug FWDGT kept when core is halted
95 | \arg DBG_WWDGT_HOLD : debug WWDGT kept when core is halted
96 | \arg DBG_CANx_HOLD (x=0,1): hold CANx counter when core is halted(170_190 series only)
97 | \arg DBG_I2Cx_HOLD (x=0,1,2): hold I2Cx smbus when core is halted
98 | \arg DBG_TIMERx_HOLD (x=0,1,2,5,13,14,15,16): hold TIMERx counter when core is halted
99 | \arg DBG_RTC_HOLD : hold RTC calendar and wakeup counter when core is halted
100 | \param[out] none
101 | \retval none
102 | */
103 | void dbg_periph_disable(dbg_periph_enum dbg_periph)
104 | {
105 | DBG_REG_VAL(dbg_periph) &= ~BIT(DBG_BIT_POS(dbg_periph));
106 | }
107 |
--------------------------------------------------------------------------------
/HoverBoardGigaDevice/RTE/Device/GD32F130C8/gd32f1x0_fwdgt.c:
--------------------------------------------------------------------------------
1 | /*!
2 | \file gd32f1x0_fwdgt.c
3 | \brief FWDGT driver
4 | */
5 |
6 | /*
7 | Copyright (C) 2017 GigaDevice
8 |
9 | 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5)
10 | 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9)
11 | 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9)
12 | 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9)
13 | */
14 |
15 | #include "gd32f1x0_fwdgt.h"
16 |
17 | /*!
18 | \brief disable write access to FWDGT_PSC,FWDGT_RLD and FWDGT_WND
19 | \param[in] none
20 | \param[out] none
21 | \retval none
22 | */
23 | void fwdgt_write_disable(void)
24 | {
25 | FWDGT_CTL = FWDGT_WRITEACCESS_DISABLE;
26 | }
27 |
28 | /*!
29 | \brief reload the counter of FWDGT
30 | \param[in] none
31 | \param[out] none
32 | \retval none
33 | */
34 | void fwdgt_counter_reload(void)
35 | {
36 | FWDGT_CTL = FWDGT_KEY_RELOAD;
37 | }
38 |
39 | /*!
40 | \brief start the free watchdog timer counter
41 | \param[in] none
42 | \param[out] none
43 | \retval none
44 | */
45 | void fwdgt_enable(void)
46 | {
47 | FWDGT_CTL = FWDGT_KEY_ENABLE;
48 | }
49 |
50 | /*!
51 | \brief configure the free watchdog timer counter window value
52 | \param[in] window_value: specify window value(0x0000 - 0x0FFF)
53 | \param[out] none
54 | \retval ErrStatus: ERROR or SUCCESS
55 | */
56 | ErrStatus fwdgt_window_value_config(uint16_t window_value)
57 | {
58 | uint32_t time_index = FWDGT_WND_TIMEOUT;
59 | uint32_t flag_status = RESET;
60 |
61 | /* enable write access to FWDGT_WND */
62 | FWDGT_CTL = FWDGT_WRITEACCESS_ENABLE;
63 |
64 | /* wait until the WUD flag to be reset */
65 | do{
66 | flag_status = FWDGT_STAT & FWDGT_STAT_WUD;
67 | }while((--time_index > 0U) && ((uint32_t)RESET != flag_status));
68 |
69 | if ((uint32_t)RESET != flag_status){
70 | return ERROR;
71 | }
72 |
73 | FWDGT_WND = WND_WND(window_value);
74 |
75 | return SUCCESS;
76 | }
77 |
78 | /*!
79 | \brief configure counter reload value, and prescaler divider value
80 | \param[in] reload_value: specify reload value(0x0000 - 0x0FFF)
81 | \param[in] prescaler_div: FWDGT prescaler value
82 | \arg FWDGT_PSC_DIV4: FWDGT prescaler set to 4
83 | \arg FWDGT_PSC_DIV8: FWDGT prescaler set to 8
84 | \arg FWDGT_PSC_DIV16: FWDGT prescaler set to 16
85 | \arg FWDGT_PSC_DIV32: FWDGT prescaler set to 32
86 | \arg FWDGT_PSC_DIV64: FWDGT prescaler set to 64
87 | \arg FWDGT_PSC_DIV128: FWDGT prescaler set to 128
88 | \arg FWDGT_PSC_DIV256: FWDGT prescaler set to 256
89 | \param[out] none
90 | \retval ErrStatus: ERROR or SUCCESS
91 | */
92 | ErrStatus fwdgt_config(uint16_t reload_value, uint8_t prescaler_div)
93 | {
94 | uint32_t timeout = FWDGT_PSC_TIMEOUT;
95 | uint32_t flag_status = RESET;
96 |
97 | /* enable write access to FWDGT_PSC,and FWDGT_RLD */
98 | FWDGT_CTL = FWDGT_WRITEACCESS_ENABLE;
99 |
100 | /* wait until the PUD flag to be reset */
101 | do{
102 | flag_status = FWDGT_STAT & FWDGT_STAT_PUD;
103 | }while((--timeout > 0U) && ((uint32_t)RESET != flag_status));
104 |
105 | if ((uint32_t)RESET != flag_status){
106 | return ERROR;
107 | }
108 |
109 | /* configure FWDGT */
110 | FWDGT_PSC = (uint32_t)prescaler_div;
111 |
112 | timeout = FWDGT_RLD_TIMEOUT;
113 | /* wait until the RUD flag to be reset */
114 | do{
115 | flag_status = FWDGT_STAT & FWDGT_STAT_RUD;
116 | }while((--timeout > 0U) && ((uint32_t)RESET != flag_status));
117 |
118 | if ((uint32_t)RESET != flag_status){
119 | return ERROR;
120 | }
121 |
122 | FWDGT_RLD = RLD_RLD(reload_value);
123 |
124 | /* reload the counter */
125 | FWDGT_CTL = FWDGT_KEY_RELOAD;
126 |
127 | return SUCCESS;
128 | }
129 |
130 | /*!
131 | \brief get flag state of FWDGT
132 | \param[in] flag: flag to get
133 | \arg FWDGT_FLAG_PUD: a write operation to FWDGT_PSC register is on going
134 | \arg FWDGT_FLAG_RUD: a write operation to FWDGT_RLD register is on going
135 | \arg FWDGT_FLAG_WUD: a write operation to FWDGT_WND register is on going
136 | \param[out] none
137 | \retval FlagStatus: SET or RESET
138 | */
139 | FlagStatus fwdgt_flag_get(uint16_t flag)
140 | {
141 | if(FWDGT_STAT & flag){
142 | return SET;
143 | }
144 |
145 | return RESET;
146 | }
147 |
--------------------------------------------------------------------------------
/HoverBoardGigaDevice/RTE/Device/GD32F130C8/gd32f1x0_gpio.c:
--------------------------------------------------------------------------------
1 | /*!
2 | \file gd32f1x0_gpio.c
3 | \brief GPIO driver
4 | */
5 |
6 | /*
7 | Copyright (C) 2017 GigaDevice
8 |
9 | 2014-12-26, V1.0.0, platform for GD32F1x0(x=3,5)
10 | 2016-01-15, V2.0.0, platform for GD32F1x0(x=3,5,7,9)
11 | 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9)
12 | 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9)
13 | */
14 |
15 | #include "gd32f1x0_gpio.h"
16 |
17 | /*!
18 | \brief reset GPIO port
19 | \param[in] gpio_periph: GPIOx(x = A,B,C,D,F)
20 | \param[out] none
21 | \retval none
22 | */
23 | void gpio_deinit(uint32_t gpio_periph)
24 | {
25 | switch(gpio_periph){
26 | case GPIOA:
27 | /* reset GPIOA */
28 | rcu_periph_reset_enable(RCU_GPIOARST);
29 | rcu_periph_reset_disable(RCU_GPIOARST);
30 | break;
31 | case GPIOB:
32 | /* reset GPIOB */
33 | rcu_periph_reset_enable(RCU_GPIOBRST);
34 | rcu_periph_reset_disable(RCU_GPIOBRST);
35 | break;
36 | case GPIOC:
37 | /* reset GPIOC */
38 | rcu_periph_reset_enable(RCU_GPIOCRST);
39 | rcu_periph_reset_disable(RCU_GPIOCRST);
40 | break;
41 | case GPIOD:
42 | /* reset GPIOD */
43 | rcu_periph_reset_enable(RCU_GPIODRST);
44 | rcu_periph_reset_disable(RCU_GPIODRST);
45 | break;
46 | case GPIOF:
47 | /* reset GPIOF */
48 | rcu_periph_reset_enable(RCU_GPIOFRST);
49 | rcu_periph_reset_disable(RCU_GPIOFRST);
50 | break;
51 | default:
52 | break;
53 | }
54 | }
55 |
56 | /*!
57 | \brief set GPIO output mode
58 | \param[in] gpio_periph: GPIOx(x = A,B,C,D,F)
59 | \param[in] mode: gpio pin mode
60 | \arg GPIO_MODE_INPUT: input mode
61 | \arg GPIO_MODE_OUTPUT: output mode
62 | \arg GPIO_MODE_AF: alternate function mode
63 | \arg GPIO_MODE_ANALOG: analog mode
64 | \param[in] pull_up_down: gpio pin with pull-up or pull-down resistor
65 | \arg GPIO_PUPD_NONE: without weak pull-up and pull-down resistors
66 | \arg GPIO_PUPD_PULLUP: with weak pull-up resistor
67 | \arg GPIO_PUPD_PULLDOWN:with weak pull-down resistor
68 | \param[in] pin: GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
69 | \param[out] none
70 | \retval none
71 | */
72 | void gpio_mode_set(uint32_t gpio_periph,uint32_t mode,uint32_t pull_up_down,uint32_t pin)
73 | {
74 | uint16_t i;
75 | uint32_t ctl, pupd;
76 |
77 | ctl = GPIO_CTL(gpio_periph);
78 | pupd = GPIO_PUD(gpio_periph);
79 |
80 | for (i = 0U; i < 16U; i++){
81 | if((1U << i) & pin){
82 | /* clear the specified pin mode bits */
83 | ctl &= ~GPIO_MODE_MASK(i);
84 | /* set the specified pin mode bits */
85 | ctl |= GPIO_MODE_SET(i, mode);
86 |
87 | /* clear the specified pin pupd bits */
88 | pupd &= ~GPIO_PUPD_MASK(i);
89 | /* set the specified pin pupd bits */
90 | pupd |= GPIO_PUPD_SET(i, pull_up_down);
91 | }
92 | }
93 |
94 | GPIO_CTL(gpio_periph) = ctl;
95 | GPIO_PUD(gpio_periph) = pupd;
96 | }
97 |
98 | /*!
99 | \brief set GPIO output type and speed
100 | \param[in] gpio_periph: GPIOx(x = A,B,C,D,F)
101 | \param[in] otype: gpio pin output mode
102 | \arg GPIO_OTYPE_PP: push pull mode
103 | \arg GPIO_OTYPE_OD: open drain mode
104 | \param[in] speed
105 | \arg GPIO_OSPEED_2MHZ: output max speed 2M
106 | \arg GPIO_OSPEED_10MHZ: output max speed 10M
107 | \arg GPIO_OSPEED_50MHZ: output max speed 50M
108 | \param[in] pin: GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
109 | \param[out] none
110 | \retval none
111 | */
112 | void gpio_output_options_set(uint32_t gpio_periph,uint8_t otype,uint32_t speed,uint32_t pin)
113 | {
114 | uint16_t i;
115 | uint32_t ospeedr;
116 |
117 | if(0x1U == otype){
118 | GPIO_OMODE(gpio_periph) |= (uint32_t)pin;
119 | }else{
120 | GPIO_OMODE(gpio_periph) &= (uint32_t)(~pin);
121 | }
122 |
123 | /* get the specified pin output speed bits value */
124 | ospeedr = GPIO_OSPD(gpio_periph);
125 |
126 | for(i = 0U;i < 16U;i++){
127 | if((1U << i) & pin){
128 | /* clear the specified pin output speed bits */
129 | ospeedr &= ~GPIO_OSPEED_MASK(i);
130 | /* set the specified pin output speed bits */
131 | ospeedr |= GPIO_OSPEED_SET(i,speed);
132 | }
133 | }
134 | GPIO_OSPD(gpio_periph) = ospeedr;
135 | }
136 |
137 | /*!
138 | \brief set GPIO pin
139 | \param[in] gpio_periph: GPIOx(x = A,B,C,D,F)
140 | \param[in] pin: GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
141 | \param[out] none
142 | \retval none
143 | */
144 | void gpio_bit_set(uint32_t gpio_periph,uint32_t pin)
145 | {
146 | GPIO_BOP(gpio_periph) = (uint32_t)pin;
147 | }
148 |
149 | /*!
150 | \brief reset GPIO pin
151 | \param[in] gpio_periph: GPIOx(x = A,B,C,D,F)
152 | \param[in] pin: GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
153 | \param[out] none
154 | \retval none
155 | */
156 | void gpio_bit_reset(uint32_t gpio_periph,uint32_t pin)
157 | {
158 | GPIO_BC(gpio_periph) = (uint32_t)pin;
159 | }
160 |
161 | /*!
162 | \brief write data to the specified GPIO pin
163 | \param[in] gpio_periph: GPIOx(x = A,B,C,D,F)
164 | \param[in] pin: GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
165 | \param[in] bit_value: SET or RESET
166 | \arg RESET: clear the port pin
167 | \arg SET: set the port pin
168 | \param[out] none
169 | \retval none
170 | */
171 | void gpio_bit_write(uint32_t gpio_periph,uint32_t pin,bit_status bit_value)
172 | {
173 | if(RESET != bit_value){
174 | GPIO_BOP(gpio_periph) = (uint32_t)pin;
175 | }else{
176 | GPIO_BC(gpio_periph) = (uint32_t)pin;
177 | }
178 | }
179 |
180 | /*!
181 | \brief write data to the specified GPIO port
182 | \param[in] gpio_periph: GPIOx(x = A,B,C,D,F)
183 | \param[in] data: specify the value to be written to the port output control register
184 | \param[out] none
185 | \retval none
186 | */
187 | void gpio_port_write(uint32_t gpio_periph,uint16_t data)
188 | {
189 | GPIO_OCTL(gpio_periph) = (uint32_t)data;
190 | }
191 |
192 | /*!
193 | \brief get GPIO pin input status
194 | \param[in] gpio_periph: GPIOx(x = A,B,C,D,F)
195 | \param[in] pin: GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
196 | \param[out] none
197 | \retval input state of gpio pin: SET or RESET
198 | */
199 | FlagStatus gpio_input_bit_get(uint32_t gpio_periph,uint32_t pin)
200 | {
201 | if((uint32_t)RESET != (GPIO_ISTAT(gpio_periph)&(pin))){
202 | return SET;
203 | }else{
204 | return RESET;
205 | }
206 | }
207 |
208 | /*!
209 | \brief get GPIO all pins input status
210 | \param[in] gpio_periph: GPIOx(x = A,B,C,D,F)
211 | \param[out] none
212 | \retval input state of gpio all pins
213 | */
214 | uint16_t gpio_input_port_get(uint32_t gpio_periph)
215 | {
216 | return (uint16_t)(GPIO_ISTAT(gpio_periph));
217 | }
218 |
219 | /*!
220 | \brief get GPIO pin output status
221 | \param[in] gpio_periph: GPIOx(x = A,B,C,D,F)
222 | \param[in] pin: GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
223 | \param[out] none
224 | \retval output state of gpio pin: SET or RESET
225 | */
226 | FlagStatus gpio_output_bit_get(uint32_t gpio_periph,uint32_t pin)
227 | {
228 | if((uint32_t)RESET !=(GPIO_OCTL(gpio_periph)&(pin))){
229 | return SET;
230 | }else{
231 | return RESET;
232 | }
233 | }
234 |
235 | /*!
236 | \brief get GPIO all pins output status
237 | \param[in] gpio_periph: GPIOx(x = A,B,C,D,F)
238 | \param[out] none
239 | \retval output state of gpio all pins
240 | */
241 | uint16_t gpio_output_port_get(uint32_t gpio_periph)
242 | {
243 | return ((uint16_t)GPIO_OCTL(gpio_periph));
244 | }
245 |
246 | /*!
247 | \brief set GPIO alternate function
248 | \param[in] gpio_periph: GPIOx(x = A,B,C,D,F)
249 | \param[in] alt_func_num: gpio pin af function, please refer to specific device datasheet
250 | \arg GPIO_AF_0: TIMER2, TIMER13, TIMER14, TIMER16, SPI0, I2S0, SPI1, SPI2, I2S2, CK_OUT,
251 | SWDIO, SWCLK, USART0, CEC, IFRP, I2C0, I2C1, TSI, EVENTOUT
252 | \arg GPIO_AF_1: USART0, USART1, IFRP, CEC, TIMER2, TIMER14, I2C0, I2C1, I2C2, EVENTOUT
253 | \arg GPIO_AF_2: TIMER0, TIMER1, TIMER15, TIMER16, EVENTOUT
254 | \arg GPIO_AF_3: TSI, I2C0, TIMER14, EVENTOUT
255 | \arg GPIO_AF_4(port A,B only): TIMER13, I2C0, I2C1, I2C2, USART1
256 | \arg GPIO_AF_5(port A,B only): TIMER15, TIMER16, SPI2, I2S2, I2C0, I2C1
257 | \arg GPIO_AF_6(port A,B only): SPI1, EVENTOUT
258 | \arg GPIO_AF_7(port A,B only): CMP0, CMP1
259 | \arg GPIO_AF_9(port A,B only): CAN0, CAN1 (for GD32F170xx and GD32F190xx devices)
260 | \arg GPIO_AF_11: SLCD (for GD32F170xx and GD32F190xx devices)
261 | \param[in] pin: GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
262 | \param[out] none
263 | \retval none
264 | */
265 | void gpio_af_set(uint32_t gpio_periph,uint32_t alt_func_num,uint32_t pin)
266 | {
267 | uint16_t i;
268 | uint32_t afrl, afrh;
269 |
270 | afrl = GPIO_AFSEL0(gpio_periph);
271 | afrh = GPIO_AFSEL1(gpio_periph);
272 |
273 | for (i = 0U; i < 8U; i++){
274 | if((1U << i) & pin){
275 | /* clear the specified pin alternate function bits */
276 | afrl &= ~GPIO_AFR_MASK(i);
277 | afrl |= GPIO_AFR_SET(i,alt_func_num);
278 | }
279 | }
280 |
281 | for (i = 8U; i < 16U; i++){
282 | if((1U << i) & pin){
283 | /* clear the specified pin alternate function bits */
284 | afrh &= ~GPIO_AFR_MASK(i - 8U);
285 | afrh |= GPIO_AFR_SET(i - 8U,alt_func_num);
286 | }
287 | }
288 |
289 | GPIO_AFSEL0(gpio_periph) = afrl;
290 | GPIO_AFSEL1(gpio_periph) = afrh;
291 | }
292 |
293 | /*!
294 | \brief lock GPIO pin
295 | \param[in] gpio_periph: GPIOx(x = A,B)
296 | \param[in] pin: GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
297 | \param[out] none
298 | \retval none
299 | */
300 | void gpio_pin_lock(uint32_t gpio_periph,uint32_t pin)
301 | {
302 | uint32_t lock = 0x00010000U;
303 | lock |= pin;
304 |
305 | /* lock key writing sequence: write 1->write 0->write 1-> read 0-> read 1 */
306 | GPIO_LOCK(gpio_periph) = (uint32_t)lock;
307 | GPIO_LOCK(gpio_periph) = (uint32_t)pin;
308 | GPIO_LOCK(gpio_periph) = (uint32_t)lock;
309 | lock = GPIO_LOCK(gpio_periph);
310 | lock = GPIO_LOCK(gpio_periph);
311 | }
312 |
313 | #ifdef GD32F170_190
314 | /*!
315 | \brief toggle GPIO pin
316 | \param[in] gpio_periph: GPIOx(x = A,B,C,D,F)
317 | \param[in] pin: GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
318 | \param[out] none
319 | \retval none
320 | */
321 | void gpio_bit_toggle(uint32_t gpio_periph,uint32_t pin)
322 | {
323 | GPIO_TG(gpio_periph) = (uint32_t)pin;
324 | }
325 |
326 | /*!
327 | \brief toggle GPIO port
328 | \param[in] gpio_periph: GPIOx(x = A,B,C,D,F)
329 | \param[out] none
330 | \retval none
331 | */
332 | void gpio_port_toggle(uint32_t gpio_periph)
333 | {
334 | GPIO_TG(gpio_periph) = 0x0000FFFFU;
335 | }
336 |
337 | #endif /* GD32F170_190 */
338 |
--------------------------------------------------------------------------------
/HoverBoardGigaDevice/RTE/Device/GD32F130C8/gd32f1x0_misc.c:
--------------------------------------------------------------------------------
1 | /*!
2 | \file gd32f1x0_misc.c
3 | \brief MISC driver
4 | */
5 |
6 | /*
7 | Copyright (C) 2017 GigaDevice
8 |
9 | 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5)
10 | 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9)
11 | 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9)
12 | 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9)
13 | */
14 |
15 | #include "gd32f1x0_misc.h"
16 |
17 | /*!
18 | \brief set the priority group
19 | \param[in] nvic_prigroup: the NVIC priority group
20 | \arg NVIC_PRIGROUP_PRE0_SUB4:0 bits for pre-emption priority 4 bits for subpriority
21 | \arg NVIC_PRIGROUP_PRE1_SUB3:1 bits for pre-emption priority 3 bits for subpriority
22 | \arg NVIC_PRIGROUP_PRE2_SUB2:2 bits for pre-emption priority 2 bits for subpriority
23 | \arg NVIC_PRIGROUP_PRE3_SUB1:3 bits for pre-emption priority 1 bits for subpriority
24 | \arg NVIC_PRIGROUP_PRE4_SUB0:4 bits for pre-emption priority 0 bits for subpriority
25 | \param[out] none
26 | \retval none
27 | */
28 | void nvic_priority_group_set(uint32_t nvic_prigroup)
29 | {
30 | /* set the priority group value */
31 | SCB->AIRCR = NVIC_AIRCR_VECTKEY_MASK | nvic_prigroup;
32 | }
33 |
34 | /*!
35 | \brief enable NVIC request
36 | \param[in] nvic_irq: the NVIC interrupt request, detailed in IRQn_Type
37 | \param[in] nvic_irq_pre_priority: the pre-emption priority needed to set
38 | \param[in] nvic_irq_sub_priority: the subpriority needed to set
39 | \param[out] none
40 | \retval none
41 | */
42 | void nvic_irq_enable(uint8_t nvic_irq, uint8_t nvic_irq_pre_priority,
43 | uint8_t nvic_irq_sub_priority)
44 | {
45 | uint32_t temp_priority = 0x00U, temp_pre = 0x00U, temp_sub = 0x00U;
46 | /* use the priority group value to get the temp_pre and the temp_sub */
47 | if(((SCB->AIRCR) & (uint32_t)0x700)==NVIC_PRIGROUP_PRE0_SUB4){
48 | temp_pre = 0U;
49 | temp_sub = 0x4U;
50 | }else if(((SCB->AIRCR) & (uint32_t)0x700)==NVIC_PRIGROUP_PRE1_SUB3){
51 | temp_pre = 1U;
52 | temp_sub = 0x3U;
53 | }else if(((SCB->AIRCR) & (uint32_t)0x700)==NVIC_PRIGROUP_PRE2_SUB2){
54 | temp_pre = 2U;
55 | temp_sub = 0x2U;
56 | }else if(((SCB->AIRCR) & (uint32_t)0x700)==NVIC_PRIGROUP_PRE3_SUB1){
57 | temp_pre = 3U;
58 | temp_sub = 0x1U;
59 | }else if(((SCB->AIRCR) & (uint32_t)0x700)==NVIC_PRIGROUP_PRE4_SUB0){
60 | temp_pre = 4U;
61 | temp_sub = 0x0U;
62 | }else{
63 | }
64 | /* get the temp_priority to fill the NVIC->IP register */
65 | temp_priority = (uint32_t)nvic_irq_pre_priority << (0x4U - temp_pre);
66 | temp_priority |= nvic_irq_sub_priority &(0x0FU >> (0x4U - temp_sub));
67 | temp_priority = temp_priority << 0x04U;
68 | NVIC->IP[nvic_irq] = (uint8_t)temp_priority;
69 | /* enable the selected IRQ */
70 | NVIC->ISER[nvic_irq >> 0x05] = (uint32_t)0x01 << (nvic_irq & (uint8_t)0x1F);
71 | }
72 |
73 | /*!
74 | \brief disable NVIC request
75 | \param[in] nvic_irq: the NVIC interrupt request, detailed in IRQn_Type
76 | \param[out] none
77 | \retval none
78 | */
79 | void nvic_irq_disable(uint8_t nvic_irq)
80 | {
81 | /* disable the selected IRQ.*/
82 | NVIC->ICER[nvic_irq >> 0x05] = (uint32_t)0x01 << (nvic_irq & (uint8_t)0x1F);
83 | }
84 |
85 | /*!
86 | \brief set the NVIC vector table base address
87 | \param[in] nvic_vict_tab: the RAM or FLASH base address
88 | \arg NVIC_VECTTAB_RAM: RAM base address
89 | \are NVIC_VECTTAB_FLASH: Flash base address
90 | \param[in] offset: Vector Table offset
91 | \param[out] none
92 | \retval none
93 | */
94 | void nvic_vector_table_set(uint32_t nvic_vict_tab, uint32_t offset)
95 | {
96 | SCB->VTOR = nvic_vict_tab | (offset & NVIC_VECTTAB_OFFSET_MASK);
97 | }
98 |
99 | /*!
100 | \brief set the state of the low power mode
101 | \param[in] lowpower_mode: the low power mode state
102 | \arg SCB_LPM_SLEEP_EXIT_ISR: if chose this para, the system always enter low power
103 | mode by exiting from ISR
104 | \arg SCB_LPM_DEEPSLEEP: if chose this para, the system will enter the DEEPSLEEP mode
105 | \arg SCB_LPM_WAKE_BY_ALL_INT: if chose this para, the lowpower mode can be woke up
106 | by all the enable and disable interrupts
107 | \param[out] none
108 | \retval none
109 | */
110 | void system_lowpower_set(uint8_t lowpower_mode)
111 | {
112 | SCB->SCR |= (uint32_t)lowpower_mode;
113 | }
114 |
115 | /*!
116 | \brief reset the state of the low power mode
117 | \param[in] lowpower_mode: the low power mode state
118 | \arg SCB_LPM_SLEEP_EXIT_ISR: if chose this para, the system will exit low power
119 | mode by exiting from ISR
120 | \arg SCB_LPM_DEEPSLEEP: if chose this para, the system will enter the SLEEP mode
121 | \arg SCB_LPM_WAKE_BY_ALL_INT: if chose this para, the lowpower mode only can be
122 | woke up by the enable interrupts
123 | \param[out] none
124 | \retval none
125 | */
126 | void system_lowpower_reset(uint8_t lowpower_mode)
127 | {
128 | SCB->SCR &= (~(uint32_t)lowpower_mode);
129 | }
130 |
131 | /*!
132 | \brief set the systick clock source
133 | \param[in] systick_clksource: the systick clock source needed to choose
134 | \arg SYSTICK_CLKSOURCE_HCLK: systick clock source is from HCLK
135 | \arg SYSTICK_CLKSOURCE_HCLK_DIV8: systick clock source is from HCLK/8
136 | \param[out] none
137 | \retval none
138 | */
139 |
140 | void systick_clksource_set(uint32_t systick_clksource)
141 | {
142 | if(SYSTICK_CLKSOURCE_HCLK == systick_clksource ){
143 | /* set the systick clock source from HCLK */
144 | SysTick->CTRL |= SYSTICK_CLKSOURCE_HCLK;
145 | }else{
146 | /* set the systick clock source from HCLK/8 */
147 | SysTick->CTRL &= SYSTICK_CLKSOURCE_HCLK_DIV8;
148 | }
149 | }
150 |
--------------------------------------------------------------------------------
/HoverBoardGigaDevice/RTE/Device/GD32F130C8/gd32f1x0_opa.c:
--------------------------------------------------------------------------------
1 | /*!
2 | \file gd32f1x0_opa.c
3 | \brief OPA driver
4 | */
5 |
6 | /*
7 | Copyright (C) 2017 GigaDevice
8 |
9 | 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5)
10 | 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9)
11 | 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9)
12 | 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9)
13 | */
14 |
15 | #ifdef GD32F170_190
16 |
17 | #include "gd32f1x0_opa.h"
18 |
19 | /*!
20 | \brief deinit the OPA register to its default reset value
21 | \param[in] none
22 | \param[out] none
23 | \retval none
24 | */
25 | void opa_deinit(void)
26 | {
27 | rcu_periph_reset_enable(RCU_OPAIVREFRST);
28 | rcu_periph_reset_disable(RCU_OPAIVREFRST);
29 | }
30 |
31 | /*!
32 | \brief enable OPA switch
33 | \param[in] opax_swy
34 | \arg OPA_T3OPA0: T3 switch enable for OPA0
35 | \arg OPA_S1OPA0: S1 switch enable for OPA0
36 | \arg OPA_S2OPA0: S2 switch enable for OPA0
37 | \arg OPA_S3OPA0: S3 switch enable for OPA0
38 | \arg OPA_T3OPA1: T3 switch enable for OPA1
39 | \arg OPA_S1OPA1: S1 switch enable for OPA1
40 | \arg OPA_S2OPA1: S2 switch enable for OPA1
41 | \arg OPA_S3OPA1: S3 switch enable for OPA1
42 | \arg OPA_S4OPA1: S4 switch enable for OPA1
43 | \arg OPA_T3OPA2: T3 switch enable for OPA2
44 | \arg OPA_S1OPA2: S3 switch enable for OPA2
45 | \arg OPA_S2OPA2: S3 switch enable for OPA2
46 | \arg OPA_S3OPA2: S3 switch enable for OPA2
47 | \param[out] none
48 | \retval none
49 | */
50 | void opa_switch_enable(uint32_t opax_swy)
51 | {
52 | OPA_CTL |= (uint32_t)(opax_swy);
53 | }
54 |
55 | /*!
56 | \brief enable OPA
57 | \param[in] opa_periph
58 | \arg OPAx(x =0,1,2)
59 | \param[out] none
60 | \retval none
61 | */
62 | void opa_enable(uint32_t opa_periph)
63 | {
64 | if(OPA0 == opa_periph){
65 | OPA_CTL &= ~OPA_CTL_OPA0PD;
66 | }else if(OPA1 == opa_periph){
67 | OPA_CTL &= ~OPA_CTL_OPA1PD;
68 | }else{
69 | OPA_CTL &= ~OPA_CTL_OPA2PD;
70 | }
71 | }
72 |
73 | /*!
74 | \brief disable OPA
75 | \param[in] opa_periph
76 | \arg OPAx(x =0,1,2)
77 | \param[out] none
78 | \retval none
79 | */
80 | void opa_disable(uint32_t opa_periph)
81 | {
82 | if(OPA0 == opa_periph){
83 | OPA_CTL |= OPA_CTL_OPA0PD;
84 | }else if(OPA1 == opa_periph){
85 | OPA_CTL |= OPA_CTL_OPA1PD;
86 | }else{
87 | OPA_CTL |= OPA_CTL_OPA2PD;
88 | }
89 | }
90 |
91 | /*!
92 | \brief disable OPA switch
93 | \param[in] opax_swy
94 | \arg OPA_T3OPA0: T3 switch enable for OPA0
95 | \arg OPA_S1OPA0: S1 switch enable for OPA0
96 | \arg OPA_S2OPA0: S2 switch enable for OPA0
97 | \arg OPA_S3OPA0: S3 switch enable for OPA0
98 | \arg OPA_T3OPA1: T3 switch enable for OPA1
99 | \arg OPA_S1OPA1: S1 switch enable for OPA1
100 | \arg OPA_S2OPA1: S2 switch enable for OPA1
101 | \arg OPA_S3OPA1: S3 switch enable for OPA1
102 | \arg OPA_S4OPA1: S4 switch enable for OPA1
103 | \arg OPA_T3OPA2: T3 switch enable for OPA2
104 | \arg OPA_S1OPA2: S3 switch enable for OPA2
105 | \arg OPA_S2OPA2: S3 switch enable for OPA2
106 | \arg OPA_S3OPA2: S3 switch enable for OPA2
107 | \param[out] none
108 | \retval none
109 | */
110 | void opa_switch_disable(uint32_t opax_swy)
111 | {
112 | OPA_CTL &= ~opax_swy;
113 | }
114 |
115 | /*!
116 | \brief enable OPA in low power mode
117 | \param[in] opa_periph
118 | \arg OPAx(x =0,1,2)
119 | \param[out] none
120 | \retval none
121 | */
122 | void opa_low_power_enable(uint32_t opa_periph)
123 | {
124 | if(OPA0 == opa_periph){
125 | OPA_CTL &= ~OPA_CTL_OPA0LPM;
126 | }else if(OPA1 == opa_periph){
127 | OPA_CTL &= ~OPA_CTL_OPA1LPM;
128 | }else{
129 | OPA_CTL &= ~OPA_CTL_OPA2LPM;
130 | }
131 | }
132 |
133 | /*!
134 | \brief disable OPA in low power mode
135 | \param[in] opa_periph
136 | \arg OPAx(x =0,1,2)
137 | \param[out] none
138 | \retval none
139 | */
140 | void opa_low_power_disable(uint32_t opa_periph)
141 | {
142 | if(OPA0 == opa_periph){
143 | OPA_CTL |= OPA_CTL_OPA0LPM;
144 | }else if(OPA1 == opa_periph){
145 | OPA_CTL |= OPA_CTL_OPA1LPM;
146 | }else{
147 | OPA_CTL |= OPA_CTL_OPA2LPM;
148 | }
149 | }
150 |
151 | /*!
152 | \brief set OPA power range
153 | \param[in] powerrange
154 | \arg OPA_POWRANGE_LOW: Low power range is selected (VDDA is lower than 3.3V)
155 | \arg OPA_POWRANGE_HIGH: High power range is selected (VDDA is higher than 3.3V)
156 | \param[out] none
157 | \retval none
158 | */
159 | void opa_power_range_config(uint32_t powerrange)
160 | {
161 | OPA_CTL &= ~OPA_CTL_OPA_RANGE;
162 | OPA_CTL |= powerrange;
163 | }
164 |
165 | /*!
166 | \brief set OPA bias trimming mode
167 | \param[in] opa_trimmode
168 | \arg OPA_BT_TRIM_FACTORY: factory trimming values are used for offset calibration
169 | \arg OPA_BT_TRIM_USER: user trimming values are used for offset calibration
170 | \param[out] none
171 | \retval none
172 | */
173 | void opa_trim_mode_set(uint32_t opa_trimmode)
174 | {
175 | OPA_BT &= ~OPA_BT_OT_USER;
176 | OPA_BT |= opa_trimmode;
177 | }
178 |
179 | /*!
180 | \brief set OPA bias trimming value
181 | \param[in] opa_periph
182 | \arg OPAx(x =0,1,2)
183 | \param[in] opa_input
184 | \arg OPA_INPUT_P: PMOS input is selected to configure the trimming value
185 | \arg OPA_INPUT_N: NMOS input is selected to configure the trimming value
186 | \param[in] opa_trimmode
187 | \arg this parameter can be any value lower or equal to 0x0000001F.
188 | \param[out] none
189 | \retval none
190 | */
191 | void opa_trim_value_config(uint32_t opa_periph,uint32_t opa_input,uint32_t opa_trimvalue)
192 | {
193 | uint32_t bt = 0U, ctl = 0U;
194 | ctl = OPA_CTL;
195 | bt = OPA_BT;
196 |
197 | if(OPA0 == opa_periph){
198 | /* clear the specified opa calibration for N diff and P diff */
199 | ctl &= (uint32_t)~(OPA_CTL_OPA0CAL_L | OPA_CTL_OPA0CAL_H);
200 | /* set the specified opa calibration for N diff or P diff */
201 | ctl |= opa_input;
202 | if(OPA_INPUT_P == opa_input){
203 | /* clear the specified PMOS pairs normal mode 5-bit offset trim value */
204 | bt &= (~OPA_BT_OA0_TRIM_LOW);
205 | bt |= (opa_trimvalue);
206 | }else{
207 | /* clear the specified NMOS pairs normal mode 5-bit offset trim value */
208 | bt &= (~OPA_BT_OA0_TRIM_HIGH);
209 | bt |= (opa_trimvalue << 5U);
210 | }
211 |
212 | }else if(OPA1 == opa_periph){
213 | ctl &= (uint32_t)~(OPA_CTL_OPA1CAL_L | OPA_CTL_OPA1CAL_H);
214 | ctl |= (uint32_t)(opa_input << 8U);
215 | if(OPA_INPUT_P == opa_input){
216 | /* clear the specified PMOS pairs normal mode 5-bit offset trim value */
217 | bt &= (~OPA_BT_OA1_TRIM_LOW);
218 | bt |= (opa_trimvalue << 10U);
219 | }else{
220 | /* clear the specified NMOS pairs normal mode 5-bit offset trim value */
221 | bt &= (~OPA_BT_OA1_TRIM_HIGH);
222 | bt |= (opa_trimvalue << 15U);
223 | }
224 | }else{
225 | ctl &= (uint32_t)~(OPA_CTL_OPA2CAL_L | OPA_CTL_OPA2CAL_H);
226 | ctl |= (uint32_t)(opa_input << 16U);
227 | if(OPA_INPUT_P == opa_input){
228 | /* clear the specified PMOS pairs normal mode 5-bit offset trim value */
229 | bt &= (~OPA_BT_OA2_TRIM_LOW);
230 | bt |= (opa_trimvalue << 20U);
231 | }else{
232 | /* clear the specified NMOS pairs normal mode 5-bit offset trim value */
233 | bt &= (~OPA_BT_OA2_TRIM_HIGH);
234 | bt |= (opa_trimvalue << 25U);
235 | }
236 | }
237 |
238 | OPA_CTL = ctl;
239 | OPA_BT = bt;
240 | }
241 |
242 | /*!
243 | \brief set OPA bias trimming value low power
244 | \param[in] opa_periph
245 | \arg OPAx(x =0,1,2)
246 | \param[in] opa_input
247 | \arg OPA_INPUT_P: PMOS input is selected to configure the trimming value
248 | \arg OPA_INPUT_N: NMOS input is selected to configure the trimming value
249 | \param[in] opa_trimmode
250 | \arg this parameter can be any value lower or equal to 0x0000001F.
251 | \param[out] none
252 | \retval none
253 | */
254 | void opa_trim_value_lp_config(uint32_t opa_periph,uint32_t opa_input,uint32_t opa_trimvalue)
255 | {
256 | uint32_t lpbt = 0U, ctl = 0U;
257 | ctl = OPA_CTL;
258 | lpbt = OPA_LPBT;
259 |
260 | if(OPA0 == opa_periph){
261 | ctl &= (uint32_t)~(OPA_CTL_OPA0CAL_L | OPA_CTL_OPA0CAL_H);
262 | ctl |= opa_input;
263 | if(OPA_INPUT_P == opa_input){
264 | /* clear the specified PMOS pairs low power mode 5-bit offset trim value */
265 | lpbt &= (~OPA_LPBT_OA0_TRIM_LOW);
266 | lpbt |= (opa_trimvalue);
267 | }else{
268 | /* clear the specified NMOS pairs low power mode 5-bit offset trim value */
269 | lpbt &= (~OPA_LPBT_OA0_TRIM_HIGH);
270 | lpbt |= (opa_trimvalue << 5U);
271 | }
272 | }else if (OPA1 == opa_periph){
273 | ctl &= (uint32_t)~(OPA_CTL_OPA0CAL_L | OPA_CTL_OPA0CAL_H);
274 | ctl |= (uint32_t)(opa_input << 8U);
275 | if(OPA_INPUT_P == opa_input){
276 | /* clear the specified PMOS pairs low power mode 5-bit offset trim value */
277 | lpbt &= (~OPA_LPBT_OA1_TRIM_LOW);
278 | lpbt |= (opa_trimvalue << 10U);
279 | }else{
280 | /* clear the specified NMOS pairs low power mode 5-bit offset trim value */
281 | lpbt &= (~OPA_LPBT_OA1_TRIM_HIGH);
282 | lpbt |= (opa_trimvalue << 15U);
283 | }
284 |
285 | }else{
286 | ctl &= (uint32_t)~(OPA_CTL_OPA2CAL_L | OPA_CTL_OPA2CAL_H);
287 | ctl |= (uint32_t)(opa_input << 16U);
288 | if(OPA_INPUT_P == opa_input){
289 | /* clear the specified PMOS pairs low power mode 5-bit offset trim value */
290 | lpbt &= (~OPA_LPBT_OA2_TRIM_LOW);
291 | lpbt |= (opa_trimvalue << 20U);
292 | }else{
293 | /* clear the specified NMOS pairs low power mode 5-bit offset trim value */
294 | lpbt &= (~OPA_LPBT_OA2_TRIM_HIGH);
295 | lpbt |= (opa_trimvalue << 25U);
296 | }
297 | }
298 |
299 | OPA_CTL = ctl;
300 | OPA_LPBT = lpbt;
301 | }
302 |
303 | /*!
304 | \brief get OPA calibration flag
305 | \param[in] opa_periph
306 | \arg OPAx(x =0,1,2)
307 | \param[out] none
308 | \retval The state of the OPA calibration flag (SET or RESET)
309 | */
310 | FlagStatus opa_cal_out_get(uint32_t opa_periph)
311 | {
312 | uint32_t data = 0U;
313 | FlagStatus bitstatus = RESET;
314 | data = OPA_CTL;
315 |
316 | if(OPA0 == opa_periph){
317 | /* get opa0 calibration output bit status */
318 | if ((uint32_t)RESET != (data & OPA_CTL_OPA1CALOUT)){
319 | bitstatus = SET;
320 | }else{
321 | bitstatus = RESET;
322 | }
323 | }else if(OPA1 == opa_periph){
324 | /* get opa1 calibration output bit status */
325 | if ((uint32_t)RESET != (data & OPA_CTL_OPA1CALOUT)){
326 | bitstatus = SET;
327 | }else{
328 | bitstatus = RESET;
329 | }
330 | }else{
331 | /* get opa2 calibration output bit status */
332 | if((uint32_t)RESET != (data & OPA_CTL_OPA1CALOUT)){
333 | bitstatus = SET;
334 | }else{
335 | bitstatus = RESET;
336 | }
337 | }
338 | return bitstatus;
339 | }
340 |
341 | #endif /* GD32F170_190 */
342 |
--------------------------------------------------------------------------------
/HoverBoardGigaDevice/RTE/Device/GD32F130C8/gd32f1x0_pmu.c:
--------------------------------------------------------------------------------
1 | /*!
2 | \file gd32f1x0_pmu.c
3 | \brief PMU driver
4 | */
5 |
6 | /*
7 | Copyright (C) 2017 GigaDevice
8 |
9 | 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5)
10 | 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9)
11 | 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9)
12 | 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9)
13 | */
14 |
15 | #include "gd32f1x0_pmu.h"
16 |
17 | /*!
18 | \brief reset PMU register
19 | \param[in] none
20 | \param[out] none
21 | \retval none
22 | */
23 | void pmu_deinit(void)
24 | {
25 | /* reset PMU */
26 | rcu_periph_reset_enable(RCU_PMURST);
27 | rcu_periph_reset_disable(RCU_PMURST);
28 | }
29 |
30 | /*!
31 | \brief select low voltage detector threshold
32 | \param[in] lvdt_n:
33 | \arg PMU_LVDT_0: voltage threshold is 2.2V (GD32F130_150) or 2.4V (GD32F170_190)
34 | \arg PMU_LVDT_1: voltage threshold is 2.3V (GD32F130_150) or 2.7V (GD32F170_190)
35 | \arg PMU_LVDT_2: voltage threshold is 2.4V (GD32F130_150) or 3.0V (GD32F170_190)
36 | \arg PMU_LVDT_3: voltage threshold is 2.5V (GD32F130_150) or 3.3V (GD32F170_190)
37 | \arg PMU_LVDT_4: voltage threshold is 2.6V (GD32F130_150) or 3.6V (GD32F170_190)
38 | \arg PMU_LVDT_5: voltage threshold is 2.7V (GD32F130_150) or 3.9V (GD32F170_190)
39 | \arg PMU_LVDT_6: voltage threshold is 2.8V (GD32F130_150) or 4.2V (GD32F170_190)
40 | \arg PMU_LVDT_7: voltage threshold is 2.9V (GD32F130_150) or 4.5V (GD32F170_190)
41 | \param[out] none
42 | \retval none
43 | */
44 | void pmu_lvd_select(uint32_t lvdt_n)
45 | {
46 | /* disable LVD */
47 | PMU_CTL &= ~PMU_CTL_LVDEN;
48 | /* clear LVDT bits */
49 | PMU_CTL &= ~PMU_CTL_LVDT;
50 | /* set LVDT bits according to lvdt_n */
51 | PMU_CTL |= lvdt_n;
52 | /* enable LVD */
53 | PMU_CTL |= PMU_CTL_LVDEN;
54 |
55 | }
56 |
57 | /*!
58 | \brief PMU lvd disable
59 | \param[in] none
60 | \param[out] none
61 | \retval none
62 | */
63 | void pmu_lvd_disable(void)
64 | {
65 | /* disable LVD */
66 | PMU_CTL &= ~PMU_CTL_LVDEN;
67 | }
68 |
69 | /*!
70 | \brief PMU work at sleep mode
71 | \param[in] sleepmodecmd:
72 | \arg WFI_CMD: use WFI command
73 | \arg WFE_CMD: use WFE command
74 | \param[out] none
75 | \retval none
76 | */
77 | void pmu_to_sleepmode(uint8_t sleepmodecmd)
78 | {
79 | /* clear sleepdeep bit of Cortex-M3 system control register */
80 | SCB->SCR &= ~((uint32_t)SCB_SCR_SLEEPDEEP_Msk);
81 |
82 | /* select WFI or WFE command to enter sleep mode */
83 | if(WFI_CMD == sleepmodecmd){
84 | __WFI();
85 | }else{
86 | __WFE();
87 | }
88 | }
89 |
90 | /*!
91 | \brief PMU work at deepsleep mode
92 | \param[in] ldo
93 | \arg PMU_LDO_NORMAL: LDO normal work when pmu enter deepsleep mode
94 | \arg PMU_LDO_LOWPOWER: LDO work at low power mode when pmu enter deepsleep mode
95 | \param[in] deepsleepmodecmd:
96 | \arg WFI_CMD: use WFI command
97 | \arg WFE_CMD: use WFE command
98 | \param[out] none
99 | \retval none
100 | */
101 | void pmu_to_deepsleepmode(uint32_t ldo,uint8_t deepsleepmodecmd)
102 | {
103 | static uint32_t reg_snap[ 4 ];
104 | /* clear stbmod and ldolp bits */
105 | PMU_CTL &= ~((uint32_t)(PMU_CTL_STBMOD | PMU_CTL_LDOLP));
106 |
107 | /* set ldolp bit according to pmu_ldo */
108 | PMU_CTL |= ldo;
109 |
110 | /* set sleepdeep bit of Cortex-M3 system control register */
111 | SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
112 |
113 | reg_snap[ 0 ] = REG32( 0xE000E010 );
114 | reg_snap[ 1 ] = REG32( 0xE000E100 );
115 | reg_snap[ 2 ] = REG32( 0xE000E104 );
116 | reg_snap[ 3 ] = REG32( 0xE000E108 );
117 |
118 | REG32( 0xE000E010 ) &= 0x00010004;
119 | REG32( 0xE000E180 ) = 0XB7FFEF19;
120 | REG32( 0xE000E184 ) = 0XFFFFFBFF;
121 | REG32( 0xE000E188 ) = 0xFFFFFFFF;
122 |
123 | /* select WFI or WFE command to enter deepsleep mode */
124 | if(WFI_CMD == deepsleepmodecmd){
125 | __WFI();
126 | }else{
127 | __SEV();
128 | __WFE();
129 | __WFE();
130 | }
131 |
132 | REG32( 0xE000E010 ) = reg_snap[ 0 ] ;
133 | REG32( 0xE000E100 ) = reg_snap[ 1 ] ;
134 | REG32( 0xE000E104 ) = reg_snap[ 2 ] ;
135 | REG32( 0xE000E108 ) = reg_snap[ 3 ] ;
136 |
137 | /* reset sleepdeep bit of Cortex-M3 system control register */
138 | SCB->SCR &= ~((uint32_t)SCB_SCR_SLEEPDEEP_Msk);
139 | }
140 |
141 | /*!
142 | \brief pmu work at standby mode
143 | \param[in] standbymodecmd:
144 | \arg WFI_CMD: use WFI command
145 | \arg WFE_CMD: use WFE command
146 | \param[out] none
147 | \retval none
148 | */
149 | void pmu_to_standbymode(uint8_t standbymodecmd)
150 | {
151 | /* set sleepdeep bit of Cortex-M3 system control register */
152 | SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
153 |
154 | /* set stbmod bit */
155 | PMU_CTL |= PMU_CTL_STBMOD;
156 |
157 | /* reset wakeup flag */
158 | PMU_CTL |= PMU_CTL_WURST;
159 |
160 | /* select WFI or WFE command to enter standby mode */
161 | if(WFI_CMD == standbymodecmd){
162 | __WFI();
163 | }else{
164 | __WFE();
165 | }
166 | }
167 |
168 | /*!
169 | \brief clear flag bit
170 | \param[in] flag_reset:
171 | \arg PMU_FLAG_RESET_WAKEUP: reset wakeup flag
172 | \arg PMU_FLAG_RESET_STANDBY: reset standby flag
173 | \param[out] none
174 | \retval none
175 | */
176 | void pmu_flag_clear(uint32_t flag_reset)
177 | {
178 | switch(flag_reset){
179 | case PMU_FLAG_RESET_WAKEUP:
180 | /* reset wakeup flag */
181 | PMU_CTL |= PMU_CTL_WURST;
182 | break;
183 | case PMU_FLAG_RESET_STANDBY:
184 | /* reset standby flag */
185 | PMU_CTL |= PMU_CTL_STBRST;
186 | break;
187 | default :
188 | break;
189 | }
190 | }
191 |
192 | /*!
193 | \brief get flag state
194 | \param[in] flag:
195 | \arg PMU_FLAG_WAKEUP: wakeup flag
196 | \arg PMU_FLAG_STANDBY: standby flag
197 | \arg PMU_FLAG_LVD: lvd flag
198 | \param[out] none
199 | \retval FlagStatus SET or RESET
200 | */
201 | FlagStatus pmu_flag_get(uint32_t flag )
202 | {
203 | if(PMU_CS & flag){
204 | return SET;
205 | }else{
206 | return RESET;
207 | }
208 | }
209 |
210 | /*!
211 | \brief backup domain write enable
212 | \param[in] none
213 | \param[out] none
214 | \retval none
215 | */
216 | void pmu_backup_write_enable(void)
217 | {
218 | PMU_CTL |= PMU_CTL_BKPWEN;
219 | }
220 |
221 | /*!
222 | \brief backup domain write disable
223 | \param[in] none
224 | \param[out] none
225 | \retval none
226 | */
227 | void pmu_backup_write_disable(void)
228 | {
229 | PMU_CTL &= ~PMU_CTL_BKPWEN;
230 | }
231 |
232 | /*!
233 | \brief wakeup pin enable
234 | \param[in] wakeup_pin:
235 | \arg PMU_WAKEUP_PIN0: wakeup pin 0
236 | \arg PMU_WAKEUP_PIN1: wakeup pin 1
237 | \param[out] none
238 | \retval none
239 | */
240 | void pmu_wakeup_pin_enable(uint32_t wakeup_pin )
241 | {
242 | PMU_CS |= wakeup_pin;
243 | }
244 |
245 | /*!
246 | \brief wakeup pin disable
247 | \param[in] wakeup_pin:
248 | \arg PMU_WAKEUP_PIN0: wakeup pin 0
249 | \arg PMU_WAKEUP_PIN1: wakeup pin 1
250 | \param[out] none
251 | \retval none
252 | */
253 | void pmu_wakeup_pin_disable(uint32_t wakeup_pin )
254 | {
255 | PMU_CS &= ~wakeup_pin;
256 |
257 | }
258 |
--------------------------------------------------------------------------------
/HoverBoardGigaDevice/RTE/Device/GD32F130C8/gd32f1x0_syscfg.c:
--------------------------------------------------------------------------------
1 | /*!
2 | \file gd32f1x0_syscfg.c
3 | \brief SYSCFG driver
4 | */
5 |
6 | /*
7 | Copyright (C) 2017 GigaDevice
8 |
9 | 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5)
10 | 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9)
11 | 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9)
12 | 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9)
13 | */
14 |
15 | #include "gd32f1x0_syscfg.h"
16 |
17 | /*!
18 | \brief reset the SYSCFG registers
19 | \param[in] none
20 | \param[out] none
21 | \retval none
22 | */
23 | void syscfg_deinit(void)
24 | {
25 | rcu_periph_reset_enable(RCU_CFGCMPRST);
26 | rcu_periph_reset_disable(RCU_CFGCMPRST);
27 | }
28 |
29 | /*!
30 | \brief enable the DMA channels remapping
31 | \param[in] syscfg_dma_remap: specify the DMA channels to remap
32 | \arg SYSCFG_DMA_REMAP_TIMER16: remap TIMER16 channel0 and UP DMA requests to channel1(defaut channel0)
33 | \arg SYSCFG_DMA_REMAP_TIMER15: remap TIMER15 channel2 and UP DMA requests to channel3(defaut channel2)
34 | \arg SYSCFG_DMA_REMAP_USART0RX: remap USART0 Rx DMA request to channel4(default channel2)
35 | \arg SYSCFG_DMA_REMAP_USART0TX: remap USART0 Tx DMA request to channel3(default channel1)
36 | \arg SYSCFG_DMA_REMAP_ADC: remap ADC DMA requests from channel0 to channel1
37 | \param[out] none
38 | \retval none
39 | */
40 | void syscfg_dma_remap_enable(uint32_t syscfg_dma_remap)
41 | {
42 | SYSCFG_CFG0 |= syscfg_dma_remap;
43 | }
44 |
45 | /*!
46 | \brief disable the DMA channels remapping
47 | \param[in] syscfg_dma_remap: specify the DMA channels to remap
48 | \arg SYSCFG_DMA_REMAP_TIMER16: remap TIMER16 channel0 and UP DMA requests to channel1(defaut channel0)
49 | \arg SYSCFG_DMA_REMAP_TIMER15: remap TIMER15 channel2 and UP DMA requests to channel3(defaut channel2)
50 | \arg SYSCFG_DMA_REMAP_USART0RX: remap USART0 Rx DMA request to channel4(default channel2)
51 | \arg SYSCFG_DMA_REMAP_USART0TX: remap USART0 Tx DMA request to channel3(default channel1)
52 | \arg SYSCFG_DMA_REMAP_ADC: remap ADC DMA requests from channel0 to channel1
53 | \param[out] none
54 | \retval none
55 | */
56 | void syscfg_dma_remap_disable(uint32_t syscfg_dma_remap)
57 | {
58 | SYSCFG_CFG0 &= ~syscfg_dma_remap;
59 | }
60 |
61 | /*!
62 | \brief enable PB9 high current capability
63 | \param[in] none
64 | \param[out] none
65 | \retval none
66 | */
67 | void syscfg_high_current_enable(void)
68 | {
69 | SYSCFG_CFG0 |= SYSCFG_HIGH_CURRENT_ENABLE;
70 | }
71 |
72 | /*!
73 | \brief disable PB9 high current capability
74 | \param[in] none
75 | \param[out] none
76 | \retval none
77 | */
78 | void syscfg_high_current_disable(void)
79 | {
80 | SYSCFG_CFG0 &= SYSCFG_HIGH_CURRENT_DISABLE;
81 | }
82 |
83 | #ifdef GD32F170_190
84 | /*!
85 | \brief configure the VLCD intermediate voltage rail
86 | \param[in] vlcd_bias: specify VLCD bias
87 | \arg VLCD_BIAS1_2_RAIL1: VLCD bias is 1/2, using rail1
88 | \arg VLCD_BIAS1_2_RAIL2: VLCD bias is 1/2, using rail2
89 | \arg VLCD_BIAS1_2_RAIL3: VLCD bias is 1/2, using rail3
90 | \arg VLCD_BIAS1_3_RAIL1_2: VLCD bias is 1/3, using rail1 and rail2
91 | \arg VLCD_BIAS1_3_RAIL1_3: VLCD bias is 1/3, using rail1 and rail3
92 | \arg VLCD_BIAS1_4_RAILALL: VLCD bias is 1/4, using all rails
93 | \param[out] none
94 | \retval none
95 | */
96 | void syscfg_vlcd_rail_config(uint8_t vlcd_bias)
97 | {
98 | uint32_t cfg1 = SYSCFG_CFG1;
99 |
100 | /* Clear system configuration register 1 */
101 | SYSCFG_CFG1 = 0U;
102 |
103 | switch(vlcd_bias){
104 | /* according to VLCD bias, configure rails combination */
105 | case VLCD_BIAS1_2_RAIL1:
106 | SYSCFG_CFG1 |= SYSCFG_VLCD_RAIL1;
107 | break;
108 | case VLCD_BIAS1_2_RAIL2:
109 | SYSCFG_CFG1 |= SYSCFG_VLCD_RAIL2;
110 | break;
111 | case VLCD_BIAS1_2_RAIL3:
112 | SYSCFG_CFG1 |= SYSCFG_VLCD_RAIL3;
113 | break;
114 | case VLCD_BIAS1_3_RAIL1_2:
115 | SYSCFG_CFG1 |= SYSCFG_VLCD_RAIL2 | SYSCFG_VLCD_RAIL1;
116 | break;
117 | case VLCD_BIAS1_3_RAIL1_3:
118 | SYSCFG_CFG1 |= SYSCFG_VLCD_RAIL3 | SYSCFG_VLCD_RAIL1;
119 | break;
120 | case VLCD_BIAS1_4_RAILALL:
121 | SYSCFG_CFG1 |= SYSCFG_VLCD_RAIL3 | SYSCFG_VLCD_RAIL2 | SYSCFG_VLCD_RAIL1;
122 | break;
123 | default:
124 | SYSCFG_CFG1 = cfg1;
125 | break;
126 | }
127 | }
128 | #endif /* GD32F170_190 */
129 |
130 | /*!
131 | \brief configure the GPIO pin as EXTI Line
132 | \param[in] exti_port: specify the GPIO port used in EXTI
133 | \arg EXTI_SOURCE_GPIOx(x = A,B,C,D,F): EXTI GPIO port
134 | \param[in] exti_pin: specify the EXTI line
135 | \arg EXTI_SOURCE_PINx(x = 0..15): EXTI GPIO pin
136 | \param[out] none
137 | \retval none
138 | */
139 | void syscfg_exti_line_config(uint8_t exti_port, uint8_t exti_pin)
140 | {
141 | uint32_t clear_exti_mask = ~((uint32_t)EXTI_SS_MASK << (EXTI_SS_MSTEP(exti_pin)));
142 | uint32_t config_exti_mask = ((uint32_t)exti_port) << (EXTI_SS_MSTEP(exti_pin));
143 |
144 | switch(exti_pin / EXTI_SS_JSTEP){
145 | case EXTISS0:
146 | /* clear EXTI source line(0..3) */
147 | SYSCFG_EXTISS0 &= clear_exti_mask;
148 | /* configure EXTI soure line(0..3) */
149 | SYSCFG_EXTISS0 |= config_exti_mask;
150 | break;
151 | case EXTISS1:
152 | /* clear EXTI soure line(4..7) */
153 | SYSCFG_EXTISS1 &= clear_exti_mask;
154 | /* configure EXTI soure line(4..7) */
155 | SYSCFG_EXTISS1 |= config_exti_mask;
156 | break;
157 | case EXTISS2:
158 | /* clear EXTI soure line(8..11) */
159 | SYSCFG_EXTISS2 &= clear_exti_mask;
160 | /* configure EXTI soure line(8..11) */
161 | SYSCFG_EXTISS2 |= config_exti_mask;
162 | break;
163 | case EXTISS3:
164 | /* clear EXTI soure line(12..15) */
165 | SYSCFG_EXTISS3 &= clear_exti_mask;
166 | /* configure EXTI soure line(12..15) */
167 | SYSCFG_EXTISS3 |= config_exti_mask;
168 | break;
169 | default:
170 | break;
171 | }
172 | }
173 |
174 | /*!
175 | \brief connect TIMER0/14/15/16 break input to the selected parameter
176 | \param[in] syscfg_lock: Specify the parameter to be connected
177 | \arg SYSCFG_LOCK_LOCKUP: Cortex-M3 lockup output connected to the break input
178 | \arg SYSCFG_LOCK_SRAM_PARITY_ERROR: SRAM_PARITY check error connected to the break input
179 | \arg SYSCFG_LOCK_LVD: LVD interrupt connected to the break input
180 | \param[out] none
181 | \retval none
182 | */
183 | void syscfg_lock_config(uint32_t syscfg_lock)
184 | {
185 | SYSCFG_CFG2 |= syscfg_lock;
186 | }
187 |
188 | /*!
189 | \brief check if the specified flag in SYSCFG_CFG2 is set or not.
190 | \param[in] syscfg_flag: specify the flag in SYSCFG_CFG2 to check.
191 | \arg SYSCFG_SRAM_PCEF: SRAM parity check error flag.
192 | \param[out] none
193 | \retval the syscfg_flag state returned (SET or RESET).
194 | */
195 | FlagStatus syscfg_flag_get(uint32_t syscfg_flag)
196 | {
197 | if((SYSCFG_CFG2 & syscfg_flag) != (uint32_t)RESET){
198 | return SET;
199 | }else{
200 | return RESET;
201 | }
202 | }
203 |
204 | /*!
205 | \brief clear the flag in SYSCFG_CFG2 by writing 1.
206 | \param[in] syscfg_flag: Specify the flag in SYSCFG_CFG2 to clear.
207 | \arg SYSCFG_SRAM_PCEF: SRAM parity check error flag.
208 | \param[out] none
209 | \retval none
210 | */
211 | void syscfg_flag_clear(uint32_t syscfg_flag)
212 | {
213 | SYSCFG_CFG2 |= (uint32_t) syscfg_flag;
214 | }
215 |
--------------------------------------------------------------------------------
/HoverBoardGigaDevice/RTE/Device/GD32F130C8/gd32f1x0_wwdgt.c:
--------------------------------------------------------------------------------
1 | /*!
2 | \file gd32f1x0_wwdgt.c
3 | \brief WWDGT driver
4 | */
5 |
6 | /*
7 | Copyright (C) 2017 GigaDevice
8 |
9 | 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5)
10 | 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9)
11 | 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9)
12 | 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9)
13 | */
14 |
15 | #include "gd32f1x0_wwdgt.h"
16 | #include "gd32f1x0_rcu.h"
17 |
18 | /*!
19 | \brief reset the window watchdog timer configuration
20 | \param[in] none
21 | \param[out] none
22 | \retval none
23 | */
24 | void wwdgt_deinit(void)
25 | {
26 | rcu_periph_reset_enable(RCU_WWDGTRST);
27 | rcu_periph_reset_disable(RCU_WWDGTRST);
28 | }
29 |
30 | /*!
31 | \brief configure the window watchdog timer counter value
32 | \param[in] counter_value: 0x00 - 0x7F
33 | \param[out] none
34 | \retval none
35 | */
36 | void wwdgt_counter_update(uint16_t counter_value)
37 | {
38 | uint32_t reg = 0U;
39 |
40 | reg = WWDGT_CTL & (~WWDGT_CTL_CNT);
41 | reg |= (uint32_t)(CTL_CNT((uint32_t)counter_value));
42 |
43 | WWDGT_CTL = (uint32_t)reg;
44 | }
45 |
46 | /*!
47 | \brief start the window watchdog timer counter
48 | \param[in] none
49 | \param[out] none
50 | \retval none
51 | */
52 | void wwdgt_enable(void)
53 | {
54 | WWDGT_CTL |= WWDGT_CTL_WDGTEN;
55 | }
56 |
57 | /*!
58 | \brief configure counter value, window value, and prescaler divider value
59 | \param[in] counter: 0x00 - 0x7F
60 | \param[in] window: 0x00 - 0x7F
61 | \param[in] prescaler: wwdgt prescaler value
62 | \arg WWDGT_CFG_PSC_DIV1: the time base of window watchdog counter = (PCLK1/4096)/1
63 | \arg WWDGT_CFG_PSC_DIV2: the time base of window watchdog counter = (PCLK1/4096)/2
64 | \arg WWDGT_CFG_PSC_DIV4: the time base of window watchdog counter = (PCLK1/4096)/4
65 | \arg WWDGT_CFG_PSC_DIV8: the time base of window watchdog counter = (PCLK1/4096)/8
66 | \param[out] none
67 | \retval none
68 | */
69 | void wwdgt_config(uint16_t counter, uint16_t window, uint32_t prescaler)
70 | {
71 | uint32_t reg_cfg = 0U, reg_ctl = 0U;
72 |
73 | /* clear WIN and PSC bits, clear CNT bit */
74 | reg_cfg = WWDGT_CFG &(~(WWDGT_CFG_WIN | WWDGT_CFG_PSC));
75 | reg_ctl = WWDGT_CTL &(~(uint32_t)WWDGT_CTL_CNT);
76 |
77 | /* configure WIN and PSC bits, configure CNT bit */
78 | reg_cfg |= (uint32_t)(CFG_WIN(window));
79 | reg_cfg |= (uint32_t)(prescaler);
80 | reg_ctl |= (uint32_t)(CTL_CNT(counter));
81 |
82 | WWDGT_CFG = (uint32_t)reg_cfg;
83 | WWDGT_CTL = (uint32_t)reg_ctl;
84 | }
85 |
86 | /*!
87 | \brief enable early wakeup interrupt of WWDGT
88 | \param[in] none
89 | \param[out] none
90 | \retval none
91 | */
92 | void wwdgt_interrupt_enable(void)
93 | {
94 | WWDGT_CFG |= WWDGT_CFG_EWIE;
95 | }
96 |
97 | /*!
98 | \brief check early wakeup interrupt state of WWDGT
99 | \param[in] none
100 | \param[out] none
101 | \retval FlagStatus: SET or RESET
102 | */
103 | FlagStatus wwdgt_flag_get(void)
104 | {
105 | if(WWDGT_STAT & WWDGT_STAT_EWIF){
106 | return SET;
107 | }
108 |
109 | return RESET;
110 | }
111 |
112 | /*!
113 | \brief clear early wakeup interrupt state of WWDGT
114 | \param[in] none
115 | \param[out] none
116 | \retval none
117 | */
118 | void wwdgt_flag_clear(void)
119 | {
120 | WWDGT_STAT &= (uint32_t)(~(uint32_t)WWDGT_STAT_EWIF);
121 | }
122 |
--------------------------------------------------------------------------------
/HoverBoardGigaDevice/RTE/Device/GD32F130C8/startup_gd32f1x0.s:
--------------------------------------------------------------------------------
1 | ;/*!
2 | ; \file startup_gd32f1x0.s
3 | ; \brief start up file
4 | ;*/
5 |
6 | ;/*
7 | ; Copyright (C) 2017 GigaDevice
8 |
9 | ; 2014-12-26, V1.0.0, firmware for GD32F1x0(x=3,5)
10 | ; 2016-01-15, V2.0.0, firmware for GD32F1x0(x=3,5,7,9)
11 | ; 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9)
12 | ; 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9)
13 | ;*/
14 |
15 | ; Stack Configuration
16 | ; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
17 | ;
18 |
19 | Stack_Size EQU 0x00000400
20 |
21 | AREA STACK, NOINIT, READWRITE, ALIGN=3
22 | Stack_Mem SPACE Stack_Size
23 | __initial_sp
24 |
25 |
26 | ; Heap Configuration
27 | ; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
28 | ;
29 |
30 | Heap_Size EQU 0x00000400
31 |
32 | AREA HEAP, NOINIT, READWRITE, ALIGN=3
33 | __heap_base
34 | Heap_Mem SPACE Heap_Size
35 | __heap_limit
36 |
37 | PRESERVE8
38 | THUMB
39 |
40 | ; /* reset Vector Mapped to at Address 0 */
41 | AREA RESET, DATA, READONLY
42 | EXPORT __Vectors
43 | EXPORT __Vectors_End
44 | EXPORT __Vectors_Size
45 |
46 | __Vectors DCD __initial_sp ; Top of Stack
47 | DCD Reset_Handler ; Reset Handler
48 | DCD NMI_Handler ; NMI Handler
49 | DCD HardFault_Handler ; Hard Fault Handler
50 | DCD MemManage_Handler ; MPU Fault Handler
51 | DCD BusFault_Handler ; Bus Fault Handler
52 | DCD UsageFault_Handler ; Usage Fault Handler
53 | DCD 0 ; Reserved
54 | DCD 0 ; Reserved
55 | DCD 0 ; Reserved
56 | DCD 0 ; Reserved
57 | DCD SVC_Handler ; SVCall Handler
58 | DCD DebugMon_Handler ; Debug Monitor Handler
59 | DCD 0 ; Reserved
60 | DCD PendSV_Handler ; PendSV Handler
61 | DCD SysTick_Handler ; SysTick Handler
62 |
63 | ; /* external interrupts handler */
64 | DCD WWDGT_IRQHandler ; 16:Window Watchdog Timer
65 | DCD LVD_IRQHandler ; 17:LVD through EXTI Line detect
66 | DCD RTC_IRQHandler ; 18:RTC through EXTI Line
67 | DCD FMC_IRQHandler ; 19:FMC
68 | DCD RCU_IRQHandler ; 20:RCU
69 | DCD EXTI0_1_IRQHandler ; 21:EXTI Line 0 and EXTI Line 1
70 | DCD EXTI2_3_IRQHandler ; 22:EXTI Line 2 and EXTI Line 3
71 | DCD EXTI4_15_IRQHandler ; 23:EXTI Line 4 to EXTI Line 15
72 | DCD TSI_IRQHandler ; 24:TSI
73 | DCD DMA_Channel0_IRQHandler ; 25:DMA Channel 0
74 | DCD DMA_Channel1_2_IRQHandler ; 26:DMA Channel 1 and DMA Channel 2
75 | DCD DMA_Channel3_4_IRQHandler ; 27:DMA Channel 3 and DMA Channel 4
76 | DCD ADC_CMP_IRQHandler ; 28:ADC and Comparator 0-1
77 | DCD TIMER0_BRK_UP_TRG_COM_IRQHandler ; 29:TIMER0 Break,Update,Trigger and Commutation
78 | DCD TIMER0_Channel_IRQHandler ; 30:TIMER0 Channel
79 | DCD TIMER1_IRQHandler ; 31:TIMER1
80 | DCD TIMER2_IRQHandler ; 32:TIMER2
81 | DCD TIMER5_DAC_IRQHandler ; 33:TIMER5 and DAC
82 | DCD 0 ; Reserved
83 | DCD TIMER13_IRQHandler ; 35:TIMER13
84 | DCD TIMER14_IRQHandler ; 36:TIMER14
85 | DCD TIMER15_IRQHandler ; 37:TIMER15
86 | DCD TIMER16_IRQHandler ; 38:TIMER16
87 | DCD I2C0_EV_IRQHandler ; 39:I2C0 Event
88 | DCD I2C1_EV_IRQHandler ; 40:I2C1 Event
89 | DCD SPI0_IRQHandler ; 41:SPI0
90 | DCD SPI1_IRQHandler ; 42:SPI1
91 | DCD USART0_IRQHandler ; 43:USART0
92 | DCD USART1_IRQHandler ; 44:USART1
93 | DCD 0 ; Reserved
94 | DCD CEC_IRQHandler ; 46:CEC
95 | DCD 0 ; Reserved
96 | DCD I2C0_ER_IRQHandler ; 48:I2C0 Error
97 | DCD 0 ; Reserved
98 | DCD I2C1_ER_IRQHandler ; 50:I2C1 Error
99 | DCD I2C2_EV_IRQHandler ; 51:I2C2 Event
100 | DCD I2C2_ER_IRQHandler ; 52:I2C2 Error
101 | DCD USBD_LP_IRQHandler ; 53:USBD LP
102 | DCD USBD_HP_IRQHandler ; 54:USBD HP
103 | DCD 0 ; Reserved
104 | DCD 0 ; Reserved
105 | DCD 0 ; Reserved
106 | DCD USBDWakeUp_IRQHandler ; 58:USBD Wakeup
107 | DCD CAN0_TX_IRQHandler ; 59:CAN0 TX
108 | DCD CAN0_RX0_IRQHandler ; 60:CAN0 RX0
109 | DCD CAN0_RX1_IRQHandler ; 61:CAN0 RX1
110 | DCD CAN0_SCE_IRQHandler ; 62:CAN0 SCE
111 | DCD SLCD_IRQHandler ; 63:SLCD
112 | DCD DMA_Channel5_6_IRQHandler ; 64:DMA Channel5 and Channel6
113 | DCD 0 ; Reserved
114 | DCD 0 ; Reserved
115 | DCD SPI2_IRQHandler ; 67:SPI2
116 | DCD 0 ; Reserved
117 | DCD 0 ; Reserved
118 | DCD 0 ; Reserved
119 | DCD 0 ; Reserved
120 | DCD 0 ; Reserved
121 | DCD 0 ; Reserved
122 | DCD 0 ; Reserved
123 | DCD 0 ; Reserved
124 | DCD 0 ; Reserved
125 | DCD 0 ; Reserved
126 | DCD 0 ; Reserved
127 | DCD 0 ; Reserved
128 | DCD 0 ; Reserved
129 | DCD 0 ; Reserved
130 | DCD 0 ; Reserved
131 | DCD 0 ; Reserved
132 | DCD 0 ; Reserved
133 | DCD 0 ; Reserved
134 | DCD CAN1_TX_IRQHandler ; 86:CAN1 TX
135 | DCD CAN1_RX0_IRQHandler ; 87:CAN1 RX0
136 | DCD CAN1_RX1_IRQHandler ; 88:CAN1 RX1
137 | DCD CAN1_SCE_IRQHandler ; 89:CAN1 SCE
138 | __Vectors_End
139 |
140 | __Vectors_Size EQU __Vectors_End - __Vectors
141 |
142 | AREA |.text|, CODE, READONLY
143 |
144 | ;/* reset Handler */
145 | Reset_Handler PROC
146 | EXPORT Reset_Handler [WEAK]
147 | IMPORT SystemInit
148 | IMPORT __main
149 | LDR R0, =SystemInit
150 | BLX R0
151 | LDR R0, =__main
152 | BX R0
153 | ENDP
154 |
155 | ;/* dummy Exception Handlers */
156 | NMI_Handler PROC
157 | EXPORT NMI_Handler [WEAK]
158 | B .
159 | ENDP
160 | HardFault_Handler\
161 | PROC
162 | EXPORT HardFault_Handler [WEAK]
163 | B .
164 | ENDP
165 | MemManage_Handler\
166 | PROC
167 | EXPORT MemManage_Handler [WEAK]
168 | B .
169 | ENDP
170 | BusFault_Handler\
171 | PROC
172 | EXPORT BusFault_Handler [WEAK]
173 | B .
174 | ENDP
175 | UsageFault_Handler\
176 | PROC
177 | EXPORT UsageFault_Handler [WEAK]
178 | B .
179 | ENDP
180 | SVC_Handler PROC
181 | EXPORT SVC_Handler [WEAK]
182 | B .
183 | ENDP
184 | DebugMon_Handler\
185 | PROC
186 | EXPORT DebugMon_Handler [WEAK]
187 | B .
188 | ENDP
189 | PendSV_Handler\
190 | PROC
191 | EXPORT PendSV_Handler [WEAK]
192 | B .
193 | ENDP
194 | SysTick_Handler\
195 | PROC
196 | EXPORT SysTick_Handler [WEAK]
197 | B .
198 | ENDP
199 |
200 | Default_Handler PROC
201 | ; /* external interrupts handler */
202 | EXPORT WWDGT_IRQHandler [WEAK]
203 | EXPORT LVD_IRQHandler [WEAK]
204 | EXPORT RTC_IRQHandler [WEAK]
205 | EXPORT FMC_IRQHandler [WEAK]
206 | EXPORT RCU_IRQHandler [WEAK]
207 | EXPORT EXTI0_1_IRQHandler [WEAK]
208 | EXPORT EXTI2_3_IRQHandler [WEAK]
209 | EXPORT EXTI4_15_IRQHandler [WEAK]
210 | EXPORT TSI_IRQHandler [WEAK]
211 | EXPORT DMA_Channel0_IRQHandler [WEAK]
212 | EXPORT DMA_Channel1_2_IRQHandler [WEAK]
213 | EXPORT DMA_Channel3_4_IRQHandler [WEAK]
214 | EXPORT ADC_CMP_IRQHandler [WEAK]
215 | EXPORT TIMER0_BRK_UP_TRG_COM_IRQHandler [WEAK]
216 | EXPORT TIMER0_Channel_IRQHandler [WEAK]
217 | EXPORT TIMER1_IRQHandler [WEAK]
218 | EXPORT TIMER2_IRQHandler [WEAK]
219 | EXPORT TIMER5_DAC_IRQHandler [WEAK]
220 | EXPORT TIMER13_IRQHandler [WEAK]
221 | EXPORT TIMER14_IRQHandler [WEAK]
222 | EXPORT TIMER15_IRQHandler [WEAK]
223 | EXPORT TIMER16_IRQHandler [WEAK]
224 | EXPORT I2C0_EV_IRQHandler [WEAK]
225 | EXPORT I2C1_EV_IRQHandler [WEAK]
226 | EXPORT SPI0_IRQHandler [WEAK]
227 | EXPORT SPI1_IRQHandler [WEAK]
228 | EXPORT USART0_IRQHandler [WEAK]
229 | EXPORT USART1_IRQHandler [WEAK]
230 | EXPORT CEC_IRQHandler [WEAK]
231 | EXPORT I2C0_ER_IRQHandler [WEAK]
232 | EXPORT I2C1_ER_IRQHandler [WEAK]
233 | EXPORT I2C2_EV_IRQHandler [WEAK]
234 | EXPORT I2C2_ER_IRQHandler [WEAK]
235 | EXPORT USBD_LP_IRQHandler [WEAK]
236 | EXPORT USBD_HP_IRQHandler [WEAK]
237 | EXPORT USBDWakeUp_IRQHandler [WEAK]
238 | EXPORT CAN0_TX_IRQHandler [WEAK]
239 | EXPORT CAN0_RX0_IRQHandler [WEAK]
240 | EXPORT CAN0_RX1_IRQHandler [WEAK]
241 | EXPORT CAN0_SCE_IRQHandler [WEAK]
242 | EXPORT SLCD_IRQHandler [WEAK]
243 | EXPORT DMA_Channel5_6_IRQHandler [WEAK]
244 | EXPORT SPI2_IRQHandler [WEAK]
245 | EXPORT CAN1_TX_IRQHandler [WEAK]
246 | EXPORT CAN1_RX0_IRQHandler [WEAK]
247 | EXPORT CAN1_RX1_IRQHandler [WEAK]
248 | EXPORT CAN1_SCE_IRQHandler [WEAK]
249 |
250 | ;/* external interrupts handler */
251 | WWDGT_IRQHandler
252 | LVD_IRQHandler
253 | RTC_IRQHandler
254 | FMC_IRQHandler
255 | RCU_IRQHandler
256 | EXTI0_1_IRQHandler
257 | EXTI2_3_IRQHandler
258 | EXTI4_15_IRQHandler
259 | TSI_IRQHandler
260 | DMA_Channel0_IRQHandler
261 | DMA_Channel1_2_IRQHandler
262 | DMA_Channel3_4_IRQHandler
263 | ADC_CMP_IRQHandler
264 | TIMER0_BRK_UP_TRG_COM_IRQHandler
265 | TIMER0_Channel_IRQHandler
266 | TIMER1_IRQHandler
267 | TIMER2_IRQHandler
268 | TIMER5_DAC_IRQHandler
269 | TIMER13_IRQHandler
270 | TIMER14_IRQHandler
271 | TIMER15_IRQHandler
272 | TIMER16_IRQHandler
273 | I2C0_EV_IRQHandler
274 | I2C1_EV_IRQHandler
275 | SPI0_IRQHandler
276 | SPI1_IRQHandler
277 | USART0_IRQHandler
278 | USART1_IRQHandler
279 | CEC_IRQHandler
280 | I2C0_ER_IRQHandler
281 | I2C1_ER_IRQHandler
282 | I2C2_EV_IRQHandler
283 | I2C2_ER_IRQHandler
284 | USBD_LP_IRQHandler
285 | USBD_HP_IRQHandler
286 | USBDWakeUp_IRQHandler
287 | CAN0_TX_IRQHandler
288 | CAN0_RX0_IRQHandler
289 | CAN0_RX1_IRQHandler
290 | CAN0_SCE_IRQHandler
291 | SLCD_IRQHandler
292 | DMA_Channel5_6_IRQHandler
293 | SPI2_IRQHandler
294 | CAN1_TX_IRQHandler
295 | CAN1_RX0_IRQHandler
296 | CAN1_RX1_IRQHandler
297 | CAN1_SCE_IRQHandler
298 | B .
299 | ENDP
300 |
301 | ALIGN
302 |
303 | ; user Initial Stack & Heap
304 |
305 | IF :DEF:__MICROLIB
306 |
307 | EXPORT __initial_sp
308 | EXPORT __heap_base
309 | EXPORT __heap_limit
310 |
311 | ELSE
312 |
313 | IMPORT __use_two_region_memory
314 | EXPORT __user_initial_stackheap
315 |
316 | __user_initial_stackheap PROC
317 | LDR R0, = Heap_Mem
318 | LDR R1, =(Stack_Mem + Stack_Size)
319 | LDR R2, = (Heap_Mem + Heap_Size)
320 | LDR R3, = Stack_Mem
321 | BX LR
322 | ENDP
323 |
324 | ALIGN
325 |
326 | ENDIF
327 |
328 | END
329 |
--------------------------------------------------------------------------------
/HoverBoardGigaDevice/RTE/Device/GD32F130C8/system_gd32f1x0.c:
--------------------------------------------------------------------------------
1 | /*!
2 | \file system_gd32f1x0.c
3 | \brief CMSIS Cortex-M3 Device Peripheral Access Layer Source File for
4 | GD32F1x0 Device Series
5 | */
6 |
7 | /* Copyright (c) 2012 ARM LIMITED
8 |
9 | All rights reserved.
10 | Redistribution and use in source and binary forms, with or without
11 | modification, are permitted provided that the following conditions are met:
12 | - Redistributions of source code must retain the above copyright
13 | notice, this list of conditions and the following disclaimer.
14 | - Redistributions in binary form must reproduce the above copyright
15 | notice, this list of conditions and the following disclaimer in the
16 | documentation and/or other materials provided with the distribution.
17 | - Neither the name of ARM nor the names of its contributors may be used
18 | to endorse or promote products derived from this software without
19 | specific prior written permission.
20 | *
21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 | ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
25 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 | POSSIBILITY OF SUCH DAMAGE.
32 | ---------------------------------------------------------------------------*/
33 |
34 | /* This file refers the CMSIS standard, some adjustments are made according to GigaDevice chips */
35 |
36 | #include "gd32f1x0.h"
37 |
38 | /* system frequency define */
39 | #define __IRC8M (IRC8M_VALUE) /* internal 8 MHz RC oscillator frequency */
40 | #define __HXTAL (HXTAL_VALUE) /* high speed crystal oscillator frequency */
41 | #define __SYS_OSC_CLK (__IRC8M) /* main oscillator frequency */
42 |
43 | /* select a system clock by uncommenting the following line */
44 | //#define __SYSTEM_CLOCK_8M_HXTAL (__HXTAL)
45 | //#define __SYSTEM_CLOCK_8M_IRC8M (__IRC8M)
46 | //#define __SYSTEM_CLOCK_72M_PLL_HXTAL (uint32_t)(72000000)
47 | #define __SYSTEM_CLOCK_72M_PLL_IRC8M_DIV2 (uint32_t)(72000000)
48 |
49 | #define SEL_IRC8M 0x00
50 | #define SEL_HXTAL 0x01
51 | #define SEL_PLL 0x02
52 |
53 | /* set the system clock frequency and declare the system clock configuration function */
54 | #ifdef __SYSTEM_CLOCK_8M_HXTAL
55 | uint32_t SystemCoreClock = __SYSTEM_CLOCK_8M_HXTAL;
56 | static void system_clock_8m_hxtal(void);
57 | #elif defined (__SYSTEM_CLOCK_72M_PLL_HXTAL)
58 | uint32_t SystemCoreClock = __SYSTEM_CLOCK_72M_PLL_HXTAL;
59 | static void system_clock_72m_hxtal(void);
60 | #elif defined (__SYSTEM_CLOCK_72M_PLL_IRC8M_DIV2)
61 | uint32_t SystemCoreClock = __SYSTEM_CLOCK_72M_PLL_IRC8M_DIV2;
62 | static void system_clock_72m_irc8m(void);
63 | #else
64 | uint32_t SystemCoreClock = __SYSTEM_CLOCK_8M_IRC8M;
65 | static void system_clock_8m_irc8m(void);
66 | #endif /* __SYSTEM_CLOCK_8M_HXTAL */
67 |
68 | /* configure the system clock */
69 | static void system_clock_config(void);
70 |
71 | /*!
72 | \brief setup the microcontroller system, initialize the system
73 | \param[in] none
74 | \param[out] none
75 | \retval none
76 | */
77 | void SystemInit (void)
78 | {
79 | /* enable IRC8M */
80 | RCU_CTL0 |= RCU_CTL0_IRC8MEN;
81 | while(0U == (RCU_CTL0 & RCU_CTL0_IRC8MSTB)){
82 | }
83 | /* reset RCU */
84 | #ifdef GD32F130_150
85 | RCU_CFG0 &= ~(RCU_CFG0_SCS | RCU_CFG0_AHBPSC | RCU_CFG0_APB1PSC | RCU_CFG0_APB2PSC |\
86 | RCU_CFG0_ADCPSC | RCU_CFG0_CKOUTSEL | RCU_CFG0_CKOUTDIV | RCU_CFG0_PLLDV);
87 | #elif defined (GD32F170_190)
88 | RCU_CFG0 &= ~(RCU_CFG0_SCS | RCU_CFG0_AHBPSC | RCU_CFG0_APB1PSC | RCU_CFG0_APB2PSC |\
89 | RCU_CFG0_ADCPSC | RCU_CFG0_CKOUT0SEL | RCU_CFG0_CKOUT0DIV | RCU_CFG0_PLLDV);
90 | #endif /* GD32F130_150 */
91 | RCU_CFG0 &= ~(RCU_CFG0_PLLSEL | RCU_CFG0_PLLMF | RCU_CFG0_PLLDV);
92 | #ifdef GD32F130_150
93 | RCU_CFG0 &= ~(RCU_CFG0_USBDPSC);
94 | #endif /* GD32F130_150 */
95 | RCU_CTL0 &= ~(RCU_CTL0_HXTALEN | RCU_CTL0_CKMEN | RCU_CTL0_PLLEN | RCU_CTL0_HXTALBPS);
96 | RCU_CFG1 &= ~RCU_CFG1_HXTALPREDV;
97 | RCU_CFG2 &= ~(RCU_CFG2_USART0SEL | RCU_CFG2_CECSEL | RCU_CFG2_ADCSEL);
98 | #ifdef GD32F130_150
99 | RCU_CTL1 &= ~RCU_CTL1_IRC14MEN;
100 | #elif defined (GD32F170_190)
101 | RCU_CFG2 &= ~RCU_CFG2_IRC28MDIV;
102 | RCU_CTL1 &= ~RCU_CTL1_IRC28MEN;
103 | RCU_CFG3 &= ~RCU_CFG3_CKOUT1SRC;
104 | RCU_CFG3 &= ~RCU_CFG3_CKOUT1DIV;
105 | #endif /* GD32F130_150 */
106 | RCU_INT = 0x00000000U;
107 |
108 | /* configure system clock */
109 | system_clock_config();
110 | }
111 |
112 | /*!
113 | \brief configure the system clock
114 | \param[in] none
115 | \param[out] none
116 | \retval none
117 | */
118 | static void system_clock_config(void)
119 | {
120 | #ifdef __SYSTEM_CLOCK_8M_HXTAL
121 | system_clock_8m_hxtal();
122 | #elif defined (__SYSTEM_CLOCK_72M_PLL_HXTAL)
123 | system_clock_72m_hxtal();
124 | #elif defined (__SYSTEM_CLOCK_72M_PLL_IRC8M_DIV2)
125 | system_clock_72m_irc8m();
126 | #else
127 | system_clock_8m_irc8m();
128 | #endif /* __SYSTEM_CLOCK_8M_HXTAL */
129 | }
130 |
131 | #ifdef __SYSTEM_CLOCK_8M_HXTAL
132 | /*!
133 | \brief configure the system clock to 8M by HXTAL
134 | \param[in] none
135 | \param[out] none
136 | \retval none
137 | */
138 | static void system_clock_8m_hxtal(void)
139 | {
140 | uint32_t timeout = 0;
141 |
142 | /* enable HXTAL */
143 | RCU_CTL0 |= RCU_CTL0_HXTALEN;
144 |
145 | /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */
146 | while((0 == (RCU_CTL0 & RCU_CTL0_HXTALSTB)) && (HXTAL_STARTUP_TIMEOUT != timeout++));
147 |
148 | /* if fail */
149 | if(0 == (RCU_CTL0 & RCU_CTL0_HXTALSTB))
150 | return;
151 |
152 | /* HXTAL is stable */
153 | /* AHB = SYSCLK */
154 | RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
155 | /* APB2 = AHB */
156 | RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
157 | /* APB1 = AHB */
158 | RCU_CFG0 |= RCU_APB1_CKAHB_DIV1;
159 |
160 | /* select HXTAL as system clock */
161 | RCU_CFG0 &= ~RCU_CFG0_SCS;
162 | RCU_CFG0 |= RCU_CKSYSSRC_HXTAL;
163 |
164 | /* wait until HXTAL is selected as system clock */
165 | while(0 == (RCU_CFG0 & RCU_SCSS_HXTAL));
166 | }
167 |
168 | #elif defined (__SYSTEM_CLOCK_72M_PLL_HXTAL)
169 | /*!
170 | \brief configure the system clock to 72M by PLL which selects HXTAL as its clock source
171 | \param[in] none
172 | \param[out] none
173 | \retval none
174 | */
175 | static void system_clock_72m_hxtal(void)
176 | {
177 | uint32_t timeout = 0U;
178 | uint32_t stab_flag = 0U;
179 |
180 | /* enable HXTAL */
181 | RCU_CTL0 |= RCU_CTL0_HXTALEN;
182 |
183 | /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */
184 | do{
185 | timeout++;
186 | stab_flag = (RCU_CTL0 & RCU_CTL0_HXTALSTB);
187 | }
188 | while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout));
189 |
190 | /* if fail */
191 | if(0U == (RCU_CTL0 & RCU_CTL0_HXTALSTB)){
192 | return;
193 | }
194 |
195 | /* HXTAL is stable */
196 | /* AHB = SYSCLK */
197 | RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
198 | /* APB2 = AHB */
199 | RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
200 | /* APB1 = AHB */
201 | RCU_CFG0 |= RCU_APB1_CKAHB_DIV1;
202 |
203 | /* PLL = HXTAL * 9 = 72 MHz */
204 | RCU_CFG0 &= ~(RCU_CFG0_PLLSEL | RCU_CFG0_PLLMF | RCU_CFG0_PLLDV);
205 | RCU_CFG0 |= (RCU_PLLSRC_HXTAL | RCU_PLL_MUL9);
206 |
207 | /* enable PLL */
208 | RCU_CTL0 |= RCU_CTL0_PLLEN;
209 |
210 | /* wait until PLL is stable */
211 | while(0U == (RCU_CTL0 & RCU_CTL0_PLLSTB)){
212 | }
213 |
214 | /* select PLL as system clock */
215 | RCU_CFG0 &= ~RCU_CFG0_SCS;
216 | RCU_CFG0 |= RCU_CKSYSSRC_PLL;
217 |
218 | /* wait until PLL is selected as system clock */
219 | while(0U == (RCU_CFG0 & RCU_SCSS_PLL)){
220 | }
221 | }
222 |
223 | #elif defined (__SYSTEM_CLOCK_72M_PLL_IRC8M_DIV2)
224 | /*!
225 | \brief configure the system clock to 72M by PLL which selects IRC8M/2 as its clock source
226 | \param[in] none
227 | \param[out] none
228 | \retval none
229 | */
230 | static void system_clock_72m_irc8m(void)
231 | {
232 | /* AHB = SYSCLK */
233 | RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
234 | /* APB2 = AHB */
235 | RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
236 | /* APB1 = AHB */
237 | RCU_CFG0 |= RCU_APB1_CKAHB_DIV1;
238 | /* PLL = (IRC8M/2) * 18 = 72 MHz */
239 | RCU_CFG0 &= ~(RCU_CFG0_PLLSEL | RCU_CFG0_PLLMF);
240 | RCU_CFG0 |= (RCU_PLLSRC_IRC8M_DIV2 | RCU_PLL_MUL18);
241 |
242 | /* enable PLL */
243 | RCU_CTL0 |= RCU_CTL0_PLLEN;
244 |
245 | /* wait until PLL is stable */
246 | while(0 == (RCU_CTL0 & RCU_CTL0_PLLSTB));
247 |
248 | /* select PLL as system clock */
249 | RCU_CFG0 &= ~RCU_CFG0_SCS;
250 | RCU_CFG0 |= RCU_CKSYSSRC_PLL;
251 |
252 | /* wait until PLL is selected as system clock */
253 | while(0 == (RCU_CFG0 & RCU_SCSS_PLL));
254 | }
255 |
256 | #else
257 | /*!
258 | \brief configure the system clock to 8M by IRC8M
259 | \param[in] none
260 | \param[out] none
261 | \retval none
262 | */
263 | static void system_clock_8m_irc8m(void)
264 | {
265 | /* AHB = SYSCLK */
266 | RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
267 | /* APB2 = AHB */
268 | RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
269 | /* APB1 = AHB */
270 | RCU_CFG0 |= RCU_APB1_CKAHB_DIV1;
271 |
272 | /* select IRC8M as system clock */
273 | RCU_CFG0 &= ~RCU_CFG0_SCS;
274 | RCU_CFG0 |= RCU_CKSYSSRC_IRC8M;
275 |
276 | /* wait until IRC8M is selected as system clock */
277 | while(0 != (RCU_CFG0 & RCU_SCSS_IRC8M));
278 | }
279 | #endif /* __SYSTEM_CLOCK_8M_HXTAL */
280 |
281 | /*!
282 | \brief update the SystemCoreClock with current core clock retrieved from cpu registers
283 | \param[in] none
284 | \param[out] none
285 | \retval none
286 | */
287 | void SystemCoreClockUpdate (void)
288 | {
289 | uint32_t sws = 0U;
290 | uint32_t pllmf = 0U, pllmf4 = 0U, pllsel = 0U, prediv = 0U, idx = 0U, clk_exp = 0U;
291 | /* exponent of AHB clock divider */
292 | const uint8_t ahb_exp[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
293 |
294 | sws = GET_BITS(RCU_CFG0, 2, 3);
295 | switch(sws){
296 | /* IRC8M is selected as CK_SYS */
297 | case SEL_IRC8M:
298 | SystemCoreClock = IRC8M_VALUE;
299 | break;
300 | /* HXTAL is selected as CK_SYS */
301 | case SEL_HXTAL:
302 | SystemCoreClock = HXTAL_VALUE;
303 | break;
304 | /* PLL is selected as CK_SYS */
305 | case SEL_PLL:
306 | /* get the value of PLLMF[3:0] */
307 | pllmf = GET_BITS(RCU_CFG0, 18, 21);
308 | pllmf4 = GET_BITS(RCU_CFG0, 27, 27);
309 | /* high 16 bits */
310 | if(1U == pllmf4){
311 | pllmf += 17U;
312 | }else{
313 | pllmf += 2U;
314 | }
315 | /* PLL clock source selection, HXTAL or IRC8M/2 */
316 | pllsel = GET_BITS(RCU_CFG0, 16, 16);
317 | if(0U != pllsel){
318 | prediv = (GET_BITS(RCU_CFG1, 0, 3) + 1U);
319 | SystemCoreClock = (HXTAL_VALUE / prediv) * pllmf;
320 | }else{
321 | SystemCoreClock = (IRC8M_VALUE >> 1) * pllmf;
322 | }
323 | break;
324 | /* IRC8M is selected as CK_SYS */
325 | default:
326 | SystemCoreClock = IRC8M_VALUE;
327 | break;
328 | }
329 | /* calculate AHB clock frequency */
330 | idx = GET_BITS(RCU_CFG0, 4, 7);
331 | clk_exp = ahb_exp[idx];
332 | SystemCoreClock >>= clk_exp;
333 | }
334 |
--------------------------------------------------------------------------------
/HoverBoardGigaDevice/RTE/_Target_1/RTE_Components.h:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Auto generated Run-Time-Environment Component Configuration File
4 | * *** Do not modify ! ***
5 | *
6 | * Project: 'Hoverboard'
7 | * Target: 'Target 1'
8 | */
9 |
10 | #ifndef RTE_COMPONENTS_H
11 | #define RTE_COMPONENTS_H
12 |
13 |
14 | /*
15 | * Define the Device Header File:
16 | */
17 | #define CMSIS_device_header "gd32f1x0.h"
18 |
19 | #define RTE_DEVICE_STDPERIPHERALS_ADC
20 | #define RTE_DEVICE_STDPERIPHERALS_DBG
21 | #define RTE_DEVICE_STDPERIPHERALS_DMA
22 | #define RTE_DEVICE_STDPERIPHERALS_FWDGT
23 | #define RTE_DEVICE_STDPERIPHERALS_GPIO
24 | #define RTE_DEVICE_STDPERIPHERALS_I2C
25 | #define RTE_DEVICE_STDPERIPHERALS_MISC
26 | #define RTE_DEVICE_STDPERIPHERALS_OPA
27 | #define RTE_DEVICE_STDPERIPHERALS_PMU
28 | #define RTE_DEVICE_STDPERIPHERALS_RCU
29 | #define RTE_DEVICE_STDPERIPHERALS_SYSCFG
30 | #define RTE_DEVICE_STDPERIPHERALS_TIMER
31 | #define RTE_DEVICE_STDPERIPHERALS_USART
32 | #define RTE_DEVICE_STDPERIPHERALS_WWDGT
33 |
34 | #endif /* RTE_COMPONENTS_H */
35 |
--------------------------------------------------------------------------------
/HoverBoardGigaDevice/Src/bldc.c:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the hoverboard-firmware-hack-V2 project. The
3 | * firmware is used to hack the generation 2 board of the hoverboard.
4 | * These new hoverboards have no mainboard anymore. They consist of
5 | * two Sensorboards which have their own BLDC-Bridge per Motor and an
6 | * ARM Cortex-M3 processor GD32F130C8.
7 | *
8 | * Copyright (C) 2018 Florian Staeblein
9 | * Copyright (C) 2018 Jakob Broemauer
10 | * Copyright (C) 2018 Kai Liebich
11 | * Copyright (C) 2018 Christoph Lehnert
12 | *
13 | * The program is based on the hoverboard project by Niklas Fauth. The
14 | * structure was tried to be as similar as possible, so that everyone
15 | * could find a better way through the code.
16 | *
17 | * This program is free software: you can redistribute it and/or modify
18 | * it under the terms of the GNU General Public License as published by
19 | * the Free Software Foundation, either version 3 of the License, or
20 | * (at your option) any later version.
21 | *
22 | * This program is distributed in the hope that it will be useful,
23 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 | * GNU General Public License for more details.
26 | *
27 | * You should have received a copy of the GNU General Public License
28 | * along with this program. If not, see .
29 | */
30 |
31 | #include "gd32f1x0.h"
32 | #include "../Inc/setup.h"
33 | #include "../Inc/defines.h"
34 | #include "../Inc/config.h"
35 |
36 | // Internal constants
37 | const int16_t pwm_res = 72000000 / 2 / PWM_FREQ; // = 2000
38 |
39 | // Global variables for voltage and current
40 | float batteryVoltage = 40.0;
41 | float currentDC = 0.0;
42 | float realSpeed = 0.0;
43 |
44 | // Timeoutvariable set by timeout timer
45 | extern FlagStatus timedOut;
46 |
47 | // Variables to be set from the main routine
48 | int16_t bldc_inputFilterPwm = 0;
49 | FlagStatus bldc_enable = RESET;
50 |
51 | // ADC buffer to be filled by DMA
52 | adc_buf_t adc_buffer;
53 |
54 | // Internal calculation variables
55 | uint8_t hall_a;
56 | uint8_t hall_b;
57 | uint8_t hall_c;
58 | uint8_t hall;
59 | uint8_t pos;
60 | uint8_t lastPos;
61 | int16_t bldc_outputFilterPwm = 0;
62 | int32_t filter_reg;
63 | FlagStatus buzzerToggle = RESET;
64 | uint8_t buzzerFreq = 0;
65 | uint8_t buzzerPattern = 0;
66 | uint16_t buzzerTimer = 0;
67 | int16_t offsetcount = 0;
68 | int16_t offsetdc = 2000;
69 | uint32_t speedCounter = 0;
70 |
71 | //----------------------------------------------------------------------------
72 | // Commutation table
73 | //----------------------------------------------------------------------------
74 | const uint8_t hall_to_pos[8] =
75 | {
76 | // annotation: for example SA=0 means hall sensor pulls SA down to Ground
77 | 0, // hall position [-] - No function (access from 1-6)
78 | 3, // hall position [1] (SA=1, SB=0, SC=0) -> PWM-position 3
79 | 5, // hall position [2] (SA=0, SB=1, SC=0) -> PWM-position 5
80 | 4, // hall position [3] (SA=1, SB=1, SC=0) -> PWM-position 4
81 | 1, // hall position [4] (SA=0, SB=0, SC=1) -> PWM-position 1
82 | 2, // hall position [5] (SA=1, SB=0, SC=1) -> PWM-position 2
83 | 6, // hall position [6] (SA=0, SB=1, SC=1) -> PWM-position 6
84 | 0, // hall position [-] - No function (access from 1-6)
85 | };
86 |
87 | //----------------------------------------------------------------------------
88 | // Block PWM calculation based on position
89 | //----------------------------------------------------------------------------
90 | __INLINE void blockPWM(int pwm, int pwmPos, int *y, int *b, int *g)
91 | {
92 | switch(pwmPos)
93 | {
94 | case 1:
95 | *y = 0;
96 | *b = pwm;
97 | *g = -pwm;
98 | break;
99 | case 2:
100 | *y = -pwm;
101 | *b = pwm;
102 | *g = 0;
103 | break;
104 | case 3:
105 | *y = -pwm;
106 | *b = 0;
107 | *g = pwm;
108 | break;
109 | case 4:
110 | *y = 0;
111 | *b = -pwm;
112 | *g = pwm;
113 | break;
114 | case 5:
115 | *y = pwm;
116 | *b = -pwm;
117 | *g = 0;
118 | break;
119 | case 6:
120 | *y = pwm;
121 | *b = 0;
122 | *g = -pwm;
123 | break;
124 | default:
125 | *y = 0;
126 | *b = 0;
127 | *g = 0;
128 | }
129 | }
130 |
131 | //----------------------------------------------------------------------------
132 | // Set motor enable
133 | //----------------------------------------------------------------------------
134 | void SetEnable(FlagStatus setEnable)
135 | {
136 | bldc_enable = setEnable;
137 | }
138 |
139 | //----------------------------------------------------------------------------
140 | // Set pwm -1000 to 1000
141 | //----------------------------------------------------------------------------
142 | void SetPWM(int16_t setPwm)
143 | {
144 | bldc_inputFilterPwm = CLAMP(setPwm, -1000, 1000);
145 | }
146 |
147 | //----------------------------------------------------------------------------
148 | // Calculation-Routine for BLDC => calculates with 16kHz
149 | //----------------------------------------------------------------------------
150 | void CalculateBLDC(void)
151 | {
152 | int y = 0; // yellow = phase A
153 | int b = 0; // blue = phase B
154 | int g = 0; // green = phase C
155 |
156 | // Calibrate ADC offsets for the first 1000 cycles
157 | if (offsetcount < 1000)
158 | {
159 | offsetcount++;
160 | offsetdc = (adc_buffer.current_dc + offsetdc) / 2;
161 | return;
162 | }
163 |
164 | // Calculate battery voltage every 100 cycles
165 | if (buzzerTimer % 100 == 0)
166 | {
167 | batteryVoltage = batteryVoltage * 0.999 + ((float)adc_buffer.v_batt * ADC_BATTERY_VOLT) * 0.001;
168 | }
169 |
170 | #ifdef MASTER
171 | // Create square wave for buzzer
172 | buzzerTimer++;
173 | if (buzzerFreq != 0 && (buzzerTimer / 5000) % (buzzerPattern + 1) == 0)
174 | {
175 | if (buzzerTimer % buzzerFreq == 0)
176 | {
177 | buzzerToggle = buzzerToggle == RESET ? SET : RESET; // toggle variable
178 | gpio_bit_write(BUZZER_PORT, BUZZER_PIN, buzzerToggle);
179 | }
180 | }
181 | else
182 | {
183 | gpio_bit_write(BUZZER_PORT, BUZZER_PIN, RESET);
184 | }
185 | #endif
186 |
187 | // Calculate current DC
188 | currentDC = ABS((adc_buffer.current_dc - offsetdc) * MOTOR_AMP_CONV_DC_AMP);
189 |
190 | // Disable PWM when current limit is reached (current chopping), enable is not set or timeout is reached
191 | if (currentDC > DC_CUR_LIMIT || bldc_enable == RESET || timedOut == SET)
192 | {
193 | timer_automatic_output_disable(TIMER_BLDC);
194 | }
195 | else
196 | {
197 | timer_automatic_output_enable(TIMER_BLDC);
198 | }
199 |
200 | // Read hall sensors
201 | hall_a = gpio_input_bit_get(HALL_A_PORT, HALL_A_PIN);
202 | hall_b = gpio_input_bit_get(HALL_B_PORT, HALL_B_PIN);
203 | hall_c = gpio_input_bit_get(HALL_C_PORT, HALL_C_PIN);
204 |
205 | // Determine current position based on hall sensors
206 | hall = hall_a * 1 + hall_b * 2 + hall_c * 4;
207 | pos = hall_to_pos[hall];
208 |
209 | // Calculate low-pass filter for pwm value
210 | filter_reg = filter_reg - (filter_reg >> FILTER_SHIFT) + bldc_inputFilterPwm;
211 | bldc_outputFilterPwm = filter_reg >> FILTER_SHIFT;
212 |
213 | // Update PWM channels based on position y(ellow), b(lue), g(reen)
214 | blockPWM(bldc_outputFilterPwm, pos, &y, &b, &g);
215 |
216 | // Set PWM output (pwm_res/2 is the mean value, setvalue has to be between 10 and pwm_res-10)
217 | timer_channel_output_pulse_value_config(TIMER_BLDC, TIMER_BLDC_CHANNEL_G, CLAMP(g + pwm_res / 2, 10, pwm_res-10));
218 | timer_channel_output_pulse_value_config(TIMER_BLDC, TIMER_BLDC_CHANNEL_B, CLAMP(b + pwm_res / 2, 10, pwm_res-10));
219 | timer_channel_output_pulse_value_config(TIMER_BLDC, TIMER_BLDC_CHANNEL_Y, CLAMP(y + pwm_res / 2, 10, pwm_res-10));
220 |
221 | // Increments with 62.5us
222 | if(speedCounter < 4000) // No speed after 250ms
223 | {
224 | speedCounter++;
225 | }
226 |
227 | // Every time position reaches value 1, one round is performed (rising edge)
228 | if (lastPos != 1 && pos == 1)
229 | {
230 | realSpeed = 1991.81f / (float)speedCounter; //[km/h]
231 | speedCounter = 0;
232 | }
233 | else
234 | {
235 | if (speedCounter >= 4000)
236 | {
237 | realSpeed = 0;
238 | }
239 | }
240 |
241 | // Safe last position
242 | lastPos = pos;
243 | }
244 |
--------------------------------------------------------------------------------
/HoverBoardGigaDevice/Src/comms.c:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the hoverboard-firmware-hack-V2 project. The
3 | * firmware is used to hack the generation 2 board of the hoverboard.
4 | * These new hoverboards have no mainboard anymore. They consist of
5 | * two Sensorboards which have their own BLDC-Bridge per Motor and an
6 | * ARM Cortex-M3 processor GD32F130C8.
7 | *
8 | * Copyright (C) 2018 Florian Staeblein
9 | * Copyright (C) 2018 Jakob Broemauer
10 | * Copyright (C) 2018 Kai Liebich
11 | * Copyright (C) 2018 Christoph Lehnert
12 | *
13 | * The program is based on the hoverboard project by Niklas Fauth. The
14 | * structure was tried to be as similar as possible, so that everyone
15 | * could find a better way through the code.
16 | *
17 | * This program is free software: you can redistribute it and/or modify
18 | * it under the terms of the GNU General Public License as published by
19 | * the Free Software Foundation, either version 3 of the License, or
20 | * (at your option) any later version.
21 | *
22 | * This program is distributed in the hope that it will be useful,
23 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 | * GNU General Public License for more details.
26 | *
27 | * You should have received a copy of the GNU General Public License
28 | * along with this program. If not, see .
29 | */
30 |
31 | #include "gd32f1x0.h"
32 |
33 | //----------------------------------------------------------------------------
34 | // Send buffer via USART
35 | //----------------------------------------------------------------------------
36 | void SendBuffer(uint32_t usart_periph, uint8_t buffer[], uint8_t length)
37 | {
38 | uint8_t index = 0;
39 |
40 | for(; index < length; index++)
41 | {
42 | usart_data_transmit(usart_periph, buffer[index]);
43 | while (usart_flag_get(usart_periph, USART_FLAG_TC) == RESET) {}
44 | }
45 | }
46 |
47 | //----------------------------------------------------------------------------
48 | // Calculate CRC
49 | //----------------------------------------------------------------------------
50 | uint16_t CalcCRC(uint8_t *ptr, int count)
51 | {
52 | uint16_t crc;
53 | uint8_t i;
54 | crc = 0;
55 | while (--count >= 0)
56 | {
57 | crc = crc ^ (uint16_t) *ptr++ << 8;
58 | i = 8;
59 | do
60 | {
61 | if (crc & 0x8000)
62 | {
63 | crc = crc << 1 ^ 0x1021;
64 | }
65 | else
66 | {
67 | crc = crc << 1;
68 | }
69 | } while(--i);
70 | }
71 | return (crc);
72 | }
73 |
--------------------------------------------------------------------------------
/HoverBoardGigaDevice/Src/commsBluetooth.c:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the hoverboard-firmware-hack-V2 project. The
3 | * firmware is used to hack the generation 2 board of the hoverboard.
4 | * These new hoverboards have no mainboard anymore. They consist of
5 | * two Sensorboards which have their own BLDC-Bridge per Motor and an
6 | * ARM Cortex-M3 processor GD32F130C8.
7 | *
8 | * Copyright (C) 2018 Florian Staeblein
9 | * Copyright (C) 2018 Jakob Broemauer
10 | * Copyright (C) 2018 Kai Liebich
11 | * Copyright (C) 2018 Christoph Lehnert
12 | *
13 | * The program is based on the hoverboard project by Niklas Fauth. The
14 | * structure was tried to be as similar as possible, so that everyone
15 | * could find a better way through the code.
16 | *
17 | * This program is free software: you can redistribute it and/or modify
18 | * it under the terms of the GNU General Public License as published by
19 | * the Free Software Foundation, either version 3 of the License, or
20 | * (at your option) any later version.
21 | *
22 | * This program is distributed in the hope that it will be useful,
23 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 | * GNU General Public License for more details.
26 | *
27 | * You should have received a copy of the GNU General Public License
28 | * along with this program. If not, see .
29 | */
30 |
31 | #include "gd32f1x0.h"
32 | #include "../Inc/defines.h"
33 | #include "../Inc/setup.h"
34 | #include "../Inc/comms.h"
35 | #include "../Inc/commsMasterSlave.h"
36 | #include "../Inc/commsBluetooth.h"
37 | #include "../Inc/led.h"
38 | #include "stdio.h"
39 | #include "string.h"
40 |
41 | // Only slave communicates over bluetooth
42 | #ifdef SLAVE
43 | // Variables which will be send over bluetooth
44 | extern float currentDC;
45 | extern float realSpeed;
46 |
47 | extern uint32_t hornCounter_ms;
48 |
49 | #define USART_BLUETOOTH_TX_BYTES 11 // Transmit byte count including start '/' and stop character '\n'
50 | #define USART_BLUETOOTH_RX_BYTES 11 // Receive byte count including start '/' and stop character '\n'
51 |
52 | extern uint8_t usartSteer_COM_rx_buf[USART_STEER_COM_RX_BUFFERSIZE];
53 | static uint8_t sBluetoothRecord = 0;
54 | static uint8_t sUSARTBluetoothRecordBuffer[USART_BLUETOOTH_RX_BYTES];
55 | static uint8_t sUSARTBluetoothRecordBufferCounter = 0;
56 |
57 | void CheckUSARTBluetoothInput(uint8_t USARTBuffer[]);
58 | void SendBluetoothDevice(uint8_t identifier, int16_t value);
59 |
60 | //----------------------------------------------------------------------------
61 | // Update USART bluetooth input
62 | //----------------------------------------------------------------------------
63 | void UpdateUSARTBluetoothInput(void)
64 | {
65 | uint8_t character = usartSteer_COM_rx_buf[0];
66 |
67 | // Start character is captured, start record
68 | if (character == '/')
69 | {
70 | sUSARTBluetoothRecordBufferCounter = 0;
71 | sBluetoothRecord = 1;
72 | }
73 |
74 | if (sBluetoothRecord)
75 | {
76 | sUSARTBluetoothRecordBuffer[sUSARTBluetoothRecordBufferCounter] = character;
77 | sUSARTBluetoothRecordBufferCounter++;
78 |
79 | if (sUSARTBluetoothRecordBufferCounter >= USART_BLUETOOTH_RX_BYTES)
80 | {
81 | sUSARTBluetoothRecordBufferCounter = 0;
82 | sBluetoothRecord = 0;
83 |
84 | // Check input
85 | CheckUSARTBluetoothInput (sUSARTBluetoothRecordBuffer);
86 | }
87 | }
88 | }
89 |
90 | //----------------------------------------------------------------------------
91 | // Check USART bluetooth input
92 | //----------------------------------------------------------------------------
93 | void CheckUSARTBluetoothInput(uint8_t USARTBuffer[])
94 | {
95 | // Auxiliary variables
96 | uint8_t identifier = 0;
97 | uint8_t readWrite = 0;
98 | int16_t sign = 0;
99 | int16_t digit1 = 0;
100 | int16_t digit2 = 0;
101 | int16_t digit3 = 0;
102 | int16_t digit4 = 0;
103 | int16_t digit5 = 0;
104 | int16_t value = 0;
105 |
106 | // Check start and stop character
107 | if ( USARTBuffer[0] != '/' ||
108 | USARTBuffer[USART_BLUETOOTH_RX_BYTES - 1] != '\n')
109 | {
110 | return;
111 | }
112 |
113 | // Calculate identifier (number 0-99)
114 | digit1 = (USARTBuffer[1] - '0') * 10;
115 | digit2 = (USARTBuffer[2] - '0');
116 | identifier = digit1 + digit2;
117 |
118 | // Calculate read or write access (0 - read, 1 - write)
119 | readWrite = USARTBuffer[3] - '0';
120 |
121 | // If read mode, answer with correct value
122 | if (readWrite == 0)
123 | {
124 | switch(identifier)
125 | {
126 | case 0:
127 | // Answer with battery voltage from master
128 | value = GetBatteryMaster();
129 | break;
130 | case 1:
131 | // Answer with current from master
132 | value = GetCurrentDCMaster();
133 | break;
134 | case 2:
135 | // Answer with current from slave
136 | value = currentDC * 100;
137 | break;
138 | case 3:
139 | // Answer with real speed of master
140 | value = GetRealSpeedMaster();
141 | break;
142 | case 4:
143 | // Answer with real speed of slave
144 | value = realSpeed * 100;
145 | break;
146 | case 5:
147 | // Answer with beeps backwards from master
148 | value = GetBeepsBackwardsMaster() == RESET ? 0 : 1;
149 | break;
150 | case 6:
151 | // Answer with lower LED state of master (music box)
152 | value = GetLowerLEDMaster() == RESET ? 0 : 1;
153 | break;
154 | case 7:
155 | // Answer with upper LED state of master (horn)
156 | value = GetUpperLEDMaster() == RESET ? 0 : 1;
157 | break;
158 | case 8:
159 | // Answer with hue value
160 | value = GetHSBHue();
161 | break;
162 | case 9:
163 | // Answer with saturation value
164 | value = GetHSBSaturation();
165 | break;
166 | case 10:
167 | // Answer with brightness value
168 | value = GetHSBBrightness();
169 | break;
170 | case 11:
171 | // Answer with LEDMode
172 | value = GetRGBProgram();
173 | break;
174 | case 12:
175 | // Answer with fading speed
176 | value = GetSpeedFading();
177 | break;
178 | case 13:
179 | // Answer with blink speed
180 | value = GetSpeedBlink();
181 | break;
182 | case 14:
183 | // Answer with strobe speed
184 | value = GetSpeedStrobe();
185 | break;
186 | }
187 |
188 | // Send Answer
189 | SendBluetoothDevice(identifier, value);
190 | }
191 | // If write mode, get result value
192 | else if ( readWrite == 1)
193 | {
194 | // Calculate result value (-10000 to 10000)
195 | sign = USARTBuffer[4] == '-' ? -1 : 1;
196 | digit1 = (USARTBuffer[5] - '0') * 10000;
197 | digit2 = (USARTBuffer[6] - '0') * 1000;
198 | digit3 = (USARTBuffer[7] - '0') * 100;
199 | digit4 = (USARTBuffer[8] - '0') * 10;
200 | digit5 = (USARTBuffer[9] - '0');
201 | value = sign * (digit1 + digit2 + digit3 + digit4 + digit5);
202 |
203 | switch(identifier)
204 | {
205 | case 5:
206 | SetBeepsBackwardsMaster(value == 0 ? RESET : SET);
207 | break;
208 | case 6:
209 | // Set lower LED of master (music box)
210 | SetLowerLEDMaster(value == 0 ? RESET : SET);
211 | break;
212 | case 7:
213 | // Set upper LED of master (horn)
214 | hornCounter_ms = 0;
215 | SetUpperLEDMaster(value == 0 ? RESET : SET);
216 | break;
217 | case 8:
218 | // Set LED hue
219 | SetHSBHue(value);
220 | break;
221 | case 9:
222 | // Set LED saturation
223 | SetHSBSaturation(value);
224 | break;
225 | case 10:
226 | // Set LED brightness
227 | SetHSBBrightness(value);
228 | break;
229 | case 11:
230 | // Set LED mode
231 | SetRGBProgram((LED_PROGRAM)value);
232 | break;
233 | case 12:
234 | // Set fading speed
235 | SetSpeedFading(value);
236 | break;
237 | case 13:
238 | // Set blink speed
239 | SetSpeedBlink(value);
240 | break;
241 | case 14:
242 | // Set strobe speed
243 | SetSpeedStrobe(value);
244 | break;
245 | default:
246 | // Do nothing for the rest of the identifiers
247 | break;
248 | }
249 | }
250 | }
251 |
252 | //----------------------------------------------------------------------------
253 | // Send frame to bluetooth device
254 | //----------------------------------------------------------------------------
255 | void SendBluetoothDevice(uint8_t identifier, int16_t value)
256 | {
257 | int index = 0;
258 | char charVal[5];
259 | uint8_t buffer[USART_BLUETOOTH_TX_BYTES];
260 |
261 | // Send bluetooth frame
262 | buffer[index++] = '/';
263 | sprintf(charVal, "%02d", identifier);
264 | buffer[index++] = charVal[0];
265 | buffer[index++] = charVal[1];
266 | buffer[index++] = '0';
267 | sprintf(charVal, "%05d", value);
268 | buffer[index++] = value < 0 ? '-' : '+';
269 | buffer[index++] = charVal[0];
270 | buffer[index++] = charVal[1];
271 | buffer[index++] = charVal[2];
272 | buffer[index++] = charVal[3];
273 | buffer[index++] = charVal[4];
274 | buffer[index++] = '\n';
275 |
276 | SendBuffer(USART_STEER_COM, buffer, index);
277 | }
278 |
279 | #endif
280 |
--------------------------------------------------------------------------------
/HoverBoardGigaDevice/Src/commsMasterSlave.c:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the hoverboard-firmware-hack-V2 project. The
3 | * firmware is used to hack the generation 2 board of the hoverboard.
4 | * These new hoverboards have no mainboard anymore. They consist of
5 | * two Sensorboards which have their own BLDC-Bridge per Motor and an
6 | * ARM Cortex-M3 processor GD32F130C8.
7 | *
8 | * Copyright (C) 2018 Florian Staeblein
9 | * Copyright (C) 2018 Jakob Broemauer
10 | * Copyright (C) 2018 Kai Liebich
11 | * Copyright (C) 2018 Christoph Lehnert
12 | *
13 | * The program is based on the hoverboard project by Niklas Fauth. The
14 | * structure was tried to be as similar as possible, so that everyone
15 | * could find a better way through the code.
16 | *
17 | * This program is free software: you can redistribute it and/or modify
18 | * it under the terms of the GNU General Public License as published by
19 | * the Free Software Foundation, either version 3 of the License, or
20 | * (at your option) any later version.
21 | *
22 | * This program is distributed in the hope that it will be useful,
23 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 | * GNU General Public License for more details.
26 | *
27 | * You should have received a copy of the GNU General Public License
28 | * along with this program. If not, see .
29 | */
30 |
31 | #include "gd32f1x0.h"
32 | #include "../Inc/it.h"
33 | #include "../Inc/comms.h"
34 | #include "../Inc/commsMasterSlave.h"
35 | #include "../Inc/setup.h"
36 | #include "../Inc/config.h"
37 | #include "../Inc/defines.h"
38 | #include "../Inc/bldc.h"
39 | #include "stdio.h"
40 | #include "string.h"
41 |
42 | #ifdef MASTER
43 | #define USART_MASTERSLAVE_TX_BYTES 10 // Transmit byte count including start '/' and stop character '\n'
44 | #define USART_MASTERSLAVE_RX_BYTES 5 // Receive byte count including start '/' and stop character '\n'
45 |
46 | // Variables which will be written by slave frame
47 | extern FlagStatus beepsBackwards;
48 | #endif
49 | #ifdef SLAVE
50 | #define USART_MASTERSLAVE_TX_BYTES 5 // Transmit byte count including start '/' and stop character '\n'
51 | #define USART_MASTERSLAVE_RX_BYTES 10 // Receive byte count including start '/' and stop character '\n'
52 |
53 | // Variables which will be send to master
54 | FlagStatus upperLEDMaster = RESET;
55 | FlagStatus lowerLEDMaster = RESET;
56 | FlagStatus mosfetOutMaster = RESET;
57 | FlagStatus beepsBackwardsMaster = RESET;
58 |
59 | // Variables which will be written by master frame
60 | int16_t currentDCMaster = 0;
61 | int16_t batteryMaster = 0;
62 | int16_t realSpeedMaster = 0;
63 |
64 | void CheckGeneralValue(uint8_t identifier, int16_t value);
65 | #endif
66 |
67 | extern uint8_t usartMasterSlave_rx_buf[USART_MASTERSLAVE_RX_BUFFERSIZE];
68 | static uint8_t sMasterSlaveRecord = 0;
69 | static uint8_t sUSARTMasterSlaveRecordBuffer[USART_MASTERSLAVE_RX_BYTES];
70 | static uint8_t sUSARTMasterSlaveRecordBufferCounter = 0;
71 |
72 | void CheckUSARTMasterSlaveInput(uint8_t u8USARTBuffer[]);
73 | void SendBuffer(uint32_t usart_periph, uint8_t buffer[], uint8_t length);
74 | uint16_t CalcCRC(uint8_t *ptr, int count);
75 |
76 | //----------------------------------------------------------------------------
77 | // Update USART master slave input
78 | //----------------------------------------------------------------------------
79 | void UpdateUSARTMasterSlaveInput(void)
80 | {
81 | uint8_t character = usartMasterSlave_rx_buf[0];
82 |
83 | // Start character is captured, start record
84 | if (character == '/')
85 | {
86 | sUSARTMasterSlaveRecordBufferCounter = 0;
87 | sMasterSlaveRecord = 1;
88 | }
89 |
90 | if (sMasterSlaveRecord)
91 | {
92 | sUSARTMasterSlaveRecordBuffer[sUSARTMasterSlaveRecordBufferCounter] = character;
93 | sUSARTMasterSlaveRecordBufferCounter++;
94 |
95 | if (sUSARTMasterSlaveRecordBufferCounter >= USART_MASTERSLAVE_RX_BYTES)
96 | {
97 | sUSARTMasterSlaveRecordBufferCounter = 0;
98 | sMasterSlaveRecord = 0;
99 |
100 | // Check input
101 | CheckUSARTMasterSlaveInput (sUSARTMasterSlaveRecordBuffer);
102 | }
103 | }
104 | }
105 |
106 | //----------------------------------------------------------------------------
107 | // Check USART master slave input
108 | //----------------------------------------------------------------------------
109 | void CheckUSARTMasterSlaveInput(uint8_t USARTBuffer[])
110 | {
111 | #ifdef MASTER
112 | // Result variables
113 | FlagStatus upperLED = RESET;
114 | FlagStatus lowerLED = RESET;
115 | FlagStatus mosfetOut = RESET;
116 |
117 | // Auxiliary variables
118 | uint8_t byte;
119 | #endif
120 | #ifdef SLAVE
121 | // Result variables
122 | int16_t pwmSlave = 0;
123 | FlagStatus enable = RESET;
124 | FlagStatus shutoff = RESET;
125 | FlagStatus chargeStateLowActive = SET;
126 |
127 | // Auxiliary variables
128 | uint8_t identifier = 0;
129 | int16_t value = 0;
130 | uint8_t byte;
131 | #endif
132 | // Auxiliary variables
133 | uint16_t crc;
134 |
135 | // Check start and stop character
136 | if ( USARTBuffer[0] != '/' ||
137 | USARTBuffer[USART_MASTERSLAVE_RX_BYTES - 1] != '\n')
138 | {
139 | return;
140 | }
141 |
142 | // Calculate CRC (first bytes except crc and stop byte)
143 | crc = CalcCRC(USARTBuffer, USART_MASTERSLAVE_RX_BYTES - 3);
144 |
145 | // Check CRC
146 | if ( USARTBuffer[USART_MASTERSLAVE_RX_BYTES - 3] != ((crc >> 8) & 0xFF) ||
147 | USARTBuffer[USART_MASTERSLAVE_RX_BYTES - 2] != (crc & 0xFF))
148 | {
149 | return;
150 | }
151 |
152 | #ifdef MASTER
153 | // Calculate setvalues for LED and mosfets
154 | byte = USARTBuffer[1];
155 |
156 | //none = (byte & BIT(7)) ? SET : RESET;
157 | //none = (byte & BIT(6)) ? SET : RESET;
158 | //none = (byte & BIT(5)) ? SET : RESET;
159 | //none = (byte & BIT(4)) ? SET : RESET;
160 | beepsBackwards = (byte & BIT(3)) ? SET : RESET;
161 | mosfetOut = (byte & BIT(2)) ? SET : RESET;
162 | lowerLED = (byte & BIT(1)) ? SET : RESET;
163 | upperLED = (byte & BIT(0)) ? SET : RESET;
164 |
165 | // Set functions according to the variables
166 | gpio_bit_write(MOSFET_OUT_PORT, MOSFET_OUT_PIN, mosfetOut);
167 | gpio_bit_write(UPPER_LED_PORT, UPPER_LED_PIN, upperLED);
168 | gpio_bit_write(LOWER_LED_PORT, LOWER_LED_PIN, lowerLED);
169 | #endif
170 | #ifdef SLAVE
171 | // Calculate result pwm value -1000 to 1000
172 | pwmSlave = (int16_t)((USARTBuffer[1] << 8) | USARTBuffer[2]);
173 |
174 | // Get identifier
175 | identifier = USARTBuffer[3];
176 |
177 | // Calculate result general value
178 | value = (int16_t)((USARTBuffer[4] << 8) | USARTBuffer[5]);
179 |
180 | // Calculate setvalues for enable and shutoff
181 | byte = USARTBuffer[6];
182 |
183 | shutoff = (byte & BIT(7)) ? SET : RESET;
184 | //none = (byte & BIT(6)) ? SET : RESET;
185 | //none = (byte & BIT(5)) ? SET : RESET;
186 | //none = (byte & BIT(4)) ? SET : RESET;
187 | //none = (byte & BIT(3)) ? SET : RESET;
188 | //none = (byte & BIT(2)) ? SET : RESET;
189 | chargeStateLowActive = (byte & BIT(1)) ? SET : RESET;
190 | enable = (byte & BIT(0)) ? SET : RESET;
191 |
192 | if (shutoff == SET)
193 | {
194 | // Disable usart
195 | usart_deinit(USART_MASTERSLAVE);
196 |
197 | // Set pwm and enable to off
198 | SetEnable(RESET);
199 | SetPWM(0);
200 |
201 | gpio_bit_write(SELF_HOLD_PORT, SELF_HOLD_PIN, RESET);
202 | while(1)
203 | {
204 | // Reload watchdog until device is off
205 | fwdgt_counter_reload();
206 | }
207 | }
208 |
209 | // Set functions according to the variables
210 | gpio_bit_write(LED_GREEN_PORT, LED_GREEN, chargeStateLowActive == SET ? SET : RESET);
211 | gpio_bit_write(LED_RED_PORT, LED_RED, chargeStateLowActive == RESET ? SET : RESET);
212 | SetEnable(enable);
213 | SetPWM(pwmSlave);
214 | CheckGeneralValue(identifier, value);
215 |
216 | // Send answer
217 | SendMaster(upperLEDMaster, lowerLEDMaster, mosfetOutMaster, beepsBackwardsMaster);
218 |
219 | // Reset the pwm timout to avoid stopping motors
220 | ResetTimeout();
221 | #endif
222 | }
223 |
224 | #ifdef MASTER
225 | //----------------------------------------------------------------------------
226 | // Send slave frame via USART
227 | //----------------------------------------------------------------------------
228 | void SendSlave(int16_t pwmSlave, FlagStatus enable, FlagStatus shutoff, FlagStatus chargeState, uint8_t identifier, int16_t value)
229 | {
230 | uint8_t index = 0;
231 | uint16_t crc = 0;
232 | uint8_t buffer[USART_MASTERSLAVE_TX_BYTES];
233 |
234 | // Format pwmValue and general value
235 | int16_t sendPwm = CLAMP(pwmSlave, -1000, 1000);
236 | uint16_t sendPwm_Uint = (uint16_t)(sendPwm);
237 | uint16_t value_Uint = (uint16_t)(value);
238 |
239 | uint8_t sendByte = 0;
240 | sendByte |= (shutoff << 7);
241 | sendByte |= (0 << 6);
242 | sendByte |= (0 << 5);
243 | sendByte |= (0 << 4);
244 | sendByte |= (0 << 3);
245 | sendByte |= (0 << 2);
246 | sendByte |= (chargeState << 1);
247 | sendByte |= (enable << 0);
248 |
249 | // Send answer
250 | buffer[index++] = '/';
251 | buffer[index++] = (sendPwm_Uint >> 8) & 0xFF;
252 | buffer[index++] = sendPwm_Uint & 0xFF;
253 | buffer[index++] = identifier;
254 | buffer[index++] = (value_Uint >> 8) & 0xFF;
255 | buffer[index++] = value_Uint & 0xFF;
256 | buffer[index++] = sendByte;
257 |
258 | // Calculate CRC
259 | crc = CalcCRC(buffer, index);
260 | buffer[index++] = (crc >> 8) & 0xFF;
261 | buffer[index++] = crc & 0xFF;
262 |
263 | // Stop byte
264 | buffer[index++] = '\n';
265 |
266 | SendBuffer(USART_MASTERSLAVE, buffer, index);
267 | }
268 | #endif
269 | #ifdef SLAVE
270 | //----------------------------------------------------------------------------
271 | // Send master frame via USART
272 | //----------------------------------------------------------------------------
273 | void SendMaster(FlagStatus upperLEDMaster, FlagStatus lowerLEDMaster, FlagStatus mosfetOutMaster, FlagStatus beepsBackwards)
274 | {
275 | uint8_t index = 0;
276 | uint16_t crc = 0;
277 | uint8_t buffer[USART_MASTERSLAVE_TX_BYTES];
278 |
279 | uint8_t sendByte = 0;
280 | sendByte |= (0 << 7);
281 | sendByte |= (0 << 6);
282 | sendByte |= (0 << 5);
283 | sendByte |= (0 << 4);
284 | sendByte |= (beepsBackwards << 3);
285 | sendByte |= (mosfetOutMaster << 2);
286 | sendByte |= (lowerLEDMaster << 1);
287 | sendByte |= (upperLEDMaster << 0);
288 |
289 | // Send answer
290 | buffer[index++] = '/';
291 | buffer[index++] = sendByte;
292 |
293 | // Calculate CRC
294 | crc = CalcCRC(buffer, index);
295 | buffer[index++] = (crc >> 8) & 0xFF;
296 | buffer[index++] = crc & 0xFF;
297 |
298 | // Stop byte
299 | buffer[index++] = '\n';
300 |
301 | SendBuffer(USART_MASTERSLAVE, buffer, index);
302 | }
303 |
304 | //----------------------------------------------------------------------------
305 | // Checks input value from master to set value depending on identifier
306 | //----------------------------------------------------------------------------
307 | void CheckGeneralValue(uint8_t identifier, int16_t value)
308 | {
309 | switch(identifier)
310 | {
311 | case 0:
312 | currentDCMaster = value;
313 | break;
314 | case 1:
315 | batteryMaster = value;
316 | break;
317 | case 2:
318 | realSpeedMaster = value;
319 | break;
320 | case 3:
321 | break;
322 | default:
323 | break;
324 | }
325 | }
326 |
327 | //----------------------------------------------------------------------------
328 | // Returns current value sent by master
329 | //----------------------------------------------------------------------------
330 | int16_t GetCurrentDCMaster(void)
331 | {
332 | return currentDCMaster;
333 | }
334 |
335 | //----------------------------------------------------------------------------
336 | // Returns battery value sent by master
337 | //----------------------------------------------------------------------------
338 | int16_t GetBatteryMaster(void)
339 | {
340 | return batteryMaster;
341 | }
342 |
343 | //----------------------------------------------------------------------------
344 | // Returns realspeed value sent by master
345 | //----------------------------------------------------------------------------
346 | int16_t GetRealSpeedMaster(void)
347 | {
348 | return realSpeedMaster;
349 | }
350 |
351 | //----------------------------------------------------------------------------
352 | // Sets upper LED value which will be send to master
353 | //----------------------------------------------------------------------------
354 | void SetUpperLEDMaster(FlagStatus value)
355 | {
356 | upperLEDMaster = value;
357 | }
358 |
359 | //----------------------------------------------------------------------------
360 | // Returns upper LED value sent by master
361 | //----------------------------------------------------------------------------
362 | FlagStatus GetUpperLEDMaster(void)
363 | {
364 | return upperLEDMaster;
365 | }
366 |
367 | //----------------------------------------------------------------------------
368 | // Sets lower LED value which will be send to master
369 | //----------------------------------------------------------------------------
370 | void SetLowerLEDMaster(FlagStatus value)
371 | {
372 | lowerLEDMaster = value;
373 | }
374 |
375 | //----------------------------------------------------------------------------
376 | // Returns lower LED value sent by master
377 | //----------------------------------------------------------------------------
378 | FlagStatus GetLowerLEDMaster(void)
379 | {
380 | return lowerLEDMaster;
381 | }
382 |
383 | //----------------------------------------------------------------------------
384 | // Sets mosfetOut value which will be send to master
385 | //----------------------------------------------------------------------------
386 | void SetMosfetOutMaster(FlagStatus value)
387 | {
388 | mosfetOutMaster = value;
389 | }
390 |
391 | //----------------------------------------------------------------------------
392 | // Returns MosfetOut value sent by master
393 | //----------------------------------------------------------------------------
394 | FlagStatus GetMosfetOutMaster(void)
395 | {
396 | return mosfetOutMaster;
397 | }
398 |
399 | //----------------------------------------------------------------------------
400 | // Sets beepsBackwards value which will be send to master
401 | //----------------------------------------------------------------------------
402 | void SetBeepsBackwardsMaster(FlagStatus value)
403 | {
404 | beepsBackwardsMaster = value;
405 | }
406 |
407 | //----------------------------------------------------------------------------
408 | // Returns beepsBackwardsMaster value sent by master
409 | //----------------------------------------------------------------------------
410 | FlagStatus GetBeepsBackwardsMaster(void)
411 | {
412 | return beepsBackwardsMaster;
413 | }
414 | #endif
415 |
--------------------------------------------------------------------------------
/HoverBoardGigaDevice/Src/commsSteering.c:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the hoverboard-firmware-hack-V2 project. The
3 | * firmware is used to hack the generation 2 board of the hoverboard.
4 | * These new hoverboards have no mainboard anymore. They consist of
5 | * two Sensorboards which have their own BLDC-Bridge per Motor and an
6 | * ARM Cortex-M3 processor GD32F130C8.
7 | *
8 | * Copyright (C) 2018 Florian Staeblein
9 | * Copyright (C) 2018 Jakob Broemauer
10 | * Copyright (C) 2018 Kai Liebich
11 | * Copyright (C) 2018 Christoph Lehnert
12 | *
13 | * The program is based on the hoverboard project by Niklas Fauth. The
14 | * structure was tried to be as similar as possible, so that everyone
15 | * could find a better way through the code.
16 | *
17 | * This program is free software: you can redistribute it and/or modify
18 | * it under the terms of the GNU General Public License as published by
19 | * the Free Software Foundation, either version 3 of the License, or
20 | * (at your option) any later version.
21 | *
22 | * This program is distributed in the hope that it will be useful,
23 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 | * GNU General Public License for more details.
26 | *
27 | * You should have received a copy of the GNU General Public License
28 | * along with this program. If not, see .
29 | */
30 |
31 | #include "gd32f1x0.h"
32 | #include "../Inc/it.h"
33 | #include "../Inc/comms.h"
34 | #include "../Inc/commsSteering.h"
35 | #include "../Inc/setup.h"
36 | #include "../Inc/config.h"
37 | #include "../Inc/defines.h"
38 | #include "../Inc/bldc.h"
39 | #include "stdio.h"
40 | #include "string.h"
41 |
42 | // Only master communicates with steerin device
43 | #ifdef MASTER
44 | #define USART_STEER_TX_BYTES 2 // Transmit byte count including start '/' and stop character '\n'
45 | #define USART_STEER_RX_BYTES 8 // Receive byte count including start '/' and stop character '\n'
46 |
47 | extern uint8_t usartSteer_COM_rx_buf[USART_STEER_COM_RX_BUFFERSIZE];
48 | static uint8_t sSteerRecord = 0;
49 | static uint8_t sUSARTSteerRecordBuffer[USART_STEER_RX_BYTES];
50 | static uint8_t sUSARTSteerRecordBufferCounter = 0;
51 |
52 | void CheckUSARTSteerInput(uint8_t u8USARTBuffer[]);
53 |
54 | extern int32_t steer;
55 | extern int32_t speed;
56 |
57 | //----------------------------------------------------------------------------
58 | // Send frame to steer device
59 | //----------------------------------------------------------------------------
60 | void SendSteerDevice(void)
61 | {
62 | int index = 0;
63 | uint8_t buffer[USART_STEER_TX_BYTES];
64 |
65 | // Ask for steer input
66 | buffer[index++] = '/';
67 | buffer[index++] = '\n';
68 |
69 | SendBuffer(USART_STEER_COM, buffer, index);
70 | }
71 |
72 | //----------------------------------------------------------------------------
73 | // Update USART steer input
74 | //----------------------------------------------------------------------------
75 | void UpdateUSARTSteerInput(void)
76 | {
77 | uint8_t character = usartSteer_COM_rx_buf[0];
78 |
79 | // Start character is captured, start record
80 | if (character == '/')
81 | {
82 | sUSARTSteerRecordBufferCounter = 0;
83 | sSteerRecord = 1;
84 | }
85 |
86 | if (sSteerRecord)
87 | {
88 | sUSARTSteerRecordBuffer[sUSARTSteerRecordBufferCounter] = character;
89 | sUSARTSteerRecordBufferCounter++;
90 |
91 | if (sUSARTSteerRecordBufferCounter >= USART_STEER_RX_BYTES)
92 | {
93 | sUSARTSteerRecordBufferCounter = 0;
94 | sSteerRecord = 0;
95 |
96 | // Check input
97 | CheckUSARTSteerInput (sUSARTSteerRecordBuffer);
98 | }
99 | }
100 | }
101 |
102 | //----------------------------------------------------------------------------
103 | // Check USART steer input
104 | //----------------------------------------------------------------------------
105 | void CheckUSARTSteerInput(uint8_t USARTBuffer[])
106 | {
107 | // Auxiliary variables
108 | uint16_t crc;
109 |
110 | // Check start and stop character
111 | if ( USARTBuffer[0] != '/' ||
112 | USARTBuffer[USART_STEER_RX_BYTES - 1] != '\n')
113 | {
114 | return;
115 | }
116 |
117 | // Calculate CRC (first bytes except crc and stop byte)
118 | crc = CalcCRC(USARTBuffer, USART_STEER_RX_BYTES - 3);
119 |
120 | // Check CRC
121 | if ( USARTBuffer[USART_STEER_RX_BYTES - 3] != ((crc >> 8) & 0xFF) ||
122 | USARTBuffer[USART_STEER_RX_BYTES - 2] != (crc & 0xFF))
123 | {
124 | return;
125 | }
126 |
127 | // Calculate result speed value -1000 to 1000
128 | speed = (int16_t)((USARTBuffer[1] << 8) | USARTBuffer[2]);
129 |
130 | // Calculate result steering value -1000 to 1000
131 | steer = (int16_t)((USARTBuffer[3] << 8) | USARTBuffer[4]);
132 |
133 | // Reset the pwm timout to avoid stopping motors
134 | ResetTimeout();
135 | }
136 | #endif
137 |
--------------------------------------------------------------------------------
/HoverBoardGigaDevice/Src/it.c:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the hoverboard-firmware-hack-V2 project. The
3 | * firmware is used to hack the generation 2 board of the hoverboard.
4 | * These new hoverboards have no mainboard anymore. They consist of
5 | * two Sensorboards which have their own BLDC-Bridge per Motor and an
6 | * ARM Cortex-M3 processor GD32F130C8.
7 | *
8 | * Copyright (C) 2018 Florian Staeblein
9 | * Copyright (C) 2018 Jakob Broemauer
10 | * Copyright (C) 2018 Kai Liebich
11 | * Copyright (C) 2018 Christoph Lehnert
12 | *
13 | * The program is based on the hoverboard project by Niklas Fauth. The
14 | * structure was tried to be as similar as possible, so that everyone
15 | * could find a better way through the code.
16 | *
17 | * This program is free software: you can redistribute it and/or modify
18 | * it under the terms of the GNU General Public License as published by
19 | * the Free Software Foundation, either version 3 of the License, or
20 | * (at your option) any later version.
21 | *
22 | * This program is distributed in the hope that it will be useful,
23 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 | * GNU General Public License for more details.
26 | *
27 | * You should have received a copy of the GNU General Public License
28 | * along with this program. If not, see .
29 | */
30 |
31 | #include "gd32f1x0.h"
32 | #include "../Inc/it.h"
33 | #include "../Inc/defines.h"
34 | #include "../Inc/config.h"
35 | #include "../Inc/bldc.h"
36 | #include "../Inc/led.h"
37 | #include "../Inc/commsMasterSlave.h"
38 | #include "../Inc/commsSteering.h"
39 | #include "../Inc/commsBluetooth.h"
40 |
41 | uint32_t msTicks;
42 | uint32_t timeoutCounter_ms = 0;
43 | FlagStatus timedOut = SET;
44 |
45 | #ifdef SLAVE
46 | uint32_t hornCounter_ms = 0;
47 | #endif
48 |
49 | extern int32_t steer;
50 | extern int32_t speed;
51 | extern FlagStatus activateWeakening;
52 | extern FlagStatus beepsBackwards;
53 |
54 | //----------------------------------------------------------------------------
55 | // SysTick_Handler
56 | //----------------------------------------------------------------------------
57 | void SysTick_Handler(void)
58 | {
59 | msTicks++;
60 | }
61 |
62 | //----------------------------------------------------------------------------
63 | // Resets the timeout to zero
64 | //----------------------------------------------------------------------------
65 | void ResetTimeout(void)
66 | {
67 | timeoutCounter_ms = 0;
68 | }
69 |
70 | //----------------------------------------------------------------------------
71 | // Timer13_Update_Handler
72 | // Is called when upcouting of timer13 is finished and the UPDATE-flag is set
73 | // -> period of timer13 running with 1kHz -> interrupt every 1ms
74 | //----------------------------------------------------------------------------
75 | void TIMER13_IRQHandler(void)
76 | {
77 | if (timeoutCounter_ms > TIMEOUT_MS)
78 | {
79 | // First timeout reset all process values
80 | if (timedOut == RESET)
81 | {
82 | #ifdef MASTER
83 | steer = 0;
84 | speed = 0;
85 | beepsBackwards = RESET;
86 | #endif
87 | #ifdef SLAVE
88 | SetPWM(0);
89 | #endif
90 | }
91 |
92 | timedOut = SET;
93 | }
94 | else
95 | {
96 | timedOut = RESET;
97 | timeoutCounter_ms++;
98 | }
99 |
100 | #ifdef SLAVE
101 | if (hornCounter_ms >= 2000)
102 | {
103 | // Avoid horn to be activated longer than 2 seconds
104 | SetUpperLEDMaster(RESET);
105 | }
106 | else if (hornCounter_ms < 2000)
107 | {
108 | hornCounter_ms++;
109 | }
110 |
111 | // Update LED program
112 | CalculateLEDProgram();
113 | #endif
114 |
115 | // Clear timer update interrupt flag
116 | timer_interrupt_flag_clear(TIMER13, TIMER_INT_UP);
117 | }
118 |
119 | //----------------------------------------------------------------------------
120 | // Timer0_Update_Handler
121 | // Is called when upcouting of timer0 is finished and the UPDATE-flag is set
122 | // AND when downcouting of timer0 is finished and the UPDATE-flag is set
123 | // -> pwm of timer0 running with 16kHz -> interrupt every 31,25us
124 | //----------------------------------------------------------------------------
125 | void TIMER0_BRK_UP_TRG_COM_IRQHandler(void)
126 | {
127 | // Start ADC conversion
128 | adc_software_trigger_enable(ADC_REGULAR_CHANNEL);
129 |
130 | // Clear timer update interrupt flag
131 | timer_interrupt_flag_clear(TIMER_BLDC, TIMER_INT_UP);
132 | }
133 |
134 | //----------------------------------------------------------------------------
135 | // This function handles DMA_Channel0_IRQHandler interrupt
136 | // Is called, when the ADC scan sequence is finished
137 | // -> ADC is triggered from timer0-update-interrupt -> every 31,25us
138 | //----------------------------------------------------------------------------
139 | void DMA_Channel0_IRQHandler(void)
140 | {
141 | // Calculate motor PWMs
142 | CalculateBLDC();
143 |
144 | #ifdef SLAVE
145 | // Calculates RGB LED
146 | CalculateLEDPWM();
147 | #endif
148 |
149 | if (dma_interrupt_flag_get(DMA_CH0, DMA_INT_FLAG_FTF))
150 | {
151 | dma_interrupt_flag_clear(DMA_CH0, DMA_INT_FLAG_FTF);
152 | }
153 | }
154 |
155 |
156 | //----------------------------------------------------------------------------
157 | // This function handles DMA_Channel1_2_IRQHandler interrupt
158 | // Is asynchronously called when USART0 RX finished
159 | //----------------------------------------------------------------------------
160 | void DMA_Channel1_2_IRQHandler(void)
161 | {
162 | // USART steer/bluetooth RX
163 | if (dma_interrupt_flag_get(DMA_CH2, DMA_INT_FLAG_FTF))
164 | {
165 | #ifdef MASTER
166 | // Update USART steer input mechanism
167 | UpdateUSARTSteerInput();
168 | #endif
169 | #ifdef SLAVE
170 | // Update USART bluetooth input mechanism
171 | UpdateUSARTBluetoothInput();
172 | #endif
173 | dma_interrupt_flag_clear(DMA_CH2, DMA_INT_FLAG_FTF);
174 | }
175 | }
176 |
177 |
178 | //----------------------------------------------------------------------------
179 | // This function handles DMA_Channel3_4_IRQHandler interrupt
180 | // Is asynchronously called when USART_SLAVE RX finished
181 | //----------------------------------------------------------------------------
182 | void DMA_Channel3_4_IRQHandler(void)
183 | {
184 | // USART master slave RX
185 | if (dma_interrupt_flag_get(DMA_CH4, DMA_INT_FLAG_FTF))
186 | {
187 | // Update USART master slave input mechanism
188 | UpdateUSARTMasterSlaveInput();
189 |
190 | dma_interrupt_flag_clear(DMA_CH4, DMA_INT_FLAG_FTF);
191 | }
192 | }
193 |
194 | //----------------------------------------------------------------------------
195 | // Returns number of milliseconds since system start
196 | //----------------------------------------------------------------------------
197 | uint32_t millis()
198 | {
199 | return msTicks;
200 | }
201 |
202 | //----------------------------------------------------------------------------
203 | // Delays number of tick Systicks (happens every 10 ms)
204 | //----------------------------------------------------------------------------
205 | void Delay (uint32_t dlyTicks)
206 | {
207 | uint32_t curTicks;
208 |
209 | curTicks = msTicks;
210 | while ((msTicks - curTicks) < dlyTicks)
211 | {
212 | __NOP();
213 | }
214 | }
215 |
216 | //----------------------------------------------------------------------------
217 | // This function handles Non maskable interrupt.
218 | //----------------------------------------------------------------------------
219 | void NMI_Handler(void)
220 | {
221 | }
222 |
223 | //----------------------------------------------------------------------------
224 | // This function handles Hard fault interrupt.
225 | //----------------------------------------------------------------------------
226 | void HardFault_Handler(void)
227 | {
228 | while(1) {}
229 | }
230 |
231 | //----------------------------------------------------------------------------
232 | // This function handles Memory management fault.
233 | //----------------------------------------------------------------------------
234 | void MemManage_Handler(void)
235 | {
236 | while(1) {}
237 | }
238 |
239 | //----------------------------------------------------------------------------
240 | // This function handles Prefetch fault, memory access fault.
241 | //----------------------------------------------------------------------------
242 | void BusFault_Handler(void)
243 | {
244 | while(1) {}
245 | }
246 |
247 | //----------------------------------------------------------------------------
248 | // This function handles Undefined instruction or illegal state.
249 | //----------------------------------------------------------------------------
250 | void UsageFault_Handler(void)
251 | {
252 | while(1) {}
253 | }
254 |
255 | //----------------------------------------------------------------------------
256 | // This function handles System service call via SWI instruction.
257 | //----------------------------------------------------------------------------
258 | void SVC_Handler(void)
259 | {
260 | }
261 |
262 | //----------------------------------------------------------------------------
263 | // This function handles Debug monitor.
264 | //----------------------------------------------------------------------------
265 | void DebugMon_Handler(void)
266 | {
267 | }
268 |
269 | //----------------------------------------------------------------------------
270 | // This function handles Pendable request for system service.
271 | //----------------------------------------------------------------------------
272 | void PendSV_Handler(void)
273 | {
274 | }
275 |
--------------------------------------------------------------------------------
/HoverBoardGigaDevice/Src/led.c:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the hoverboard-firmware-hack-V2 project. The
3 | * firmware is used to hack the generation 2 board of the hoverboard.
4 | * These new hoverboards have no mainboard anymore. They consist of
5 | * two Sensorboards which have their own BLDC-Bridge per Motor and an
6 | * ARM Cortex-M3 processor GD32F130C8.
7 | *
8 | * Copyright (C) 2018 Florian Staeblein
9 | * Copyright (C) 2018 Jakob Broemauer
10 | * Copyright (C) 2018 Kai Liebich
11 | * Copyright (C) 2018 Christoph Lehnert
12 | *
13 | * The program is based on the hoverboard project by Niklas Fauth. The
14 | * structure was tried to be as similar as possible, so that everyone
15 | * could find a better way through the code.
16 | *
17 | * This program is free software: you can redistribute it and/or modify
18 | * it under the terms of the GNU General Public License as published by
19 | * the Free Software Foundation, either version 3 of the License, or
20 | * (at your option) any later version.
21 | *
22 | * This program is distributed in the hope that it will be useful,
23 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 | * GNU General Public License for more details.
26 | *
27 | * You should have received a copy of the GNU General Public License
28 | * along with this program. If not, see .
29 | */
30 |
31 | #include "gd32f1x0.h"
32 | #include "../Inc/led.h"
33 | #include "../Inc/defines.h"
34 |
35 | // Only slave has LED mechanism
36 | #ifdef SLAVE
37 |
38 | // Lookuptable for brightness
39 | static unsigned char su8BrightnessTable[64] =
40 | {0,0,1,1,1,2,2,2,2,2,2,3,3,3,3,4,4,4,5,5,6,
41 | 6,7,8,8,9,10,11,12,13,14,15,17,18,20,22,24,
42 | 26,28,31,34,37,40,44,48,52,57,62,68,74,81,89,
43 | 97,106,116,126,138,150,164,179,196,214,234,255};
44 |
45 | // Variables for RGB output
46 | uint8_t counter_Red = 0;
47 | uint8_t counter_Green = 0;
48 | uint8_t counter_Blue = 0;
49 | uint8_t setValue_Red = 0;
50 | uint8_t setValue_Green = 0;
51 | uint8_t setValue_Blue = 0;
52 |
53 | // Variables for HSB calculation
54 | static uint16_t hueValue = 0;
55 | static uint8_t saturationValue = 128;
56 | static uint8_t brightnessValue = 63;
57 |
58 | // Variable for LED-program
59 | static LED_PROGRAM sLEDProgram = LED_OFF;
60 |
61 | // Variables for effects
62 | static uint16_t speedFading = 150; // Fading-Delay
63 | static uint16_t speedBlink = 1274; // Blink-Delay
64 | static uint16_t speedStrobe = 40; // Strobe-Delay
65 |
66 | // Counter for effects
67 | static uint16_t fadingCounter = 0;
68 | static uint16_t blinkCounter = 0;
69 | static uint16_t strobeCounter = 0;
70 | static FlagStatus strobeToggle = RESET;
71 |
72 | // Prototypes
73 | uint8_t HSBtoRed(uint16_t hue, uint8_t sat);
74 | uint8_t HSBtoGreen(uint16_t hue, uint8_t sat);
75 | uint8_t HSBtoBlue(uint16_t hue, uint8_t sat);
76 |
77 | //----------------------------------------------------------------------------
78 | // Update RGB LED output with 16kHz
79 | //----------------------------------------------------------------------------
80 | void CalculateLEDPWM(void)
81 | {
82 | // Upcounting with overflow
83 | counter_Red++;
84 | counter_Green++;
85 | counter_Blue++;
86 |
87 | // Set LEDs
88 | gpio_bit_write(UPPER_LED_PORT, UPPER_LED_PIN, counter_Red >= setValue_Red ? RESET : SET);
89 | gpio_bit_write(LOWER_LED_PORT, LOWER_LED_PIN, counter_Green >= setValue_Green ? RESET : SET);
90 | gpio_bit_write(MOSFET_OUT_PORT, MOSFET_OUT_PIN, counter_Blue >= setValue_Blue ? RESET : SET);
91 | }
92 |
93 | //----------------------------------------------------------------------------
94 | // Update RGB LED program every 1ms
95 | //----------------------------------------------------------------------------
96 | void CalculateLEDProgram(void)
97 | {
98 | if (GetRGBProgram() == LED_HSB_FADE)
99 | {
100 | fadingCounter++;
101 | if(fadingCounter >= GetSpeedFading())
102 | {
103 | fadingCounter = 0;
104 | SetHSBHue(GetHSBHue()+1);
105 | }
106 | }
107 | if (GetRGBProgram() == LED_HSB_BLINK)
108 | {
109 | blinkCounter++;
110 | if(blinkCounter >= GetSpeedBlink())
111 | {
112 | blinkCounter = 0;
113 | SetHSBHue(GetHSBHue()+50);
114 | }
115 | }
116 | if(GetRGBProgram() == LED_HSB_STROBE)
117 | {
118 | strobeCounter++;
119 | if(strobeCounter >= GetSpeedStrobe())
120 | {
121 | strobeCounter = 0;
122 | if(strobeToggle == RESET)
123 | {
124 | strobeToggle = SET;
125 | SetHSBBrightness(0);
126 | }
127 | else
128 | {
129 | strobeToggle = RESET;
130 | SetHSBBrightness(63);
131 | }
132 | }
133 | }
134 | }
135 |
136 | //----------------------------------------------------------------------------
137 | // Sets LED program
138 | //----------------------------------------------------------------------------
139 | void SetRGBProgram(LED_PROGRAM Program)
140 | {
141 | // Check program count
142 | if(!(Program < COUNT_PROGRAMS))
143 | {
144 | Program = LED_OFF;
145 | }
146 |
147 | // Save program for later
148 | sLEDProgram = Program;
149 |
150 | switch(Program)
151 | {
152 | case LED_HSB:
153 | case LED_HSB_BLINK:
154 | case LED_HSB_FADE:
155 | case LED_HSB_STROBE:
156 | SetHSBHue(hueValue);
157 | SetHSBSaturation(saturationValue);
158 | SetHSBBrightness(brightnessValue);
159 | break;
160 | case LED_OFF:
161 | default:
162 | setValue_Red = 0;
163 | setValue_Green = 0;
164 | setValue_Blue = 0;
165 | break;
166 | }
167 | }
168 |
169 | //----------------------------------------------------------------------------
170 | // Gets LED program
171 | //----------------------------------------------------------------------------
172 | LED_PROGRAM GetRGBProgram(void)
173 | {
174 | return sLEDProgram;
175 | }
176 |
177 | //----------------------------------------------------------------------------
178 | // Sets hue from 0-764
179 | //----------------------------------------------------------------------------
180 | void SetHSBHue(uint16_t hue)
181 | {
182 | uint8_t brightness = 0;
183 |
184 | // Save hue for later
185 | if (hue > 764)
186 | {
187 | hueValue = 0;
188 | }
189 | else
190 | {
191 | hueValue = hue;
192 | }
193 |
194 | // Calculate brightness with the lookuptable
195 | brightness = su8BrightnessTable[brightnessValue]; //input: 0..63 output: 0..255
196 |
197 | // Calculate RGB values
198 | setValue_Red = ((brightness + 1) * HSBtoRed(hueValue, saturationValue)) >> 8;
199 | setValue_Green = ((brightness + 1) * HSBtoGreen(hueValue, saturationValue)) >> 8;
200 | setValue_Blue = ((brightness + 1) * HSBtoBlue(hueValue, saturationValue)) >> 8;
201 | }
202 |
203 | //----------------------------------------------------------------------------
204 | // Gets hue from 0-764
205 | //----------------------------------------------------------------------------
206 | uint16_t GetHSBHue(void)
207 | {
208 | return hueValue;
209 | }
210 |
211 | //----------------------------------------------------------------------------
212 | // Sets saturation from 0-128
213 | //----------------------------------------------------------------------------
214 | void SetHSBSaturation(uint8_t saturation)
215 | {
216 | uint8_t brightness = 0;
217 |
218 | // Save Saturation for later
219 | saturationValue = MAX(saturation, 128);
220 |
221 | // Calculate brightness with the lookuptable
222 | brightness = su8BrightnessTable[brightnessValue]; //input: 0..63 output: 0..255
223 |
224 | // Calculate RGB values
225 | setValue_Red = ((brightness + 1) * HSBtoRed(hueValue, saturationValue)) >> 8;
226 | setValue_Green = ((brightness + 1) * HSBtoGreen(hueValue, saturationValue)) >> 8;
227 | setValue_Blue = ((brightness + 1) * HSBtoBlue(hueValue, saturationValue)) >> 8;
228 | }
229 |
230 | //----------------------------------------------------------------------------
231 | // Gets saturation from 0-128
232 | //----------------------------------------------------------------------------
233 | uint8_t GetHSBSaturation(void)
234 | {
235 | return saturationValue;
236 | }
237 |
238 | //----------------------------------------------------------------------------
239 | // Sets brightness from 0-63
240 | //----------------------------------------------------------------------------
241 | void SetHSBBrightness(uint8_t brightnessVal)
242 | {
243 | uint8_t brightness = 0;
244 |
245 | // Save brightness for later
246 | brightnessValue = MAX(brightnessVal, 63);
247 |
248 | // Calculate brightness with the lookuptable
249 | brightness = su8BrightnessTable[brightnessValue]; //input: 0..63 output: 0..255
250 |
251 | // Calculate RGB values
252 | setValue_Red = ((brightness + 1) * HSBtoRed(hueValue, saturationValue)) >> 8;
253 | setValue_Green = ((brightness + 1) * HSBtoGreen(hueValue, saturationValue)) >> 8;
254 | setValue_Blue = ((brightness + 1) * HSBtoBlue(hueValue, saturationValue)) >> 8;
255 | }
256 |
257 | //----------------------------------------------------------------------------
258 | // Gets brightness from 0-63
259 | //----------------------------------------------------------------------------
260 | uint8_t GetHSBBrightness(void)
261 | {
262 | return brightnessValue;
263 | }
264 |
265 | //----------------------------------------------------------------------------
266 | // Sets fading speed from 200-1000
267 | //----------------------------------------------------------------------------
268 | void SetSpeedFading(uint16_t speed)
269 | {
270 | speedFading = CLAMP(speed, 200, 1000);
271 | }
272 |
273 | //----------------------------------------------------------------------------
274 | // Gets fading speed from 200-1000
275 | //----------------------------------------------------------------------------
276 | uint16_t GetSpeedFading(void)
277 | {
278 | return speedFading;
279 | }
280 |
281 | //----------------------------------------------------------------------------
282 | // Sets blink speed from 700-2400
283 | //----------------------------------------------------------------------------
284 | void SetSpeedBlink(uint16_t speed)
285 | {
286 | speedBlink = CLAMP(speed, 700, 2400);
287 | }
288 |
289 | //----------------------------------------------------------------------------
290 | // Gets blink speed from 700-2400
291 | //----------------------------------------------------------------------------
292 | uint16_t GetSpeedBlink(void)
293 | {
294 | return speedBlink;
295 | }
296 |
297 | //----------------------------------------------------------------------------
298 | // Sets strobe speed from 0-1000
299 | //----------------------------------------------------------------------------
300 | void SetSpeedStrobe(uint16_t speed)
301 | {
302 | speedStrobe = CLAMP(speed, 40, 400);
303 | }
304 |
305 | //----------------------------------------------------------------------------
306 | // Gets strobe speed from 0-1000
307 | //----------------------------------------------------------------------------
308 | uint16_t GetSpeedStrobe(void)
309 | {
310 | return speedStrobe;
311 | }
312 |
313 | //----------------------------------------------------------------------------
314 | // Hue to red
315 | //----------------------------------------------------------------------------
316 | uint8_t HSBtoRed(uint16_t hue, uint8_t sat)
317 | {
318 | unsigned char red_val = 0;
319 |
320 | if (hue > 764)
321 | {
322 | hue = 0;
323 | }
324 | if (hue < 255)
325 | {
326 | red_val = (10880 - sat * (hue - 170)) >> 7;
327 | }
328 | else if (hue < 510)
329 | {
330 | red_val = (10880 - sat * 85) >> 7;
331 | }
332 | else
333 | {
334 | red_val = (10880 - sat * (595 - hue)) >> 7;
335 | }
336 |
337 | return red_val;
338 | }
339 |
340 | //----------------------------------------------------------------------------
341 | // Hue to green
342 | //----------------------------------------------------------------------------
343 | uint8_t HSBtoGreen(uint16_t hue, uint8_t sat)
344 | {
345 | uint8_t green_val = 0;
346 |
347 | if (hue > 764)
348 | {
349 | hue = 0;
350 | }
351 | if (hue < 255)
352 | {
353 | green_val = (10880 - sat * (85 - hue)) >> 7;
354 | }
355 | else if (hue < 510)
356 | {
357 | green_val = (10880 - sat * (hue - 425)) >> 7;
358 | }
359 | else
360 | {
361 | green_val = (10880 - sat * 85) >> 7;
362 | }
363 |
364 | return green_val;
365 | }
366 |
367 | //----------------------------------------------------------------------------
368 | // Hue to blue
369 | //----------------------------------------------------------------------------
370 | uint8_t HSBtoBlue(uint16_t hue, uint8_t sat)
371 | {
372 | uint8_t blue_val = 0;
373 |
374 | if (hue > 764)
375 | {
376 | hue = 0;
377 | }
378 | if (hue < 255)
379 | {
380 | blue_val = (10880 - sat * 85) >> 7;
381 | }
382 | else if (hue < 510)
383 | {
384 | blue_val = (10880 - sat * (340 - hue)) >> 7;
385 | }
386 | else
387 | {
388 | blue_val = (10880 - sat * (hue - 680)) >> 7;
389 | }
390 |
391 | return blue_val;
392 | }
393 | #endif
394 |
--------------------------------------------------------------------------------
/HoverBoardGigaDevice/Src/main.c:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the hoverboard-firmware-hack-V2 project. The
3 | * firmware is used to hack the generation 2 board of the hoverboard.
4 | * These new hoverboards have no mainboard anymore. They consist of
5 | * two Sensorboards which have their own BLDC-Bridge per Motor and an
6 | * ARM Cortex-M3 processor GD32F130C8.
7 | *
8 | * Copyright (C) 2018 Florian Staeblein
9 | * Copyright (C) 2018 Jakob Broemauer
10 | * Copyright (C) 2018 Kai Liebich
11 | * Copyright (C) 2018 Christoph Lehnert
12 | *
13 | * The program is based on the hoverboard project by Niklas Fauth. The
14 | * structure was tried to be as similar as possible, so that everyone
15 | * could find a better way through the code.
16 | *
17 | * This program is free software: you can redistribute it and/or modify
18 | * it under the terms of the GNU General Public License as published by
19 | * the Free Software Foundation, either version 3 of the License, or
20 | * (at your option) any later version.
21 | *
22 | * This program is distributed in the hope that it will be useful,
23 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 | * GNU General Public License for more details.
26 | *
27 | * You should have received a copy of the GNU General Public License
28 | * along with this program. If not, see .
29 | */
30 |
31 | #define ARM_MATH_CM3
32 |
33 | #include "gd32f1x0.h"
34 |
35 | #include "../Inc/setup.h"
36 | #include "../Inc/defines.h"
37 | #include "../Inc/config.h"
38 | #include "../Inc/it.h"
39 | #include "../Inc/bldc.h"
40 | #include "../Inc/commsMasterSlave.h"
41 | #include "../Inc/commsSteering.h"
42 | #include "../Inc/commsBluetooth.h"
43 | #include "stdio.h"
44 | #include "stdlib.h"
45 | #include "string.h"
46 | #include
47 | #include "arm_math.h"
48 |
49 | #ifdef MASTER
50 | int32_t steer = 0; // global variable for steering. -1000 to 1000
51 | int32_t speed = 0; // global variable for speed. -1000 to 1000
52 | FlagStatus activateWeakening = RESET; // global variable for weakening
53 | FlagStatus beepsBackwards = RESET; // global variable for beeps backwards
54 |
55 | extern uint8_t buzzerFreq; // global variable for the buzzer pitch. can be 1, 2, 3, 4, 5, 6, 7...
56 | extern uint8_t buzzerPattern; // global variable for the buzzer pattern. can be 1, 2, 3, 4, 5, 6, 7...
57 |
58 | extern float batteryVoltage; // global variable for battery voltage
59 | extern float currentDC; // global variable for current dc
60 | extern float realSpeed; // global variable for real Speed
61 | uint8_t slaveError = 0; // global variable for slave error
62 |
63 | extern FlagStatus timedOut; // Timeoutvariable set by timeout timer
64 |
65 | uint32_t inactivity_timeout_counter = 0; // Inactivity counter
66 | uint32_t steerCounter = 0; // Steer counter for setting update rate
67 |
68 | void ShowBatteryState(uint32_t pin);
69 | void BeepsBackwards(FlagStatus beepsBackwards);
70 | void ShutOff(void);
71 | #endif
72 |
73 | const float lookUpTableAngle[181] =
74 | {
75 | -1,
76 | -0.937202577,
77 | -0.878193767,
78 | -0.822607884,
79 | -0.770124422,
80 | -0.720461266,
81 | -0.673369096,
82 | -0.628626737,
83 | -0.58603728,
84 | -0.545424828,
85 | -0.506631749,
86 | -0.46951635,
87 | -0.433950895,
88 | -0.399819915,
89 | -0.367018754,
90 | -0.335452314,
91 | -0.30503398,
92 | -0.275684674,
93 | -0.24733204,
94 | -0.219909731,
95 | -0.193356783,
96 | -0.167617063,
97 | -0.142638788,
98 | -0.118374098,
99 | -0.094778672,
100 | -0.071811398,
101 | -0.049434068,
102 | -0.027611115,
103 | -0.006309372,
104 | 0.014502141,
105 | 0.03485241,
106 | 0.054768601,
107 | 0.074276213,
108 | 0.093399224,
109 | 0.112160212,
110 | 0.130580478,
111 | 0.148680146,
112 | 0.166478264,
113 | 0.183992885,
114 | 0.201241154,
115 | 0.218239378,
116 | 0.235003093,
117 | 0.251547129,
118 | 0.267885663,
119 | 0.284032276,
120 | 0.3,
121 | 0.315801365,
122 | 0.331448439,
123 | 0.34695287,
124 | 0.362325923,
125 | 0.377578512,
126 | 0.392721236,
127 | 0.407764409,
128 | 0.422718089,
129 | 0.437592106,
130 | 0.45239609,
131 | 0.467139493,
132 | 0.48183162,
133 | 0.496481645,
134 | 0.511098642,
135 | 0.5256916,
136 | 0.540269454,
137 | 0.554841097,
138 | 0.569415411,
139 | 0.584001283,
140 | 0.598607627,
141 | 0.613243408,
142 | 0.627917665,
143 | 0.642639528,
144 | 0.657418247,
145 | 0.672263213,
146 | 0.687183982,
147 | 0.702190301,
148 | 0.717292134,
149 | 0.732499689,
150 | 0.747823448,
151 | 0.763274197,
152 | 0.778863056,
153 | 0.794601516,
154 | 0.810501473,
155 | 0.826575268,
156 | 0.842835728,
157 | 0.859296209,
158 | 0.875970644,
159 | 0.892873598,
160 | 0.910020317,
161 | 0.927426794,
162 | 0.94510983,
163 | 0.963087109,
164 | 0.981377271,
165 | 1,
166 | 1.018976116,
167 | 1.038327677,
168 | 1.058078086,
169 | 1.07825222,
170 | 1.098876565,
171 | 1.119979359,
172 | 1.141590767,
173 | 1.163743061,
174 | 1.186470823,
175 | 1.209811179,
176 | 1.23380405,
177 | 1.258492439,
178 | 1.283922754,
179 | 1.310145166,
180 | 1.33721402,
181 | 1.365188293,
182 | 1.394132116,
183 | 1.42411537,
184 | 1.455214362,
185 | 1.487512601,
186 | 1.521101681,
187 | 1.556082309,
188 | 1.592565485,
189 | 1.630673867,
190 | 1.670543366,
191 | 1.712325006,
192 | 1.7561871,
193 | 1.802317825,
194 | 1.85092826,
195 | 1.902255998,
196 | 1.956569473,
197 | 2.014173151,
198 | 2.075413814,
199 | 2.140688197,
200 | 2.210452351,
201 | 2.28523318,
202 | 2.365642792,
203 | 2.452396478,
204 | 2.546335439,
205 | 2.648455802,
206 | 2.75994605,
207 | 2.882235846,
208 | 3.01706052,
209 | 3.166547428,
210 | 3.333333333,
211 | 3.520726642,
212 | 3.732935875,
213 | 3.97539819,
214 | 4.255263139,
215 | 4.582124498,
216 | 4.96916252,
217 | 5.434992778,
218 | 6.006790189,
219 | 6.72584757,
220 | 7.658112588,
221 | 8.915817681,
222 | 10.70672711,
223 | 13.46326037,
224 | 18.25863694,
225 | 28.69242032,
226 | 68.95533643,
227 | -158.4943784,
228 | -36.21729907,
229 | -20.22896451,
230 | -13.92536607,
231 | -10.55089693,
232 | -8.447794056,
233 | -7.010715755,
234 | -5.965979741,
235 | -5.171786508,
236 | -4.547320366,
237 | -4.043147824,
238 | -3.62733258,
239 | -3.278323283,
240 | -2.981049637,
241 | -2.72465641,
242 | -2.501126036,
243 | -2.304408198,
244 | -2.129851283,
245 | -1.973820239,
246 | -1.833433222,
247 | -1.706376086,
248 | -1.590769119,
249 | -1.485069639,
250 | -1.387999671,
251 | -1.29849148,
252 | -1.21564602,
253 | -1.138700863,
254 | -1.067005175,
255 | -1
256 | };
257 |
258 |
259 | //----------------------------------------------------------------------------
260 | // MAIN function
261 | //----------------------------------------------------------------------------
262 | int main (void)
263 | {
264 | #ifdef MASTER
265 | FlagStatus enable = RESET;
266 | FlagStatus enableSlave = RESET;
267 | FlagStatus chargeStateLowActive = SET;
268 | int16_t sendSlaveValue = 0;
269 | uint8_t sendSlaveIdentifier = 0;
270 | int8_t index = 8;
271 | int16_t pwmSlave = 0;
272 | int16_t pwmMaster = 0;
273 | int16_t scaledSpeed = 0;
274 | int16_t scaledSteer = 0;
275 | float expo = 0;
276 | float steerAngle = 0;
277 | float xScale = 0;
278 | #endif
279 |
280 | //SystemClock_Config();
281 | SystemCoreClockUpdate();
282 | SysTick_Config(SystemCoreClock / 100);
283 |
284 | // Init watchdog
285 | if (Watchdog_init() == ERROR)
286 | {
287 | // If an error accours with watchdog initialization do not start device
288 | while(1);
289 | }
290 |
291 | // Init Interrupts
292 | Interrupt_init();
293 |
294 | // Init timeout timer
295 | TimeoutTimer_init();
296 |
297 | // Init GPIOs
298 | GPIO_init();
299 |
300 | // Activate self hold direct after GPIO-init
301 | gpio_bit_write(SELF_HOLD_PORT, SELF_HOLD_PIN, SET);
302 |
303 | // Init usart master slave
304 | USART_MasterSlave_init();
305 |
306 | // Init ADC
307 | ADC_init();
308 |
309 | // Init PWM
310 | PWM_init();
311 |
312 | // Device has 1,6 seconds to do all the initialization
313 | // afterwards watchdog will be fired
314 | fwdgt_counter_reload();
315 |
316 | // Init usart steer/bluetooth
317 | USART_Steer_COM_init();
318 |
319 | #ifdef MASTER
320 | // Startup-Sound
321 | for (; index >= 0; index--)
322 | {
323 | buzzerFreq = index;
324 | Delay(10);
325 | }
326 | buzzerFreq = 0;
327 |
328 | // Wait until button is pressed
329 | while (gpio_input_bit_get(BUTTON_PORT, BUTTON_PIN))
330 | {
331 | // Reload watchdog while button is pressed
332 | fwdgt_counter_reload();
333 | }
334 | #endif
335 |
336 | while(1)
337 | {
338 | #ifdef MASTER
339 | steerCounter++;
340 | if ((steerCounter % 2) == 0)
341 | {
342 | // Request steering data
343 | SendSteerDevice();
344 | }
345 |
346 | // Calculate expo rate for less steering with higher speeds
347 | expo = MAP((float)ABS(speed), 0, 1000, 1, 0.5);
348 |
349 | // Each speedvalue or steervalue between 50 and -50 means absolutely no pwm
350 | // -> to get the device calm 'around zero speed'
351 | scaledSpeed = speed < 50 && speed > -50 ? 0 : CLAMP(speed, -1000, 1000) * SPEED_COEFFICIENT;
352 | scaledSteer = steer < 50 && steer > -50 ? 0 : CLAMP(steer, -1000, 1000) * STEER_COEFFICIENT * expo;
353 |
354 | // Map to an angle of 180 degress to 0 degrees for array access (means angle -90 to 90 degrees)
355 | steerAngle = MAP((float)scaledSteer, -1000, 1000, 180, 0);
356 | xScale = lookUpTableAngle[(uint16_t)steerAngle];
357 |
358 | // Mix steering and speed value for right and left speed
359 | if(steerAngle >= 90)
360 | {
361 | pwmSlave = CLAMP(scaledSpeed, -1000, 1000);
362 | pwmMaster = CLAMP(pwmSlave / xScale, -1000, 1000);
363 | }
364 | else
365 | {
366 | pwmMaster = CLAMP(scaledSpeed, -1000, 1000);
367 | pwmSlave = CLAMP(xScale * pwmMaster, -1000, 1000);
368 | }
369 |
370 | // Read charge state
371 | chargeStateLowActive = gpio_input_bit_get(CHARGE_STATE_PORT, CHARGE_STATE_PIN);
372 |
373 | // Enable is depending on charger is connected or not
374 | enable = chargeStateLowActive;
375 |
376 | // Enable channel output
377 | SetEnable(enable);
378 |
379 | // Decide if slave will be enabled
380 | enableSlave = (enable == SET && timedOut == RESET) ? SET : RESET;
381 |
382 | // Decide which process value has to be sent
383 | switch(sendSlaveIdentifier)
384 | {
385 | case 0:
386 | sendSlaveValue = currentDC * 100;
387 | break;
388 | case 1:
389 | sendSlaveValue = batteryVoltage * 100;
390 | break;
391 | case 2:
392 | sendSlaveValue = realSpeed * 100;
393 | break;
394 | default:
395 | break;
396 | }
397 |
398 | // Set output
399 | SetPWM(pwmMaster);
400 | SendSlave(-pwmSlave, enableSlave, RESET, chargeStateLowActive, sendSlaveIdentifier, sendSlaveValue);
401 |
402 | // Increment identifier
403 | sendSlaveIdentifier++;
404 | if (sendSlaveIdentifier > 2)
405 | {
406 | sendSlaveIdentifier = 0;
407 | }
408 |
409 | // Show green battery symbol when battery level BAT_LOW_LVL1 is reached
410 | if (batteryVoltage > BAT_LOW_LVL1)
411 | {
412 | // Show green battery light
413 | ShowBatteryState(LED_GREEN);
414 |
415 | // Beeps backwards
416 | BeepsBackwards(beepsBackwards);
417 | }
418 | // Make silent sound and show orange battery symbol when battery level BAT_LOW_LVL2 is reached
419 | else if (batteryVoltage > BAT_LOW_LVL2 && batteryVoltage < BAT_LOW_LVL1)
420 | {
421 | // Show orange battery light
422 | ShowBatteryState(LED_ORANGE);
423 |
424 | buzzerFreq = 5;
425 | buzzerPattern = 8;
426 | }
427 | // Make even more sound and show red battery symbol when battery level BAT_LOW_DEAD is reached
428 | else if (batteryVoltage > BAT_LOW_DEAD && batteryVoltage < BAT_LOW_LVL2)
429 | {
430 | // Show red battery light
431 | ShowBatteryState(LED_RED);
432 |
433 | buzzerFreq = 5;
434 | buzzerPattern = 1;
435 | }
436 | // Shut device off, when battery is dead
437 | else if (batteryVoltage < BAT_LOW_DEAD)
438 | {
439 | ShutOff();
440 | }
441 | else
442 | {
443 | ShutOff();
444 | }
445 |
446 | // Shut device off when button is pressed
447 | if (gpio_input_bit_get(BUTTON_PORT, BUTTON_PIN))
448 | {
449 | while (gpio_input_bit_get(BUTTON_PORT, BUTTON_PIN)) {}
450 | ShutOff();
451 | }
452 |
453 | // Calculate inactivity timeout (Except, when charger is active -> keep device running)
454 | if (ABS(pwmMaster) > 50 || ABS(pwmSlave) > 50 || !chargeStateLowActive)
455 | {
456 | inactivity_timeout_counter = 0;
457 | }
458 | else
459 | {
460 | inactivity_timeout_counter++;
461 | }
462 |
463 | // Shut off device after INACTIVITY_TIMEOUT in minutes
464 | if (inactivity_timeout_counter > (INACTIVITY_TIMEOUT * 60 * 1000) / (DELAY_IN_MAIN_LOOP + 1))
465 | {
466 | ShutOff();
467 | }
468 | #endif
469 |
470 | Delay(DELAY_IN_MAIN_LOOP);
471 |
472 | // Reload watchdog (watchdog fires after 1,6 seconds)
473 | fwdgt_counter_reload();
474 | }
475 | }
476 |
477 | #ifdef MASTER
478 | //----------------------------------------------------------------------------
479 | // Turns the device off
480 | //----------------------------------------------------------------------------
481 | void ShutOff(void)
482 | {
483 | int index = 0;
484 |
485 | buzzerPattern = 0;
486 | for (; index < 8; index++)
487 | {
488 | buzzerFreq = index;
489 | Delay(10);
490 | }
491 | buzzerFreq = 0;
492 |
493 | // Send shut off command to slave
494 | SendSlave(0, RESET, SET, RESET, RESET, RESET);
495 |
496 | // Disable usart
497 | usart_deinit(USART_MASTERSLAVE);
498 |
499 | // Set pwm and enable to off
500 | SetEnable(RESET);
501 | SetPWM(0);
502 |
503 | gpio_bit_write(SELF_HOLD_PORT, SELF_HOLD_PIN, RESET);
504 | while(1)
505 | {
506 | // Reload watchdog until device is off
507 | fwdgt_counter_reload();
508 | }
509 | }
510 |
511 | //----------------------------------------------------------------------------
512 | // Shows the battery state on the LEDs
513 | //----------------------------------------------------------------------------
514 | void ShowBatteryState(uint32_t pin)
515 | {
516 | gpio_bit_write(LED_GREEN_PORT, LED_GREEN, pin == LED_GREEN ? SET : RESET);
517 | gpio_bit_write(LED_ORANGE_PORT, LED_ORANGE, pin == LED_ORANGE ? SET : RESET);
518 | gpio_bit_write(LED_RED_PORT, LED_RED, pin == LED_RED ? SET : RESET);
519 | }
520 |
521 | //----------------------------------------------------------------------------
522 | // Beeps while driving backwards
523 | //----------------------------------------------------------------------------
524 | void BeepsBackwards(FlagStatus beepsBackwards)
525 | {
526 | // If the speed is less than -50, beep while driving backwards
527 | if (beepsBackwards == SET && speed < -50)
528 | {
529 | buzzerFreq = 5;
530 | buzzerPattern = 4;
531 | }
532 | else
533 | {
534 | buzzerFreq = 0;
535 | buzzerPattern = 0;
536 | }
537 | }
538 | #endif
539 |
--------------------------------------------------------------------------------
/PPMDeviceArduino_V1.0/PPMDevice/PPMDevice.ino:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the hoverboard-firmware-hack-V2 project. The
3 | * firmware is used to hack the generation 2 board of the hoverboard.
4 | * These new hoverboards have no mainboard anymore. They consist of
5 | * two Sensorboards which have their own BLDC-Bridge per Motor and an
6 | * ARM Cortex-M3 processor GD32F130C8.
7 | *
8 | * Copyright (C) 2018 Florian Staeblein
9 | * Copyright (C) 2018 Jakob Broemauer
10 | * Copyright (C) 2018 Kai Liebich
11 | * Copyright (C) 2018 Christoph Lehnert
12 | *
13 | * The program is based on the hoverboard project by Niklas Fauth. The
14 | * structure was tried to be as similar as possible, so that everyone
15 | * could find a better way through the code.
16 | *
17 | * This program is free software: you can redistribute it and/or modify
18 | * it under the terms of the GNU General Public License as published by
19 | * the Free Software Foundation, either version 3 of the License, or
20 | * (at your option) any later version.
21 | *
22 | * This program is distributed in the hope that it will be useful,
23 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 | * GNU General Public License for more details.
26 | *
27 | * You should have received a copy of the GNU General Public License
28 | * along with this program. If not, see .
29 | */
30 |
31 | #include "RCReceiver.h"
32 | #include "SteeringSerial.h"
33 | #include "utils.h"
34 |
35 | void setup()
36 | {
37 | // Initialize steering serial
38 | InitSteeringSerial();
39 |
40 | // Enable Debug LED
41 | pinMode(LED_BUILTIN, OUTPUT);
42 | digitalWrite(LED_BUILTIN, 1);
43 |
44 | // Initialize RC receiver
45 | InitRCReceiver();
46 |
47 | // Start RC receiver
48 | RCReceiverStart();
49 | }
50 |
51 | void loop()
52 | {
53 | uint16_t channel1 = GetRCValue(0);
54 | uint16_t channel2 = GetRCValue(1);
55 | uint16_t channel3 = GetRCValue(2);
56 |
57 | // Activate/deactivate speed mode
58 | float factor = channel3 < 1500 ? 0.5 : 1;
59 |
60 | // Handle receiver values
61 | SetSpeed(channel1, factor);
62 | SetSteer(channel2);
63 |
64 | /* SendDebug(); */
65 |
66 | // Reply only when you receive data
67 | if (Serial.available() > 0)
68 | {
69 | char character = Serial.read();
70 | if (character == '\n')
71 | {
72 | SendAnswer();
73 | }
74 | }
75 | }
76 |
77 |
--------------------------------------------------------------------------------
/PPMDeviceArduino_V1.0/PPMDevice/RCReceiver.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the hoverboard-firmware-hack-V2 project. The
3 | * firmware is used to hack the generation 2 board of the hoverboard.
4 | * These new hoverboards have no mainboard anymore. They consist of
5 | * two Sensorboards which have their own BLDC-Bridge per Motor and an
6 | * ARM Cortex-M3 processor GD32F130C8.
7 | *
8 | * Copyright (C) 2018 Florian Staeblein
9 | * Copyright (C) 2018 Jakob Broemauer
10 | * Copyright (C) 2018 Kai Liebich
11 | * Copyright (C) 2018 Christoph Lehnert
12 | *
13 | * The program is based on the hoverboard project by Niklas Fauth. The
14 | * structure was tried to be as similar as possible, so that everyone
15 | * could find a better way through the code.
16 | *
17 | * This program is free software: you can redistribute it and/or modify
18 | * it under the terms of the GNU General Public License as published by
19 | * the Free Software Foundation, either version 3 of the License, or
20 | * (at your option) any later version.
21 | *
22 | * This program is distributed in the hope that it will be useful,
23 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 | * GNU General Public License for more details.
26 | *
27 | * You should have received a copy of the GNU General Public License
28 | * along with this program. If not, see .
29 | */
30 |
31 | #include "RCReceiver.h"
32 |
33 | uint16_t m_pulseStart[SERVOS]; // Last measured pulse start for each input.
34 | uint16_t m_pulseLength_us[SERVOS]; // Last measured pulse length for each input.
35 | static uint8_t lastB = 0;
36 | volatile static bool enable = false;
37 | volatile static bool pinChangeActive = false;
38 |
39 | uint16_t RCReceiverGetStartCount();
40 | uint16_t RCReceiverGetStopCount(uint8_t p_servo);
41 | uint16_t RCReceiverGetCnt();
42 |
43 | //----------------------------------------------------------------------------
44 | // Initializes the steering serial
45 | //----------------------------------------------------------------------------
46 | void InitRCReceiver(void)
47 | {
48 | // Deinitialize timer1
49 | TCCR1A = 0;
50 | TCCR1B = 0;
51 | TCCR1C = 0;
52 | TIMSK1 = 0;
53 | OCR1A = 0;
54 | OCR1B = 0;
55 | TCNT1 = 0;
56 |
57 | // We use pin 8-10 PB0, PB1, PB2 as Servo input pins
58 | pinMode(8, INPUT);
59 | pinMode(9, INPUT);
60 | pinMode(10, INPUT);
61 |
62 | // We use pin change interrupts to detect changes in the signal
63 | // Only allow pin change interrupts for PB0-3 (digital pins 8-10)
64 | PCMSK0 |= (1 << PCINT0) | (1 << PCINT1) | (1 << PCINT2);
65 |
66 | // Enable pin change interrupt 0
67 | PCICR |= (1 << PCIE0);
68 | }
69 |
70 | //----------------------------------------------------------------------------
71 | // Starts the receiver
72 | //----------------------------------------------------------------------------
73 | void RCReceiverStart()
74 | {
75 | // Clean buffers
76 | for (uint8_t i = 0; i < SERVOS; ++i)
77 | {
78 | m_pulseStart[i] = 0;
79 | m_pulseLength_us[i] = ZERO_US;
80 | }
81 |
82 | // Start Timer 1
83 | // Timer 1 counts up with 1MHz, so that 1 count = 1us
84 | // Overflow interrupt after 1000000MHz / 65536 = 0,065536s -> every 65,5ms
85 | TCCR1B = (TCCR1B & ~(_BV(CS12) | _BV(CS11) | _BV(CS10))) | _BV(CS11);
86 | TIMSK1 |= _BV(TOIE1);
87 | }
88 |
89 | //----------------------------------------------------------------------------
90 | // Returns the current result value of specified pin
91 | //----------------------------------------------------------------------------
92 | uint16_t GetRCValue(uint8_t pin)
93 | {
94 | if (pin < 0 || pin > SERVOS)
95 | {
96 | return ZERO_US;
97 | }
98 | return m_pulseLength_us[pin];
99 | }
100 |
101 | //----------------------------------------------------------------------------
102 | // Will be called when a reciever pin changes
103 | //----------------------------------------------------------------------------
104 | void RCReceiverPinChanged(uint8_t p_servo, bool p_high)
105 | {
106 | if (p_high)
107 | {
108 | // Start of pulse
109 | m_pulseStart[p_servo] = RCReceiverGetStartCount();
110 | }
111 | else
112 | {
113 | // End of pulse
114 | m_pulseLength_us[p_servo] = CLAMP(RCReceiverGetStopCount(p_servo), 1000, 2000);
115 | }
116 | }
117 |
118 | //----------------------------------------------------------------------------
119 | // Returns the start count of the timer
120 | //----------------------------------------------------------------------------
121 | uint16_t RCReceiverGetStartCount()
122 | {
123 | uint16_t cnt = RCReceiverGetCnt();
124 |
125 | // Start of pulse
126 | return cnt;
127 | }
128 |
129 | //----------------------------------------------------------------------------
130 | // Returns the stop count of the specified input pin
131 | //----------------------------------------------------------------------------
132 | uint16_t RCReceiverGetStopCount(uint8_t p_servo)
133 | {
134 | uint16_t cnt = RCReceiverGetCnt();
135 |
136 | // End of pulse
137 | return (cnt - m_pulseStart[p_servo]) >> 1;
138 | }
139 |
140 | //----------------------------------------------------------------------------
141 | // Returns the count value of the timer
142 | //----------------------------------------------------------------------------
143 | uint16_t RCReceiverGetCnt()
144 | {
145 | uint8_t oldSREG = SREG;
146 | cli();
147 | uint16_t cnt = TCNT1;
148 | SREG = oldSREG;
149 |
150 | return cnt;
151 | }
152 |
153 | //----------------------------------------------------------------------------
154 | // Interrupt service routine for timer1 overflow
155 | //----------------------------------------------------------------------------
156 | ISR(TIMER1_OVF_vect)
157 | {
158 | sei();
159 |
160 | // Between two overflow interrupts (every 65,5ms) should be
161 | // at least one pin change interrupt (receiver pwm period is 6ms)
162 | if (pinChangeActive)
163 | {
164 | enable = true;
165 | }
166 | else
167 | {
168 | m_pulseLength_us[0] = ZERO_US;
169 | m_pulseLength_us[1] = ZERO_US;
170 | m_pulseLength_us[2] = ZERO_US;
171 | enable = false;
172 | }
173 | pinChangeActive = false;
174 | }
175 |
176 | //
177 | //----------------------------------------------------------------------------
178 | // Interrupt service routine for pin change port 0 interrupt
179 | //----------------------------------------------------------------------------
180 | ISR(PCINT0_vect)
181 | {
182 | if (enable == false)
183 | {
184 | pinChangeActive = true;
185 | return;
186 | }
187 | pinChangeActive = true;
188 | uint8_t newB = PINB;
189 |
190 | // Bitwise XOR will set all bits that have changed
191 | uint8_t chgB = newB ^ lastB;
192 | lastB = newB;
193 |
194 | // Has any of the pins changed?
195 | if (chgB)
196 | {
197 | // Find out which pin has changed
198 | if (chgB & _BV(0))
199 | {
200 | RCReceiverPinChanged(0, newB & _BV(0));
201 | }
202 | if (chgB & _BV(1))
203 | {
204 | RCReceiverPinChanged(1, newB & _BV(1));
205 | }
206 | if (chgB & _BV(2))
207 | {
208 | RCReceiverPinChanged(2, newB & _BV(2));
209 | }
210 | }
211 | }
212 |
--------------------------------------------------------------------------------
/PPMDeviceArduino_V1.0/PPMDevice/RCReceiver.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the hoverboard-firmware-hack-V2 project. The
3 | * firmware is used to hack the generation 2 board of the hoverboard.
4 | * These new hoverboards have no mainboard anymore. They consist of
5 | * two Sensorboards which have their own BLDC-Bridge per Motor and an
6 | * ARM Cortex-M3 processor GD32F130C8.
7 | *
8 | * Copyright (C) 2018 Florian Staeblein
9 | * Copyright (C) 2018 Jakob Broemauer
10 | * Copyright (C) 2018 Kai Liebich
11 | * Copyright (C) 2018 Christoph Lehnert
12 | *
13 | * The program is based on the hoverboard project by Niklas Fauth. The
14 | * structure was tried to be as similar as possible, so that everyone
15 | * could find a better way through the code.
16 | *
17 | * This program is free software: you can redistribute it and/or modify
18 | * it under the terms of the GNU General Public License as published by
19 | * the Free Software Foundation, either version 3 of the License, or
20 | * (at your option) any later version.
21 | *
22 | * This program is distributed in the hope that it will be useful,
23 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 | * GNU General Public License for more details.
26 | *
27 | * You should have received a copy of the GNU General Public License
28 | * along with this program. If not, see .
29 | */
30 |
31 | #ifndef RCRECEIVER_H
32 | #define RCRECEIVER_H
33 |
34 | #include
35 | #include
36 | #include "utils.h"
37 | //----------------------------------------------------------------------------
38 | // Defines
39 | //----------------------------------------------------------------------------
40 | #define SERVOS 3
41 | #define ZERO_US 1500
42 |
43 | //----------------------------------------------------------------------------
44 | // Initializes the RC receiver
45 | //----------------------------------------------------------------------------
46 | void InitRCReceiver(void);
47 |
48 | //----------------------------------------------------------------------------
49 | // Starts the receiver
50 | //----------------------------------------------------------------------------
51 | void RCReceiverStart();
52 |
53 | //----------------------------------------------------------------------------
54 | // Returns the current result value of specified pin
55 | //----------------------------------------------------------------------------
56 | uint16_t GetRCValue(uint8_t pin);
57 |
58 | #endif
59 |
--------------------------------------------------------------------------------
/PPMDeviceArduino_V1.0/PPMDevice/SteeringSerial.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the hoverboard-firmware-hack-V2 project. The
3 | * firmware is used to hack the generation 2 board of the hoverboard.
4 | * These new hoverboards have no mainboard anymore. They consist of
5 | * two Sensorboards which have their own BLDC-Bridge per Motor and an
6 | * ARM Cortex-M3 processor GD32F130C8.
7 | *
8 | * Copyright (C) 2018 Florian Staeblein
9 | * Copyright (C) 2018 Jakob Broemauer
10 | * Copyright (C) 2018 Kai Liebich
11 | * Copyright (C) 2018 Christoph Lehnert
12 | *
13 | * The program is based on the hoverboard project by Niklas Fauth. The
14 | * structure was tried to be as similar as possible, so that everyone
15 | * could find a better way through the code.
16 | *
17 | * This program is free software: you can redistribute it and/or modify
18 | * it under the terms of the GNU General Public License as published by
19 | * the Free Software Foundation, either version 3 of the License, or
20 | * (at your option) any later version.
21 | *
22 | * This program is distributed in the hope that it will be useful,
23 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 | * GNU General Public License for more details.
26 | *
27 | * You should have received a copy of the GNU General Public License
28 | * along with this program. If not, see .
29 | */
30 |
31 | #include "SteeringSerial.h"
32 |
33 | //----------------------------------------------------------------------------
34 | // Variables
35 | //----------------------------------------------------------------------------
36 | int32_t speedValue = 0;
37 | int32_t steerValue = 0;
38 | uint8_t upperLEDMaster = 0;
39 | uint8_t lowerLEDMaster = 0;
40 | uint8_t mosfetOutMaster = 0;
41 | uint8_t upperLEDSlave = 0;
42 | uint8_t lowerLEDSlave = 0;
43 | uint8_t mosfetOutSlave = 0;
44 | uint8_t beepsBackwards = 0;
45 | uint8_t activateWeakening = 0;
46 |
47 | void SendBuffer(uint8_t buffer[], uint8_t length);
48 | uint16_t CalcCRC(uint8_t *ptr, int count);
49 |
50 | //----------------------------------------------------------------------------
51 | // Initializes the steering serial
52 | //----------------------------------------------------------------------------
53 | void InitSteeringSerial(void)
54 | {
55 | // Set up serial communication
56 | Serial.begin(19200, SERIAL_8N1);
57 | }
58 |
59 | //----------------------------------------------------------------------------
60 | // Sets the speed value
61 | //----------------------------------------------------------------------------
62 | void SetSpeed(uint16_t data, float factor)
63 | {
64 | int16_t tempValue = ((float)data * 2 ) - 3000.0; // Value -1000 to 1000
65 | tempValue *= factor;
66 | tempValue = CLAMP(tempValue, -1000, 1000); // Avoid calculation failure
67 | speedValue = tempValue;
68 | }
69 |
70 | //----------------------------------------------------------------------------
71 | // Sets the steering value
72 | //----------------------------------------------------------------------------
73 | void SetSteer(uint16_t data)
74 | {
75 | int16_t tempValue = ((float)data * 2 ) - 3000.0; // Value -1000 to 1000
76 | tempValue = CLAMP(tempValue, -1000, 1000); // Avoid calculation failure
77 | if (speedValue < 0)
78 | {
79 | steerValue *= -1;
80 | }
81 | steerValue = tempValue;
82 | }
83 |
84 | //----------------------------------------------------------------------------
85 | // Sends answer to master device
86 | //----------------------------------------------------------------------------
87 | void SendAnswer(void)
88 | {
89 | int index = 0;
90 | uint8_t buffer[9];
91 | uint8_t byte1 = 0;
92 | uint8_t byte2 = 0;
93 | uint8_t byte3 = 0;
94 | uint8_t byte4 = 0;
95 |
96 | uint8_t sendByte = 0;
97 | sendByte |= (activateWeakening << 7);
98 | sendByte |= (beepsBackwards << 6);
99 | sendByte |= (mosfetOutSlave << 5);
100 | sendByte |= (lowerLEDSlave << 4);
101 | sendByte |= (upperLEDSlave << 3);
102 | sendByte |= (mosfetOutMaster << 2);
103 | sendByte |= (lowerLEDMaster << 1);
104 | sendByte |= (upperLEDMaster << 0);
105 |
106 | uint16_t speedValue_Format = (uint16_t)(speedValue);
107 | byte1 |= (speedValue_Format >> 8) & 0xFF;
108 | byte2 |= speedValue_Format & 0xFF;
109 |
110 | uint16_t steerValue_Format = (uint16_t)(steerValue);
111 | byte3 |= (steerValue_Format >> 8) & 0xFF;
112 | byte4 |= steerValue_Format & 0xFF;
113 |
114 | // Send answer
115 | buffer[index++] = '/';
116 | buffer[index++] = byte1;
117 | buffer[index++] = byte2;
118 | buffer[index++] = byte3;
119 | buffer[index++] = byte4;
120 | buffer[index++] = sendByte;
121 |
122 | // Calculate CRC
123 | uint16_t crc = CalcCRC(buffer, index);
124 | buffer[index++] = (crc >> 8) & 0xFF;
125 | buffer[index++] = crc & 0xFF;
126 |
127 | // Stop byte
128 | buffer[index++] = '\n';
129 |
130 | SendBuffer(buffer, index);
131 | }
132 |
133 | //----------------------------------------------------------------------------
134 | // Calculates CRC value
135 | //----------------------------------------------------------------------------
136 | uint16_t CalcCRC(uint8_t *ptr, int count)
137 | {
138 | uint16_t crc;
139 | uint8_t i;
140 | crc = 0;
141 | while (--count >= 0)
142 | {
143 | crc = crc ^ (uint16_t) *ptr++ << 8;
144 | i = 8;
145 | do
146 | {
147 | if (crc & 0x8000)
148 | {
149 | crc = crc << 1 ^ 0x1021;
150 | }
151 | else
152 | {
153 | crc = crc << 1;
154 | }
155 | } while(--i);
156 | }
157 | return (crc);
158 | }
159 |
160 | //----------------------------------------------------------------------------
161 | // Sends buffer
162 | //----------------------------------------------------------------------------
163 | void SendBuffer(uint8_t buffer[], uint8_t length)
164 | {
165 | uint8_t index = 0;
166 |
167 | for(; index < length; index++)
168 | {
169 | Serial.write(buffer[index]);
170 | }
171 | }
172 |
173 | //----------------------------------------------------------------------------
174 | // Sends debug infos
175 | //----------------------------------------------------------------------------
176 | void SendDebug()
177 | {
178 | Serial.print(speedValue);
179 | Serial.print(",");
180 | Serial.println(steerValue);
181 | }
182 |
--------------------------------------------------------------------------------
/PPMDeviceArduino_V1.0/PPMDevice/SteeringSerial.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the hoverboard-firmware-hack-V2 project. The
3 | * firmware is used to hack the generation 2 board of the hoverboard.
4 | * These new hoverboards have no mainboard anymore. They consist of
5 | * two Sensorboards which have their own BLDC-Bridge per Motor and an
6 | * ARM Cortex-M3 processor GD32F130C8.
7 | *
8 | * Copyright (C) 2018 Florian Staeblein
9 | * Copyright (C) 2018 Jakob Broemauer
10 | * Copyright (C) 2018 Kai Liebich
11 | * Copyright (C) 2018 Christoph Lehnert
12 | *
13 | * The program is based on the hoverboard project by Niklas Fauth. The
14 | * structure was tried to be as similar as possible, so that everyone
15 | * could find a better way through the code.
16 | *
17 | * This program is free software: you can redistribute it and/or modify
18 | * it under the terms of the GNU General Public License as published by
19 | * the Free Software Foundation, either version 3 of the License, or
20 | * (at your option) any later version.
21 | *
22 | * This program is distributed in the hope that it will be useful,
23 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 | * GNU General Public License for more details.
26 | *
27 | * You should have received a copy of the GNU General Public License
28 | * along with this program. If not, see .
29 | */
30 |
31 | #ifndef STEERINGSERIAL_H
32 | #define STEERINGSERIAL_H
33 |
34 | #include
35 | #include
36 | #include "utils.h"
37 |
38 | //----------------------------------------------------------------------------
39 | // Initializes the steering serial
40 | //----------------------------------------------------------------------------
41 | void InitSteeringSerial(void);
42 |
43 | //----------------------------------------------------------------------------
44 | // Sets the speed value
45 | //----------------------------------------------------------------------------
46 | void SetSpeed(uint16_t data, float factor);
47 |
48 | //----------------------------------------------------------------------------
49 | // Sets the steering value
50 | //----------------------------------------------------------------------------
51 | void SetSteer(uint16_t data);
52 |
53 | //----------------------------------------------------------------------------
54 | // Sends answer to master device
55 | //----------------------------------------------------------------------------
56 | void SendAnswer(void);
57 |
58 |
59 | //----------------------------------------------------------------------------
60 | // Sends debug infos
61 | //----------------------------------------------------------------------------
62 | void SendDebug();
63 |
64 | #endif
65 |
--------------------------------------------------------------------------------
/PPMDeviceArduino_V1.0/PPMDevice/utils.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the hoverboard-firmware-hack-V2 project. The
3 | * firmware is used to hack the generation 2 board of the hoverboard.
4 | * These new hoverboards have no mainboard anymore. They consist of
5 | * two Sensorboards which have their own BLDC-Bridge per Motor and an
6 | * ARM Cortex-M3 processor GD32F130C8.
7 | *
8 | * Copyright (C) 2018 Florian Staeblein
9 | * Copyright (C) 2018 Jakob Broemauer
10 | * Copyright (C) 2018 Kai Liebich
11 | * Copyright (C) 2018 Christoph Lehnert
12 | *
13 | * The program is based on the hoverboard project by Niklas Fauth. The
14 | * structure was tried to be as similar as possible, so that everyone
15 | * could find a better way through the code.
16 | *
17 | * This program is free software: you can redistribute it and/or modify
18 | * it under the terms of the GNU General Public License as published by
19 | * the Free Software Foundation, either version 3 of the License, or
20 | * (at your option) any later version.
21 | *
22 | * This program is distributed in the hope that it will be useful,
23 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 | * GNU General Public License for more details.
26 | *
27 | * You should have received a copy of the GNU General Public License
28 | * along with this program. If not, see .
29 | */
30 |
31 | #ifndef UTILS_H
32 | #define UTILS_H
33 |
34 | #define ABS(a) (((a) < 0.0) ? -(a) : (a))
35 | #define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
36 | #define MAP(x, xMin, xMax, yMin, yMax) ((x - xMin) * (yMax - yMin) / (xMax - xMin) + yMin)
37 |
38 | #endif
39 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | #### Updates:
2 | ````
3 | - Firmware is ready.
4 | - Sadly I can not support any issues. I'm not a student, less free time :)
5 | ````
6 |
7 | ### Hoverboard-Firmware-Hack-Gen2
8 |
9 | Hoverboard Hack Firmware Generation 2 for the Hoverboard with the two Mainboards instead of the Sensorboards (See Pictures).
10 |
11 | This repo contains open source firmware for generic Hoverboards with two mainboards. It allows you to control the hardware of the new version of hoverboards (like the Mainboard, Motors and Battery) with an arduino or some other steering device for projects like driving armchairs.
12 |
13 | The structure of the firmware is based on the firmware hack of Niklas Fauth (https://github.com/NiklasFauth/hoverboard-firmware-hack/). Because of a different model of processor (GD32F130C8 instead of STM32F103) it was not possible to use the same firmware and it has to be written from scratch (Different hardware, different, pins, different registers :( )
14 |
15 | - This project requires knowledge of the initial project linked above.
16 | - At the current point I am not able to support any questions or issues - sorry!
17 |
18 | ---
19 |
20 | #### Hardware
21 | 
22 |
23 | The hardware has two main boards, which are different equipped. They are connected via USART. Additionally there are some LED PCB connected at X1 and X2 which signalize the battery state and the error state. There is an programming connector for ST-Link/V2 and they break out GND, USART/I2C, 5V on a second pinhead.
24 |
25 | The reverse-engineered schematics of the mainboards can be found here:
26 | https://github.com/flo199213/Hoverboard-Firmware-Hack-Gen2/blob/master/Schematics/HoverBoard_CoolAndFun.pdf
27 |
28 |
29 | ---
30 |
31 | #### Flashing
32 | The firmware is built with Keil (free up to 32KByte). To build the firmware, open the Keil project file which is includes in repository. Right to the STM32, there is a debugging header with GND, 3V3, SWDIO and SWCLK. Connect GND, SWDIO and SWCLK to your SWD programmer, like the ST-Link found on many STM devboards.
33 |
34 | - If you never flashed your mainboard before, the controller is locked. To unlock the flash, use STM32 ST-LINK Utility or openOCD.
35 | - To flash the STM32, use the STM32 ST-LINK Utility as well, ST-Flash utility or Keil by itself.
36 | - Hold the powerbutton while flashing the firmware, as the controller releases the power latch and switches itself off during flashing
37 |
--------------------------------------------------------------------------------
/Raumzeigerdiagramm.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flo199213/Hoverboard-Firmware-Hack-Gen2/e138b221aed944478d12e15d81fb858f44f4a289/Raumzeigerdiagramm.png
--------------------------------------------------------------------------------
/Schematics/HoverBoard_CoolAndFun.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flo199213/Hoverboard-Firmware-Hack-Gen2/e138b221aed944478d12e15d81fb858f44f4a289/Schematics/HoverBoard_CoolAndFun.pdf
--------------------------------------------------------------------------------