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
+33 -15
View File
@@ -15,6 +15,7 @@
#include "main.h"
#include "CH390.h"
#include "CH390_Interface.h"
#include "SEGGER_RTT.h"
/* FreeRTOS includes */
#ifdef USE_FREERTOS
@@ -47,6 +48,13 @@
#define CH390_INT_PORT GPIOB
#define CH390_INT_PIN GPIO_PIN_0
#define CH390_SCK_PORT GPIOA
#define CH390_SCK_PIN GPIO_PIN_5
#define CH390_MISO_PORT GPIOA
#define CH390_MISO_PIN GPIO_PIN_6
#define CH390_MOSI_PORT GPIOA
#define CH390_MOSI_PIN GPIO_PIN_7
/* External SPI handle from spi.c */
extern SPI_HandleTypeDef hspi1;
@@ -65,6 +73,7 @@ static inline void ch390_cs(uint8_t state)
{
HAL_GPIO_WritePin(CH390_CS_PORT, CH390_CS_PIN,
state ? GPIO_PIN_SET : GPIO_PIN_RESET);
ch390_delay_us(2);
}
/**
@@ -89,10 +98,24 @@ static inline void ch390_rst(uint8_t state)
static uint8_t ch390_spi_exchange_byte(uint8_t byte)
{
uint8_t rx_data = 0;
HAL_SPI_TransmitReceive(&hspi1, &byte, &rx_data, 1, SPI_TIMEOUT);
if (HAL_SPI_TransmitReceive(&hspi1, &byte, &rx_data, 1, SPI_TIMEOUT) != HAL_OK)
{
return 0;
}
return rx_data;
}
static void ch390_spi_apply_mode(uint32_t polarity, uint32_t phase)
{
hspi1.Init.CLKPolarity = polarity;
hspi1.Init.CLKPhase = phase;
hspi1.Init.NSS = SPI_NSS_SOFT;
if (HAL_SPI_Init(&hspi1) != HAL_OK)
{
Error_Handler();
}
}
/**
* @brief Read a dummy byte (send 0x00)
* @return Received byte
@@ -161,16 +184,7 @@ void ch390_spi_init(void)
/* - CPOL = High (idle clock is high) */
/* - CPHA = 2Edge (data captured on second edge) */
/* Reconfigure SPI for CH390 if needed */
hspi1.Init.CLKPolarity = SPI_POLARITY_HIGH;
hspi1.Init.CLKPhase = SPI_PHASE_2EDGE;
hspi1.Init.NSS = SPI_NSS_SOFT; /* We control CS manually */
if (HAL_SPI_Init(&hspi1) != HAL_OK)
{
/* Handle error */
Error_Handler();
}
ch390_spi_apply_mode(SPI_POLARITY_HIGH, SPI_PHASE_2EDGE);
}
/**
@@ -222,9 +236,9 @@ void ch390_delay_us(uint32_t time)
void ch390_hardware_reset(void)
{
ch390_rst(0); /* Assert reset (low) */
ch390_delay_us(100); /* Hold reset for 100us (min 10us required) */
ch390_delay_us(1000); /* Hold reset for 1ms to satisfy datasheet minimum */
ch390_rst(1); /* Release reset (high) */
ch390_delay_us(10000); /* Wait 10ms for CH390 to initialize */
ch390_delay_us(50000); /* Wait 50ms for CH390 to initialize reliably */
}
/*----------------------------------------------------------------------------
@@ -255,9 +269,13 @@ uint8_t ch390_read_reg(uint8_t reg)
*/
void ch390_write_reg(uint8_t reg, uint8_t value)
{
uint8_t frame[2];
frame[0] = reg | OPC_REG_W;
frame[1] = value;
ch390_cs(0); /* CS low - select */
ch390_spi_exchange_byte(reg | OPC_REG_W); /* Send write command */
ch390_spi_exchange_byte(value); /* Write register value */
ch390_spi_exchange_byte(frame[0]); /* Send write command */
ch390_spi_exchange_byte(frame[1]); /* Send write data */
ch390_cs(1); /* CS high - deselect */
}