From efb88ea367d96cc1a1978bdd5b61272cee5be717 Mon Sep 17 00:00:00 2001 From: xiao Date: Sun, 5 Apr 2026 03:47:54 +0800 Subject: [PATCH] feat(ch390): optimize SPI transfer, MAC fallback, and build settings for V1.0.0 - increase UART DMA/ring buffer sizes for mux traffic - switch SPI1 to Mode0 with prescaler /2 and align CubeMX settings - refactor CH390 memory read/write path with chunked SPI read and HAL bulk write - fallback to hardware MAC when configured MAC is invalid (all-zero) - add mux frame RTT logs and remove redundant UART1 polling - update Keil post-build viewer integration and include build viewer artifacts - update AT manual with all-zero MAC behavior --- AT固件使用手册.md | 4 ++ App/uart_trans.h | 8 ++-- Core/Src/main.c | 12 +---- Core/Src/spi.c | 2 +- Drivers/CH390/CH390_Interface.c | 49 +++++++++++++------- Drivers/CH390/ch390_runtime.c | 27 ++++++++++- MDK-ARM/TCP2UART.uvoptx | 4 +- MDK-ARM/TCP2UART.uvprojx | 6 +-- MDK-ARM/keil-build-viewer-record.txt | 64 +++++++++++++++++++++++++++ MDK-ARM/keil-build-viewer.exe | Bin 0 -> 101256 bytes TCP2UART.ioc | 8 ++-- 11 files changed, 143 insertions(+), 41 deletions(-) create mode 100644 MDK-ARM/keil-build-viewer-record.txt create mode 100644 MDK-ARM/keil-build-viewer.exe diff --git a/AT固件使用手册.md b/AT固件使用手册.md index 5b277da..d88bc34 100644 --- a/AT固件使用手册.md +++ b/AT固件使用手册.md @@ -235,6 +235,10 @@ AT+NET?\r\n OK ``` +**MAC 设置说明:** + +当MAC设置为全0时,固件将使用硬件MAC地址,此时通过AT+?查询到的MAC地址即为当前生效的硬件MAC地址。 + ### 8.5 LINK 类命令 #### 设置单条 LINK 记录 diff --git a/App/uart_trans.h b/App/uart_trans.h index 94dc4e4..3024021 100644 --- a/App/uart_trans.h +++ b/App/uart_trans.h @@ -26,10 +26,10 @@ typedef struct { uint8_t payload[256]; } uart_mux_frame_t; -#define UART_RX_DMA_BUFFER_SIZE 128u -#define UART_TX_DMA_BUFFER_SIZE 128u -#define UART_RX_RING_BUFFER_SIZE 256u -#define UART_TX_RING_BUFFER_SIZE 256u +#define UART_RX_DMA_BUFFER_SIZE 256u +#define UART_TX_DMA_BUFFER_SIZE 256u +#define UART_RX_RING_BUFFER_SIZE 512u +#define UART_TX_RING_BUFFER_SIZE 384u #define UART_DEFAULT_BAUDRATE 115200u typedef struct { diff --git a/Core/Src/main.c b/Core/Src/main.c index 7eae588..6d3a6a9 100644 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -57,7 +57,6 @@ void SystemClock_Config(void); static void LED_Init(void); static void LED_StartBlink(void); static void BootDiag_ReportCh390(void); -static void App_PollUart1ConfigRx(void); static void App_Init(void); static void App_Poll(void); static void App_ConfigureLinks(const device_config_t *cfg); @@ -143,14 +142,6 @@ static void BootDiag_ReportCh390(void) cfg->mux_mode); } -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_ConfigureLinks(const device_config_t *cfg) { tcp_server_instance_config_t server_cfg; @@ -352,6 +343,7 @@ static void App_RouteMuxUartTraffic(void) const device_config_t *cfg = config_get(); while (uart_mux_try_extract_frame(UART_CHANNEL_U0, &frame)) { + SEGGER_RTT_printf(0, "Mux frame from UART0: src_id=%u dst_mask=0x%02X len=%u\r\n", frame.src_id, frame.dst_mask, frame.payload_len); if (frame.dst_mask == 0u) { at_result_t result; char *response_text = (char *)&g_mux_response_frame[5]; @@ -390,6 +382,7 @@ static void App_RouteMuxUartTraffic(void) } while (uart_mux_try_extract_frame(UART_CHANNEL_U1, &frame)) { + SEGGER_RTT_printf(0, "Mux frame from UART1: src_id=%u dst_mask=0x%02X len=%u\r\n", frame.src_id, frame.dst_mask, frame.payload_len); if (frame.dst_mask == 0u) { at_result_t result; char *response_text = (char *)&g_mux_response_frame[5]; @@ -437,7 +430,6 @@ static void App_Poll(void) App_StartLinksIfNeeded(); tcp_client_poll(); uart_trans_poll(); - App_PollUart1ConfigRx(); StackGuard_Check(); config_poll(); App_RouteTcpTraffic(); diff --git a/Core/Src/spi.c b/Core/Src/spi.c index c04adb0..b879e0f 100644 --- a/Core/Src/spi.c +++ b/Core/Src/spi.c @@ -44,7 +44,7 @@ void MX_SPI1_Init(void) hspi1.Init.CLKPolarity = SPI_POLARITY_LOW; /* Match CH390 runtime baseline: CPOL=Low */ hspi1.Init.CLKPhase = SPI_PHASE_1EDGE; /* Match CH390 runtime baseline: CPHA=1Edge (Mode 0) */ hspi1.Init.NSS = SPI_NSS_SOFT; /* Software CS control for CH390 */ - hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64; /* 72MHz/64 = 1.125MHz for conservative CH390 bring-up */ + hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2; /* 72MHz/2 = 36MHz, max SPI1 clock at current APB2 */ hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB; hspi1.Init.TIMode = SPI_TIMODE_DISABLE; hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; diff --git a/Drivers/CH390/CH390_Interface.c b/Drivers/CH390/CH390_Interface.c index d55da0c..c6c2a16 100644 --- a/Drivers/CH390/CH390_Interface.c +++ b/Drivers/CH390/CH390_Interface.c @@ -60,6 +60,7 @@ extern SPI_HandleTypeDef hspi1; /* Timeout for SPI operations (ms) */ #define SPI_TIMEOUT 100 +#define CH390_SPI_CHUNK_SIZE 64u /*---------------------------------------------------------------------------- * Low-level GPIO operations @@ -105,6 +106,24 @@ static uint8_t ch390_spi_exchange_byte(uint8_t byte) return rx_data; } +static int ch390_spi_read_bytes(uint8_t *data, uint16_t length) +{ + static const uint8_t dummy_tx[CH390_SPI_CHUNK_SIZE] = {0}; + + while (length > 0u) + { + uint16_t chunk = (length > CH390_SPI_CHUNK_SIZE) ? CH390_SPI_CHUNK_SIZE : length; + if (HAL_SPI_TransmitReceive(&hspi1, (uint8_t *)dummy_tx, data, chunk, SPI_TIMEOUT) != HAL_OK) + { + return -1; + } + data += chunk; + length = (uint16_t)(length - chunk); + } + + return 0; +} + static void ch390_spi_apply_mode(uint32_t polarity, uint32_t phase) { hspi1.Init.CLKPolarity = polarity; @@ -281,16 +300,15 @@ void ch390_write_reg(uint8_t reg, uint8_t value) */ void ch390_read_mem(uint8_t *data, int length) { - int i; - + if (data == NULL || length <= 0) + { + return; + } + ch390_cs(0); /* CS low - select */ ch390_spi_exchange_byte(OPC_MEM_READ); /* Send memory read command */ - - /* Read data bytes */ - for (i = 0; i < length; i++) - { - data[i] = ch390_spi_dummy_read(); - } + + (void)ch390_spi_read_bytes(data, (uint16_t)length); ch390_cs(1); /* CS high - deselect */ } @@ -322,16 +340,15 @@ void ch390_read_mem_dma(uint8_t *data, int length) */ void ch390_write_mem(uint8_t *data, int length) { - int i; - + if (data == NULL || length <= 0) + { + return; + } + ch390_cs(0); /* CS low - select */ ch390_spi_exchange_byte(OPC_MEM_WRITE); /* Send memory write command */ - - /* Write data bytes */ - for (i = 0; i < length; i++) - { - ch390_spi_exchange_byte(data[i]); - } + + (void)HAL_SPI_Transmit(&hspi1, data, (uint16_t)length, SPI_TIMEOUT); ch390_cs(1); /* CS high - deselect */ } diff --git a/Drivers/CH390/ch390_runtime.c b/Drivers/CH390/ch390_runtime.c index afbb699..dd930a6 100644 --- a/Drivers/CH390/ch390_runtime.c +++ b/Drivers/CH390/ch390_runtime.c @@ -157,6 +157,19 @@ struct pbuf *ch390_runtime_input_frame(struct netif *netif) return p; } +bool ch390_mac_address_valid(const uint8_t *mac) +{ + if (mac == NULL) { + return false; + } + for (uint8_t i = 0; i < ETHARP_HWADDR_LEN; ++i) { + if (mac[i] == 0u) { + return false; + } + } + return true; +} + void ch390_runtime_init(struct netif *netif, const uint8_t *mac) { struct ethernetif *ethernetif = (struct ethernetif *)netif->state; @@ -186,7 +199,19 @@ void ch390_runtime_init(struct netif *netif, const uint8_t *mac) SEGGER_RTT_WriteString(0, "ETH init: default\r\n"); ch390_default_config(); SEGGER_RTT_WriteString(0, "ETH init: mac\r\n"); - ch390_set_mac_address((uint8_t *)mac); + if (ch390_mac_address_valid(mac)) { + ch390_set_mac_address((uint8_t *)mac); + } + else { + if (mac != NULL) { + ch390_get_mac((uint8_t *)mac); + SEGGER_RTT_printf(0, "ETH init: invalid MAC in config, using hardware MAC: %02X:%02X:%02X:%02X:%02X:%02X\r\n", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + } + else { + SEGGER_RTT_WriteString(0, "ETH init: no MAC in config\r\n"); + } + } netif->hwaddr_len = ETHARP_HWADDR_LEN; SEGGER_RTT_WriteString(0, "ETH init: getmac\r\n"); diff --git a/MDK-ARM/TCP2UART.uvoptx b/MDK-ARM/TCP2UART.uvoptx index 25488f9..2a37074 100644 --- a/MDK-ARM/TCP2UART.uvoptx +++ b/MDK-ARM/TCP2UART.uvoptx @@ -45,7 +45,7 @@ 79 66 8 - + .\TCP2UART\ 1 @@ -140,7 +140,7 @@ 0 CMSIS_AGDI - -X"Any" -UAny -O206 -S8 -C0 -P00000000 -N00("ARM CoreSight SW-DP") -D00(1BA01477) -L00(0) -TO65554 -TC10000000 -TT10000000 -TP20 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32F10x_128.FLM -FS08000000 -FL020000 -FP0($$Device:STM32F103R8$Flash\STM32F10x_128.FLM) + -X"Any" -UAny -O206 -S8 -C0 -P00000000 -N00("ARM CoreSight SW-DP") -D00(1BA01477) -L00(0) -TO65554 -TC10000000 -TT10000000 -TP20 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO15 -FD20000000 -FC1000 -FN1 -FF0STM32F10x_128.FLM -FS08000000 -FL020000 -FP0($$Device:STM32F103R8$Flash\STM32F10x_128.FLM) 0 diff --git a/MDK-ARM/TCP2UART.uvprojx b/MDK-ARM/TCP2UART.uvprojx index 7abe30f..5071c1c 100644 --- a/MDK-ARM/TCP2UART.uvprojx +++ b/MDK-ARM/TCP2UART.uvprojx @@ -55,7 +55,7 @@ 1 1 1 - + .\TCP2UART\ 1 0 0 @@ -80,9 +80,9 @@ 0 - 0 + 1 0 - + keil-build-viewer.exe -NOPATH 0 0 diff --git a/MDK-ARM/keil-build-viewer-record.txt b/MDK-ARM/keil-build-viewer-record.txt new file mode 100644 index 0000000..6be3ba3 --- /dev/null +++ b/MDK-ARM/keil-build-viewer-record.txt @@ -0,0 +1,64 @@ + Code (inc. data) RO Data RW Data ZI Data Debug Object Name + 590 0 0 0 0 0 ch390.o + 616 0 64 0 0 0 ch390_interface.o + 1446 0 85 3 88 0 ch390_runtime.o + 3690 0 591 8 1240 0 config.o + 8 0 0 0 0 0 def.o + 124 0 0 0 0 0 dma.o + 1772 0 0 1 240 0 etharp.o + 238 0 12 0 0 0 ethernet.o + 178 0 0 0 48 0 ethernetif.o + 246 0 0 0 0 0 flash_param.o + 240 0 0 0 0 0 gpio.o + 452 0 0 0 0 0 icmp.o + 334 0 0 0 0 0 inet_chksum.o + 26 0 0 0 0 0 init.o + 0 0 0 0 24 0 ip.o + 778 0 0 2 0 0 ip4.o + 46 0 4 0 0 0 ip4_addr.o + 0 0 0 0 12 0 iwdg.o + 2746 0 185 6 272 0 main.o + 828 0 0 12 4115 0 mem.o + 196 0 244 32 6464 0 memp.o + 582 0 0 12 0 0 netif.o + 1118 0 0 0 0 0 pbuf.o + 248 0 0 4 0 0 raw.o + 214 0 9 168 272 0 segger_rtt.o + 64 0 0 0 0 0 segger_rtt_printf.o + 216 0 0 0 88 0 spi.o + 60 0 236 0 1024 0 startup_stm32f103xb.o + 128 0 0 12 0 0 stm32f1xx_hal.o + 198 0 0 0 0 0 stm32f1xx_hal_cortex.o + 808 0 0 0 0 0 stm32f1xx_hal_dma.o + 392 0 0 0 32 0 stm32f1xx_hal_flash.o + 240 0 0 0 0 0 stm32f1xx_hal_flash_ex.o + 516 0 0 0 0 0 stm32f1xx_hal_gpio.o + 12 0 0 0 0 0 stm32f1xx_hal_iwdg.o + 60 0 0 0 0 0 stm32f1xx_hal_msp.o + 1240 0 18 0 0 0 stm32f1xx_hal_rcc.o + 1510 0 0 0 0 0 stm32f1xx_hal_spi.o + 936 0 0 0 0 0 stm32f1xx_hal_tim.o + 108 0 0 0 0 0 stm32f1xx_hal_tim_ex.o + 2300 0 0 0 0 0 stm32f1xx_hal_uart.o + 490 0 0 0 0 0 stm32f1xx_it.o + 2 0 24 4 0 0 system_stm32f1xx.o + 3474 0 193 32 0 0 tcp.o + 1216 0 0 0 1120 0 tcp_client.o + 3684 0 0 36 20 0 tcp_in.o + 3862 0 0 0 0 0 tcp_out.o + 962 0 0 0 1104 0 tcp_server.o + 164 0 0 0 72 0 tim.o + 374 0 16 12 0 0 timeouts.o + 1268 0 0 0 2936 0 uart_trans.o + 816 0 0 0 624 0 usart.o +Object Totals + +Memory Map of the image + + Load Region LR_IROM1 + + Execution Region ER_IROM1 (Exec base: 0x08000000, Size: 0x0000D178, Max: 0x00010000, END) + + Execution Region RW_IRAM1 (Exec base: 0x20000000, Size: 0x00004FF8, Max: 0x00005000, END) + +Image component sizes \ No newline at end of file diff --git a/MDK-ARM/keil-build-viewer.exe b/MDK-ARM/keil-build-viewer.exe new file mode 100644 index 0000000000000000000000000000000000000000..9f1184fbe2495c83443d8ae8400e3fe5494bdd04 GIT binary patch literal 101256 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 Y(wJOOGF8VOt5_qtMio}XzVr3}0yh$Nl>h($ literal 0 HcmV?d00001 diff --git a/TCP2UART.ioc b/TCP2UART.ioc index 648961c..5d25a8d 100644 --- a/TCP2UART.ioc +++ b/TCP2UART.ioc @@ -234,10 +234,10 @@ RCC.USBFreq_Value=72000000 RCC.VCOOutput2Freq_Value=8000000 SH.GPXTI0.0=GPIO_EXTI0 SH.GPXTI0.ConfNb=1 -SPI1.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_8 -SPI1.CLKPhase=SPI_PHASE_2EDGE -SPI1.CLKPolarity=SPI_POLARITY_HIGH -SPI1.CalculateBaudRate=9.0 MBits/s +SPI1.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_2 +SPI1.CLKPhase=SPI_PHASE_1EDGE +SPI1.CLKPolarity=SPI_POLARITY_LOW +SPI1.CalculateBaudRate=36.0 MBits/s SPI1.Direction=SPI_DIRECTION_2LINES SPI1.IPParameters=VirtualType,Mode,Direction,CalculateBaudRate,BaudRatePrescaler,VirtualNSS,CLKPolarity,CLKPhase SPI1.Mode=SPI_MODE_MASTER