/*
 *  ======== CameraCC3200DMA_configDMA ========
 */
static void CameraCC3200DMA_configDMA(Camera_Handle handle)
{
    CameraCC3200DMA_Object           *object = handle->object;
    CameraCC3200DMA_HWAttrs const    *hwAttrs = handle->hwAttrs;
    unsigned long **bufferPtr = (unsigned long**)&object->captureBuf;


    /* Setup ping-pong transfer */
    MAP_uDMAChannelControlSet(hwAttrs->channelIndex,
              UDMA_SIZE_32 | UDMA_SRC_INC_32 | UDMA_DST_INC_32 | UDMA_ARB_8);
    MAP_uDMAChannelAttributeEnable(hwAttrs->channelIndex,UDMA_ATTR_USEBURST);
    MAP_uDMAChannelTransferSet(hwAttrs->channelIndex, UDMA_MODE_PINGPONG,
                               (void *)CAM_BUFFER_ADDR, (void *)*bufferPtr,
                               CameraCC3200DMA_DMA_TRANSFER_SIZE);
    MAP_uDMAChannelEnable(hwAttrs->channelIndex);

    /* Pong Buffer */
    *bufferPtr += CameraCC3200DMA_DMA_TRANSFER_SIZE;
    MAP_uDMAChannelControlSet(hwAttrs->channelIndex | UDMA_ALT_SELECT,
              UDMA_SIZE_32 | UDMA_SRC_INC_32 | UDMA_DST_INC_32 | UDMA_ARB_8);
    MAP_uDMAChannelAttributeEnable(hwAttrs->channelIndex | UDMA_ALT_SELECT,
                                                       UDMA_ATTR_USEBURST);
    MAP_uDMAChannelTransferSet(hwAttrs->channelIndex | UDMA_ALT_SELECT,
                                UDMA_MODE_PINGPONG,
                               (void *)CAM_BUFFER_ADDR,
                               (void *)*bufferPtr,
                               CameraCC3200DMA_DMA_TRANSFER_SIZE);
    MAP_uDMAChannelEnable(hwAttrs->channelIndex | UDMA_ALT_SELECT);

    /*  Ping Buffer */
    *bufferPtr += CameraCC3200DMA_DMA_TRANSFER_SIZE;

    DebugP_log1("Camera:(%p) DMA transfer enabled", hwAttrs->baseAddr);

    /* Set mode to Ping buffer initially */
    object->cameraDMA_PingPongMode = 0;

    /* Clear any pending interrupt */
    MAP_CameraIntClear(hwAttrs->baseAddr, CAM_INT_DMA);

    /* DMA Interrupt unmask from apps config */
    MAP_CameraIntEnable(hwAttrs->baseAddr, CAM_INT_DMA);

    DebugP_log3("Camera:(%p) DMA receive, "
                   "CaptureBuf: %p; Count: %d",
                    hwAttrs->baseAddr,
                    (uintptr_t)*bufferPtr,
                    (uintptr_t)object->bufferlength);
}
Exemple #2
0
static void  
SetupSGMemTransfer(unsigned long ulChannel,void *pvSrcBuf0,
                             void *pvSrcBuf1,void *pvDstBuf,unsigned long size)
{
    //
    // Create task0
    //
    tDMAControlTable task0=uDMATaskStructEntry(size, UDMA_SIZE_8,
                            UDMA_SRC_INC_8, pvSrcBuf0,
                             UDMA_DST_INC_8,pvDstBuf,
                            UDMA_ARB_8, UDMA_MODE_MEM_SCATTER_GATHER);

    //
    // create task1
    //
    tDMAControlTable task1=uDMATaskStructEntry(size, UDMA_SIZE_8,
                            UDMA_SRC_INC_8, pvSrcBuf1,
                             UDMA_DST_INC_8, (char *)pvDstBuf+size,
                            UDMA_ARB_8, UDMA_MODE_AUTO);

    //
    // Copy to TaskList
    //
    memcpy(&TaskList[0],&task0,sizeof(tDMAControlTable));
    memcpy(&TaskList[1],&task1,sizeof(tDMAControlTable));
    memset(pvDstBuf,0,size);
    //
    // Setup Scatter Gather with two tasks
    //
    MAP_uDMAChannelScatterGatherSet(ulChannel, 2,TaskList,0);
    MAP_uDMAChannelEnable(ulChannel);
}
Exemple #3
0
void DMASetupTransfer(unsigned long ulChannel, unsigned long ulMode,
                      unsigned long ulItemCount, unsigned long ulItemSize,
                      unsigned long ulArbSize, void *pvSrcBuf,
                      unsigned long ulSrcInc, void *pvDstBuf, unsigned long ulDstInc)
{
    MAP_uDMAChannelControlSet(ulChannel, ulItemSize | ulSrcInc | ulDstInc | ulArbSize);
    MAP_uDMAChannelAttributeEnable(ulChannel,UDMA_ATTR_USEBURST);
    MAP_uDMAChannelTransferSet(ulChannel, ulMode, pvSrcBuf, pvDstBuf, ulItemCount);
    MAP_uDMAChannelEnable(ulChannel);
}
Exemple #4
0
//*****************************************************************************
//
// USBLibDMAChannelEnable() for USB controllers that use uDMA.
//
//*****************************************************************************
static void
uDMAUSBChannelEnable(tUSBDMAInstance *psUSBDMAInst, uint32_t ui32Channel)
{
    uint32_t ui32IntEnabled;

    //
    // Save if the interrupt was enabled or not.
    //
    ui32IntEnabled = IntIsEnabled(psUSBDMAInst->ui32IntNum);

    //
    // Disable the USB interrupt if it was enabled.
    //
    if(ui32IntEnabled)
    {
        OS_INT_DISABLE(psUSBDMAInst->ui32IntNum);
    }

    //
    // Mark this channel as pending and not complete.
    //
    psUSBDMAInst->ui32Pending |= (1 << (ui32Channel - 1));
    psUSBDMAInst->ui32Complete &= ~(1 << (ui32Channel - 1));

    //
    // Enable DMA for the endpoint.
    //
    if(UDMAConfigIsRx(psUSBDMAInst->pui32Config[ui32Channel - 1]))
    {
        MAP_USBEndpointDMAEnable(psUSBDMAInst->ui32Base,
                                 psUSBDMAInst->pui8Endpoint[ui32Channel - 1],
                                 USB_EP_DEV_OUT | USB_EP_HOST_IN);
    }
    else
    {
        MAP_USBEndpointDMAEnable(psUSBDMAInst->ui32Base,
                                 psUSBDMAInst->pui8Endpoint[ui32Channel - 1],
                                 USB_EP_DEV_IN | USB_EP_HOST_OUT);
    }

    //
    // Enable the DMA in the uDMA controller.
    //
    MAP_uDMAChannelEnable(ui32Channel - 1);

    //
    // Enable the USB interrupt if it was enabled before.
    //
    if(ui32IntEnabled)
    {
        OS_INT_ENABLE(psUSBDMAInst->ui32IntNum);
    }
}
Exemple #5
0
inline void kickoff_transfer(unsigned int channel, unsigned int bus, int base) {
	const int transfer = sizeof(busbuffer) / 2;
_Static_assert(BUS_SIZE/2<=1024, "DMA Transfer must not be more than 1024");
	MAP_uDMAChannelTransferSet(channel | UDMA_PRI_SELECT, UDMA_MODE_BASIC, (unsigned char*)(&framebuffer_output[bus]), (void *)(base + SSI_O_DR), transfer);
	MAP_uDMAChannelEnable(channel);
}
Exemple #6
0
//*****************************************************************************
//!
//! 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);
    }
}
/*
 *  ======== CameraCC3200DMA_hwiIntFxn ========
 *  Hwi function that processes Camera interrupts.
 *
 *  The Frame end,DMA interrupts is enabled for the camera.
 *  The DMA interrupt is triggered for every 64 elements.
 *  The ISR will check for Frame end interrupt to trigger the callback
 *  in the non-blocking mode/post a semaphore in the blocking mode to
 *  indicate capture complete.
 *
 *  @param(arg)         The Camera_Handle for this Hwi.
 */
