コード例 #1
0
//*****************************************************************************
//
//! Handles the I2S sound interrupt.
//!
//! This function services the I2S interrupt and ensures that DMA buffers are
//! correctly handled to ensure smooth flow of audio data to the DAC.
//!
//! \return None.
//
//*****************************************************************************
void
SoundIntHandler(void)
{
    unsigned long ulStatus;
    unsigned long *pulTemp;

    //
    // Get the interrupt status and clear any pending interrupts.
    //
    ulStatus = I2SIntStatus(I2S0_BASE, 1);

    //
    // Clear out any interrupts.
    //
    I2SIntClear(I2S0_BASE, ulStatus);

    //
    // Handle the TX channel interrupt
    //
    if(HWREGBITW(&g_ulDMAFlags, FLAG_TX_PENDING))
    {
        //
        // If the TX DMA is done, then call the callback if present.
        //
        if(ROM_uDMAChannelModeGet(UDMA_CHANNEL_I2S0TX | UDMA_PRI_SELECT) ==
           UDMA_MODE_STOP)
        {
            //
            // Save a temp pointer so that the current pointer can be set to
            // zero before calling the callback.
            //
            pulTemp = (unsigned long *)g_sBuffers[0].pulData;

            //
            // If at the mid point then refill the first half of the buffer.
            //
            if((g_sBuffers[0].pfnBufferCallback) &&
               (g_sBuffers[0].pulData != 0))
            {
                g_sBuffers[0].pulData = 0;
                g_sBuffers[0].pfnBufferCallback(pulTemp, BUFFER_EVENT_FREE);
            }
        }

        //
        // If the TX DMA is done, then call the callback if present.
        //
        if(ROM_uDMAChannelModeGet(UDMA_CHANNEL_I2S0TX | UDMA_ALT_SELECT) ==
           UDMA_MODE_STOP)
        {
            //
            // Save a temp pointer so that the current pointer can be set to
            // zero before calling the callback.
            //
            pulTemp = (unsigned long *)g_sBuffers[1].pulData;

            //
            // If at the mid point then refill the first half of the buffer.
            //
            if((g_sBuffers[1].pfnBufferCallback) &&
               (g_sBuffers[1].pulData != 0))
            {
                g_sBuffers[1].pulData = 0;
                g_sBuffers[1].pfnBufferCallback(pulTemp, BUFFER_EVENT_FREE);
            }
        }

        //
        // If no more buffers are pending then clear the flag.
        //
        if((g_sBuffers[0].pulData == 0) && (g_sBuffers[1].pulData == 0))
        {
            HWREGBITW(&g_ulDMAFlags, FLAG_TX_PENDING) = 0;
        }
    }
}
コード例 #2
0
ファイル: sound.c プロジェクト: coolt/RTOS_15
//*****************************************************************************
//
//! Handles the I2S sound interrupt.
//!
//! This function services the I2S interrupt and will call the callback function
//! provided with the buffer that was given to the SoundBufferPlay() or
//! SoundBufferRead() functions to handle emptying or filling the buffers and
//! starting up DMA transfers again.  It is solely the responsibility of the
//! callback functions to continuing sending or receiving data to or from the
//! audio codec.
//!
//! \return None.
//
//*****************************************************************************
void
SoundIntHandler(void)
{
    unsigned long ulStatus;
    unsigned long *pulTemp;

    //
    // Get the interrupt status and clear any pending interrupts.
    //
    ulStatus = I2SIntStatus(I2S0_BASE, 1);

    //
    // Clear out any interrupts.
    //
    I2SIntClear(I2S0_BASE, ulStatus);

    //
    // Handle the RX channel interrupt
    //
    if(HWREGBITW(&g_ulDMAFlags, FLAG_RX_PENDING))
    {
        //
        // If the RX DMA is done, then start another one using the same
        // RX buffer.  This keeps the RX running continuously.
        //
        if(uDMAChannelModeGet(UDMA_CHANNEL_I2S0RX | UDMA_PRI_SELECT) ==
                UDMA_MODE_STOP)
        {
            //
            // Save a temp pointer so that the current pointer can be set to
            // zero before calling the callback.
            //
            pulTemp = g_sInBuffers[0].pulData;

            //
            // If at the mid point the refill the first half of the buffer.
            //
            if(g_sInBuffers[0].pfnBufferCallback)
            {
                g_sInBuffers[0].pulData = 0;

                g_sInBuffers[0].pfnBufferCallback(pulTemp, BUFFER_EVENT_FULL);
            }
        }
        else if(uDMAChannelModeGet(UDMA_CHANNEL_I2S0RX | UDMA_ALT_SELECT) ==
                UDMA_MODE_STOP)
        {
            //
            // Save a temp pointer so that the current pointer can be set to
            // zero before calling the callback.
            //
            pulTemp = g_sInBuffers[1].pulData;

            //
            // If at the mid point the refill the first half of the buffer.
            //
            if(g_sInBuffers[1].pfnBufferCallback)
            {
                g_sInBuffers[1].pulData = 0;
                g_sInBuffers[1].pfnBufferCallback(pulTemp, BUFFER_EVENT_FULL);
            }
        }

        //
        // If there are no more scheduled buffers then there are no more
        // pending DMA transfers.
        //
        if((g_sInBuffers[0].pulData == 0) && (g_sInBuffers[1].pulData == 0))
        {
            HWREGBITW(&g_ulDMAFlags, FLAG_RX_PENDING) = 0;
        }
    }

    //
    // Handle the TX channel interrupt
    //
    if(HWREGBITW(&g_ulDMAFlags, FLAG_TX_PENDING))
    {
        //
        // If the TX DMA is done, then call the callback if present.
        //
        if(uDMAChannelModeGet(UDMA_CHANNEL_I2S0TX | UDMA_PRI_SELECT) ==
                UDMA_MODE_STOP)
        {
            //
            // Save a temp pointer so that the current pointer can be set to
            // zero before calling the callback.
            //
            pulTemp = g_sOutBuffers[0].pulData;

            //
            // If at the mid point then refill the first half of the buffer.
            //
            if((g_sOutBuffers[0].pfnBufferCallback) &&
                    (g_sOutBuffers[0].pulData != 0))
            {
                g_sOutBuffers[0].pulData = 0;
                g_sOutBuffers[0].pfnBufferCallback(pulTemp, BUFFER_EVENT_FREE);
            }
        }

        //
        // If the TX DMA is done, then call the callback if present.
        //
        if(uDMAChannelModeGet(UDMA_CHANNEL_I2S0TX | UDMA_ALT_SELECT) ==
                UDMA_MODE_STOP)
        {
            //
            // Save a temporary pointer so that the current pointer can be set
            // to zero before calling the callback.
            //
            pulTemp = g_sOutBuffers[1].pulData;

            //
            // If at the mid point then refill the first half of the buffer.
            //
            if((g_sOutBuffers[1].pfnBufferCallback) &&
                    (g_sOutBuffers[1].pulData != 0))
            {
                g_sOutBuffers[1].pulData = 0;
                g_sOutBuffers[1].pfnBufferCallback(pulTemp, BUFFER_EVENT_FREE);
            }
        }

        //
        // If no more buffers are pending then clear the flag.
        //
        if((g_sOutBuffers[0].pulData == 0) && (g_sOutBuffers[1].pulData == 0))
        {
            HWREGBITW(&g_ulDMAFlags, FLAG_TX_PENDING) = 0;
        }
    }
}