feat: 保存已验证的CH390网络打通基线
This commit is contained in:
+175
-24
@@ -11,6 +11,18 @@
|
||||
******************************************************************************/
|
||||
#include "CH390.h"
|
||||
#include "CH390_Interface.h"
|
||||
#include "../../App/app_runtime.h"
|
||||
#include "../../Core/Inc/debug_log.h"
|
||||
|
||||
void ch390_probe_rx_header(uint8_t *head)
|
||||
{
|
||||
if (head == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ch390_read_mem(head, 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* @name ch390_receive_packet
|
||||
@@ -22,45 +34,133 @@
|
||||
*/
|
||||
uint32_t ch390_receive_packet(uint8_t *buff, uint8_t *rx_status)
|
||||
{
|
||||
static uint32_t s_rxrdy_miss_log_count = 0u;
|
||||
uint32_t i;
|
||||
uint8_t rx_ready;
|
||||
uint8_t nsr;
|
||||
uint16_t rx_len = 0;
|
||||
uint8_t ReceiveData[4];
|
||||
|
||||
// Check packet ready or not
|
||||
ch390_read_reg(CH390_MRCMDX);
|
||||
rx_ready = ch390_read_reg(CH390_MRCMDX);
|
||||
if (rx_status != 0)
|
||||
{
|
||||
*rx_status = 0u;
|
||||
}
|
||||
g_eth_last_rx_fail_stage = 0u;
|
||||
g_eth_last_rx_status = 0u;
|
||||
g_eth_last_rx_len = 0u;
|
||||
g_eth_last_rx_head0 = 0u;
|
||||
g_eth_last_rx_head1 = 0u;
|
||||
g_eth_last_rx_head2 = 0u;
|
||||
g_eth_last_rx_head3 = 0u;
|
||||
g_eth_probe_rx_status = 0u;
|
||||
g_eth_probe_rx_len = 0u;
|
||||
g_eth_probe_head0 = 0u;
|
||||
g_eth_probe_head1 = 0u;
|
||||
g_eth_probe_head2 = 0u;
|
||||
g_eth_probe_head3 = 0u;
|
||||
for (i = 0u; i < 32u; ++i)
|
||||
{
|
||||
g_eth_probe_dump[i] = 0u;
|
||||
}
|
||||
g_eth_reprobe_rx_status = 0u;
|
||||
g_eth_reprobe_rx_len = 0u;
|
||||
g_eth_reprobe_head0 = 0u;
|
||||
g_eth_reprobe_head1 = 0u;
|
||||
g_eth_reprobe_head2 = 0u;
|
||||
g_eth_reprobe_head3 = 0u;
|
||||
|
||||
// if rxbyte != 1 or 0 reset pointer
|
||||
if (rx_ready & CH390_PKT_ERR)
|
||||
{
|
||||
// Reset RX FIFO pointer
|
||||
uint8_t rcr = ch390_read_reg(CH390_RCR);
|
||||
ch390_write_reg(CH390_RCR, rcr & ~RCR_RXEN); //RX disable
|
||||
ch390_write_reg(CH390_MPTRCR, 0x01); //Reset RX FIFO pointer
|
||||
ch390_write_reg(CH390_MRRH, 0x0c);
|
||||
ch390_delay_us(1000);
|
||||
ch390_write_reg(CH390_RCR, rcr | RCR_RXEN); //RX Enable
|
||||
return 0;
|
||||
}
|
||||
if (!(rx_ready & CH390_PKT_RDY))
|
||||
nsr = ch390_read_reg(CH390_NSR);
|
||||
g_eth_last_nsr = nsr;
|
||||
|
||||
if ((nsr & NSR_RXRDY) == 0u)
|
||||
{
|
||||
g_eth_last_rx_fail_stage = 2u;
|
||||
return 0;
|
||||
}
|
||||
|
||||
rx_ready = 0u;
|
||||
g_eth_last_rx_ready = 0u;
|
||||
g_eth_last_mrcmdx = 0u;
|
||||
g_eth_last_mrcmdx1 = 0u;
|
||||
g_eth_last_mrrl = 0u;
|
||||
g_eth_last_mrrh = 0u;
|
||||
|
||||
ch390_read_mem(ReceiveData, 4);
|
||||
g_eth_last_rx_head0 = ReceiveData[0];
|
||||
g_eth_last_rx_head1 = ReceiveData[1];
|
||||
g_eth_last_rx_head2 = ReceiveData[2];
|
||||
g_eth_last_rx_head3 = ReceiveData[3];
|
||||
|
||||
*rx_status = ReceiveData[1];
|
||||
rx_len = ReceiveData[2] | (ReceiveData[3] << 8);
|
||||
if (rx_status != 0)
|
||||
{
|
||||
*rx_status = ReceiveData[1];
|
||||
}
|
||||
rx_len = (uint16_t)ReceiveData[2] | ((uint16_t)ReceiveData[3] << 8);
|
||||
g_eth_last_rx_status = ReceiveData[1];
|
||||
g_eth_last_rx_len = rx_len;
|
||||
|
||||
if (((ReceiveData[1] & 0x3Fu) != 0u) ||
|
||||
(rx_len < 14u) ||
|
||||
(rx_len > CH390_PKT_MAX))
|
||||
{
|
||||
g_eth_last_rx_ready = rx_ready;
|
||||
g_eth_last_mrcmdx = 0u;
|
||||
g_eth_last_mrcmdx1 = 0u;
|
||||
g_eth_last_mrrl = 0u;
|
||||
g_eth_last_mrrh = 0u;
|
||||
|
||||
g_eth_last_rx_fail_stage = 2u;
|
||||
g_eth_probe_attempted += 1u;
|
||||
g_eth_probe_head0 = ReceiveData[0];
|
||||
g_eth_probe_head1 = ReceiveData[1];
|
||||
g_eth_probe_head2 = ReceiveData[2];
|
||||
g_eth_probe_head3 = ReceiveData[3];
|
||||
g_eth_probe_rx_status = ReceiveData[1];
|
||||
for (i = 0u; i < 32u; ++i)
|
||||
{
|
||||
g_eth_probe_dump[i] = 0u;
|
||||
}
|
||||
|
||||
g_eth_probe_rx_len = (uint32_t)rx_len;
|
||||
g_eth_rx_fallback_reject_count += 1u;
|
||||
s_rxrdy_miss_log_count += 1u;
|
||||
if ((s_rxrdy_miss_log_count & 0xFFu) == 1u)
|
||||
{
|
||||
debug_log_printf("[ETH] rxhdr-bad #%lu nsr=0x%02X rr=0x%02X mrx=0x%02X mrx1=0x%02X mrr=0x%02X%02X h=%02X %02X %02X %02X\r\n",
|
||||
(unsigned long)s_rxrdy_miss_log_count,
|
||||
(unsigned int)nsr,
|
||||
(unsigned int)rx_ready,
|
||||
(unsigned int)g_eth_last_mrcmdx,
|
||||
(unsigned int)g_eth_last_mrcmdx1,
|
||||
(unsigned int)g_eth_last_mrrh,
|
||||
(unsigned int)g_eth_last_mrrl,
|
||||
(unsigned int)ReceiveData[0],
|
||||
(unsigned int)ReceiveData[1],
|
||||
(unsigned int)ReceiveData[2],
|
||||
(unsigned int)ReceiveData[3]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
g_eth_rx_gate_ok_count += 1u;
|
||||
g_eth_rx_fallback_ok_count += 1u;
|
||||
|
||||
if(rx_len <= CH390_PKT_MAX)
|
||||
{
|
||||
ch390_read_mem(buff, rx_len);
|
||||
}
|
||||
|
||||
if ((*rx_status & 0x3f) || (rx_len > CH390_PKT_MAX))
|
||||
else
|
||||
{
|
||||
g_eth_last_rx_fail_stage = 3u;
|
||||
}
|
||||
|
||||
if ((rx_len > CH390_PKT_MAX))
|
||||
{
|
||||
g_eth_last_rx_fail_stage = 4u;
|
||||
return 0;
|
||||
}
|
||||
g_eth_last_rx_fail_stage = 5u;
|
||||
return rx_len;
|
||||
}
|
||||
|
||||
@@ -81,6 +181,13 @@ void ch390_send_packet(uint8_t *buff, uint16_t length)
|
||||
ch390_write_reg(CH390_TXPLH, (length >> 8) & 0xff);
|
||||
// Issue transmit request
|
||||
ch390_send_request();
|
||||
|
||||
g_eth_last_tcr_after = (uint32_t)ch390_read_reg(CH390_TCR);
|
||||
g_eth_last_nsr_after = (uint32_t)ch390_read_reg(CH390_NSR);
|
||||
g_eth_last_tsra = (uint32_t)ch390_read_reg(CH390_TSRA);
|
||||
g_eth_last_tsrb = (uint32_t)ch390_read_reg(CH390_TSRB);
|
||||
g_eth_last_txpll_rb = (uint32_t)ch390_read_reg(CH390_TXPLL);
|
||||
g_eth_last_txplh_rb = (uint32_t)ch390_read_reg(CH390_TXPLH);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -101,7 +208,7 @@ void ch390_send_request()
|
||||
*/
|
||||
void ch390_drop_packet(uint16_t len)
|
||||
{
|
||||
uint16_t mdr = ch390_read_reg(CH390_MRRL) | (ch390_read_reg(CH390_MRRH) << 8);
|
||||
uint16_t mdr = (uint16_t)ch390_read_mrrl() | ((uint16_t)ch390_read_mrrh() << 8);
|
||||
#ifdef CH390_INTERFACE_16_BIT
|
||||
mdr = mdr + (len + 1) / 2 * 2;
|
||||
#else
|
||||
@@ -191,20 +298,23 @@ void ch390_default_config()
|
||||
// CH390 has built-in MAC, this is not necessary
|
||||
// uint8_t mac_addr[6] = { 0x50, 0x54, 0x7B, 0x84, 0x00, 0x73 };
|
||||
// Multicast address hash table
|
||||
uint8_t multicase_addr[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
|
||||
uint8_t multicase_addr[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
ch390_set_phy_mode(CH390_AUTO);
|
||||
// Clear status
|
||||
ch390_write_reg(CH390_NSR, NSR_WAKEST | NSR_TX2END | NSR_TX1END);
|
||||
ch390_write_reg(CH390_ISR, 0xFF); // Clear interrupt status
|
||||
ch390_write_reg(CH390_INTCR, (uint8_t)(INCR_TYPE_OD | INCR_POL_L));
|
||||
ch390_write_reg(CH390_TCR2, 0x80); // LED mode 1
|
||||
ch390_write_reg(CH390_TCSCR, TCSCR_ALL); // Enable check sum generation
|
||||
|
||||
// ch390_set_mac_address(mac_addr);
|
||||
ch390_set_multicast(multicase_addr);
|
||||
ch390_write_reg(CH390_BCASTCR, 0x00);
|
||||
ch390_write_reg(CH390_MAR + 7, 0x80);
|
||||
|
||||
// Enable all interrupt and PAR
|
||||
ch390_write_reg(CH390_IMR, IMR_ALL);
|
||||
// Keep pointer auto-return enabled to stay aligned with the reference behavior.
|
||||
ch390_write_reg(CH390_IMR, (uint8_t)(IMR_PAR | IMR_PRI | IMR_LNKCHGI | IMR_ROOI | IMR_ROI));
|
||||
// Enable RX
|
||||
ch390_write_reg(CH390_RCR, RCR_DIS_CRC | RCR_RXEN);
|
||||
}
|
||||
@@ -613,3 +723,44 @@ uint8_t ch390_get_int_status()
|
||||
ch390_write_reg(CH390_ISR, int_status);
|
||||
return int_status;
|
||||
}
|
||||
|
||||
uint8_t ch390_runtime_poll(struct ch390_runtime_status *status)
|
||||
{
|
||||
uint8_t int_status = ch390_read_reg(CH390_ISR);
|
||||
|
||||
if (status != 0)
|
||||
{
|
||||
status->int_status = int_status;
|
||||
status->nsr = ch390_read_reg(CH390_NSR);
|
||||
status->bcastcr = ch390_read_reg(CH390_BCASTCR);
|
||||
status->mar7 = ch390_read_reg(CH390_MAR + 7u);
|
||||
status->mrcmdx = 0u;
|
||||
status->mrcmdx1 = 0u;
|
||||
status->mrrl = 0u;
|
||||
status->mrrh = 0u;
|
||||
status->link_up = ((status->nsr & NSR_LINKST) != 0u) ? 1u : 0u;
|
||||
}
|
||||
|
||||
ch390_write_reg(CH390_ISR, int_status);
|
||||
return int_status;
|
||||
}
|
||||
|
||||
int ch390_runtime_link_up_from_status(const struct ch390_runtime_status *status)
|
||||
{
|
||||
if (status == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (status->link_up != 0u) ? 1 : 0;
|
||||
}
|
||||
|
||||
uint32_t ch390_runtime_receive_packet(uint8_t *buff, uint8_t *rx_status)
|
||||
{
|
||||
return ch390_receive_packet(buff, rx_status);
|
||||
}
|
||||
|
||||
void ch390_runtime_send_packet(uint8_t *buff, uint16_t length)
|
||||
{
|
||||
ch390_send_packet(buff, length);
|
||||
}
|
||||
|
||||
@@ -359,6 +359,19 @@ enum ch390_phy_mode
|
||||
#define CH390_PKT_MAX 1536 /* Received packet max size */
|
||||
#define CH390_PKT_MIN 64
|
||||
|
||||
struct ch390_runtime_status
|
||||
{
|
||||
uint8_t int_status;
|
||||
uint8_t nsr;
|
||||
uint8_t bcastcr;
|
||||
uint8_t mar7;
|
||||
uint8_t mrcmdx;
|
||||
uint8_t mrcmdx1;
|
||||
uint8_t mrrl;
|
||||
uint8_t mrrh;
|
||||
uint8_t link_up;
|
||||
};
|
||||
|
||||
/********************************************************************
|
||||
* Functions
|
||||
*/
|
||||
@@ -620,4 +633,45 @@ void ch390_int_pin_config(uint8_t type, uint8_t pol);
|
||||
*/
|
||||
uint8_t ch390_get_int_status(void);
|
||||
|
||||
/**
|
||||
* @name ch390_runtime_poll
|
||||
* @brief Poll runtime state, sample diagnostic registers, and clear ISR flags.
|
||||
* @param status - Output runtime status snapshot
|
||||
* @return Interrupt status snapshot
|
||||
*/
|
||||
uint8_t ch390_runtime_poll(struct ch390_runtime_status *status);
|
||||
|
||||
/**
|
||||
* @name ch390_runtime_link_up_from_status
|
||||
* @brief Get link state from a runtime status snapshot
|
||||
* @param status - Runtime status snapshot
|
||||
* @return 0: Link down 1: Link up
|
||||
*/
|
||||
int ch390_runtime_link_up_from_status(const struct ch390_runtime_status *status);
|
||||
|
||||
/**
|
||||
* @name ch390_probe_rx_header
|
||||
* @brief Diagnostic helper: read 4-byte RX header directly from RX SRAM.
|
||||
* Caller must restore MRR if a non-destructive probe is required.
|
||||
* @param head - Output buffer with at least 4 bytes.
|
||||
*/
|
||||
void ch390_probe_rx_header(uint8_t *head);
|
||||
|
||||
/**
|
||||
* @name ch390_runtime_receive_packet
|
||||
* @brief Runtime RX entry point for packet receive
|
||||
* @param buff - Size equal to CH390_PKT_MAX
|
||||
* @param rx_status - Output abnormal status while receiving packet
|
||||
* @return Packet length
|
||||
*/
|
||||
uint32_t ch390_runtime_receive_packet(uint8_t *buff, uint8_t *rx_status);
|
||||
|
||||
/**
|
||||
* @name ch390_runtime_send_packet
|
||||
* @brief Runtime TX entry point for packet transmit
|
||||
* @param buff - Data to be sent
|
||||
* @param length - Less than 3k bytes.
|
||||
*/
|
||||
void ch390_runtime_send_packet(uint8_t *buff, uint16_t length);
|
||||
|
||||
#endif /* __CH390_H */
|
||||
|
||||
+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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -28,6 +28,34 @@ void ch390_hardware_reset(void);
|
||||
*/
|
||||
uint8_t ch390_read_reg(uint8_t reg);
|
||||
|
||||
/**
|
||||
* @name ch390_read_mrcmdx
|
||||
* @brief Read MRCMDX via memory-dummy-read opcode
|
||||
* @return Register value
|
||||
*/
|
||||
uint8_t ch390_read_mrcmdx(void);
|
||||
|
||||
/**
|
||||
* @name ch390_read_mrcmdx1
|
||||
* @brief Read MRCMDX1 via memory-dummy-read opcode
|
||||
* @return Register value
|
||||
*/
|
||||
uint8_t ch390_read_mrcmdx1(void);
|
||||
|
||||
/**
|
||||
* @name ch390_read_mrrl
|
||||
* @brief Read MRRL via memory-dummy-read opcode
|
||||
* @return Register value
|
||||
*/
|
||||
uint8_t ch390_read_mrrl(void);
|
||||
|
||||
/**
|
||||
* @name ch390_read_mrrh
|
||||
* @brief Read MRRH via memory-dummy-read opcode
|
||||
* @return Register value
|
||||
*/
|
||||
uint8_t ch390_read_mrrh(void);
|
||||
|
||||
/**
|
||||
* @name ch390_write_reg
|
||||
* @brief Write register
|
||||
|
||||
Reference in New Issue
Block a user