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
This commit is contained in:
2026-04-05 03:47:54 +08:00
parent c5b2bdd2d2
commit efb88ea367
11 changed files with 143 additions and 41 deletions
+4
View File
@@ -235,6 +235,10 @@ AT+NET?\r\n
OK
```
**MAC 设置说明:**
当MAC设置为全0时,固件将使用硬件MAC地址,此时通过AT+?查询到的MAC地址即为当前生效的硬件MAC地址。
### 8.5 LINK 类命令
#### 设置单条 LINK 记录
+4 -4
View File
@@ -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 {
+2 -10
View File
@@ -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();
+1 -1
View File
@@ -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;
+29 -12
View File
@@ -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 */
}
+25
View File
@@ -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");
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");
+2 -2
View File
@@ -45,7 +45,7 @@
<PageWidth>79</PageWidth>
<PageLength>66</PageLength>
<TabStop>8</TabStop>
<ListingPath></ListingPath>
<ListingPath>.\TCP2UART\</ListingPath>
</OPTLEX>
<ListingPage>
<CreateCListing>1</CreateCListing>
@@ -140,7 +140,7 @@
<SetRegEntry>
<Number>0</Number>
<Key>CMSIS_AGDI</Key>
<Name>-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)</Name>
<Name>-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)</Name>
</SetRegEntry>
<SetRegEntry>
<Number>0</Number>
+3 -3
View File
@@ -55,7 +55,7 @@
<CreateHexFile>1</CreateHexFile>
<DebugInformation>1</DebugInformation>
<BrowseInformation>1</BrowseInformation>
<ListingPath></ListingPath>
<ListingPath>.\TCP2UART\</ListingPath>
<HexFormatSelection>1</HexFormatSelection>
<Merge32K>0</Merge32K>
<CreateBatchFile>0</CreateBatchFile>
@@ -80,9 +80,9 @@
<nStopB2X>0</nStopB2X>
</BeforeMake>
<AfterMake>
<RunUserProg1>0</RunUserProg1>
<RunUserProg1>1</RunUserProg1>
<RunUserProg2>0</RunUserProg2>
<UserProg1Name></UserProg1Name>
<UserProg1Name>keil-build-viewer.exe -NOPATH</UserProg1Name>
<UserProg2Name></UserProg2Name>
<UserProg1Dos16Mode>0</UserProg1Dos16Mode>
<UserProg2Dos16Mode>0</UserProg2Dos16Mode>
+64
View File
@@ -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
Binary file not shown.
+4 -4
View File
@@ -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