static void CameraCC3200DMA_hwiIntFxn(uintptr_t arg)
{
    uint32_t                     status;
    CameraCC3200DMA_Object        *object = ((Camera_Handle)arg)->object;
    CameraCC3200DMA_HWAttrs const *hwAttrs = ((Camera_Handle)arg)->hwAttrs;
    unsigned long **bufferPtr = (unsigned long**)&object->captureBuf;

    status = MAP_CameraIntStatus(hwAttrs->baseAddr);
    if ((object->cameraDMAxIntrRcvd > 1) && (status & (CAM_INT_FE))) {
        DebugP_log2("Camera:(%p) Interrupt with mask 0x%x",
               hwAttrs->baseAddr,status);

        MAP_CameraIntClear(hwAttrs->baseAddr, CAM_INT_FE);
        object->captureCallback((Camera_Handle)arg, *bufferPtr,
                                 object->frameLength);
        DebugP_log2("Camera:(%p) capture finished, %d bytes written",
                hwAttrs->baseAddr, object->frameLength);
        object->inUse = 0;

        MAP_CameraCaptureStop(hwAttrs->baseAddr, true);

        Power_releaseConstraint(PowerCC3200_DISALLOW_DEEPSLEEP);
    }

    if (status & CAM_INT_DMA) {
        // Camera DMA Done clear
        MAP_CameraIntClear(hwAttrs->baseAddr, CAM_INT_DMA);

        object->cameraDMAxIntrRcvd++;

        object->frameLength +=
         (CameraCC3200DMA_DMA_TRANSFER_SIZE*sizeof(unsigned long));
        if (object->frameLength < object->bufferlength) {
             if (object->cameraDMA_PingPongMode == 0) {
                MAP_uDMAChannelControlSet(hwAttrs->channelIndex,
                UDMA_SIZE_32 | UDMA_SRC_INC_32 | UDMA_DST_INC_32 | UDMA_ARB_8);

                MAP_uDMAChannelAttributeEnable(hwAttrs->channelIndex,
                                                 UDMA_ATTR_USEBURST);
                MAP_uDMAChannelTransferSet(hwAttrs->channelIndex,
                                           UDMA_MODE_PINGPONG,
                                           (void *)CAM_BUFFER_ADDR,
                                           (void *)*bufferPtr,
                                           CameraCC3200DMA_DMA_TRANSFER_SIZE);
                MAP_uDMAChannelEnable(hwAttrs->channelIndex);
                *bufferPtr += CameraCC3200DMA_DMA_TRANSFER_SIZE;
                object->cameraDMA_PingPongMode = 1;
            }
            else {
                MAP_uDMAChannelControlSet(hwAttrs->channelIndex | UDMA_ALT_SELECT,
                  UDMA_SIZE_32 | UDMA_SRC_INC_32 | UDMA_DST_INC_32 | UDMA_ARB_8);

                MAP_uDMAChannelAttributeEnable(
                    hwAttrs->channelIndex | UDMA_ALT_SELECT,
                    UDMA_ATTR_USEBURST);
                MAP_uDMAChannelTransferSet(
                    hwAttrs->channelIndex | UDMA_ALT_SELECT,
                    UDMA_MODE_PINGPONG,
                    (void *)CAM_BUFFER_ADDR, (void *)*bufferPtr,
                    CameraCC3200DMA_DMA_TRANSFER_SIZE);
                MAP_uDMAChannelEnable(hwAttrs->channelIndex | UDMA_ALT_SELECT);
                *bufferPtr += CameraCC3200DMA_DMA_TRANSFER_SIZE;
                object->cameraDMA_PingPongMode = 0;
            }
        }
        else {
            // Disable DMA
            MAP_UtilsDelay(20000);
            MAP_uDMAChannelDisable(hwAttrs->channelIndex);
            MAP_CameraIntDisable(hwAttrs->baseAddr, CAM_INT_DMA);
            object->cameraDMA_PingPongMode = 0;
            object->captureCallback((Camera_Handle)arg, *bufferPtr,
                                     object->frameLength);
            DebugP_log2("Camera:(%p) capture finished, %d bytes written",
                    hwAttrs->baseAddr, object->frameLength);

            MAP_CameraCaptureStop(hwAttrs->baseAddr, true);

            Power_releaseConstraint(PowerCC3200_DISALLOW_DEEPSLEEP);
        }
    }
}
/*
 *  ======== SPICC3200DMA_configDMA ========
 *  This functions configures the transmit and receive DMA channels for a given
 *  SPI_Handle and SPI_Transaction
 *
 *  @pre    Function assumes that the handle and transaction is not NULL
 */
