detect MCU flash size and config usart

This commit is contained in:
2025-08-20 21:02:52 +08:00
parent b6485c5c39
commit c93704383a
8 changed files with 164 additions and 16 deletions

View File

@@ -32,6 +32,7 @@ set(TARGET_SRC
Src/i2c.c Src/i2c.c
Src/ldc1612.c Src/ldc1612.c
Src/tmp112.c Src/tmp112.c
Src/mcu_config.c
) )
# 设置输出目录 # 设置输出目录

View File

@@ -21,6 +21,29 @@
// #define EDDY_DRIVE_CURRENT_DETECTION // Eddy Drive Current Detection : Enable // #define EDDY_DRIVE_CURRENT_DETECTION // Eddy Drive Current Detection : Enable
#undef EDDY_DRIVE_CURRENT_DETECTION // Eddy Drive Current Detection : Disable #undef EDDY_DRIVE_CURRENT_DETECTION // Eddy Drive Current Detection : Disable
#define GD32E23XF4 0x10
#define GD32E23XF6 0x20
#define GD32E23XF8 0x40
/* MCU Type Detection */
extern uint8_t g_mcu_type;
/* Dynamic USART Configuration Structure */
typedef struct {
uint32_t rcu_usart;
uint32_t usart_periph;
uint8_t gpio_af;
IRQn_Type irq_type;
} usart_config_t;
extern usart_config_t g_usart_config;
/* Function to detect MCU type and configure USART */
void mcu_detect_and_config(void);
/* Function to get current MCU type */
uint8_t get_mcu_type(void);
/******************************************************************************/ /******************************************************************************/
#define RCU_GPIO_I2C RCU_GPIOF #define RCU_GPIO_I2C RCU_GPIOF
@@ -31,7 +54,7 @@
#define I2C_SDA_PIN GPIO_PIN_0 #define I2C_SDA_PIN GPIO_PIN_0
#define I2C_GPIO_AF GPIO_AF_1 #define I2C_GPIO_AF GPIO_AF_1
#define I2C_DEBUG_UART USART0 #define I2C_DEBUG_UART USART1
/******************************************************************************/ /******************************************************************************/
@@ -41,15 +64,19 @@
/******************************************************************************/ /******************************************************************************/
#define RS485_RCU RCU_USART0 /* Use dynamic configuration instead of static defines */
#define RS485_GPIO_RCU RCU_GPIOA #define RS485_GPIO_RCU RCU_GPIOA
#define RS485_GPIO_PORT GPIOA #define RS485_GPIO_PORT GPIOA
#define RS485_TX_PIN GPIO_PIN_2 #define RS485_TX_PIN GPIO_PIN_2
#define RS485_RX_PIN GPIO_PIN_3 #define RS485_RX_PIN GPIO_PIN_3
#define RS485_PHY USART0
#define RS485_BAUDRATE 115200U #define RS485_BAUDRATE 115200U
#define RS485_EN_PIN GPIO_PIN_1 #define RS485_EN_PIN GPIO_PIN_1
#define RS485_IRQ USART0_IRQn
/* Dynamic configuration - will be set by mcu_detect_and_config() */
#define RS485_RCU (g_usart_config.rcu_usart)
#define RS485_PHY (g_usart_config.usart_periph)
#define RS485_IRQ (g_usart_config.irq_type)
#define RS485_GPIO_AF (g_usart_config.gpio_af)
/******************************************************************************/ /******************************************************************************/

View File

@@ -12,8 +12,8 @@ _Min_Stack_Size = 0x400; /* required amount of stack */
/* Memories definition */ /* Memories definition */
MEMORY MEMORY
{ {
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 16K FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 64K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 4K RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 8K
} }
/* Sections */ /* Sections */

View File

