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
+175 -24
View File
@@ -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);
}