static void SPICC3200DMA_configDMA(SPI_Handle handle, SPI_Transaction *transaction)
{
    uintptr_t                   key;
    SPIDataType                 dummy;
    void                       *buf;
    uint32_t                    channelControlOptions;
    SPICC3200DMA_Object        *object = handle->object;
    SPICC3200DMA_HWAttrs const *hwAttrs = handle->hwAttrs;

    /* Clear out the FIFO */
    while (MAP_SPIDataGetNonBlocking(hwAttrs->baseAddr, &dummy)) {}

    /* Configure DMA for RX */
    MAP_uDMAChannelAssign(hwAttrs->rxChannelIndex);
    MAP_uDMAChannelAttributeDisable(hwAttrs->rxChannelIndex, UDMA_ATTR_ALTSELECT);

    if (transaction->rxBuf) {
        channelControlOptions = dmaRxConfig[object->frameSize];
        buf = transaction->rxBuf;
    }
    else {
        channelControlOptions = dmaNullConfig[object->frameSize];
        buf = hwAttrs->scratchBufPtr;
    }
    MAP_uDMAChannelControlSet(hwAttrs->rxChannelIndex | UDMA_PRI_SELECT,
                              channelControlOptions);
    MAP_uDMAChannelTransferSet(hwAttrs->rxChannelIndex | UDMA_PRI_SELECT,
                               UDMA_MODE_BASIC,
                               (void *)(hwAttrs->baseAddr + MCSPI_O_RX0),
                               buf,
                               transaction->count);

    /* Configure DMA for TX */
    MAP_uDMAChannelAssign(hwAttrs->txChannelIndex);
    MAP_uDMAChannelAttributeDisable(hwAttrs->txChannelIndex, UDMA_ATTR_ALTSELECT);

    if (transaction->txBuf) {
        channelControlOptions = dmaTxConfig[object->frameSize];
        buf = transaction->txBuf;
    }
    else {
        channelControlOptions = dmaNullConfig[object->frameSize];
        *hwAttrs->scratchBufPtr = hwAttrs->defaultTxBufValue;
        buf = hwAttrs->scratchBufPtr;
    }
    MAP_uDMAChannelControlSet(hwAttrs->txChannelIndex | UDMA_PRI_SELECT,
                              channelControlOptions);
    MAP_uDMAChannelTransferSet(hwAttrs->txChannelIndex | UDMA_PRI_SELECT,
                               UDMA_MODE_BASIC,
                               buf,
                               (void *)(hwAttrs->baseAddr + MCSPI_O_TX0),
                               transaction->count);

    DebugP_log1("SPI:(%p) DMA transfer enabled", hwAttrs->baseAddr);
    DebugP_log4("SPI:   DMA transaction: %p, rxBuf: %p; txBuf: %p; Count: %d",
                (uintptr_t)transaction, (uintptr_t)transaction->rxBuf,
                (uintptr_t)transaction->txBuf, (uintptr_t)transaction->count);

    key = HwiP_disable();
    MAP_uDMAChannelEnable(hwAttrs->rxChannelIndex);
    MAP_uDMAChannelEnable(hwAttrs->txChannelIndex);
    HwiP_restore(key);

    MAP_SPIWordCountSet(hwAttrs->baseAddr, transaction->count);
}
//*****************************************************************************
//
// The main function sets up the peripherals for the example, then enters
// a wait loop until the DMA transfers are complete.  At the end some
// information is printed for the user.
//
//*****************************************************************************
int
main(void)
{
    unsigned long ulIdx;

    //
    // Set the clocking to run directly from the PLL at 50 MHz.
    //
    MAP_SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN |
                       SYSCTL_XTAL_16MHZ);

    //
    // Initialize the console UART and write a message to the terminal.
    //
    MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    MAP_GPIOPinConfigure(GPIO_PA0_U0RX);
    MAP_GPIOPinConfigure(GPIO_PA1_U0TX);
    MAP_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
    UARTStdioInit(0);
    UARTprintf("\033[2JMemory/UART scatter-gather uDMA example\n\n");

    //
    // Configure UART1 to be used for the loopback peripheral
    //
    MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART1);

    //
    // Configure the UART communication parameters.
    //
    MAP_UARTConfigSetExpClk(UART1_BASE, MAP_SysCtlClockGet(), 115200,
                            UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
                            UART_CONFIG_PAR_NONE);

    //
    // Set both the TX and RX trigger thresholds to one-half (8 bytes).  This
    // will be used by the uDMA controller to signal when more data should be
    // transferred.  The uDMA TX and RX channels will be configured so that it
    // can transfer 8 bytes in a burst when the UART is ready to transfer more
    // data.
    //
    MAP_UARTFIFOLevelSet(UART1_BASE, UART_FIFO_TX4_8, UART_FIFO_RX4_8);

    //
    // Enable the UART for operation, and enable the uDMA interface for both TX
    // and RX channels.
    //
    MAP_UARTEnable(UART1_BASE);
    MAP_UARTDMAEnable(UART1_BASE, UART_DMA_RX | UART_DMA_TX);

    //
    // This register write will set the UART to operate in loopback mode.  Any
    // data sent on the TX output will be received on the RX input.
    //
    HWREG(UART1_BASE + UART_O_CTL) |= UART_CTL_LBE;

    //
    // Enable the UART peripheral interrupts.  Note that no UART interrupts
    // were enabled, but the uDMA controller will cause an interrupt on the
    // UART interrupt signal when a uDMA transfer is complete.
    //
    MAP_IntEnable(INT_UART1);

    //
    // Enable the uDMA peripheral clocking.
    //
    MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);

    //
    // Enable the uDMA controller.
    //
    MAP_uDMAEnable();

    //
    // Point at the control table to use for channel control structures.
    //
    MAP_uDMAControlBaseSet(sControlTable);

    //
    // Configure the UART TX channel for scatter-gather
    // Peripheral scatter-gather is used because transfers are gated by
    // requests from the peripheral
    //
    UARTprintf("Configuring UART TX uDMA channel for scatter-gather\n");
