Exemplo n.º 1
0
void kickoff_transfers() {
	while(MAP_uDMAChannelIsEnabled(11)
			|| MAP_uDMAChannelIsEnabled(25)
			|| MAP_uDMAChannelIsEnabled(13)
			|| MAP_uDMAChannelIsEnabled(15)){
		UARTprintf("A DMA tranfer is still running\n");
		/* Idle for some time to give the µDMA controller a chance to complete its job */
		SysCtlDelay(5000);
	}
	/* Wait 1.2ms (20kCy @ 50MHz) to ensure the WS2801 latch this frame's data */
	SysCtlDelay(20000);
	/* Swap buffers */
	if(swap_buffers) {
	volatile busbuffer *tmp = framebuffer_output;
	framebuffer_output = framebuffer_input;
	framebuffer_input = tmp;
		swap_buffers = 0;
	}
	/* Re-schedule DMA transfers */
	// caution, du to funny alignments of the buffers, these need to stay in order, to prevent someone from clearing the wrong stuff...
	kickoff_transfer(11, 0, SSI0_BASE);
	kickoff_transfer(25, 1, SSI1_BASE);
	kickoff_transfer(13, 2, SSI2_BASE);
	kickoff_transfer(15, 3, SSI3_BASE);
}
Exemplo n.º 2
0
Arquivo: main.c Projeto: dlugaz/All
//*****************************************************************************
//
//! Start a DMA transfer and wait for it to finish.
//!
//! This function will perform the steps necessary to initiate a DMA transfer
//! It waits until the transfer is complete before returning to the caller.
//!
//! \param ulChannel DMA Channel
//!
//! \return Zero if there is no error 
//
//*****************************************************************************
unsigned long
StartAndCompleteSWTransfer(unsigned long ulChannel)
{
    unsigned long ulIdx;
    //
    // Clear interrupt status
    //
    MAP_uDMAIntClear(0xffffffff);
    MAP_uDMAChannelRequest(ulChannel);
    //
    // Wait for the mode to change to stopped
    //
    ulIdx = 0;
    while(MAP_uDMAChannelModeGet(ulChannel) != UDMA_MODE_STOP)
    {
        ulIdx++;
        if(ulIdx > 200000)
        {
            break;
        }
    }
    if(MAP_uDMAChannelIsEnabled(ulChannel))
    {
        UART_PRINT("Error, channel was enabled at end of transfer\n");
        return 1;
    }
    UART_PRINT("Transfer complete \n\r");
    return(0);
}
/*
*  ======== SPICC3200DMA_hwiFxn ========
*  ISR for the SPI when we use the DMA is used.
*/
void SPICC3200DMA_hwiFxn(uintptr_t arg)
{
    SPI_Transaction            *msg;
    SPICC3200DMA_Object        *object = ((SPI_Handle)arg)->object;
    SPICC3200DMA_HWAttrs const *hwAttrs = ((SPI_Handle)arg)->hwAttrs;
    uint32_t                    intCode = 0;

    DebugP_log1("SPI:(%p) interrupt context start", hwAttrs->baseAddr);

    intCode = MAP_SPIIntStatus(hwAttrs->baseAddr, false);
    if (intCode & SPI_INT_DMATX) {
        /* DMA finished transfering; clear & disable interrupt */
        MAP_SPIIntDisable(hwAttrs->baseAddr, SPI_INT_DMATX);
        MAP_SPIIntClear(hwAttrs->baseAddr, SPI_INT_DMATX);
    }

    /* Determine if the TX & RX DMA channels have completed */
    if ((object->transaction) &&
            (MAP_uDMAChannelIsEnabled(hwAttrs->rxChannelIndex) == false) &&
            (MAP_uDMAIntStatus() & (1 << hwAttrs->rxChannelIndex))) {

        MAP_SPIDisable(hwAttrs->baseAddr);
        MAP_SPICSDisable(hwAttrs->baseAddr);

        MAP_SPIIntDisable(hwAttrs->baseAddr, SPI_INT_DMARX);
        MAP_SPIIntClear(hwAttrs->baseAddr, SPI_INT_DMARX);
        MAP_SPIIntClear(hwAttrs->baseAddr, SPI_INT_EOW);

        /*
         * Clear any pending interrupt
         * As the TX DMA channel interrupt gets service, it may be possible
         * that the RX DMA channel finished in the meantime, which means
         * the IRQ for RX DMA channel is still pending...
         */
        HwiP_clearInterrupt(hwAttrs->intNum);

        /*
         * Use a temporary transaction pointer in case the callback function
         * attempts to perform another SPI_transfer call
         */
        msg = object->transaction;

        /* Indicate we are done with this transfer */
        object->transaction = NULL;

        /* Release constraint since transaction is done */
        Power_releaseConstraint(PowerCC3200_DISALLOW_DEEPSLEEP);

        DebugP_log2("SPI:(%p) DMA transaction: %p complete",
                    hwAttrs->baseAddr, (uintptr_t)msg);

        object->transferCallbackFxn((SPI_Handle)arg, msg);
    }

    DebugP_log1("SPI:(%p) interrupt context end", hwAttrs->baseAddr);
}
//*****************************************************************************
//
// The interrupt handler for UART1.  This interrupt will occur when a DMA
// transfer is complete using the UART1 uDMA channel.  It will also be
// triggered if the peripheral signals an error.  This interrupt handler
// will set a flag when each scatter-gather transfer is complete (one for each
// of UART RX and TX).
//
//*****************************************************************************
void
UART1IntHandler(void)
{
    unsigned long ulStatus;

    //
    // Read the interrupt status of the UART.
    //
    ulStatus = MAP_UARTIntStatus(UART1_BASE, 1);

    //
    // Clear any pending status, even though there should be none since no UART
    // interrupts were enabled.  If UART error interrupts were enabled, then
    // those interrupts could occur here and should be handled.  Since uDMA is
    // used for both the RX and TX, then neither of those interrupts should be
    // enabled.
    //
    MAP_UARTIntClear(UART1_BASE, ulStatus);

    //
    // Count the number of times this interrupt occurred.
    //
    g_ulDMAIntCount++;

    //
    // Check the UART TX DMA channel to see if it is enabled.  When it is
    // finished with the transfer it will be automatically disabled.
    //
    if(!MAP_uDMAChannelIsEnabled(UDMA_CHANNEL_UART1TX))
    {
        g_bTXdone= 1;
    }

    //
    // Check the UART RX DMA channel to see if it is enabled.  When it is
    // finished with the transfer it will be automatically disabled.
    //
    if(!MAP_uDMAChannelIsEnabled(UDMA_CHANNEL_UART1RX))
    {
        g_bRXdone= 1;
    }
}
Exemplo n.º 5
0
Arquivo: main.c Projeto: dlugaz/All
//*****************************************************************************
//!
//! The interrupt handler for UART0.  This interrupt will occur when a DMA
//! transfer is complete using the UART0 uDMA channel.This interrupt handler will
//! switch between receive ping-pong buffers A and B.  It will also restart a TX
//! uDMA transfer if the prior transfer is complete.  This will keep the UART
//! running continuously (looping TX data back to RX).
//!
//! \param None
//!
//! \return None
//*****************************************************************************
void
UART0IntHandler(void)
{
    unsigned long ulStatus;
    unsigned long ulMode;
    //
    // Read the interrupt status of the UART.
    //
    ulStatus = MAP_UARTIntStatus(UARTA0_BASE, 1);
    //
    // Clear any pending status, even though there should be none since no UART
    // interrupts were enabled.  
    //
    MAP_UARTIntClear(UARTA0_BASE, ulStatus);
    if(uiCount<6)
    {
    //
    // Check the DMA control table to see if the ping-pong "A" transfer is
    // complete.  The "A" transfer uses receive buffer "A", and the primary
    // control structure.
    //
    ulMode = MAP_uDMAChannelModeGet(UDMA_CH8_UARTA0_RX | UDMA_PRI_SELECT);

    //
    // If the primary control structure indicates stop, that means the "A"
    // receive buffer is done.  The uDMA controller should still be receiving
    // data into the "B" buffer.
    //
    if(ulMode == UDMA_MODE_STOP)
    {
        //
        // Increment a counter to indicate data was received into buffer A.  
        //
        g_ulRxBufACount++;

        //
        // Set up the next transfer for the "A" buffer, using the primary
        // control structure.  When the ongoing receive into the "B" buffer is
        // done, the uDMA controller will switch back to this one.  
        //
        UDMASetupTransfer(UDMA_CH8_UARTA0_RX | UDMA_PRI_SELECT, UDMA_MODE_PINGPONG,
                          sizeof(g_ucRxBufA),UDMA_SIZE_8, UDMA_ARB_4,
                          (void *)(UARTA0_BASE + UART_O_DR), UDMA_SRC_INC_NONE,
                                            g_ucRxBufA, UDMA_DST_INC_8);
    }

    //
    // Check the DMA control table to see if the ping-pong "B" transfer is
    // complete.  The "B" transfer uses receive buffer "B", and the alternate
    // control structure.
    //
    ulMode = MAP_uDMAChannelModeGet(UDMA_CH8_UARTA0_RX | UDMA_ALT_SELECT);

    //
    // If the alternate control structure indicates stop, that means the "B"
    // receive buffer is done.  The uDMA controller should still be receiving
    // data into the "A" buffer.
    //
    if(ulMode == UDMA_MODE_STOP)
    {
        //
        // Increment a counter to indicate data was received into buffer A. 
        //
        g_ulRxBufBCount++;

        //
        // Set up the next transfer for the "B" buffer, using the alternate
        // control structure.  When the ongoing receive into the "A" buffer is
        // done, the uDMA controller will switch back to this one. 
        //
        UDMASetupTransfer(UDMA_CH8_UARTA0_RX | UDMA_ALT_SELECT,
                          UDMA_MODE_PINGPONG, sizeof(g_ucRxBufB),UDMA_SIZE_8,
                          UDMA_ARB_4,(void *)(UARTA0_BASE + UART_O_DR), 
                          UDMA_SRC_INC_NONE, g_ucRxBufB, UDMA_DST_INC_8);
    }

    //
    // If the UART0 DMA TX channel is disabled, that means the TX DMA transfer
    // is done.
    //
    if(!MAP_uDMAChannelIsEnabled(UDMA_CH9_UARTA0_TX))
    {
        g_ulTxCount++;
        //
        // Start another DMA transfer to UART0 TX.
        //
        UDMASetupTransfer(UDMA_CH9_UARTA0_TX| UDMA_PRI_SELECT, UDMA_MODE_BASIC,
           sizeof(g_ucTxBuf),UDMA_SIZE_8, UDMA_ARB_4,g_ucTxBuf, UDMA_SRC_INC_8,
                          (void *)(UARTA0_BASE + UART_O_DR), UDMA_DST_INC_NONE);
        //
        // The uDMA TX channel must be re-enabled.
        //
        MAP_uDMAChannelEnable(UDMA_CH9_UARTA0_TX);
    }
    }
    else
    {
        UARTDone=1;
        MAP_UARTIntUnregister(UARTA0_BASE);
    }
}