static void
lwIPInterruptTask(void *pvArg)
{
    //
    // Loop forever.
    //
    while(1)
    {
        //
        // Wait until the semaphore has been signaled.
        //
        while(xQueueReceive(g_pInterrupt, &pvArg, portMAX_DELAY) != pdPASS)
        {
        }

        //
        // Processes any packets waiting to be sent or received.
        //
        tivaif_interrupt(&g_sNetIF, (uint32_t)pvArg);

        //
        // Re-enable the Ethernet interrupts.
        //
        MAP_EMACIntEnable(EMAC0_BASE, (EMAC_INT_RECEIVE | EMAC_INT_TRANSMIT |
                                       EMAC_INT_TX_STOPPED |
                                       EMAC_INT_RX_NO_BUFFER |
                                       EMAC_INT_RX_STOPPED | EMAC_INT_PHY));
    }
}
Esempio n. 2
0
/**
 * Task for feeding packets from ISR to lwIP
 * Loops forever blocking on queue waiting for next status from ISR
 * @param arg Unused
 */
static void eth_int_task(void* arg){/*{{{*/
    uint32_t status;
    while(1){

        //Loop waiting max time between loops until queue item received
        while(xQueueReceive(eth_int_q_handle, &status, portMAX_DELAY)!=pdPASS);

        tivaif_interrupt(&lwip_netif, status);
        // Reenable interrupts disabled in lwIP_eth_isr()
        MAP_EMACIntEnable(EMAC0_BASE, (EMAC_INT_PHY|
                    EMAC_INT_RECEIVE|
                    EMAC_INT_RX_NO_BUFFER|
                    EMAC_INT_RX_STOPPED|
                    EMAC_INT_TRANSMIT|
                    EMAC_INT_TX_STOPPED));

#if DEBUG_STACK
        DEBUG_OUT("Stack Usage: %s: %d\n", __PRETTY_FUNCTION__, uxTaskGetStackHighWaterMark(NULL));
#endif
    }
}/*}}}*/
//*****************************************************************************
//
//! 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
}