#ifndef USE_SGSET_API
    //
    // Use the original method for configuring the scatter-gather transfer
    //
    uDMAChannelControlSet(UDMA_CHANNEL_UART1TX, UDMA_SIZE_32 |
                          UDMA_SRC_INC_32 | UDMA_DST_INC_32 | UDMA_ARB_4);
    uDMAChannelTransferSet(UDMA_CHANNEL_UART1TX, UDMA_MODE_PER_SCATTER_GATHER,
                           g_TaskTableSrc,
                           &sControlTable[UDMA_CHANNEL_UART1TX], 6 * 4);
#else
    //
    // Use the simplified API for configuring the scatter-gather transfer
    //
    uDMAChannelScatterGatherSet(UDMA_CHANNEL_UART1TX, 6, g_TaskTableSrc, 1);
#endif

    //
    // Configure the UART RX channel for scatter-gather task list.
    // This is set to peripheral s-g because it starts by receiving data
    // from the UART
    //
    UARTprintf("Configuring UART RX uDMA channel for scatter-gather\n");
#ifndef USE_SGSET_API
    //
    // Use the original method for configuring the scatter-gather transfer
    //
    uDMAChannelControlSet(UDMA_CHANNEL_UART1RX, UDMA_SIZE_32 |
                          UDMA_SRC_INC_32 | UDMA_DST_INC_32 | UDMA_ARB_4);
    uDMAChannelTransferSet(UDMA_CHANNEL_UART1RX, UDMA_MODE_PER_SCATTER_GATHER,
                           g_TaskTableDst,
                           &sControlTable[UDMA_CHANNEL_UART1RX], 7 * 4);
