From e814012f09fbf9e91064cf97fb184164903785db Mon Sep 17 00:00:00 2001 From: kuwoyuki Date: Sat, 8 Nov 2025 21:01:04 +0600 Subject: [PATCH] get RXIF to work --- README.md | 6 +++--- port/ethernetif.c | 31 +++++++++++++++++++++---------- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 147fc5f..b96fdcd 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ while (1) { ## Impl note -This driver is kinda functional but not optimized at all +This driver is kinda functional but not optimized -- **Packet RX:** This is done by polling. You must call `ethernetif_input()` continuously in your main loop to check for and process incoming packets -- **Packet TX:** Kicking off a transmission is a blocking copy, but freeing the transmit buffer on completion is handled by the `ETH_IRQHandler` ISR +- **Packet RX:** ~~This is done by polling~~ RXIF works now. You must call `ethernetif_input()` continuously in your main loop to check for and process incoming packets +- **Packet TX:** TX isn't exactly typical DMA? The CPU has to copy the packet into a single transmit buffer and then manually start the transmission. An ISR will signal when the buffer is free to send the next packet diff --git a/port/ethernetif.c b/port/ethernetif.c index 39751a8..75d3463 100644 --- a/port/ethernetif.c +++ b/port/ethernetif.c @@ -29,6 +29,7 @@ __attribute__((aligned(4))) uint8_t MACRxBuf[ETH_RXBUFNB * ETH_RX_BUF_SZE]; __attribute__((aligned(4))) uint8_t MACTxBuf[ETH_TXBUFNB * ETH_TX_BUF_SZE]; static volatile bool g_link_interrupt_flag = false; +static volatile bool g_packet_received_flag = false; static struct ethernetif eth_state; static void low_level_init(struct netif* netif); @@ -130,8 +131,9 @@ static void low_level_init(struct netif* netif) { WritePHYReg(PHY_BMCR, PHY_BMCR_FULL_DUPLEX); ETH10M->EIR = 0xFF; // clear all interrupt flags - ETH10M->EIE = RB_ETH_EIE_INTIE | RB_ETH_EIE_TXIE | RB_ETH_EIE_LINKIE | - RB_ETH_EIE_TXERIE | RB_ETH_EIE_RXERIE | RB_ETH_EIE_R_EN50; + ETH10M->EIE = RB_ETH_EIE_INTIE | RB_ETH_EIE_RXIE | RB_ETH_EIE_TXIE | + RB_ETH_EIE_LINKIE | RB_ETH_EIE_TXERIE | RB_ETH_EIE_RXERIE | + RB_ETH_EIE_R_EN50; NVIC_EnableIRQ(ETH_IRQn); } @@ -166,15 +168,10 @@ static err_t low_level_output(struct netif* netif, struct pbuf* p) { static struct pbuf* low_level_input(struct netif* netif) { struct ethernetif* ethernetif = netif->state; - if (!(ETH10M->EIR & RB_ETH_EIR_RXIF)) { - return NULL; - } - uint16_t len = ETH10M->ERXLN; if (len < MIN_ETH_FRAME_SIZE || len > ETH_MAX_PACKET_SIZE) { LINK_STATS_INC(link.lenerr); - ETH10M->EIR = RB_ETH_EIR_RXIF; ETH10M->ECON1 |= RB_ETH_ECON1_RXEN; return NULL; } @@ -201,15 +198,24 @@ static struct pbuf* low_level_input(struct netif* netif) { ethernetif->DMARxDescToGet = (ETH_DMADESCTypeDef*)ethernetif->DMARxDescToGet->Buffer2NextDescAddr; ETH10M->ERXST = (uint32_t)ethernetif->DMARxDescToGet->Buffer1Addr; - ETH10M->EIR = RB_ETH_EIR_RXIF; ETH10M->ECON1 |= RB_ETH_ECON1_RXEN; return p; } void ethernetif_input(struct netif* netif) { - struct pbuf* p; - while ((p = low_level_input(netif)) != NULL) { + if (!g_packet_received_flag) { + return; + } + + NVIC_DisableIRQ(ETH_IRQn); + if (g_packet_received_flag) { + g_packet_received_flag = false; + } + NVIC_EnableIRQ(ETH_IRQn); + + struct pbuf* p = low_level_input(netif); + if (p != NULL) { if (netif->input(p, netif) != ERR_OK) { pbuf_free(p); } @@ -240,6 +246,11 @@ void ETH_IRQHandler(void) __attribute__((interrupt)) __attribute__((used)); void ETH_IRQHandler(void) { uint32_t flags = ETH10M->EIR; + if (flags & RB_ETH_EIR_RXIF) { + g_packet_received_flag = true; + ETH10M->EIR = RB_ETH_EIR_RXIF; + } + if (flags & RB_ETH_EIR_TXIF) { DMATxDscrTab[0].Status &= ~ETH_DMATxDesc_OWN; ETH10M->EIR = RB_ETH_EIR_TXIF;