//***************************************************************************** // // The interrupt handler for the Ethernet interrupt. // //***************************************************************************** void EthernetIntHandler(void) { uint32_t ui32Temp; // // Read and Clear the interrupt. // ui32Temp = MAP_EMACIntStatus(EMAC0_BASE, true); MAP_EMACIntClear(EMAC0_BASE, ui32Temp); // // Check to see if an RX Interrupt has occurred. // if(ui32Temp & EMAC_INT_RECEIVE) { // // Indicate that a packet has been received. // HWREGBITW(&g_ui32Flags, FLAG_RXPKT) = 1; } // // Has the DMA finished transferring a packet to the transmitter? // if(ui32Temp & EMAC_INT_TRANSMIT) { // // Indicate that a packet has been sent. // HWREGBITW(&g_ui32Flags, FLAG_TXPKT) = 0; } }
/** * ISR for handling interrupts from Ethernet MAC (ISR 56) */ void lwIP_eth_isr(void){/*{{{*/ uint32_t status; BaseType_t wake; status = MAP_EMACIntStatus(EMAC0_BASE, true); // If PTP implemented like lwiplib: // Check if from timer // clear timer interrupt // However, we have already run EMACTimestampDisable() so we don't need to // worry about MAC timer interrupts //Clear interrupt if(status) { MAP_EMACIntClear(EMAC0_BASE, status); } // Disable ethernet interrupts here, reenable in task, as we don't want // ethernet interrupts while already processing ethernet interrupts See // tivaif_hwinit() for list of interrupts MAP_EMACIntDisable(EMAC0_BASE, (EMAC_INT_RECEIVE | EMAC_INT_TRANSMIT | EMAC_INT_TX_STOPPED | EMAC_INT_RX_NO_BUFFER | EMAC_INT_RX_STOPPED | EMAC_INT_PHY)); // Enqueue status to eth_int_task // If sending to queue unblocks task, wake should equal true, // This freeRTOS function copies status by value, so status going out of // scope after yielding is not a problem. // We could use semaphore instead of queue by making status a global var xQueueSendToBackFromISR(eth_int_q_handle, &status, &wake); //Yield to eth_int_task portYIELD_FROM_ISR((pdTRUE == wake)); }/*}}}*/
//***************************************************************************** // //! Handles Ethernet interrupts for the lwIP TCP/IP stack. //! //! This function handles Ethernet interrupts for the lwIP TCP/IP stack. At //! the lowest level, all receive packets are placed into a packet queue for //! processing at a higher level. Also, the transmit packet queue is checked //! and packets are drained and transmitted through the Ethernet MAC as needed. //! If the system is configured without an RTOS, additional processing is //! performed at the interrupt level. The packet queues are processed by the //! lwIP TCP/IP code, and lwIP periodic timers are serviced (as needed). //! //! \return None. // //***************************************************************************** void lwIPEthernetIntHandler(void) { uint32_t ui32Status; uint32_t ui32TimerStatus; #if !NO_SYS portBASE_TYPE xWake; #endif // // Read and Clear the interrupt. // ui32Status = MAP_EMACIntStatus(EMAC0_BASE, true); // // If the interrupt really came from the Ethernet and not our // timer, clear it. // if(ui32Status) { MAP_EMACIntClear(EMAC0_BASE, ui32Status); } // // Check to see whether a hardware timer interrupt has been reported. // if(ui32Status & EMAC_INT_TIMESTAMP) { // // Yes - read and clear the timestamp interrupt status. // ui32TimerStatus = EMACTimestampIntStatus(EMAC0_BASE); // // If a timer interrupt handler has been registered, call it. // if(g_pfnTimerHandler) { g_pfnTimerHandler(EMAC0_BASE, ui32TimerStatus); } } // // The handling of the interrupt is different based on the use of a RTOS. // #if NO_SYS // // No RTOS is being used. If a transmit/receive interrupt was active, // run the low-level interrupt handler. // if(ui32Status) { tivaif_interrupt(&g_sNetIF, ui32Status); } // // Service the lwIP timers. // lwIPServiceTimers(); #else // // A RTOS is being used. Signal the Ethernet interrupt task. // xQueueSendFromISR(g_pInterrupt, (void *)&ui32Status, &xWake); // // Disable the Ethernet interrupts. Since the interrupts have not been // handled, they are not asserted. Once they are handled by the Ethernet // interrupt task, it will re-enable the interrupts. // MAP_EMACIntDisable(EMAC0_BASE, (EMAC_INT_RECEIVE | EMAC_INT_TRANSMIT | EMAC_INT_TX_STOPPED | EMAC_INT_RX_NO_BUFFER | EMAC_INT_RX_STOPPED | EMAC_INT_PHY)); // // Potentially task switch as a result of the above queue write. // #if RTOS_FREERTOS if(xWake == pdTRUE) { portYIELD_FROM_ISR(true); } #endif #endif }