#else
    //
    // Use the simplified API for configuring the scatter-gather transfer
    //
    uDMAChannelScatterGatherSet(UDMA_CHANNEL_UART1RX, 7, g_TaskTableDst, 1);
#endif

    //
    // Fill the source buffer with a pattern
    //
    for(ulIdx = 0; ulIdx < 1024; ulIdx++)
    {
        g_ucSrcBuf[ulIdx] = ulIdx + (ulIdx / 256);
    }

    //
    // Enable the uDMA controller error interrupt.  This interrupt will occur
    // if there is a bus error during a transfer.
    //
    IntEnable(INT_UDMAERR);

    //
    // Enable the UART RX DMA channel.  It will wait for data to be available
    // from the UART.
    //
    UARTprintf("Enabling uDMA channel for UART RX\n");
    MAP_uDMAChannelEnable(UDMA_CHANNEL_UART1RX);

    //
    // Enable the UART TX DMA channel.  Since the UART TX will be asserting
    // a DMA request (since the TX FIFO is empty), this will cause this
    // DMA channel to start running.
    //
    UARTprintf("Enabling uDMA channel for UART TX\n");
    MAP_uDMAChannelEnable(UDMA_CHANNEL_UART1TX);

    //
    // Wait for the TX task list to be finished
    //
    UARTprintf("Waiting for TX task list to finish ... ");
    while(!g_bTXdone)
    {
    }
    UARTprintf("done\n");

    //
    // Wait for the RX task list to be finished
    //
    UARTprintf("Waiting for RX task list to finish ... ");
    while(!g_bRXdone)
    {
    }
    UARTprintf("done\n");

    //
    // Verify that all the counters are in the expected state
    //
    UARTprintf("Verifying counters\n");
    if(g_ulDMAIntCount != 2)
    {
        UARTprintf("ERROR in interrupt count, found %d, expected 2\n",
                  g_ulDMAIntCount);
    }
    if(g_uluDMAErrCount != 0)
    {
        UARTprintf("ERROR in error counter, found %d, expected 0\n",
                  g_uluDMAErrCount);
    }

    //
    // Now verify the contents of the final destination buffer.  Compare it
    // to the original source buffer.
    //
    UARTprintf("Verifying buffer contents ... ");
    for(ulIdx = 0; ulIdx < 1024; ulIdx++)
    {
        if(g_ucDstBuf[ulIdx] != g_ucSrcBuf[ulIdx])
        {
            UARTprintf("ERROR\n    @ index %d: expected 0x%02X, found 0x%02X\n",
                       ulIdx, g_ucSrcBuf[ulIdx], g_ucDstBuf[ulIdx]);
            UARTprintf("Checking stopped.  There may be additional errors\n");
            break;
        }
    }
    if(ulIdx == 1024)
    {
        UARTprintf("OK\n");
    }

    //
    // End of program, loop forever
    //
    for(;;)
    {
    }
}