get RXIF to work
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user