feat: 保存已验证的CH390网络打通基线

This commit is contained in:
2026-04-17 07:09:55 +08:00
parent 59eecf428f
commit 6aba77df9a
44 changed files with 6428 additions and 3372 deletions
+121 -35
View File
@@ -12,6 +12,7 @@
* Modified for STM32F103 HAL Library with FreeRTOS support.
******************************************************************************/
#include "stm32f1xx_hal.h"
#include "main.h"
#include "CH390.h"
#include "CH390_Interface.h"
@@ -51,6 +52,15 @@ extern SPI_HandleTypeDef hspi1;
/* Timeout for SPI operations (ms) */
#define SPI_TIMEOUT 100
#define CH390_SPI_CHUNK_SIZE 64u
#ifdef USE_FREERTOS
#define CH390_SPI_ATOMIC_ENTER() taskENTER_CRITICAL()
#define CH390_SPI_ATOMIC_EXIT() taskEXIT_CRITICAL()
#else
#define CH390_SPI_ATOMIC_ENTER() ((void)0)
#define CH390_SPI_ATOMIC_EXIT() ((void)0)
#endif
/*----------------------------------------------------------------------------
* Low-level GPIO operations
@@ -64,6 +74,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);
}
/**
@@ -88,10 +99,43 @@ 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 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;
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
@@ -155,21 +199,8 @@ void ch390_interrupt_init(void)
*/
void ch390_spi_init(void)
{
/* SPI1 is initialized by MX_SPI1_Init() in main.c */
/* We need to ensure correct SPI mode for CH390: */
/* - 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();
}
/* Reference CH390 SPI path uses mode 3. */
ch390_spi_apply_mode(SPI_POLARITY_HIGH, SPI_PHASE_2EDGE);
}
/**
@@ -220,10 +251,11 @@ void ch390_delay_us(uint32_t time)
*/
void ch390_hardware_reset(void)
{
ch390_delay_us(10000); /* Short delay before reset */
ch390_rst(0); /* Assert reset (low) */
ch390_delay_us(100); /* Hold reset for 100us (min 10us required) */
ch390_delay_us(3000); /* Hold reset for 3ms 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 */
}
/*----------------------------------------------------------------------------
@@ -238,15 +270,60 @@ void ch390_hardware_reset(void)
uint8_t ch390_read_reg(uint8_t reg)
{
uint8_t value;
CH390_SPI_ATOMIC_ENTER();
ch390_cs(0); /* CS low - select */
ch390_spi_exchange_byte(reg | OPC_REG_R); /* Send read command */
value = ch390_spi_dummy_read(); /* Read register value */
ch390_cs(1); /* CS high - deselect */
CH390_SPI_ATOMIC_EXIT();
return value;
}
static uint8_t ch390_read_rx_reg(uint8_t reg)
{
uint8_t tx_buf[3];
uint8_t rx_buf[3];
tx_buf[0] = OPC_MEM_DMY_R;
tx_buf[1] = reg;
tx_buf[2] = 0x00u;
CH390_SPI_ATOMIC_ENTER();
ch390_cs(0);
if (HAL_SPI_TransmitReceive(&hspi1, tx_buf, rx_buf, 3, SPI_TIMEOUT) != HAL_OK)
{
ch390_cs(1);
CH390_SPI_ATOMIC_EXIT();
return 0u;
}
ch390_cs(1);
CH390_SPI_ATOMIC_EXIT();
return rx_buf[2];
}
uint8_t ch390_read_mrcmdx(void)
{
return ch390_read_rx_reg(CH390_MRCMDX);
}
uint8_t ch390_read_mrcmdx1(void)
{
return ch390_read_rx_reg(CH390_MRCMDX1);
}
uint8_t ch390_read_mrrl(void)
{
return ch390_read_rx_reg(CH390_MRRL);
}
uint8_t ch390_read_mrrh(void)
{
return ch390_read_rx_reg(CH390_MRRH);
}
/**
* @brief Write a CH390 register
* @param reg Register address
@@ -254,10 +331,12 @@ uint8_t ch390_read_reg(uint8_t reg)
*/
void ch390_write_reg(uint8_t reg, uint8_t value)
{
CH390_SPI_ATOMIC_ENTER();
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_cs(1); /* CS high - deselect */
CH390_SPI_ATOMIC_EXIT();
}
/**
@@ -267,18 +346,19 @@ 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_SPI_ATOMIC_ENTER();
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 */
CH390_SPI_ATOMIC_EXIT();
}
/**
@@ -309,17 +389,23 @@ 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_SPI_ATOMIC_ENTER();
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++)
for (i = 0; i < length; ++i)
{
ch390_spi_exchange_byte(data[i]);
(void)ch390_spi_exchange_byte(data[i]);
}
ch390_cs(1); /* CS high - deselect */
CH390_SPI_ATOMIC_EXIT();
}
/**