feat(device): 添加早期诊断功能并优化SPI通信实现
- 在startup_gd32e50x_cl.s中添加USART0早期诊断代码,在Reset_Handler中 发送'R'字符以确认启动过程 - 修改system_gd32e50x.c中的时钟初始化逻辑,支持动态检测当前时钟源 (PLL或IRC8M)并相应调整串口波特率设置 - 在系统时钟配置函数中添加HXTAL故障诊断输出,当外部晶振启动失败时 通过USART0输出"HXTAL FAIL"错误信息 - 在AppSpiCommand类中实现DMA传输机制,使用DMA0_CH2进行SPI0数据发送, 提升传输效率并与BOOT端保持一致 - 重构SPI命令处理逻辑,优化PING命令响应格式,包含APP和BOOT版本信息 以及运行时间统计 - 添加事务过滤机制,忽略全0xFF或全0x00的数据包以及短帧 - 更新配置文件定义APP固件版本号和OTA配置页面地址 - 修复region配置文件中的ROM大小数值精度问题 - 调整NVIC中断优先级设置,优化SPI中断处理
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
#ifndef REGIONS_GD32E508VE_H
|
||||
#ifndef REGIONS_GD32E508VE_H
|
||||
#define REGIONS_GD32E508VE_H
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
#define __ROM0_BASE 0x08048000
|
||||
// <o> Region size [bytes] <0x0-0xFFFFFFFF:8>
|
||||
// <i> Defines size of memory region. Default: 0x00080000
|
||||
#define __ROM0_SIZE 0x00036000
|
||||
#define __ROM0_SIZE 0x00035FFC
|
||||
// </h>
|
||||
|
||||
// <h> __ROM1 (unused)
|
||||
|
||||
@@ -175,6 +175,48 @@ Reset_Handler PROC
|
||||
EXPORT Reset_Handler [WEAK]
|
||||
IMPORT SystemInit
|
||||
IMPORT __main
|
||||
|
||||
;=== EARLY DIAG: send 'R' via raw USART0 before any C code ===
|
||||
; 使 GPIOA + USART0 时钟可用
|
||||
LDR R1, =0x40021018 ; RCU_APB2EN
|
||||
LDR R2, [R1]
|
||||
ORRS R2, R2, #(1 << 2) ; RCU_GPIOA
|
||||
ORRS R2, R2, #(1 << 14) ; RCU_USART0
|
||||
STR R2, [R1]
|
||||
; PA9 设为 AF_PP 50MHz (CTL1 bits[7:4] = 0xB)
|
||||
LDR R1, =0x40010804 ; GPIOA_CTL1
|
||||
LDR R2, [R1]
|
||||
LDR R3, =0xFFFFFF0F ; mask: keep all except bits[7:4]
|
||||
ANDS R2, R2, R3
|
||||
ORRS R2, R2, #0xB0 ; bits[7:4] = 0xB (AF_PP 50MHz)
|
||||
STR R2, [R1]
|
||||
; 检测当前时钟源,选择正确波特率
|
||||
LDR R1, =0x40021000 ; RCU_CFG0
|
||||
LDR R2, [R1]
|
||||
LSRS R2, R2, #2 ; SCSS bits [3:2]
|
||||
ANDS R2, R2, #0x3
|
||||
CMP R2, #0x2 ; SCSS == PLL ?
|
||||
LDR R3, =1562 ; 180MHz / 115200
|
||||
LDR R4, =69 ; 8MHz / 115200
|
||||
ITE EQ
|
||||
MOVEQ R2, R3 ; PLL -> 180MHz baud divisor
|
||||
MOVNE R2, R4 ; IRC8M -> 8MHz baud divisor
|
||||
LDR R1, =0x40013808 ; USART0_BAUD
|
||||
STR R2, [R1]
|
||||
LDR R1, =0x40013800 ; USART0_CTL0
|
||||
MOVS R2, #(1 << 3) ; TE
|
||||
ORRS R2, R2, #(1 << 13) ; | USARTEN
|
||||
STR R2, [R1]
|
||||
LDR R1, =0x40013804 ; USART0_DATA
|
||||
MOVS R2, #'R'
|
||||
STR R2, [R1]
|
||||
LDR R1, =0x40013800 ; USART0_CTL0
|
||||
_rh_wait_tc
|
||||
LDR R2, [R1]
|
||||
LSRS R2, R2, #7 ; TC bit
|
||||
BCC _rh_wait_tc
|
||||
;=== END EARLY DIAG ===
|
||||
|
||||
LDR R0, =SystemInit
|
||||
BLX R0
|
||||
LDR R0, =__main
|
||||
|
||||
@@ -162,7 +162,7 @@ static void _soft_delay_(uint32_t time)
|
||||
*/
|
||||
void SystemInit (void)
|
||||
{
|
||||
/* ===== DIAG: raw USART0 output at IRC8M (8MHz) ===== */
|
||||
/* ===== DIAG: raw USART0 output — detect current clock for baudrate ===== */
|
||||
/* Enable AFIO + GPIOA + USART0 clocks via raw register */
|
||||
*((volatile uint32_t *)0x40021018U) |= (1U << 14) | (1U << 2) | (1U << 0);
|
||||
/* PA9 = AF_PP, 50MHz (CTL=0b11, MD=0b11) -> CTL1 bit[4..7]=0b1011 */
|
||||
@@ -172,8 +172,18 @@ void SystemInit (void)
|
||||
ctl |= (0xBU << 4); /* AF_PP 50MHz */
|
||||
*((volatile uint32_t *)0x40010804U) = ctl;
|
||||
}
|
||||
/* USART0 baud: BAUD = 8000000/115200 = 69 */
|
||||
*((volatile uint32_t *)0x40013808U) = 69U;
|
||||
/* Detect current system clock: if PLL is selected, assume 180MHz; otherwise IRC8M=8MHz.
|
||||
* This handles both cold boot (IRC8M) and BOOT jump (PLL 180MHz). */
|
||||
{
|
||||
uint32_t scss = (*((volatile uint32_t *)0x40021000U) >> 2) & 0x3U; /* RCU_CFG0 SCSS bits */
|
||||
uint32_t baud_div;
|
||||
if (scss == 0x2U) { /* PLL selected as system clock -> 180MHz */
|
||||
baud_div = 180000000U / 115200U; /* = 1562 */
|
||||
} else { /* IRC8M or HXTAL -> 8MHz */
|
||||
baud_div = 8000000U / 115200U; /* = 69 */
|
||||
}
|
||||
*((volatile uint32_t *)0x40013808U) = baud_div;
|
||||
}
|
||||
/* USART0 CTL0: TE + EN = bit3 + bit13 */
|
||||
*((volatile uint32_t *)0x40013800U) = (1U << 3) | (1U << 13);
|
||||
/* Send "APP" via USART0 DATA register */
|
||||
@@ -647,8 +657,18 @@ static void system_clock_hxtal(void)
|
||||
|
||||
/* if fail */
|
||||
if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)){
|
||||
while(1){
|
||||
}
|
||||
/* HXTAL failed: output diagnostic via USART0 at IRC8M */
|
||||
*((volatile uint32_t *)0x40021018U) |= (1U << 2) | (1U << 0);
|
||||
{ volatile uint32_t _ctl = *((volatile uint32_t *)0x40010804U);
|
||||
_ctl &= ~(0xFU << 4); _ctl |= (0xBU << 4);
|
||||
*((volatile uint32_t *)0x40010804U) = _ctl; }
|
||||
*((volatile uint32_t *)0x40013808U) = 69U; /* 8MHz/115200 */
|
||||
*((volatile uint32_t *)0x40013800U) = (1U << 3) | (1U << 13);
|
||||
{ const char *_msg = "HXTAL FAIL\r\n";
|
||||
for(int i=0; _msg[i]; i++){
|
||||
*((volatile uint32_t *)0x40013804U) = _msg[i];
|
||||
while((*((volatile uint32_t *)0x40013800U) & (1U << 7)) == 0U) {} } }
|
||||
while(1){ }
|
||||
}
|
||||
|
||||
/* AHB = SYSCLK */
|
||||
@@ -693,8 +713,18 @@ static void system_clock_72m_hxtal(void)
|
||||
|
||||
/* if fail */
|
||||
if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)){
|
||||
while(1){
|
||||
}
|
||||
/* HXTAL failed: output diagnostic via USART0 at IRC8M */
|
||||
*((volatile uint32_t *)0x40021018U) |= (1U << 2) | (1U << 0);
|
||||
{ volatile uint32_t _ctl = *((volatile uint32_t *)0x40010804U);
|
||||
_ctl &= ~(0xFU << 4); _ctl |= (0xBU << 4);
|
||||
*((volatile uint32_t *)0x40010804U) = _ctl; }
|
||||
*((volatile uint32_t *)0x40013808U) = 69U; /* 8MHz/115200 */
|
||||
*((volatile uint32_t *)0x40013800U) = (1U << 3) | (1U << 13);
|
||||
{ const char *_msg = "HXTAL FAIL\r\n";
|
||||
for(int i=0; _msg[i]; i++){
|
||||
*((volatile uint32_t *)0x40013804U) = _msg[i];
|
||||
while((*((volatile uint32_t *)0x40013800U) & (1U << 7)) == 0U) {} } }
|
||||
while(1){ }
|
||||
}
|
||||
|
||||
FMC_WS = (FMC_WS & (~FMC_WS_WSCNT)) | WS_WSCNT(1);
|
||||
@@ -801,8 +831,18 @@ static void system_clock_120m_hxtal(void)
|
||||
|
||||
/* if fail */
|
||||
if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)){
|
||||
while(1){
|
||||
}
|
||||
/* HXTAL failed: output diagnostic via USART0 at IRC8M */
|
||||
*((volatile uint32_t *)0x40021018U) |= (1U << 2) | (1U << 0);
|
||||
{ volatile uint32_t _ctl = *((volatile uint32_t *)0x40010804U);
|
||||
_ctl &= ~(0xFU << 4); _ctl |= (0xBU << 4);
|
||||
*((volatile uint32_t *)0x40010804U) = _ctl; }
|
||||
*((volatile uint32_t *)0x40013808U) = 69U; /* 8MHz/115200 */
|
||||
*((volatile uint32_t *)0x40013800U) = (1U << 3) | (1U << 13);
|
||||
{ const char *_msg = "HXTAL FAIL\r\n";
|
||||
for(int i=0; _msg[i]; i++){
|
||||
*((volatile uint32_t *)0x40013804U) = _msg[i];
|
||||
while((*((volatile uint32_t *)0x40013800U) & (1U << 7)) == 0U) {} } }
|
||||
while(1){ }
|
||||
}
|
||||
|
||||
FMC_WS = (FMC_WS & (~FMC_WS_WSCNT)) | WS_WSCNT(3);
|
||||
@@ -910,8 +950,18 @@ static void system_clock_168m_hxtal(void)
|
||||
|
||||
/* if fail */
|
||||
if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)){
|
||||
while(1){
|
||||
}
|
||||
/* HXTAL failed: output diagnostic via USART0 at IRC8M */
|
||||
*((volatile uint32_t *)0x40021018U) |= (1U << 2) | (1U << 0);
|
||||
{ volatile uint32_t _ctl = *((volatile uint32_t *)0x40010804U);
|
||||
_ctl &= ~(0xFU << 4); _ctl |= (0xBU << 4);
|
||||
*((volatile uint32_t *)0x40010804U) = _ctl; }
|
||||
*((volatile uint32_t *)0x40013808U) = 69U; /* 8MHz/115200 */
|
||||
*((volatile uint32_t *)0x40013800U) = (1U << 3) | (1U << 13);
|
||||
{ const char *_msg = "HXTAL FAIL\r\n";
|
||||
for(int i=0; _msg[i]; i++){
|
||||
*((volatile uint32_t *)0x40013804U) = _msg[i];
|
||||
while((*((volatile uint32_t *)0x40013800U) & (1U << 7)) == 0U) {} } }
|
||||
while(1){ }
|
||||
}
|
||||
|
||||
FMC_WS = (FMC_WS & (~FMC_WS_WSCNT)) | WS_WSCNT(4);
|
||||
@@ -1019,8 +1069,18 @@ static void system_clock_180m_hxtal(void)
|
||||
|
||||
/* if fail */
|
||||
if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)){
|
||||
while(1){
|
||||
}
|
||||
/* HXTAL failed: output diagnostic via USART0 at IRC8M */
|
||||
*((volatile uint32_t *)0x40021018U) |= (1U << 2) | (1U << 0);
|
||||
{ volatile uint32_t _ctl = *((volatile uint32_t *)0x40010804U);
|
||||
_ctl &= ~(0xFU << 4); _ctl |= (0xBU << 4);
|
||||
*((volatile uint32_t *)0x40010804U) = _ctl; }
|
||||
*((volatile uint32_t *)0x40013808U) = 69U; /* 8MHz/115200 */
|
||||
*((volatile uint32_t *)0x40013800U) = (1U << 3) | (1U << 13);
|
||||
{ const char *_msg = "HXTAL FAIL\r\n";
|
||||
for(int i=0; _msg[i]; i++){
|
||||
*((volatile uint32_t *)0x40013804U) = _msg[i];
|
||||
while((*((volatile uint32_t *)0x40013800U) & (1U << 7)) == 0U) {} } }
|
||||
while(1){ }
|
||||
}
|
||||
|
||||
FMC_WS = (FMC_WS & (~FMC_WS_WSCNT)) | WS_WSCNT(4);
|
||||
|
||||
Reference in New Issue
Block a user