refactor: serialize CH390 runtime SPI access

Move runtime CH390 transactions behind a single ch390_runtime owner so main, lwIP glue, and EXTI no longer compete for SPI access. Keep the system stable under runtime load and capture the remaining CH390 readback failure as a credible low-level device-response issue in the handoff logs.
This commit is contained in:
2026-04-01 03:39:08 +08:00
parent e5fffaccdf
commit 14a532290d
11 changed files with 892 additions and 255 deletions
+19 -2
View File
@@ -12,6 +12,8 @@
#include "CH390.h"
#include "CH390_Interface.h"
#define CH390_PHY_BUSY_TIMEOUT_LOOPS 2000u
/**
* @name ch390_receive_packet
* @brief Receive packet
@@ -119,10 +121,17 @@ void ch390_drop_packet(uint16_t len)
*/
uint16_t ch390_read_phy(uint8_t reg)
{
uint32_t timeout = CH390_PHY_BUSY_TIMEOUT_LOOPS;
ch390_write_reg(CH390_EPAR, CH390_PHY | reg);
// Chose PHY, send read command
ch390_write_reg(CH390_EPCR, EPCR_ERPRR | EPCR_EPOS);
while(ch390_read_reg(CH390_EPCR) & 0x01);
while ((ch390_read_reg(CH390_EPCR) & EPCR_ERRE) != 0u) {
if (timeout-- == 0u) {
ch390_write_reg(CH390_EPCR, 0x00);
return 0;
}
}
// Clear read command
ch390_write_reg(CH390_EPCR, 0x00);
return (ch390_read_reg(CH390_EPDRH) << 8) |
@@ -137,12 +146,19 @@ uint16_t ch390_read_phy(uint8_t reg)
*/
void ch390_write_phy(uint8_t reg, uint16_t value)
{
uint32_t timeout = CH390_PHY_BUSY_TIMEOUT_LOOPS;
ch390_write_reg(CH390_EPAR, CH390_PHY | reg);
ch390_write_reg(CH390_EPDRL, (value & 0xff)); // Low byte
ch390_write_reg(CH390_EPDRH, ((value >> 8) & 0xff)); // High byte
// Chose PHY, send write command
ch390_write_reg(CH390_EPCR, 0x0A);
while(ch390_read_reg(CH390_EPCR) & 0x01);
while ((ch390_read_reg(CH390_EPCR) & EPCR_ERRE) != 0u) {
if (timeout-- == 0u) {
ch390_write_reg(CH390_EPCR, 0x00);
return;
}
}
// Clear write command
ch390_write_reg(CH390_EPCR, 0x00);
}
@@ -194,6 +210,7 @@ void ch390_default_config()
uint8_t multicase_addr[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
ch390_set_phy_mode(CH390_AUTO);
ch390_write_reg(CH390_INTCR, (uint8_t)(INCR_TYPE_OD | INCR_POL_L));
// Clear status
ch390_write_reg(CH390_NSR, NSR_WAKEST | NSR_TX2END | NSR_TX1END);
ch390_write_reg(CH390_ISR, 0xFF); // Clear interrupt status