refactor: 清理UART调试代码并保留RTT诊断

This commit is contained in:
2026-03-31 22:28:41 +08:00
parent 0f4f89eae4
commit e5fffaccdf
13 changed files with 448 additions and 88 deletions
+174
View File
@@ -0,0 +1,174 @@
# TCP2UART Debug Handoff
## Scope
This log records the debugging work completed so far for:
- UART1 config/debug path on `COM9`
- UART2/UART3 transparent UART paths on `COM8`/`COM7`
- CH390 and lwIP bring-up status
The goal is to preserve the usable conclusions and avoid repeating invalid test paths after context cleanup.
## Final State Summary
### Confirmed working
- HSE clock path is working on the current board/chip/crystal combination.
- ST-Link + RTT debugging works.
- Firmware boots and RTT shows stable startup output.
- UART2 and UART3 TX paths were validated earlier by host-side observation:
- `COM8` receives UART2 debug output.
- `COM7` receives UART3 debug output.
- UART1 config path is working in the current cleaned firmware when the host sends commands with a line ending that the parser actually consumes.
- `AT+?` over UART1 was successfully validated when sent with `\n`.
### Confirmed not yet working
- CH390 is still not operating normally.
- Current one-shot RTT report still shows abnormal values:
- `CH390 VID=0x3A3A PID=0xCCCC REV=0x00 NSR=0x00 LINK=0`
- Therefore lwIP / Ethernet / TCP end-to-end validation remains blocked by CH390 low-level failure.
## Most Important Lessons Learned
### 1. UART1 config failures were partly test-method failures
Several earlier negative conclusions about UART1 config were caused by the debug method rather than firmware defects.
Examples:
- Sending `AT+?` without the line ending expected by the current parser caused false negatives.
- Frequent open/close cycles on the serial port changed timing and control-line behavior.
- Breakpoints in RX callback / parser code prevented reply transmission and created false "no response" results.
- Heavy RTT logging inside hot UART paths distorted timing and even corrupted RTT control state once.
### 2. UART1 parser expects terminators
`config_uart_rx_byte()` only dispatches a command when it sees `\r` or `\n`.
Successful command form that was confirmed:
```text
AT+?\n
```
Do not assume `AT+?` without line ending is valid for this firmware.
### 3. Cleaned firmware state is preferable for future work
Temporary UART diagnostics were removed again after debugging:
- removed boot markers like `BOOT_UARTx_OK`
- removed periodic UART spam
- removed UART1 byte echo
- removed temporary `config_diag` counters
Useful RTT remains:
- `TCP2UART boot`
- HSE fallback warning if used
- CH390 one-shot status report
## Relevant Code Changes Left In Place
These are intentional and should remain unless there is a specific reason to change them.
### UART1 config path
- `App/config.c`
- config handle is back on `huart1`
- `config_uart_rx_byte()` assembles frames from UART1 bytes
- `config_poll()` dispatches a pending complete frame to `config_try_process_frame()`
- `config_try_process_frame()` calls `config_process_at_cmd()` and transmits the response on UART1
- `Core/Src/stm32f1xx_it.c`
- `HAL_UART_RxCpltCallback()` for `huart1` feeds the received byte into `config_uart_rx_byte()` and rearms `HAL_UART_Receive_IT()`
### RTT boot diagnostics
- `Core/Src/main.c`
- retains RTT boot banner
- retains one-shot CH390 report
- no temporary UART spam remains
## Current Firmware Behavior Worth Remembering
### UART1
- UART1 is used for config/debug interaction.
- UART1 parser is line-oriented.
- Use a terminal that sends `LF` or `CRLF` explicitly.
### UART2 / UART3
- UART2 and UART3 are for bridge channels, not the config path.
- Earlier mapping observed during testing:
- `COM8` aligned with UART2 TX activity
- `COM7` aligned with UART3 TX activity
### CH390
- Still unresolved at the low level.
- Do not spend time on lwIP / TCP behavior until CH390 register reads look sane.
## Recommended Next Debug Order
### Priority 1: Preserve UART1 config as known-good
Before touching UART1 code again:
1. Open `COM9` at `115200 8N1`
2. Send:
```text
AT+?\n
```
3. Confirm a full config dump is returned.
If this fails again, check the terminal's actual line ending first before changing code.
### Priority 2: Re-verify UART2/UART3 only if needed
If bridge debugging resumes, first confirm the host can actually open `COM7` and `COM8`.
Host-side availability was inconsistent during the previous session and caused false negatives.
### Priority 3: Resume CH390 low-level debugging
This is the real remaining blocker.
Suggested next steps:
1. Focus on SPI-level sanity before lwIP.
2. Re-check CH390 reset / CS / SPI timing and electrical path.
3. Verify whether SPI mode is correct for the actual hardware.
4. Confirm register reads from CH390 return plausible values before attempting link/TCP tests.
## What Not To Repeat
- Do not judge UART1 config by sending commands without a terminator.
- Do not leave breakpoints inside UART RX callback or parser while expecting normal replies.
- Do not flood RTT inside hot UART receive paths.
- Do not conclude lwIP is broken before CH390 identity reads are sane.
- Do not trust `Win32_SerialPort` alone for COM availability; sometimes `mode COMx` / `Get-PnpDevice -Class Ports` gives a different picture.
## Known Useful Commands
### UART1 config test
```text
AT+?\n
```
### Optional follow-ups
```text
AT+BAUD1=115200\n
AT+SAVE\n
AT+RESET\n
```
## One-Line Handoff
UART1 config is working when tested correctly with a terminator; CH390 is still the unresolved core issue and should be the next serious debug target.
+4
View File
@@ -7,6 +7,7 @@
*.map *.map
*.lst *.lst
*.out *.out
*.log
# IDE # IDE
.vscode/ .vscode/
@@ -34,3 +35,6 @@ Desktop.ini
# 项目文档 # 项目文档
项目计划.md 项目计划.md
# Local debug handoff logs
.debug/
+86 -35
View File
@@ -13,15 +13,20 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#define CONFIG_RX_BUFFER_SIZE 128u #include "SEGGER_RTT.h"
#define CONFIG_TX_BUFFER_SIZE 256u #define CONFIG_TX_BUFFER_SIZE 256u
#define CONFIG_CMD_MAX_LEN 128u #define CONFIG_CMD_MAX_LEN 128u
#define CONFIG_UART_HANDLE huart1
static device_config_t g_config; static device_config_t g_config;
static uint8_t g_rx_buffer[CONFIG_RX_BUFFER_SIZE];
static volatile uint16_t g_rx_index;
static volatile bool g_rx_complete;
static volatile bool g_reset_requested; static volatile bool g_reset_requested;
static char g_uart_cmd_buffer[CONFIG_CMD_MAX_LEN];
static uint16_t g_uart_cmd_len;
static char g_pending_cmd_buffer[CONFIG_CMD_MAX_LEN];
static volatile uint16_t g_pending_cmd_len;
static volatile bool g_pending_cmd_ready;
static uint32_t config_calc_crc(const device_config_t *cfg) static uint32_t config_calc_crc(const device_config_t *cfg)
{ {
@@ -62,6 +67,28 @@ static bool equals_ignore_case(const char *a, const char *b)
return (*a == '\0' && *b == '\0'); return (*a == '\0' && *b == '\0');
} }
static int parse_baudrate_value(const char *value, uint32_t *baudrate)
{
char *endptr;
unsigned long parsed;
if (value == NULL || baudrate == NULL) {
return -1;
}
parsed = strtoul(value, &endptr, 10);
if (endptr == value || *skip_whitespace(endptr) != '\0') {
return -1;
}
if (parsed < 1200ul || parsed > 921600ul) {
return -1;
}
*baudrate = (uint32_t)parsed;
return 0;
}
static at_result_t handle_query(char *response, uint16_t max_len) static at_result_t handle_query(char *response, uint16_t max_len)
{ {
char ip_str[16]; char ip_str[16];
@@ -294,12 +321,18 @@ at_result_t config_process_at_cmd(const char *cmd, char *response, uint16_t max_
return AT_NEED_REBOOT; return AT_NEED_REBOOT;
} }
if (equals_ignore_case(cmd_name, "BAUD1") && value != NULL) { if (equals_ignore_case(cmd_name, "BAUD1") && value != NULL) {
g_config.uart2_baudrate = (uint32_t)atoi(value); if (parse_baudrate_value(value, &g_config.uart2_baudrate) != 0) {
snprintf(response, max_len, "ERROR: Invalid baudrate\r\n");
return AT_INVALID_PARAM;
}
snprintf(response, max_len, "OK\r\n"); snprintf(response, max_len, "OK\r\n");
return AT_NEED_REBOOT; return AT_NEED_REBOOT;
} }
if (equals_ignore_case(cmd_name, "BAUD2") && value != NULL) { if (equals_ignore_case(cmd_name, "BAUD2") && value != NULL) {
g_config.uart3_baudrate = (uint32_t)atoi(value); if (parse_baudrate_value(value, &g_config.uart3_baudrate) != 0) {
snprintf(response, max_len, "ERROR: Invalid baudrate\r\n");
return AT_INVALID_PARAM;
}
snprintf(response, max_len, "OK\r\n"); snprintf(response, max_len, "OK\r\n");
return AT_NEED_REBOOT; return AT_NEED_REBOOT;
} }
@@ -369,54 +402,72 @@ int config_str_to_mac(const char *str, uint8_t *mac)
return 0; return 0;
} }
void config_uart_idle_handler(void)
{
uint16_t dma_counter = __HAL_DMA_GET_COUNTER(huart1.hdmarx);
uint16_t len = (uint16_t)(CONFIG_RX_BUFFER_SIZE - dma_counter);
if (len > 0u) {
g_rx_index = len;
g_rx_complete = true;
}
HAL_UART_DMAStop(&huart1);
HAL_UART_Receive_DMA(&huart1, g_rx_buffer, CONFIG_RX_BUFFER_SIZE);
}
void config_start_reception(void)
{
__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);
HAL_UART_Receive_DMA(&huart1, g_rx_buffer, CONFIG_RX_BUFFER_SIZE);
}
void config_poll(void) void config_poll(void)
{
if (g_pending_cmd_ready) {
uint16_t len = g_pending_cmd_len;
g_pending_cmd_ready = false;
g_pending_cmd_len = 0u;
(void)config_try_process_frame((const uint8_t *)g_pending_cmd_buffer, len);
}
}
void config_uart_rx_byte(uint8_t byte)
{
if (byte == '\r' || byte == '\n') {
if (g_uart_cmd_len > 0u) {
if (!g_pending_cmd_ready) {
memcpy(g_pending_cmd_buffer, g_uart_cmd_buffer, g_uart_cmd_len);
g_pending_cmd_buffer[g_uart_cmd_len] = '\0';
g_pending_cmd_len = g_uart_cmd_len;
g_pending_cmd_ready = true;
}
g_uart_cmd_len = 0u;
}
return;
}
if (g_uart_cmd_len < (CONFIG_CMD_MAX_LEN - 1u)) {
g_uart_cmd_buffer[g_uart_cmd_len++] = (char)byte;
g_uart_cmd_buffer[g_uart_cmd_len] = '\0';
} else {
g_uart_cmd_len = 0u;
}
}
bool config_try_process_frame(const uint8_t *data, uint16_t len)
{ {
char response[CONFIG_TX_BUFFER_SIZE]; char response[CONFIG_TX_BUFFER_SIZE];
char cmd_buffer[CONFIG_CMD_MAX_LEN]; char cmd_buffer[CONFIG_CMD_MAX_LEN];
at_result_t result; at_result_t result;
uint16_t len; HAL_StatusTypeDef tx_status;
if (!g_rx_complete) { if (data == NULL || len < 2u) {
return; return false;
} }
len = g_rx_index;
if (len >= CONFIG_CMD_MAX_LEN) { if (len >= CONFIG_CMD_MAX_LEN) {
len = CONFIG_CMD_MAX_LEN - 1u; len = CONFIG_CMD_MAX_LEN - 1u;
} }
memcpy(cmd_buffer, g_rx_buffer, len); memcpy(cmd_buffer, data, len);
cmd_buffer[len] = '\0'; cmd_buffer[len] = '\0';
g_rx_complete = false;
g_rx_index = 0u; if (((cmd_buffer[0] != 'A') && (cmd_buffer[0] != 'a')) ||
((cmd_buffer[1] != 'T') && (cmd_buffer[1] != 't'))) {
return false;
}
result = config_process_at_cmd(cmd_buffer, response, sizeof(response)); result = config_process_at_cmd(cmd_buffer, response, sizeof(response));
HAL_UART_Transmit(&huart1, (uint8_t *)response, (uint16_t)strlen(response), 1000u); tx_status = HAL_UART_Transmit(&CONFIG_UART_HANDLE, (uint8_t *)response, (uint16_t)strlen(response), 1000u);
if (result == AT_NEED_REBOOT) { if (result == AT_NEED_REBOOT) {
static const char hint[] = "Note: Use AT+SAVE then AT+RESET to apply changes\r\n"; static const char hint[] = "Note: Use AT+SAVE then AT+RESET to apply changes\r\n";
HAL_UART_Transmit(&huart1, (uint8_t *)hint, sizeof(hint) - 1u, 1000u); tx_status = HAL_UART_Transmit(&CONFIG_UART_HANDLE, (uint8_t *)hint, sizeof(hint) - 1u, 1000u);
} }
return true;
} }
bool config_is_reset_requested(void) bool config_is_reset_requested(void)
+14 -10
View File
@@ -144,21 +144,25 @@ device_config_t *config_get_mutable(void);
*/ */
at_result_t config_process_at_cmd(const char *cmd, char *response, uint16_t max_len); at_result_t config_process_at_cmd(const char *cmd, char *response, uint16_t max_len);
/**
* @brief UART1 IDLE interrupt handler for config module
*/
void config_uart_idle_handler(void);
/**
* @brief Start UART1 reception for configuration
*/
void config_start_reception(void);
/** /**
* @brief Poll configuration UART and process pending AT commands * @brief Poll configuration UART and process pending AT commands
*/ */
void config_poll(void); void config_poll(void);
/**
* @brief Feed one byte received from the config UART.
* @param byte Received byte.
*/
void config_uart_rx_byte(uint8_t byte);
/**
* @brief Try to process one AT command frame from an external UART source.
* @param data Input bytes.
* @param len Input length.
* @return true if the frame was recognized as an AT/config command.
*/
bool config_try_process_frame(const uint8_t *data, uint16_t len);
/** /**
* @brief Check whether AT+RESET requested a system reset * @brief Check whether AT+RESET requested a system reset
*/ */
+4
View File
@@ -192,6 +192,7 @@ int uart_trans_start(uart_channel_t channel)
ctx->tx_tail = 0u; ctx->tx_tail = 0u;
ctx->tx_dma_len = 0u; ctx->tx_dma_len = 0u;
ctx->tx_busy = false; ctx->tx_busy = false;
memset(&ctx->stats, 0, sizeof(ctx->stats));
__HAL_UART_ENABLE_IT(ctx->huart, UART_IT_IDLE); __HAL_UART_ENABLE_IT(ctx->huart, UART_IT_IDLE);
if (HAL_UART_Receive_DMA(ctx->huart, ctx->rx_dma_buffer, UART_RX_DMA_BUFFER_SIZE) != HAL_OK) { if (HAL_UART_Receive_DMA(ctx->huart, ctx->rx_dma_buffer, UART_RX_DMA_BUFFER_SIZE) != HAL_OK) {
@@ -302,6 +303,7 @@ void uart_trans_idle_handler(uart_channel_t channel)
} }
huart = g_channels[channel].huart; huart = g_channels[channel].huart;
g_channels[channel].stats.idle_events++;
dma_write_index = (uint16_t)(UART_RX_DMA_BUFFER_SIZE - __HAL_DMA_GET_COUNTER(huart->hdmarx)); dma_write_index = (uint16_t)(UART_RX_DMA_BUFFER_SIZE - __HAL_DMA_GET_COUNTER(huart->hdmarx));
if (dma_write_index >= UART_RX_DMA_BUFFER_SIZE) { if (dma_write_index >= UART_RX_DMA_BUFFER_SIZE) {
dma_write_index = 0u; dma_write_index = 0u;
@@ -316,6 +318,7 @@ void uart_trans_rx_half_cplt_handler(uart_channel_t channel)
return; return;
} }
g_channels[channel].stats.rx_half_events++;
process_rx_snapshot(channel, UART_RX_DMA_BUFFER_SIZE / 2u); process_rx_snapshot(channel, UART_RX_DMA_BUFFER_SIZE / 2u);
} }
@@ -325,6 +328,7 @@ void uart_trans_rx_cplt_handler(uart_channel_t channel)
return; return;
} }
g_channels[channel].stats.rx_full_events++;
process_rx_snapshot(channel, 0u); process_rx_snapshot(channel, 0u);
} }
+3
View File
@@ -41,6 +41,9 @@ typedef struct {
uint32_t tx_bytes; uint32_t tx_bytes;
uint32_t rx_packets; uint32_t rx_packets;
uint32_t tx_packets; uint32_t tx_packets;
uint32_t idle_events;
uint32_t rx_half_events;
uint32_t rx_full_events;
uint32_t errors; uint32_t errors;
} uart_stats_t; } uart_stats_t;
+1
View File
@@ -53,6 +53,7 @@ extern "C" {
void Error_Handler(void); void Error_Handler(void);
/* USER CODE BEGIN EFP */ /* USER CODE BEGIN EFP */
void Debug_TrapWithRttHint(const char *tag);
/* USER CODE END EFP */ /* USER CODE END EFP */
+120 -12
View File
@@ -31,6 +31,7 @@
#include <string.h> #include <string.h>
#include "CH390.h" #include "CH390.h"
#include "CH390_Interface.h"
#include "SEGGER_RTT.h" #include "SEGGER_RTT.h"
#include "config.h" #include "config.h"
#include "flash_param.h" #include "flash_param.h"
@@ -69,6 +70,8 @@
/* USER CODE BEGIN PV */ /* USER CODE BEGIN PV */
static volatile uint16_t g_led_blink_ticks = 0; static volatile uint16_t g_led_blink_ticks = 0;
static uint8_t g_clock_fallback_to_hsi = 0u;
volatile uint8_t g_uart1_rx_probe_byte = 0u;
/* USER CODE END PV */ /* USER CODE END PV */
@@ -78,6 +81,8 @@ void SystemClock_Config(void);
static void CH390_HardwareReset(void); static void CH390_HardwareReset(void);
static void LED_Init(void); static void LED_Init(void);
static void LED_StartBlink(void); static void LED_StartBlink(void);
static void BootDiag_ReportCh390(void);
static void App_PollUart1ConfigRx(void);
static void App_Init(void); static void App_Init(void);
static void App_Poll(void); static void App_Poll(void);
/* USER CODE END PFP */ /* USER CODE END PFP */
@@ -138,6 +143,77 @@ void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
} }
} }
static void BootDiag_ReportCh390(void)
{
uint16_t vendor_id;
uint16_t product_id;
uint8_t revision;
uint8_t nsr;
uint8_t ncr;
uint8_t rcr;
uint8_t imr;
uint8_t intcr;
uint8_t gpr;
uint8_t isr;
uint8_t ncr_before;
uint8_t ncr_after;
uint8_t intcr_before;
uint8_t intcr_after;
int link_status;
vendor_id = ch390_get_vendor_id();
product_id = ch390_get_product_id();
revision = ch390_get_revision();
nsr = ch390_read_reg(CH390_NSR);
ncr = ch390_read_reg(CH390_NCR);
rcr = ch390_read_reg(CH390_RCR);
imr = ch390_read_reg(CH390_IMR);
intcr = ch390_read_reg(CH390_INTCR);
gpr = ch390_read_reg(CH390_GPR);
isr = ch390_read_reg(CH390_ISR);
link_status = ch390_get_link_status();
ncr_before = ncr;
ch390_write_reg(CH390_NCR, (uint8_t)(ncr_before ^ NCR_FDX));
ncr_after = ch390_read_reg(CH390_NCR);
ch390_write_reg(CH390_NCR, ncr_before);
intcr_before = intcr;
ch390_write_reg(CH390_INTCR, (uint8_t)(INCR_TYPE_OD | INCR_POL_L));
intcr_after = ch390_read_reg(CH390_INTCR);
ch390_write_reg(CH390_INTCR, intcr_before);
SEGGER_RTT_printf(0,
"CH390 VID=0x%04X PID=0x%04X REV=0x%02X NSR=0x%02X LINK=%d\r\n",
vendor_id,
product_id,
revision,
nsr,
link_status);
SEGGER_RTT_printf(0,
"CH390 NCR=0x%02X RCR=0x%02X IMR=0x%02X INTCR=0x%02X GPR=0x%02X ISR=0x%02X\r\n",
ncr,
rcr,
imr,
intcr,
gpr,
isr);
SEGGER_RTT_printf(0,
"CH390 WRCHK NCR:0x%02X->0x%02X INTCR:0x%02X->0x%02X\r\n",
ncr_before,
ncr_after,
intcr_before,
intcr_after);
}
static void App_PollUart1ConfigRx(void)
{
while (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_RXNE) != RESET) {
uint8_t byte = (uint8_t)(huart1.Instance->DR & 0xFFu);
config_uart_rx_byte(byte);
}
}
static void App_Init(void) static void App_Init(void)
{ {
const device_config_t *cfg; const device_config_t *cfg;
@@ -167,16 +243,19 @@ static void App_Init(void)
uart_trans_start(UART_CHANNEL_SERVER); uart_trans_start(UART_CHANNEL_SERVER);
uart_trans_start(UART_CHANNEL_CLIENT); uart_trans_start(UART_CHANNEL_CLIENT);
config_start_reception();
SEGGER_RTT_Init(); SEGGER_RTT_Init();
SEGGER_RTT_WriteString(0, "\r\nTCP2UART boot\r\n"); SEGGER_RTT_WriteString(0, "\r\nTCP2UART boot\r\n");
if (g_clock_fallback_to_hsi != 0u) {
SEGGER_RTT_WriteString(0, "WARN: HSE start failed, fallback to HSI PLL\r\n");
}
lwip_init(); lwip_init();
IP4_ADDR(&ipaddr, cfg->ip[0], cfg->ip[1], cfg->ip[2], cfg->ip[3]); IP4_ADDR(&ipaddr, cfg->ip[0], cfg->ip[1], cfg->ip[2], cfg->ip[3]);
IP4_ADDR(&netmask, cfg->mask[0], cfg->mask[1], cfg->mask[2], cfg->mask[3]); IP4_ADDR(&netmask, cfg->mask[0], cfg->mask[1], cfg->mask[2], cfg->mask[3]);
IP4_ADDR(&gateway, cfg->gw[0], cfg->gw[1], cfg->gw[2], cfg->gw[3]); IP4_ADDR(&gateway, cfg->gw[0], cfg->gw[1], cfg->gw[2], cfg->gw[3]);
lwip_netif_init(&ipaddr, &netmask, &gateway); lwip_netif_init(&ipaddr, &netmask, &gateway);
BootDiag_ReportCh390();
server_cfg.port = cfg->server_port; server_cfg.port = cfg->server_port;
server_cfg.auto_reconnect = true; server_cfg.auto_reconnect = true;
@@ -189,6 +268,11 @@ static void App_Init(void)
client_cfg.reconnect_interval_ms = cfg->reconnect_interval; client_cfg.reconnect_interval_ms = cfg->reconnect_interval;
tcp_client_init(&client_cfg); tcp_client_init(&client_cfg);
tcp_client_connect(); tcp_client_connect();
/* Arm UART1 RX interrupt path so config commands can enter via USART1. */
if (HAL_UART_Receive_IT(&huart1, (uint8_t *)&g_uart1_rx_probe_byte, 1u) != HAL_OK) {
Error_Handler();
}
} }
static void App_Poll(void) static void App_Poll(void)
@@ -201,6 +285,7 @@ static void App_Poll(void)
sys_check_timeouts(); sys_check_timeouts();
tcp_client_poll(); tcp_client_poll();
uart_trans_poll(); uart_trans_poll();
App_PollUart1ConfigRx();
config_poll(); config_poll();
len = tcp_server_recv(buffer, sizeof(buffer), 0u); len = tcp_server_recv(buffer, sizeof(buffer), 0u);
@@ -275,9 +360,6 @@ int main(void)
LED_Init(); LED_Init();
LED_StartBlink(); LED_StartBlink();
/* CH390 硬件复位 */
CH390_HardwareReset();
App_Init(); App_Init();
/* USER CODE END 2 */ /* USER CODE END 2 */
@@ -303,6 +385,8 @@ void SystemClock_Config(void)
RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
g_clock_fallback_to_hsi = 0u;
/** Initializes the RCC Oscillators according to the specified parameters /** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure. * in the RCC_OscInitTypeDef structure.
*/ */
@@ -314,10 +398,24 @@ void SystemClock_Config(void)
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9; RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
{ /*
* Some bring-up boards fail to start the external crystal cleanly.
* Fall back to HSI-based PLL so the firmware can still boot and expose
* RTT / debugger evidence instead of trapping during clock init.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSEState = RCC_HSE_OFF;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.LSIState = RCC_LSI_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI_DIV2;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL16;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
Error_Handler(); Error_Handler();
} }
g_clock_fallback_to_hsi = 1u;
}
/** Initializes the CPU, AHB and APB buses clocks /** Initializes the CPU, AHB and APB buses clocks
*/ */
@@ -354,6 +452,18 @@ int fputc(int ch, FILE *f)
} }
#endif #endif
void Debug_TrapWithRttHint(const char *tag)
{
SEGGER_RTT_WriteString(0, "\r\nTRAP: ");
SEGGER_RTT_WriteString(0, tag);
SEGGER_RTT_WriteString(0, "\r\n");
__disable_irq();
__BKPT(0);
while (1)
{
}
}
/* USER CODE END 4 */ /* USER CODE END 4 */
/** /**
@@ -364,12 +474,7 @@ void Error_Handler(void)
{ {
/* USER CODE BEGIN Error_Handler_Debug */ /* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */ /* User can add his own implementation to report the HAL error return state */
SEGGER_RTT_WriteString(0, "\r\nError_Handler hit\r\n"); Debug_TrapWithRttHint("Error_Handler");
__disable_irq();
__BKPT(0);
while (1)
{
}
/* USER CODE END Error_Handler_Debug */ /* USER CODE END Error_Handler_Debug */
} }
#ifdef USE_FULL_ASSERT #ifdef USE_FULL_ASSERT
@@ -383,6 +488,9 @@ void Error_Handler(void)
void assert_failed(uint8_t *file, uint32_t line) void assert_failed(uint8_t *file, uint32_t line)
{ {
/* USER CODE BEGIN 6 */ /* USER CODE BEGIN 6 */
(void)file;
(void)line;
Debug_TrapWithRttHint("assert_failed");
/* User can add his own implementation to report the file name and line number, /* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */ /* USER CODE END 6 */
+14 -30
View File
@@ -23,6 +23,7 @@
/* Private includes ----------------------------------------------------------*/ /* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */ /* USER CODE BEGIN Includes */
#include "ethernetif.h" #include "ethernetif.h"
#include "SEGGER_RTT.h"
#include "uart_trans.h" #include "uart_trans.h"
#include "config.h" #include "config.h"
/* USER CODE END Includes */ /* USER CODE END Includes */
@@ -85,9 +86,7 @@ void NMI_Handler(void)
/* USER CODE END NonMaskableInt_IRQn 0 */ /* USER CODE END NonMaskableInt_IRQn 0 */
/* USER CODE BEGIN NonMaskableInt_IRQn 1 */ /* USER CODE BEGIN NonMaskableInt_IRQn 1 */
while (1) Debug_TrapWithRttHint("NMI_Handler");
{
}
/* USER CODE END NonMaskableInt_IRQn 1 */ /* USER CODE END NonMaskableInt_IRQn 1 */
} }
@@ -99,11 +98,7 @@ void HardFault_Handler(void)
/* USER CODE BEGIN HardFault_IRQn 0 */ /* USER CODE BEGIN HardFault_IRQn 0 */
/* USER CODE END HardFault_IRQn 0 */ /* USER CODE END HardFault_IRQn 0 */
while (1) Debug_TrapWithRttHint("HardFault_Handler");
{
/* USER CODE BEGIN W1_HardFault_IRQn 0 */
/* USER CODE END W1_HardFault_IRQn 0 */
}
} }
/** /**
@@ -114,11 +109,7 @@ void MemManage_Handler(void)
/* USER CODE BEGIN MemoryManagement_IRQn 0 */ /* USER CODE BEGIN MemoryManagement_IRQn 0 */
/* USER CODE END MemoryManagement_IRQn 0 */ /* USER CODE END MemoryManagement_IRQn 0 */
while (1) Debug_TrapWithRttHint("MemManage_Handler");
{
/* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */
/* USER CODE END W1_MemoryManagement_IRQn 0 */
}
} }
/** /**
@@ -129,11 +120,7 @@ void BusFault_Handler(void)
/* USER CODE BEGIN BusFault_IRQn 0 */ /* USER CODE BEGIN BusFault_IRQn 0 */
/* USER CODE END BusFault_IRQn 0 */ /* USER CODE END BusFault_IRQn 0 */
while (1) Debug_TrapWithRttHint("BusFault_Handler");
{
/* USER CODE BEGIN W1_BusFault_IRQn 0 */
/* USER CODE END W1_BusFault_IRQn 0 */
}
} }
/** /**
@@ -144,11 +131,7 @@ void UsageFault_Handler(void)
/* USER CODE BEGIN UsageFault_IRQn 0 */ /* USER CODE BEGIN UsageFault_IRQn 0 */
/* USER CODE END UsageFault_IRQn 0 */ /* USER CODE END UsageFault_IRQn 0 */
while (1) Debug_TrapWithRttHint("UsageFault_Handler");
{
/* USER CODE BEGIN W1_UsageFault_IRQn 0 */
/* USER CODE END W1_UsageFault_IRQn 0 */
}
} }
/** /**
@@ -303,12 +286,6 @@ void SPI1_IRQHandler(void)
void USART1_IRQHandler(void) void USART1_IRQHandler(void)
{ {
/* USER CODE BEGIN USART1_IRQn 0 */ /* USER CODE BEGIN USART1_IRQn 0 */
/* Handle IDLE interrupt for configuration */
if (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE))
{
__HAL_UART_CLEAR_IDLEFLAG(&huart1);
config_uart_idle_handler();
}
/* USER CODE END USART1_IRQn 0 */ /* USER CODE END USART1_IRQn 0 */
HAL_UART_IRQHandler(&huart1); HAL_UART_IRQHandler(&huart1);
/* USER CODE BEGIN USART1_IRQn 1 */ /* USER CODE BEGIN USART1_IRQn 1 */
@@ -355,6 +332,8 @@ void USART3_IRQHandler(void)
} }
/* USER CODE BEGIN 1 */ /* USER CODE BEGIN 1 */
extern volatile uint8_t g_uart1_rx_probe_byte;
/** /**
* @brief This function handles EXTI0 interrupt (CH390D INT pin). * @brief This function handles EXTI0 interrupt (CH390D INT pin).
*/ */
@@ -390,7 +369,12 @@ void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
*/ */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{ {
if (huart == &huart2) if (huart == &huart1)
{
config_uart_rx_byte(g_uart1_rx_probe_byte);
HAL_UART_Receive_IT(&huart1, (uint8_t *)&g_uart1_rx_probe_byte, 1u);
}
else if (huart == &huart2)
{ {
uart_trans_rx_cplt_handler(UART_CHANNEL_SERVER); uart_trans_rx_cplt_handler(UART_CHANNEL_SERVER);
} }
+2 -1
View File
@@ -21,6 +21,7 @@
*/ */
/* Includes */ /* Includes */
#include "main.h"
#include <sys/stat.h> #include <sys/stat.h>
#include <stdlib.h> #include <stdlib.h>
#include <errno.h> #include <errno.h>
@@ -61,7 +62,7 @@ int _kill(int pid, int sig)
void _exit (int status) void _exit (int status)
{ {
_kill(status, -1); _kill(status, -1);
while (1) {} /* Make sure we hang here */ Debug_TrapWithRttHint("_exit");
} }
__attribute__((weak)) int _read(int file, char *ptr, int len) __attribute__((weak)) int _read(int file, char *ptr, int len)
+1 -1
View File
@@ -78,7 +78,7 @@
</option> </option>
<option> <option>
<name>OGChipSelectEditMenu</name> <name>OGChipSelectEditMenu</name>
<state>STM32F103RC ST STM32F103RC</state> <state>STM32F103R8 ST STM32F103R8</state>
</option> </option>
<option> <option>
<name>GenLowLevelInterface</name> <name>GenLowLevelInterface</name>
+17 -1
View File
@@ -2,8 +2,20 @@
#include <string.h> #include <string.h>
SEGGER_RTT_CB _SEGGER_RTT;
static char _acUpBuffer[BUFFER_SIZE_UP]; static char _acUpBuffer[BUFFER_SIZE_UP];
static char _acDownBuffer[BUFFER_SIZE_DOWN];
SEGGER_RTT_CB _SEGGER_RTT = {
"SEGGER RTT",
SEGGER_RTT_MAX_NUM_UP_BUFFERS,
SEGGER_RTT_MAX_NUM_DOWN_BUFFERS,
{
{ "Terminal", _acUpBuffer, BUFFER_SIZE_UP, 0u, 0u, SEGGER_RTT_MODE_DEFAULT }
},
{
{ "Terminal", _acDownBuffer, BUFFER_SIZE_DOWN, 0u, 0u, SEGGER_RTT_MODE_DEFAULT }
}
};
void SEGGER_RTT_Init(void) void SEGGER_RTT_Init(void)
{ {
@@ -15,6 +27,10 @@ void SEGGER_RTT_Init(void)
_SEGGER_RTT.aUp[0].pBuffer = _acUpBuffer; _SEGGER_RTT.aUp[0].pBuffer = _acUpBuffer;
_SEGGER_RTT.aUp[0].SizeOfBuffer = BUFFER_SIZE_UP; _SEGGER_RTT.aUp[0].SizeOfBuffer = BUFFER_SIZE_UP;
_SEGGER_RTT.aUp[0].Flags = SEGGER_RTT_MODE_DEFAULT; _SEGGER_RTT.aUp[0].Flags = SEGGER_RTT_MODE_DEFAULT;
_SEGGER_RTT.aDown[0].sName = "Terminal";
_SEGGER_RTT.aDown[0].pBuffer = _acDownBuffer;
_SEGGER_RTT.aDown[0].SizeOfBuffer = BUFFER_SIZE_DOWN;
_SEGGER_RTT.aDown[0].Flags = SEGGER_RTT_MODE_DEFAULT;
} }
static void _EnsureInit(void) static void _EnsureInit(void)
+10
View File
@@ -18,11 +18,21 @@ typedef struct {
unsigned Flags; unsigned Flags;
} SEGGER_RTT_BUFFER_UP; } SEGGER_RTT_BUFFER_UP;
typedef struct {
const char *sName;
char *pBuffer;
unsigned SizeOfBuffer;
volatile unsigned WrOff;
unsigned RdOff;
unsigned Flags;
} SEGGER_RTT_BUFFER_DOWN;
typedef struct { typedef struct {
char acID[16]; char acID[16];
int MaxNumUpBuffers; int MaxNumUpBuffers;
int MaxNumDownBuffers; int MaxNumDownBuffers;
SEGGER_RTT_BUFFER_UP aUp[SEGGER_RTT_MAX_NUM_UP_BUFFERS]; SEGGER_RTT_BUFFER_UP aUp[SEGGER_RTT_MAX_NUM_UP_BUFFERS];
SEGGER_RTT_BUFFER_DOWN aDown[SEGGER_RTT_MAX_NUM_DOWN_BUFFERS];
} SEGGER_RTT_CB; } SEGGER_RTT_CB;
extern SEGGER_RTT_CB _SEGGER_RTT; extern SEGGER_RTT_CB _SEGGER_RTT;