@@ -37,6 +37,7 @@ OF SUCH DAMAGE.
#include "uart.h" #include "uart.h"
#include "uart_ring_buffer.h" #include "uart_ring_buffer.h"
#include "led.h" #include "led.h"
#include "board_config.h"
/*! /*!
\brief this function handles NMI exception \brief this function handles NMI exception
@@ -102,8 +103,19 @@ void SysTick_Handler(void) {
} }
void USART0_IRQHandler(void) { void USART0_IRQHandler(void) {
if (RESET != usart_interrupt_flag_get(USART0, USART_INT_FLAG_RBNE)) { if (get_mcu_type() == GD32E23XF4) {
uint8_t data = usart_data_receive(USART0); if (RESET != usart_interrupt_flag_get(USART0, USART_INT_FLAG_RBNE)) {
(void)uart_ring_buffer_put(data); // 缓冲满时丢弃,返回值可用于统计 uint8_t data = usart_data_receive(USART0);
(void)uart_ring_buffer_put(data); // 缓冲满时丢弃,返回值可用于统计
}
}
}
void USART1_IRQHandler(void) {
if (get_mcu_type() == GD32E23XF6 || get_mcu_type() == GD32E23XF8) {
if (RESET != usart_interrupt_flag_get(USART1, USART_INT_FLAG_RBNE)) {
uint8_t data = usart_data_receive(USART1);
(void)uart_ring_buffer_put(data); // 缓冲满时丢弃,返回值可用于统计
}
} }
} }

View File

@@ -43,6 +43,8 @@ OF SUCH DAMAGE.
#include "ldc1612.h" #include "ldc1612.h"
#include "tmp112.h" #include "tmp112.h"
#define FLASH_SIZE_ADDR (*(const uint16_t *)0x1FFFF7E0)
/*! /*!
\brief main function \brief main function
\param[in] none \param[in] none
@@ -51,13 +53,41 @@ OF SUCH DAMAGE.
*/ */
int main(void) int main(void)
{ {
systick_config();
/* Detect MCU type and configure USART accordingly */
mcu_detect_and_config();
uint16_t flash_kb = FLASH_SIZE_ADDR;
rs485_init();
printf("MCU Type detected: ");
switch (get_mcu_type()) {
case GD32E23XF4:
printf("GD32E23XF4 (using USART0)\r\n");
break;
case GD32E23XF6:
printf("GD32E23XF6 (using USART1)\r\n");
break;
case GD32E23XF8:
printf("GD32E23XF8 (using USART1)\r\n");
break;
default:
printf("Unknown (default to GD32E23XF8)\r\n");
break;
}
setbuf(stdout, NULL); setbuf(stdout, NULL);
systick_config();
rs485_init(); rs485_init();
led_init(); led_init();
printf("Flash Size: %d KB\r\n", flash_kb);
printf("%x\r\n", flash_kb);
printf("Flash Size Bytes: %02X\r\n", flash_kb & 0xFF);
#ifdef DEBUG_VERBOSE #ifdef DEBUG_VERBOSE
char hello_world[] = {"Hello World!\r\n"}; char hello_world[] = {"Hello World!\r\n"};

77
Src/mcu_config.c Normal file
View File

@@ -0,0 +1,77 @@
/*!
\file mcu_config.c
\brief MCU type detection and dynamic configuration
\version 2025-08-20, V1.0.0, MCU detection for GD32E23x
*/
#include "gd32e23x.h"
#include "board_config.h"
#define FLASH_SIZE_ADDR (*(const uint16_t *)0x1FFFF7E0)
/* Global variables for dynamic configuration */
uint8_t g_mcu_type = 0;
usart_config_t g_usart_config = {0};
/*!
\brief detect MCU type and configure USART accordingly
\param[in] none
\param[out] none
\retval none
*/
void mcu_detect_and_config(void)
{
uint16_t flash_kb = FLASH_SIZE_ADDR;
uint8_t size = (flash_kb >> 8) & 0xFF;
/* Detect MCU type based on flash size */
switch (size) {
case GD32E23XF4:
g_mcu_type = GD32E23XF4;
/* Configure for USART0 (GD32E23XF4) */
g_usart_config.rcu_usart = RCU_USART0;
g_usart_config.usart_periph = USART0;
g_usart_config.gpio_af = GPIO_AF_1;
g_usart_config.irq_type = USART0_IRQn;
break;
case GD32E23XF6:
g_mcu_type = GD32E23XF6;
/* Configure for USART1 (GD32E23XF6) */
g_usart_config.rcu_usart = RCU_USART1;
g_usart_config.usart_periph = USART1;
g_usart_config.gpio_af = GPIO_AF_1;
g_usart_config.irq_type = USART1_IRQn;
break;
case GD32E23XF8:
g_mcu_type = GD32E23XF8;
/* Configure for USART1 (GD32E23XF8) */
g_usart_config.rcu_usart = RCU_USART1;
g_usart_config.usart_periph = USART1;
g_usart_config.gpio_af = GPIO_AF_1;
g_usart_config.irq_type = USART1_IRQn;
break;
default:
/* Default to GD32E23XF8 configuration */
g_mcu_type = GD32E23XF8;
g_usart_config.rcu_usart = RCU_USART1;
g_usart_config.usart_periph = USART1;
g_usart_config.gpio_af = GPIO_AF_1;
g_usart_config.irq_type = USART1_IRQn;
break;
}
}
/*!
\brief get current MCU type
\param[in] none
\param[out] none
\retval MCU type (GD32E23XF4, GD32E23XF6, or GD32E23XF8)
*/
uint8_t get_mcu_type(void)
{
return g_mcu_type;
}

View File

@@ -16,6 +16,7 @@
#include <unistd.h> #include <unistd.h>
#include <sys/wait.h> #include <sys/wait.h>
#include "gd32e23x_usart.h" #include "gd32e23x_usart.h"
#include "board_config.h"
#undef errno #undef errno
extern int errno; extern int errno;
@@ -164,7 +165,7 @@ int _execve(char *name, char **argv, char **env)
// USART0 printf重定向实现 // USART0 printf重定向实现
int __io_putchar(int ch) { int __io_putchar(int ch) {
// 等待发送缓冲区空 // 等待发送缓冲区空
while (usart_flag_get(USART0, USART_FLAG_TBE) == RESET) {} while (usart_flag_get(RS485_PHY, USART_FLAG_TBE) == RESET) {}
usart_data_transmit(USART0, (uint8_t)ch); usart_data_transmit(RS485_PHY, (uint8_t)ch);
return ch; return ch;
} }

View File

@@ -8,12 +8,12 @@
void rs485_init(void) { void rs485_init(void) {
#ifndef RS485_MAX13487 #ifndef RS485_MAX13487
/* 使能 GPIOA 和 USART0 时钟 */ /* 使能 GPIOA 和 USART 时钟 */
rcu_periph_clock_enable(RS485_GPIO_RCU); rcu_periph_clock_enable(RS485_GPIO_RCU);
rcu_periph_clock_enable(RS485_RCU); rcu_periph_clock_enable(RS485_RCU);
/* 配置 PA2 为 USART0_TXPA3 为 USART0_RX */ /* 配置 PA2 为 USART_TXPA3 为 USART_RX */
gpio_af_set(RS485_GPIO_PORT, GPIO_AF_1, RS485_TX_PIN | RS485_RX_PIN | RS485_EN_PIN); gpio_af_set(RS485_GPIO_PORT, RS485_GPIO_AF, RS485_TX_PIN | RS485_RX_PIN | RS485_EN_PIN);
gpio_mode_set(RS485_GPIO_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP, RS485_TX_PIN | RS485_RX_PIN); gpio_mode_set(RS485_GPIO_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP, RS485_TX_PIN | RS485_RX_PIN);
gpio_output_options_set(RS485_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, RS485_TX_PIN | RS485_RX_PIN); gpio_output_options_set(RS485_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, RS485_TX_PIN | RS485_RX_PIN);
@@ -37,7 +37,7 @@ void rs485_init(void) {
usart_enable(RS485_PHY); usart_enable(RS485_PHY);
nvic_irq_enable(USART0_IRQn, 0); nvic_irq_enable(RS485_IRQ, 0);
usart_interrupt_enable(RS485_PHY, USART_INT_RBNE); usart_interrupt_enable(RS485_PHY, USART_INT_RBNE);
// usart_interrupt_enable(RS485_PHY, USART_INT_IDLE); // usart_interrupt_enable(RS485_PHY, USART_INT_IDLE);