get RXIF to work
This commit is contained in:
@@ -30,7 +30,7 @@ while (1) {
|
|||||||
|
|
||||||
## Impl note
|
## 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 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:** Kicking off a transmission is a blocking copy, but freeing the transmit buffer on completion is handled by the `ETH_IRQHandler` ISR
|
- **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];
|
__attribute__((aligned(4))) uint8_t MACTxBuf[ETH_TXBUFNB * ETH_TX_BUF_SZE];
|
||||||
|
|
||||||
static volatile bool g_link_interrupt_flag = false;
|
static volatile bool g_link_interrupt_flag = false;
|
||||||
|
static volatile bool g_packet_received_flag = false;
|
||||||
static struct ethernetif eth_state;
|
static struct ethernetif eth_state;
|
||||||
|
|
||||||
static void low_level_init(struct netif* netif);
|
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);
|
WritePHYReg(PHY_BMCR, PHY_BMCR_FULL_DUPLEX);
|
||||||
|
|
||||||
ETH10M->EIR = 0xFF; // clear all interrupt flags
|
ETH10M->EIR = 0xFF; // clear all interrupt flags
|
||||||
ETH10M->EIE = RB_ETH_EIE_INTIE | RB_ETH_EIE_TXIE | RB_ETH_EIE_LINKIE |
|
ETH10M->EIE = RB_ETH_EIE_INTIE | RB_ETH_EIE_RXIE | RB_ETH_EIE_TXIE |
|
||||||
RB_ETH_EIE_TXERIE | RB_ETH_EIE_RXERIE | RB_ETH_EIE_R_EN50;
|
RB_ETH_EIE_LINKIE | RB_ETH_EIE_TXERIE | RB_ETH_EIE_RXERIE |
|
||||||
|
RB_ETH_EIE_R_EN50;
|
||||||
|
|
||||||
NVIC_EnableIRQ(ETH_IRQn);
|
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) {
|
static struct pbuf* low_level_input(struct netif* netif) {
|
||||||
struct ethernetif* ethernetif = netif->state;
|
struct ethernetif* ethernetif = netif->state;
|
||||||
|
|
||||||
if (!(ETH10M->EIR & RB_ETH_EIR_RXIF)) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t len = ETH10M->ERXLN;
|
uint16_t len = ETH10M->ERXLN;
|
||||||
|
|
||||||
if (len < MIN_ETH_FRAME_SIZE || len > ETH_MAX_PACKET_SIZE) {
|
if (len < MIN_ETH_FRAME_SIZE || len > ETH_MAX_PACKET_SIZE) {
|
||||||
LINK_STATS_INC(link.lenerr);
|
LINK_STATS_INC(link.lenerr);
|
||||||
ETH10M->EIR = RB_ETH_EIR_RXIF;
|
|
||||||
ETH10M->ECON1 |= RB_ETH_ECON1_RXEN;
|
ETH10M->ECON1 |= RB_ETH_ECON1_RXEN;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -201,15 +198,24 @@ static struct pbuf* low_level_input(struct netif* netif) {
|
|||||||
ethernetif->DMARxDescToGet =
|
ethernetif->DMARxDescToGet =
|
||||||
(ETH_DMADESCTypeDef*)ethernetif->DMARxDescToGet->Buffer2NextDescAddr;
|
(ETH_DMADESCTypeDef*)ethernetif->DMARxDescToGet->Buffer2NextDescAddr;
|
||||||
ETH10M->ERXST = (uint32_t)ethernetif->DMARxDescToGet->Buffer1Addr;
|
ETH10M->ERXST = (uint32_t)ethernetif->DMARxDescToGet->Buffer1Addr;
|
||||||
ETH10M->EIR = RB_ETH_EIR_RXIF;
|
|
||||||
ETH10M->ECON1 |= RB_ETH_ECON1_RXEN;
|
ETH10M->ECON1 |= RB_ETH_ECON1_RXEN;
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ethernetif_input(struct netif* netif) {
|
void ethernetif_input(struct netif* netif) {
|
||||||
struct pbuf* p;
|
if (!g_packet_received_flag) {
|
||||||
while ((p = low_level_input(netif)) != NULL) {
|
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) {
|
if (netif->input(p, netif) != ERR_OK) {
|
||||||
pbuf_free(p);
|
pbuf_free(p);
|
||||||
}
|
}
|
||||||
@@ -240,6 +246,11 @@ void ETH_IRQHandler(void) __attribute__((interrupt)) __attribute__((used));
|
|||||||
void ETH_IRQHandler(void) {
|
void ETH_IRQHandler(void) {
|
||||||
uint32_t flags = ETH10M->EIR;
|
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) {
|
if (flags & RB_ETH_EIR_TXIF) {
|
||||||
DMATxDscrTab[0].Status &= ~ETH_DMATxDesc_OWN;
|
DMATxDscrTab[0].Status &= ~ETH_DMATxDesc_OWN;
|
||||||
ETH10M->EIR = RB_ETH_EIR_TXIF;
|
ETH10M->EIR = RB_ETH_EIR_TXIF;
|
||||||
|
|||||||
Reference in New Issue
Block a user