refactor: 清理UART调试代码并保留RTT诊断
This commit is contained in:
@@ -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.
|
||||||
@@ -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
@@ -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
@@ -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
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user