feat: 保存已验证的CH390网络打通基线
This commit is contained in:
+121
-35
@@ -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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user