mirror of
https://github.com/EFeru/hoverboard-sideboard-hack-GD.git
synced 2025-07-27 01:29:32 +00:00
355 lines
13 KiB
C
355 lines
13 KiB
C
/**
|
|
* This file is part of the hoverboard-sideboard-hack project.
|
|
*
|
|
* Copyright (C) 2020-2021 Emanuel FERU <aerdronix@gmail.com>
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
// Includes
|
|
#include "gd32f1x0.h"
|
|
#include "systick.h"
|
|
#include "setup.h"
|
|
#include "defines.h"
|
|
#include "config.h"
|
|
#include "util.h"
|
|
|
|
// Global variables
|
|
|
|
|
|
// Private variables
|
|
static rcu_periph_enum USART_CLK[USARTn] = { USART0_CLK,
|
|
USART1_CLK
|
|
};
|
|
|
|
static uint32_t USART_TX_PIN[USARTn] = { USART0_TX_PIN,
|
|
USART1_TX_PIN
|
|
};
|
|
|
|
static uint32_t USART_RX_PIN[USARTn] = { USART0_RX_PIN,
|
|
USART1_RX_PIN
|
|
};
|
|
|
|
static dma_channel_enum USART_TX_DMA_CH[USARTn] = { USART0_TX_DMA_CH,
|
|
USART1_TX_DMA_CH
|
|
};
|
|
|
|
static dma_channel_enum USART_RX_DMA_CH[USARTn] = { USART0_RX_DMA_CH,
|
|
USART1_RX_DMA_CH
|
|
};
|
|
|
|
static uint32_t USART_TDATA_ADDRESS[USARTn] = { USART0_TDATA_ADDRESS,
|
|
USART1_TDATA_ADDRESS
|
|
};
|
|
|
|
static uint32_t USART_RDATA_ADDRESS[USARTn] = { USART0_RDATA_ADDRESS,
|
|
USART1_RDATA_ADDRESS
|
|
};
|
|
|
|
|
|
void gpio_config(void) {
|
|
|
|
/* =========================== Configure LEDs GPIOs =========================== */
|
|
/* enable the GPIO clock */
|
|
rcu_periph_clock_enable(RCU_GPIOA);
|
|
rcu_periph_clock_enable(RCU_GPIOB);
|
|
|
|
/* configure GPIO port */
|
|
gpio_mode_set(LED1_GPIO_Port, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED1_Pin);
|
|
gpio_mode_set(LED2_GPIO_Port, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED2_Pin);
|
|
gpio_mode_set(LED3_GPIO_Port, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED3_Pin);
|
|
gpio_mode_set(LED4_GPIO_Port, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED4_Pin);
|
|
gpio_mode_set(LED5_GPIO_Port, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED5_Pin);
|
|
gpio_output_options_set(LED1_GPIO_Port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, LED1_Pin);
|
|
gpio_output_options_set(LED2_GPIO_Port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, LED2_Pin);
|
|
gpio_output_options_set(LED3_GPIO_Port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, LED3_Pin);
|
|
gpio_output_options_set(LED4_GPIO_Port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, LED4_Pin);
|
|
gpio_output_options_set(LED5_GPIO_Port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, LED5_Pin);
|
|
|
|
/* reset GPIO pin */
|
|
gpio_bit_reset(LED1_GPIO_Port, LED1_Pin);
|
|
gpio_bit_reset(LED2_GPIO_Port, LED2_Pin);
|
|
gpio_bit_reset(LED3_GPIO_Port, LED3_Pin);
|
|
gpio_bit_reset(LED4_GPIO_Port, LED4_Pin);
|
|
gpio_bit_reset(LED5_GPIO_Port, LED5_Pin);
|
|
|
|
|
|
/* =========================== Configure Sensors GPIOs =========================== */
|
|
/* enable the GPIO clock */
|
|
rcu_periph_clock_enable(RCU_GPIOA);
|
|
rcu_periph_clock_enable(RCU_GPIOC);
|
|
|
|
/* configure GPIO port */
|
|
gpio_mode_set(SENSOR1_GPIO_Port, GPIO_MODE_INPUT, GPIO_PUPD_NONE, SENSOR1_Pin);
|
|
gpio_mode_set(SENSOR2_GPIO_Port, GPIO_MODE_INPUT, GPIO_PUPD_NONE, SENSOR2_Pin);
|
|
|
|
|
|
/* =========================== Configure I2C GPIOs =========================== */
|
|
/* enable I2C clock */
|
|
rcu_periph_clock_enable(RCU_GPIOB);
|
|
rcu_periph_clock_enable(MPU_RCU_I2C);
|
|
|
|
/* connect PB6 to I2C_SCL and PB7 to I2C_SDA */
|
|
gpio_af_set(MPU_SCL_GPIO_Port, GPIO_AF_1, MPU_SCL_Pin);
|
|
gpio_af_set(MPU_SDA_GPIO_Port, GPIO_AF_1, MPU_SDA_Pin);
|
|
|
|
/* configure GPIO port */
|
|
gpio_mode_set(MPU_SCL_GPIO_Port, GPIO_MODE_AF, GPIO_PUPD_PULLUP, MPU_SCL_Pin);
|
|
gpio_output_options_set(MPU_SCL_GPIO_Port, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, MPU_SCL_Pin);
|
|
gpio_mode_set(MPU_SDA_GPIO_Port, GPIO_MODE_AF, GPIO_PUPD_PULLUP, MPU_SDA_Pin);
|
|
gpio_output_options_set(MPU_SDA_GPIO_Port, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, MPU_SDA_Pin);
|
|
|
|
#ifdef AUX45_USE_I2C
|
|
/* enable I2C clock */
|
|
rcu_periph_clock_enable(RCU_GPIOA);
|
|
rcu_periph_clock_enable(AUX_RCU_I2C);
|
|
|
|
/* connect PB6 to I2C_SCL and PB7 to I2C_SDA */
|
|
gpio_af_set(AUX_SCL_GPIO_Port, GPIO_AF_1, AUX_SCL_Pin);
|
|
gpio_af_set(AUX_SDA_GPIO_Port, GPIO_AF_1, AUX_SDA_Pin);
|
|
|
|
/* configure GPIO port */
|
|
gpio_mode_set(AUX_SCL_GPIO_Port, GPIO_MODE_AF, GPIO_PUPD_PULLUP, AUX_SCL_Pin);
|
|
gpio_output_options_set(AUX_SCL_GPIO_Port, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, AUX_SCL_Pin);
|
|
gpio_mode_set(AUX_SDA_GPIO_Port, GPIO_MODE_AF, GPIO_PUPD_PULLUP, AUX_SDA_Pin);
|
|
gpio_output_options_set(AUX_SDA_GPIO_Port, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, AUX_SDA_Pin);
|
|
#endif
|
|
|
|
|
|
/* =========================== Configure AUX GPIOs =========================== */
|
|
/* configure AUX GPIO port */
|
|
rcu_periph_clock_enable(RCU_GPIOA);
|
|
rcu_periph_clock_enable(RCU_GPIOB);
|
|
rcu_periph_clock_enable(RCU_GPIOC);
|
|
|
|
/* configure GPIO port - inputs */
|
|
gpio_mode_set(AUX1_PU_GPIO_Port, GPIO_MODE_INPUT, GPIO_PUPD_NONE, AUX1_PU_Pin);
|
|
|
|
/* configure GPIO port - outputs */
|
|
gpio_mode_set(AUX2_GPIO_Port, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, AUX2_Pin);
|
|
gpio_mode_set(AUX3_GPIO_Port, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, AUX3_Pin);
|
|
gpio_output_options_set(AUX2_GPIO_Port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, AUX2_Pin);
|
|
gpio_output_options_set(AUX3_GPIO_Port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, AUX3_Pin);
|
|
|
|
/* reset GPIO pin */
|
|
gpio_bit_reset(AUX2_GPIO_Port, AUX2_Pin);
|
|
gpio_bit_reset(AUX3_GPIO_Port, AUX3_Pin);
|
|
|
|
#ifdef AUX45_USE_GPIO
|
|
/* configure GPIO port - outputs */
|
|
gpio_mode_set(AUX4_GPIO_Port, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, AUX4_Pin);
|
|
gpio_mode_set(AUX5_GPIO_Port, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, AUX5_Pin);
|
|
gpio_output_options_set(AUX4_GPIO_Port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, AUX4_Pin);
|
|
gpio_output_options_set(AUX5_GPIO_Port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, AUX5_Pin);
|
|
|
|
/* reset GPIO pin */
|
|
gpio_bit_reset(AUX4_GPIO_Port, AUX4_Pin);
|
|
gpio_bit_reset(AUX5_GPIO_Port, AUX5_Pin);
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
void usart_config(uint32_t selUSART, uint32_t selBaudRate) {
|
|
|
|
uint8_t USART_ID = 0U;
|
|
if(selUSART == USART0){
|
|
USART_ID = 0U;
|
|
}
|
|
if(selUSART == USART1){
|
|
USART_ID = 1U;
|
|
}
|
|
|
|
/* enable GPIO clock */
|
|
rcu_periph_clock_enable(USART_GPIO_CLK);
|
|
|
|
/* enable USART clock */
|
|
rcu_periph_clock_enable(USART_CLK[USART_ID]);
|
|
|
|
/* connect port to USARTx_Tx */
|
|
gpio_af_set(USART_GPIO_PORT, USART_AF, USART_TX_PIN[USART_ID]);
|
|
|
|
/* connect port to USARTx_Rx */
|
|
gpio_af_set(USART_GPIO_PORT, USART_AF, USART_RX_PIN[USART_ID]);
|
|
|
|
/* configure USART Tx as alternate function push-pull */
|
|
gpio_mode_set(USART_GPIO_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP, USART_TX_PIN[USART_ID]);
|
|
gpio_output_options_set(USART_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, USART_TX_PIN[USART_ID]);
|
|
|
|
/* configure USART Rx as alternate function push-pull */
|
|
gpio_mode_set(USART_GPIO_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP, USART_RX_PIN[USART_ID]);
|
|
gpio_output_options_set(USART_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, USART_RX_PIN[USART_ID]);
|
|
|
|
/* USART configure */
|
|
usart_deinit(selUSART);
|
|
usart_baudrate_set(selUSART, selBaudRate);
|
|
usart_transmit_config(selUSART, USART_TRANSMIT_ENABLE);
|
|
usart_receive_config(selUSART, USART_RECEIVE_ENABLE);
|
|
usart_oversample_config(selUSART, USART_OVSMOD_16); // oversampling: {USART_OVSMOD_8, USART_OVSMOD_16}
|
|
usart_sample_bit_config(selUSART, USART_OSB_3BIT); // sample bit: {USART_OSB_1BIT, USART_OSB_3BIT }
|
|
usart_enable(selUSART);
|
|
|
|
/* enable the USART IDLE line detection interrupt */
|
|
usart_interrupt_enable(selUSART, USART_INT_IDLE);
|
|
|
|
}
|
|
|
|
|
|
// DMA_CH1 = USART0_TX
|
|
// DMA_CH2 = USART0_RX
|
|
// DMA_CH3 = USART1_TX
|
|
// DMA_CH4 = USART1_RX
|
|
|
|
void usart_Tx_DMA_config(uint32_t selUSART, uint8_t *pData, uint32_t dSize) {
|
|
|
|
dma_parameter_struct dma_init_struct;
|
|
|
|
// --------------------------- TX Channel ---------------------------
|
|
|
|
uint8_t USART_ID = 0U;
|
|
if(selUSART == USART0){
|
|
USART_ID = 0U;
|
|
}
|
|
if(selUSART == USART1){
|
|
USART_ID = 1U;
|
|
}
|
|
|
|
/* enable DMA clock */
|
|
rcu_periph_clock_enable(RCU_DMA);
|
|
|
|
/* deinitialize DMA channel2 */
|
|
dma_deinit(USART_TX_DMA_CH[USART_ID]);
|
|
dma_init_struct.direction = DMA_MEMORY_TO_PERIPHERAL;
|
|
dma_init_struct.memory_addr = (uint32_t)pData;
|
|
dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
|
|
dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT;
|
|
dma_init_struct.number = dSize;
|
|
dma_init_struct.periph_addr = USART_TDATA_ADDRESS[USART_ID];
|
|
dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
|
|
dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT;
|
|
dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH; // Priorities: *_LOW, *_MEDIUM, *_HIGH, *_ULTRA_HIGH,
|
|
dma_init(USART_TX_DMA_CH[USART_ID], dma_init_struct);
|
|
|
|
/* configure DMA mode */
|
|
dma_circulation_disable(USART_TX_DMA_CH[USART_ID]);
|
|
dma_memory_to_memory_disable(USART_TX_DMA_CH[USART_ID]);
|
|
|
|
/* USART DMA enable for transmission */
|
|
usart_dma_transmit_config(selUSART, USART_DENT_ENABLE);
|
|
|
|
/* enable DMA channel1 */
|
|
dma_channel_enable(USART_TX_DMA_CH[USART_ID]);
|
|
|
|
/* wait DMA channel transfer complete */
|
|
// while (RESET == dma_flag_get(USART_TX_DMA[USART_ID], DMA_FLAG_FTF));
|
|
|
|
}
|
|
|
|
|
|
void usart_Rx_DMA_config(uint32_t selUSART, uint8_t *pData, uint32_t dSize) {
|
|
|
|
dma_parameter_struct dma_init_struct;
|
|
|
|
// --------------------------- RX Channel ---------------------------
|
|
|
|
uint8_t USART_ID = 0U;
|
|
if(selUSART == USART0){
|
|
USART_ID = 0U;
|
|
}
|
|
if(selUSART == USART1){
|
|
USART_ID = 1U;
|
|
}
|
|
|
|
/* enable DMA clock */
|
|
rcu_periph_clock_enable(RCU_DMA);
|
|
|
|
/* deinitialize DMA channel4 */
|
|
dma_deinit(USART_RX_DMA_CH[USART_ID]);
|
|
dma_init_struct.direction = DMA_PERIPHERAL_TO_MEMORY;
|
|
dma_init_struct.memory_addr = (uint32_t)pData;
|
|
dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
|
|
dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT;
|
|
dma_init_struct.number = dSize;
|
|
dma_init_struct.periph_addr = USART_RDATA_ADDRESS[USART_ID];
|
|
dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
|
|
dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT;
|
|
dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH; // Priorities: *_LOW, *_MEDIUM, *_HIGH, *_ULTRA_HIGH,
|
|
dma_init(USART_RX_DMA_CH[USART_ID], dma_init_struct);
|
|
|
|
/* configure DMA mode */
|
|
dma_circulation_enable(USART_RX_DMA_CH[USART_ID]); // dma_circulation_disable(USART_RX_DMA[USART_ID]);
|
|
dma_memory_to_memory_disable(USART_RX_DMA_CH[USART_ID]);
|
|
|
|
/* USART DMA enable for reception */
|
|
usart_dma_receive_config(selUSART, USART_DENR_ENABLE);
|
|
|
|
/* enable DMA channel */
|
|
dma_channel_enable(USART_RX_DMA_CH[USART_ID]);
|
|
|
|
/* wait DMA channel transfer complete */
|
|
// while (RESET == dma_flag_get(USART_RX_DMA[USART_ID], DMA_FLAG_FTF));
|
|
|
|
}
|
|
|
|
|
|
void i2c_config(void) {
|
|
|
|
/* I2C clock configure */
|
|
//i2c_clock_config(MPU_I2C, MPU_I2C_SPEED, I2C_DTCY_2); // I2C duty cycle in fast mode
|
|
i2c_clock_config(MPU_I2C, MPU_I2C_SPEED, I2C_DTCY_16_9); // I2C duty cycle in fast mode plus
|
|
/* I2C address configure */
|
|
i2c_mode_addr_config(MPU_I2C, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, I2C_OWN_ADDRESS7);
|
|
/* enable I2C */
|
|
i2c_enable(MPU_I2C);
|
|
/* enable acknowledge */
|
|
i2c_ack_config(MPU_I2C, I2C_ACK_ENABLE);
|
|
|
|
#ifdef AUX45_USE_I2C
|
|
/* I2C clock configure */
|
|
//i2c_clock_config(AUX_I2C, AUX_I2C_SPEED, I2C_DTCY_2); // I2C duty cycle in fast mode
|
|
i2c_clock_config(AUX_I2C, AUX_I2C_SPEED, I2C_DTCY_16_9); // I2C duty cycle in fast mode plus
|
|
/* I2C address configure */
|
|
i2c_mode_addr_config(AUX_I2C, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, AUX_I2C_OWN_ADDRESS7);
|
|
/* enable I2C */
|
|
i2c_enable(AUX_I2C);
|
|
/* enable acknowledge */
|
|
i2c_ack_config(AUX_I2C, I2C_ACK_ENABLE);
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
void usart_nvic_config(void)
|
|
{
|
|
nvic_irq_enable(USART0_IRQn, 0, 1); // Enable USART0 interrupt
|
|
nvic_irq_enable(USART1_IRQn, 0, 1); // Enable USART1 interrupt
|
|
}
|
|
|
|
|
|
void i2c_nvic_config(void)
|
|
{
|
|
/* configure the NVIC peripheral */
|
|
nvic_priority_group_set(NVIC_PRIGROUP_PRE1_SUB3);
|
|
|
|
nvic_irq_enable(I2C0_EV_IRQn, 0, 0);
|
|
nvic_irq_enable(I2C0_ER_IRQn, 0, 0);
|
|
|
|
#ifdef AUX45_USE_I2C
|
|
nvic_irq_enable(I2C1_EV_IRQn, 0, 2);
|
|
nvic_irq_enable(I2C1_ER_IRQn, 0, 2);
|
|
#endif
|
|
}
|
|
|
|
|