//*****************************************************************************
//
// Initializes the uDMA software channel to perform a memory to memory uDMA
// transfer.
//
//*****************************************************************************
void
InitSWTransfer(void)
{
    unsigned int uIdx;

    //
    // Fill the source memory buffer with a simple incrementing pattern.
    //
    for(uIdx = 0; uIdx < MEM_BUFFER_SIZE; uIdx++)
    {
        g_ulSrcBuf[uIdx] = uIdx;
    }

    //
    // Enable interrupts from the uDMA software channel.
    //
    ROM_IntEnable(INT_UDMA);

    //
    // Put the attributes in a known state for the uDMA software channel.
    // These should already be disabled by default.
    //
    ROM_uDMAChannelAttributeDisable(UDMA_CHANNEL_SW,
                                    UDMA_ATTR_USEBURST | UDMA_ATTR_ALTSELECT |
                                    (UDMA_ATTR_HIGH_PRIORITY |
                                    UDMA_ATTR_REQMASK));

    //
    // Configure the control parameters for the SW channel.  The SW channel
    // will be used to transfer between two memory buffers, 32 bits at a time.
    // Therefore the data size is 32 bits, and the address increment is 32 bits
    // for both source and destination.  The arbitration size will be set to 8,
    // which causes the uDMA controller to rearbitrate after 8 items are
    // transferred.  This keeps this channel from hogging the uDMA controller
    // once the transfer is started, and allows other channels cycles if they
    // are higher priority.
    //
    ROM_uDMAChannelControlSet(UDMA_CHANNEL_SW | UDMA_PRI_SELECT,
                              UDMA_SIZE_32 | UDMA_SRC_INC_32 | UDMA_DST_INC_32 |
                              UDMA_ARB_8);

    //
    // Set up the transfer parameters for the software channel.  This will
    // configure the transfer buffers and the transfer size.  Auto mode must be
    // used for software transfers.
    //
    ROM_uDMAChannelTransferSet(UDMA_CHANNEL_SW | UDMA_PRI_SELECT,
                               UDMA_MODE_AUTO, g_ulSrcBuf, g_ulDstBuf,
                               MEM_BUFFER_SIZE);

    //
    // Now the software channel is primed to start a transfer.  The channel
    // must be enabled.  For software based transfers, a request must be
    // issued.  After this, the uDMA memory transfer begins.
    //
    ROM_uDMAChannelEnable(UDMA_CHANNEL_SW);
    ROM_uDMAChannelRequest(UDMA_CHANNEL_SW);
}
Exemple #2
0
BOOL  xMBTCPPortSendResponse (const UCHAR * pucMBTCPFrame, USHORT  usLength)
{

	ROM_uDMAChannelTransferSet(UDMA_CHANNEL_UART1TX | UDMA_PRI_SELECT,
	        	                               UDMA_MODE_BASIC,(void *)  pucMBTCPFrame,
	        	                               (void *)(WIZ610_UART_BASE + UART_O_DR),
											   usLength);
	ROM_uDMAChannelEnable(UDMA_CHANNEL_UART1TX);
	modbus_tcp_rab=MODBUS_TCP_IDLE;
	xMBPortEventPost(EV_READY);
	return TRUE;
}
Exemple #3
0
unsigned char Wiz610_put_buf(unsigned char *buf, unsigned long count)
{
	unsigned long i;
	unsigned long ulMode;
	ulMode=ROM_uDMAChannelModeGet(UDMA_CHANNEL_UART1TX | UDMA_PRI_SELECT);
	if (ulMode!=UDMA_MODE_STOP) return false;
	i=0;
	while(i<count)
	{
		g_ucTxBuf[i]=*buf++;
		i++;
	}
	ROM_uDMAChannelTransferSet(UDMA_CHANNEL_UART1TX | UDMA_PRI_SELECT,
	                               UDMA_MODE_BASIC,(void *) g_ucTxBuf,
	                               (void *)(UART1_BASE + UART_O_DR),
	                                count);
	ROM_UARTEnable(WIZ610_UART_BASE);
	ROM_uDMAChannelEnable(UDMA_CHANNEL_UART1TX);
    return true;
}
//*****************************************************************************
//
// The interrupt handler for uDMA interrupts from the memory channel.  This
// interrupt will increment a counter, and then restart another memory
// transfer.
//
//*****************************************************************************
void
uDMAIntHandler(void)
{
    uint32_t ui32Mode;

    //
    // Check for the primary control structure to indicate complete.
    //
    ui32Mode = ROM_uDMAChannelModeGet(UDMA_CHANNEL_SW);
    if(ui32Mode == UDMA_MODE_STOP)
    {
        //
        // Increment the count of completed transfers.
        //
        g_ui32MemXferCount++;

        //
        // Configure it for another transfer.
        //
        ROM_uDMAChannelTransferSet(UDMA_CHANNEL_SW, UDMA_MODE_AUTO,
                                     g_ui32SrcBuf, g_ui32DstBuf,
                                     MEM_BUFFER_SIZE);

        //
        // Initiate another transfer.
        //
        ROM_uDMAChannelEnable(UDMA_CHANNEL_SW);
        ROM_uDMAChannelRequest(UDMA_CHANNEL_SW);
    }

    //
    // If the channel is not stopped, then something is wrong.
    //
    else
    {
        g_ui32BadISR++;
    }
}
//*****************************************************************************
//
// CS Rising Edge Interrupt Handler
//
//*****************************************************************************
void gpioQ1IntHandler(void) {
    uint32_t ui32Status;

    ui32Status = ROM_GPIOIntStatus(GPIO_PORTQ_BASE, 1);
    ROM_GPIOIntClear(GPIO_PORTQ_BASE, ui32Status);

    uint32_t xferSize = ROM_uDMAChannelSizeGet(UDMA_CH14_SSI3RX | UDMA_PRI_SELECT);

	//Calculate next RxWriteIndex (buffer in which to write the next set of data)
	uint8_t nextIndex = g_ui8RxWriteIndex + 1;
	if(nextIndex >= SSI_RX_BUFFER_COUNT) nextIndex = 0;

	//Get the size of the completed transfer
	uint32_t msgSize = SSI_BUFFER_SIZE - xferSize;
	g_ui32MessageSizes[g_ui8RxWriteIndex] = msgSize;

	//Store index value of this transaction for print debug message
	uint8_t previousIndex = g_ui8RxWriteIndex;

	//Move current rx write index to the next buffer
	g_ui8RxWriteIndex = nextIndex;

	ROM_uDMAChannelDisable(UDMA_CH14_SSI3RX);

	//Enable DMA channel to write in the next buffer position
	ROM_uDMAChannelTransferSet(UDMA_CH14_SSI3RX | UDMA_PRI_SELECT,
							   UDMA_MODE_BASIC,
							   (void *)(SSI3_BASE + SSI_O_DR),
							   g_ui8SSIRxBuf[g_ui8RxWriteIndex], sizeof(g_ui8SSIRxBuf[g_ui8RxWriteIndex]));

	ROM_uDMAChannelEnable(UDMA_CH14_SSI3RX);

	//Increment receive count
	g_ui32SSIRxWriteCount++;

	//UARTprintf("%d\t%d\t%x\t%x\n", previousIndex, msgSize, g_ui8SSIRxBuf[previousIndex][0], g_ui8SSIRxBuf[previousIndex][msgSize - 1]);
}
//*****************************************************************************
//
// This example application demonstrates the use of a periodic timer to
// request DMA transfers.
//
// Timer0 is used as the periodic timer that requests DMA transfers.
// Timer1 is a free running counter that is used as the source data for
// DMA transfers.  The captured counter values from Timer1 are copied by
// uDMA into a buffer.
//
//*****************************************************************************
int
main(void)
{
    unsigned long ulIdx;
    unsigned long ulThisTimerVal;
    unsigned long ulPrevTimerVal;
    unsigned long ulTimerElapsed;
    unsigned long ulTimerErr;

    //
    // Set the clocking to run directly from the crystal.
    //
    ROM_SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
                       SYSCTL_XTAL_16MHZ);

    //
    // Initialize the UART and write status.
    //
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    GPIOPinConfigure(GPIO_PA0_U0RX);
    GPIOPinConfigure(GPIO_PA1_U0TX);
    ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
    UARTStdioInit(0);
    UARTprintf("\033[2JuDMA periodic timer example\n\n");

    //
    // Enable the timers used by this example.
    //
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER1);

    //
    // Enable the uDMA peripheral
    //
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);

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

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

    //
    // Point at the control table to use for channel control structures.
    //
    ROM_uDMAControlBaseSet(ucControlTable);

    //
    // Enable processor interrupts.
    //
    ROM_IntMasterEnable();

    //
    // Configure one of the timers as free running 32-bit counter.  Its
    // value will be used as a time reference.
    //
    ROM_TimerConfigure(TIMER1_BASE, TIMER_CFG_PERIODIC);
    ROM_TimerLoadSet(TIMER1_BASE, TIMER_A, ~0);
    ROM_TimerEnable(TIMER1_BASE, TIMER_A);

    //
    // Configure the 32-bit periodic timer.
    //
    ROM_TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC);
    ROM_TimerLoadSet(TIMER0_BASE, TIMER_A, TIMEOUT_VAL - 1);

    //
    // Enable the timer master interrupt.  The timer interrupt will actually
    // be generated by the uDMA controller when the timer channel transfer is
    // complete.  The interrupts on the timer (TimerIntEnable) do not need
    // to be configured.
    //
    ROM_IntEnable(INT_TIMER0A);

    //
    // Put the attributes in a known state for the uDMA Timer0A channel.  These
    // should already be disabled by default.
    //
    ROM_uDMAChannelAttributeDisable(UDMA_CHANNEL_TMR0A,
                                    UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST |
                                    UDMA_ATTR_HIGH_PRIORITY |
                                    UDMA_ATTR_REQMASK);

    //
    // Set up the DMA channel for Timer 0A.  Set it up to transfer single
    // 32-bit words at a time.  The source is non-incrementing, the
    // destination is incrementing.
    //
    ROM_uDMAChannelControlSet(UDMA_CHANNEL_TMR0A | UDMA_PRI_SELECT,
                              UDMA_SIZE_32 |
                              UDMA_SRC_INC_NONE | UDMA_DST_INC_32 |
                              UDMA_ARB_1);

    //
    // Set up the transfer for Timer 0A DMA channel.  Basic mode is used,
    // which means that one transfer will occur per timer request (timeout).
    // The amount transferred per timeout is determined by the arbitration
    // size (see function above).  The source will be the value of free running
    // Timer1, and the destination is a memory buffer.  Thus, the value of the
    // free running Timer1 will be stored in a buffer every time the periodic
    // Timer0 times out.
    //
    ROM_uDMAChannelTransferSet(UDMA_CHANNEL_TMR0A | UDMA_PRI_SELECT,
                               UDMA_MODE_BASIC,
                               (void *)(TIMER1_BASE + TIMER_O_TAV),
                               g_ulTimerBuf, MAX_TIMER_EVENTS);

    //
    // Enable the timers and the DMA channel.
    //
    UARTprintf("Using timeout value of %u\n", TIMEOUT_VAL);
    UARTprintf("Starting timer and uDMA\n");
    TimerEnable(TIMER0_BASE, TIMER_A);
    uDMAChannelEnable(UDMA_CHANNEL_TMR0A);

    //
    // Wait for the transfer to complete.
    //
    UARTprintf("Waiting for transfers to complete\n");
    while(!g_bDoneFlag)
    {
    }

    //
    // Check for the expected number of occurrences of the interrupt handler,
    // and that there are no DMA errors
    //
    if(g_uluDMAErrCount != 0)
    {
        UARTprintf("\nuDMA errors were detected!!!\n\n");
    }
    if(g_ulTimer0AIntCount != 1)
    {
        UARTprintf("\nUnexpected number of interrupts occurrred (%d)!!!\n\n",
                   g_ulTimer0AIntCount);
    }

    //
    // Display the timer values that were transferred using timer triggered
    // uDMA.  Compare the difference between stored values to the timer
    // period and make sure they match.  This verifies that the periodic
    // DMA transfers were occuring with the correct timing.
    //
    UARTprintf("\n       Captured\n");
    UARTprintf("Event    Value    Difference  Status\n");
    UARTprintf("----- ----------  ----------  ------\n");
    for(ulIdx = 1; ulIdx < MAX_TIMER_EVENTS; ulIdx++)
    {
        //
        // Compute the difference between adjacent captured values, and then
        // compare that to the expected timeout period.
        //
        ulThisTimerVal = g_ulTimerBuf[ulIdx];
        ulPrevTimerVal = g_ulTimerBuf[ulIdx - 1];
        ulTimerElapsed = ulThisTimerVal > ulPrevTimerVal ?
                         ulThisTimerVal - ulPrevTimerVal :
                         ulPrevTimerVal - ulThisTimerVal;
        ulTimerErr = ulTimerElapsed > TIMEOUT_VAL ?
                     ulTimerElapsed - TIMEOUT_VAL :
                     TIMEOUT_VAL - ulTimerElapsed;

        //
        // Print the captured value and the difference from the previous
        //
        UARTprintf(" %2u   0x%08X  %8u   ", ulIdx, ulThisTimerVal,
                   ulTimerElapsed);

        //
        // Print error status based on the deviation from expected difference
        // between samples (calculated above).  Allow for a difference of up
        // to 1 cycle.  Any more than that is considered an error.
        //
        if(ulTimerErr >  1)
        {
            UARTprintf(" ERROR\n");
        }
        else
        {
            UARTprintf(" OK\n");
        }
    }

    //
    // End of application
    //
    while(1)
    {
    }
}
Exemple #7
0
//*****************************************************************************
//
// Perform an CCM decryption operation.
// 
//*****************************************************************************
bool
AES128CCMDecrypt(uint32_t *pui32Key, uint32_t *pui32Src, uint32_t *pui32Dst,
                 uint32_t ui32DataLength, uint32_t *pui32Nonce, 
                 uint32_t ui32NonceLength, uint32_t *pui32AuthData, 
                 uint32_t ui32AuthDataLength, uint32_t *pui32Tag, 
                 uint32_t ui32TagLength, bool bUseDMA)
{
    uint32_t pui32IV[4], ui32Idx;
    uint32_t ui32M, ui32L;
    uint8_t *pui8Nonce, *pui8IV;

    //
    // Determine the value of M.  It is determined using 
    // the tag length.
    //
    if(ui32TagLength == 4)
    {
        ui32M = AES_CFG_CCM_M_4;
    }
    else if(ui32TagLength == 6)
    {
        ui32M = AES_CFG_CCM_M_6;
    }
    else if(ui32TagLength == 8)
    {
        ui32M = AES_CFG_CCM_M_8;
    }
    else if(ui32TagLength == 10)
    {
        ui32M = AES_CFG_CCM_M_10;
    }
    else if(ui32TagLength == 12)
    {
        ui32M = AES_CFG_CCM_M_12;
    }
    else if(ui32TagLength == 14)
    {
        ui32M = AES_CFG_CCM_M_14;
    }
    else if(ui32TagLength == 16)
    {
        ui32M = AES_CFG_CCM_M_16;
    }
    else
    {
        UARTprintf("Unexpected tag length.\n");
        return(false);
    }

    //
    // Determine the value of L. This is determined by using
    // the value of q from the NIST document:  n + q = 15
    //
    if(ui32NonceLength == 7)
    {   
        ui32L = AES_CFG_CCM_L_8;
    }
    else if(ui32NonceLength == 8)
    {   
        ui32L = AES_CFG_CCM_L_7;
    }
    else if(ui32NonceLength == 9)
    {   
        ui32L = AES_CFG_CCM_L_6;
    }
    else if(ui32NonceLength == 10)
    {   
        ui32L = AES_CFG_CCM_L_5;
    }
    else if(ui32NonceLength == 11)
    {
        ui32L = AES_CFG_CCM_L_4;
    }
    else if(ui32NonceLength == 12)
    {
        ui32L = AES_CFG_CCM_L_3;
    }
    else if(ui32NonceLength == 13)
    {
        ui32L = AES_CFG_CCM_L_2;
    }
    else if(ui32NonceLength == 14)
    {
        ui32L = AES_CFG_CCM_L_1;
    }
    else
    {
        UARTprintf("Unexpected nonce length.\n");
        return(false);
    }

    //
    // Perform a soft reset.
    //
    ROM_AESReset(AES_BASE);

    //
    // Clear the interrupt flags.
    //
    g_bContextInIntFlag = false;
    g_bDataInIntFlag = false;
    g_bContextOutIntFlag = false;
    g_bDataOutIntFlag = false;
    g_bContextInDMADoneIntFlag = false;
    g_bDataInDMADoneIntFlag = false;
    g_bContextOutDMADoneIntFlag = false;
    g_bDataOutDMADoneIntFlag = false;

    //
    // Enable all interrupts.
    //
    ROM_AESIntEnable(AES_BASE, (AES_INT_CONTEXT_IN | AES_INT_CONTEXT_OUT |
                                AES_INT_DATA_IN | AES_INT_DATA_OUT));

    //
    // Configure the AES module.
    //
    ROM_AESConfigSet(AES_BASE, (AES_CFG_KEY_SIZE_128BIT | AES_CFG_DIR_DECRYPT |
                                AES_CFG_CTR_WIDTH_128 |
                                AES_CFG_MODE_CCM | ui32L | ui32M));

    //
    // Determine the value to be written in the initial value registers.  It is 
    // the concatenation of 5 bits of zero, 3 bits of L, nonce, and the counter
    // value.  First, clear the contents of the IV.
    //
    for(ui32Idx = 0; ui32Idx < 4; ui32Idx++)
    {
        pui32IV[ui32Idx] = 0;
    }

    //
    // Now find the binary value of L.
    //
    if(ui32L == AES_CFG_CCM_L_8)
    {
        pui32IV[0] = 0x7;
    }
    else if(ui32L == AES_CFG_CCM_L_7)
    {
        pui32IV[0] = 0x6;
    }
    else if(ui32L == AES_CFG_CCM_L_6)
    {
        pui32IV[0] = 0x5;
    }
    else if(ui32L == AES_CFG_CCM_L_5)
    {
        pui32IV[0] = 0x4;
    }
    else if(ui32L == AES_CFG_CCM_L_4)
    {
        pui32IV[0] = 0x3;
    }
    else if(ui32L == AES_CFG_CCM_L_3)
    {
        pui32IV[0] = 0x2;
    }
    else if(ui32L == AES_CFG_CCM_L_2)
    {
        pui32IV[0] = 0x1;
    }

    //
    // Finally copy the contents of the nonce into the IV.  Convert
    // the pointers to simplify the copying.
    //
    pui8Nonce = (uint8_t *)pui32Nonce; 
    pui8IV = (uint8_t *)pui32IV;
    for(ui32Idx = 0; ui32Idx < ui32NonceLength; ui32Idx++)
    {
        pui8IV[ui32Idx + 1] = pui8Nonce[ui32Idx];
    }

    //
    // Write the initial value.
    //
    ROM_AESIVSet(AES_BASE, pui32IV);

    //
    // Write the key.
    //
    ROM_AESKey1Set(AES_BASE, pui32Key, AES_CFG_KEY_SIZE_128BIT);
    
    //
    // Depending on the argument, perform the decryption
    // with or without uDMA.
    //
    if(bUseDMA)
    {
        //
        // Enable DMA interrupts.
        //
        ROM_AESIntEnable(AES_BASE, (AES_INT_DMA_CONTEXT_IN |
                                    AES_INT_DMA_DATA_IN |
                                    AES_INT_DMA_CONTEXT_OUT |
                                    AES_INT_DMA_DATA_OUT));

        //
        // Setup the DMA module to copy auth data in.
        //
        ROM_uDMAChannelAssign(UDMA_CH14_AES0DIN);
        ROM_uDMAChannelAttributeDisable(UDMA_CH14_AES0DIN,
                                        UDMA_ATTR_ALTSELECT |
                                        UDMA_ATTR_USEBURST |
                                        UDMA_ATTR_HIGH_PRIORITY |
                                        UDMA_ATTR_REQMASK);
        ROM_uDMAChannelControlSet(UDMA_CH14_AES0DIN | UDMA_PRI_SELECT,
                                  UDMA_SIZE_32 | UDMA_SRC_INC_32 |
                                  UDMA_DST_INC_NONE | UDMA_ARB_4 |
                                  UDMA_DST_PROT_PRIV);
        ROM_uDMAChannelTransferSet(UDMA_CH14_AES0DIN | UDMA_PRI_SELECT,
                                   UDMA_MODE_BASIC, (void *)pui32AuthData,
                                   (void *)(AES_BASE + AES_O_DATA_IN_0),
                                   LengthRoundUp(ui32AuthDataLength) / 4);
        UARTprintf("Data in DMA request enabled.\n");

        //
        // Setup the DMA module to copy the data out.
        //
        ROM_uDMAChannelAssign(UDMA_CH15_AES0DOUT);
        ROM_uDMAChannelAttributeDisable(UDMA_CH15_AES0DOUT,
                                        UDMA_ATTR_ALTSELECT |
                                        UDMA_ATTR_USEBURST |
                                        UDMA_ATTR_HIGH_PRIORITY |
                                        UDMA_ATTR_REQMASK);
        ROM_uDMAChannelControlSet(UDMA_CH15_AES0DOUT | UDMA_PRI_SELECT,
                                  UDMA_SIZE_32 | UDMA_SRC_INC_NONE |
                                  UDMA_DST_INC_32 | UDMA_ARB_4 |
                                  UDMA_SRC_PROT_PRIV);
        ROM_uDMAChannelTransferSet(UDMA_CH15_AES0DOUT | UDMA_PRI_SELECT,
                                   UDMA_MODE_BASIC,
                                   (void *)(AES_BASE + AES_O_DATA_IN_0),
                                   (void *)pui32Dst,
                                   LengthRoundUp(ui32DataLength) / 4);
        UARTprintf("Data out DMA request enabled.\n");

        //
        // Write the length registers.
        //
        ROM_AESLengthSet(AES_BASE, (uint64_t)ui32DataLength);

        //
        // Write the auth length registers to start the process.
        //
        ROM_AESAuthLengthSet(AES_BASE, ui32AuthDataLength);
        
        //
        // Enable the DMA channels to start the transfers.  This must be done after
        // writing the length to prevent data from copying before the context is 
        // truly ready.
        // 
        ROM_uDMAChannelEnable(UDMA_CH14_AES0DIN);
        ROM_uDMAChannelEnable(UDMA_CH15_AES0DOUT);

        //
        // Enable DMA requests.
        //
        ROM_AESDMAEnable(AES_BASE, AES_DMA_DATA_IN | AES_DMA_DATA_OUT);

        //
        // Wait for the data in DMA done interrupt.
        //
        while(!g_bDataInDMADoneIntFlag)
        {
        }

        //
        // Setup the uDMA to copy the plaintext data.
        //
        ROM_uDMAChannelAssign(UDMA_CH14_AES0DIN);
        ROM_uDMAChannelAttributeDisable(UDMA_CH14_AES0DIN,
                                        UDMA_ATTR_ALTSELECT |
                                        UDMA_ATTR_USEBURST |
                                        UDMA_ATTR_HIGH_PRIORITY |
                                        UDMA_ATTR_REQMASK);
        ROM_uDMAChannelControlSet(UDMA_CH14_AES0DIN | UDMA_PRI_SELECT,
                                  UDMA_SIZE_32 | UDMA_SRC_INC_32 |
                                  UDMA_DST_INC_NONE | UDMA_ARB_4 |
                                  UDMA_DST_PROT_PRIV);
        ROM_uDMAChannelTransferSet(UDMA_CH14_AES0DIN | UDMA_PRI_SELECT,
                                   UDMA_MODE_BASIC, (void *)pui32Src,
                                   (void *)(AES_BASE + AES_O_DATA_IN_0),
                                   LengthRoundUp(ui32DataLength) / 4);
        ROM_uDMAChannelEnable(UDMA_CH14_AES0DIN);
        UARTprintf("Data in DMA request enabled.\n");

        //
        // Wait for the data out DMA done interrupt.
        //
        while(!g_bDataOutDMADoneIntFlag)
        {
        }

        //
        // Read the tag out.
        //
        ROM_AESTagRead(AES_BASE, pui32Tag);
    }
    else
    {
        //
        // Perform the decryption.
        //
        ROM_AESDataProcessAuth(AES_BASE, pui32Src, pui32Dst, ui32DataLength,
                               pui32AuthData, ui32AuthDataLength, pui32Tag);
    }
    return(true);
}
void SSI3DMASlaveClass::configureDMA() {
  //Enable uDMA
  ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);
  ROM_SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_UDMA);

  //Register DMA interrupt to handler
  IntRegister(INT_UDMAERR, uDMAErrorHandler);
  
  //Enable interrupt
  ROM_IntEnable(INT_UDMAERR);

  // Enable the uDMA controller.
  ROM_uDMAEnable();

  // Point at the control table to use for channel control structures.
  ROM_uDMAControlBaseSet(pui8ControlTable);

  //Assign DMA channels to SSI3
  ROM_uDMAChannelAssign(UDMA_CH14_SSI3RX);
  ROM_uDMAChannelAssign(UDMA_CH15_SSI3TX);

  // Put the attributes in a known state for the uDMA SSI0RX channel.  These
  // should already be disabled by default.
  ROM_uDMAChannelAttributeDisable(UDMA_CH14_SSI3RX, UDMA_ATTR_USEBURST | UDMA_ATTR_ALTSELECT |
    (UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK));

  // Configure the control parameters for the primary control structure for
  // the SSIORX channel.
  ROM_uDMAChannelControlSet(UDMA_CH14_SSI3RX | UDMA_PRI_SELECT,
                            UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 |
                            UDMA_ARB_4);


//Enable DMA channel to write in the next buffer position
ROM_uDMAChannelTransferSet(UDMA_CH14_SSI3RX | UDMA_PRI_SELECT,
               UDMA_MODE_BASIC,
               (void *)(SSI3_BASE + SSI_O_DR),
               g_ui8SSIRxBuf[g_ui8RxWriteIndex], sizeof(g_ui8SSIRxBuf[g_ui8RxWriteIndex]));

// Configure TX

//
// Put the attributes in a known state for the uDMA SSI0TX channel.  These
// should already be disabled by default.
//
ROM_uDMAChannelAttributeDisable(UDMA_CH15_SSI3TX,
                UDMA_ATTR_ALTSELECT |
                UDMA_ATTR_HIGH_PRIORITY |
                UDMA_ATTR_REQMASK);

//	//
//	// Configure the control parameters for the primary control structure for
//	// the SSIORX channel.
//	//
//	ROM_uDMAChannelControlSet(UDMA_CH15_SSI3TX | UDMA_PRI_SELECT,
//							  UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_NONE |
//							  UDMA_ARB_4);
//
//	//Configure TX to always write 0xFF?
//	g_ui8SSITxBuf[0] = 0xFF;
//
//	//Enable DMA channel to write in the next buffer position
//	ROM_uDMAChannelTransferSet(UDMA_CH15_SSI3TX | UDMA_PRI_SELECT,
//							   UDMA_MODE_BASIC, g_ui8SSITxBuf,
//							   (void *)(SSI3_BASE + SSI_O_DR),
//							   sizeof(g_ui8SSITxBuf));

ROM_uDMAChannelEnable(UDMA_CH14_SSI3RX);
//	ROM_uDMAChannelEnable(UDMA_CH15_SSI3TX);

//	//
//	// Enable the SSI3 DMA TX/RX interrupts.
//	//
//	ROM_SSIIntEnable(SSI3_BASE, SSI_DMARX);
//
//	//
//	// Enable the SSI3 peripheral interrupts.
//	//
//	ROM_IntEnable(INT_SSI3);
}
//*****************************************************************************
//
// Initializes the UART0 peripheral and sets up the TX and RX uDMA channels.
// The UART is configured for loopback mode so that any data sent on TX will be
// received on RX.  The uDMA channels are configured so that the TX channel
// will copy data from a buffer to the UART TX output.  And the uDMA RX channel
// will receive any incoming data into a pair of buffers in ping-pong mode.
//
//*****************************************************************************
void
InitUART0Transfer(void)
{
    unsigned int uIdx;

    //
    // Fill the TX buffer with a simple data pattern.
    //
    for(uIdx = 0; uIdx < UART_TXBUF_SIZE; uIdx++)
    {
        g_ucTxBuf[uIdx] = uIdx;
    }

    //
    // Enable the UART peripheral, and configure it to operate even if the CPU
    // is in sleep.
    //
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
    ROM_SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_UART0);

    //
    // Configure the UART communication parameters.
    //
    ROM_UARTConfigSetExpClk(UART0_BASE, ROM_SysCtlClockGet(), 115200,
                            UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
                            UART_CONFIG_PAR_NONE);

    //
    // Set both the TX and RX trigger thresholds to 4.  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 4
    // bytes in a burst when the UART is ready to transfer more data.
    //
    ROM_UARTFIFOLevelSet(UART0_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.
    //
    ROM_UARTEnable(UART0_BASE);
    ROM_UARTDMAEnable(UART0_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(UART0_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.
    //
    ROM_IntEnable(INT_UART0);

    //
    // Put the attributes in a known state for the uDMA UART0RX channel.  These
    // should already be disabled by default.
    //
    ROM_uDMAChannelAttributeDisable(UDMA_CHANNEL_UART0RX,
                                    UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST |
                                    UDMA_ATTR_HIGH_PRIORITY |
                                    UDMA_ATTR_REQMASK);

    //
    // Configure the control parameters for the primary control structure for
    // the UART RX channel.  The primary contol structure is used for the "A"
    // part of the ping-pong receive.  The transfer data size is 8 bits, the
    // source address does not increment since it will be reading from a
    // register.  The destination address increment is byte 8-bit bytes.  The
    // arbitration size is set to 4 to match the RX FIFO trigger threshold.
    // The uDMA controller will use a 4 byte burst transfer if possible.  This
    // will be somewhat more effecient that single byte transfers.
    //
    ROM_uDMAChannelControlSet(UDMA_CHANNEL_UART0RX | UDMA_PRI_SELECT,
                              UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 |
                              UDMA_ARB_4);

    //
    // Configure the control parameters for the alternate control structure for
    // the UART RX channel.  The alternate contol structure is used for the "B"
    // part of the ping-pong receive.  The configuration is identical to the
    // primary/A control structure.
    //
    ROM_uDMAChannelControlSet(UDMA_CHANNEL_UART0RX | UDMA_ALT_SELECT,
                              UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 |
                              UDMA_ARB_4);

    //
    // Set up the transfer parameters for the UART RX primary control
    // structure.  The mode is set to ping-pong, the transfer source is the
    // UART data register, and the destination is the receive "A" buffer.  The
    // transfer size is set to match the size of the buffer.
    //
    ROM_uDMAChannelTransferSet(UDMA_CHANNEL_UART0RX | UDMA_PRI_SELECT,
                               UDMA_MODE_PINGPONG,
                               (void *)(UART0_BASE + UART_O_DR),
                               g_ucRxBufA, sizeof(g_ucRxBufA));

    //
    // Set up the transfer parameters for the UART RX alternate control
    // structure.  The mode is set to ping-pong, the transfer source is the
    // UART data register, and the destination is the receive "B" buffer.  The
    // transfer size is set to match the size of the buffer.
    //
    ROM_uDMAChannelTransferSet(UDMA_CHANNEL_UART0RX | UDMA_ALT_SELECT,
                               UDMA_MODE_PINGPONG,
                               (void *)(UART0_BASE + UART_O_DR),
                               g_ucRxBufB, sizeof(g_ucRxBufB));

    //
    // Put the attributes in a known state for the uDMA UART0TX channel.  These
    // should already be disabled by default.
    //
    ROM_uDMAChannelAttributeDisable(UDMA_CHANNEL_UART0TX,
                                    UDMA_ATTR_ALTSELECT |
                                    UDMA_ATTR_HIGH_PRIORITY |
                                    UDMA_ATTR_REQMASK);

    //
    // Set the USEBURST attribute for the uDMA UART TX channel.  This will
    // force the controller to always use a burst when transferring data from
    // the TX buffer to the UART.  This is somewhat more effecient bus usage
    // than the default which allows single or burst transfers.
    //
    ROM_uDMAChannelAttributeEnable(UDMA_CHANNEL_UART0TX, UDMA_ATTR_USEBURST);

    //
    // Configure the control parameters for the UART TX.  The uDMA UART TX
    // channel is used to transfer a block of data from a buffer to the UART.
    // The data size is 8 bits.  The source address increment is 8-bit bytes
    // since the data is coming from a buffer.  The destination increment is
    // none since the data is to be written to the UART data register.  The
    // arbitration size is set to 4, which matches the UART TX FIFO trigger
    // threshold.
    //
    ROM_uDMAChannelControlSet(UDMA_CHANNEL_UART0TX | UDMA_PRI_SELECT,
                              UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE |
                              UDMA_ARB_4);

    //
    // Set up the transfer parameters for the uDMA UART TX channel.  This will
    // configure the transfer source and destination and the transfer size.
    // Basic mode is used because the peripheral is making the uDMA transfer
    // request.  The source is the TX buffer and the destination is the UART
    // data register.
    //
    ROM_uDMAChannelTransferSet(UDMA_CHANNEL_UART0TX | UDMA_PRI_SELECT,
                               UDMA_MODE_BASIC, g_ucTxBuf,
                               (void *)(UART0_BASE + UART_O_DR),
                               sizeof(g_ucTxBuf));

    //
    // Now both the uDMA UART TX and RX channels are primed to start a
    // transfer.  As soon as the channels are enabled, the peripheral will
    // issue a transfer request and the data transfers will begin.
    //
    ROM_uDMAChannelEnable(UDMA_CHANNEL_UART0RX);
    ROM_uDMAChannelEnable(UDMA_CHANNEL_UART0TX);
}
//*****************************************************************************
//
// The interrupt handler for UART0.  This interrupt will occur when a DMA
// transfer is complete using the UART0 uDMA channel.  It will also be
// triggered if the peripheral signals an error.  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).
//
//*****************************************************************************
void
UART0IntHandler(void)
{
    unsigned long ulStatus;
    unsigned long ulMode;

    //
    // Read the interrupt status of the UART.
    //
    ulStatus = ROM_UARTIntStatus(UART0_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.
    //
    ROM_UARTIntClear(UART0_BASE, ulStatus);

    //
    // 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 = ROM_uDMAChannelModeGet(UDMA_CHANNEL_UART0RX | 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.  In
        // a real application this would be used to signal the main thread that
        // data was received so the main thread can process the data.
        //
        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.  This
        // example re-uses buffer A, but a more sophisticated application could
        // use a rotating set of buffers to increase the amount of time that
        // the main thread has to process the data in the buffer before it is
        // reused.
        //
        ROM_uDMAChannelTransferSet(UDMA_CHANNEL_UART0RX | UDMA_PRI_SELECT,
                                   UDMA_MODE_PINGPONG,
                                   (void *)(UART0_BASE + UART_O_DR),
                                   g_ucRxBufA, sizeof(g_ucRxBufA));
    }

    //
    // 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 = ROM_uDMAChannelModeGet(UDMA_CHANNEL_UART0RX | 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.  In
        // a real application this would be used to signal the main thread that
        // data was received so the main thread can process the data.
        //
        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.  This
        // example re-uses buffer B, but a more sophisticated application could
        // use a rotating set of buffers to increase the amount of time that
        // the main thread has to process the data in the buffer before it is
        // reused.
        //
        ROM_uDMAChannelTransferSet(UDMA_CHANNEL_UART0RX | UDMA_ALT_SELECT,
                                   UDMA_MODE_PINGPONG,
                                   (void *)(UART0_BASE + UART_O_DR),
                                   g_ucRxBufB, sizeof(g_ucRxBufB));
    }

    //
    // If the UART0 DMA TX channel is disabled, that means the TX DMA transfer
    // is done.
    //
    if(!ROM_uDMAChannelIsEnabled(UDMA_CHANNEL_UART0TX))
    {
        //
        // Start another DMA transfer to UART0 TX.
        //
        ROM_uDMAChannelTransferSet(UDMA_CHANNEL_UART0TX | UDMA_PRI_SELECT,
                                   UDMA_MODE_BASIC, g_ucTxBuf,
                                   (void *)(UART0_BASE + UART_O_DR),
                                   sizeof(g_ucTxBuf));

        //
        // The uDMA TX channel must be re-enabled.
        //
        ROM_uDMAChannelEnable(UDMA_CHANNEL_UART0TX);
    }
}
//*****************************************************************************
//
// Perform an encryption operation.
//
//*****************************************************************************
bool
TDESCBCEncrypt(uint32_t *pui32Src, uint32_t *pui32Dst, uint32_t *pui32Key,
                 uint32_t ui32Length, uint32_t *pui32IV, bool bUseDMA)
{
    //
    // Perform a soft reset.
    //
    ROM_DESReset(DES_BASE);

    //
    // Clear the interrupt flags.
    //
    g_bContextInIntFlag = false;
    g_bDataInIntFlag = false;
    g_bDataOutIntFlag = false;
    g_bContextInDMADoneIntFlag = false;
    g_bDataInDMADoneIntFlag = false;
    g_bDataOutDMADoneIntFlag = false;

    //
    // Enable all interrupts.
    //
    ROM_DESIntEnable(DES_BASE, (DES_INT_CONTEXT_IN |
                                DES_INT_DATA_IN | DES_INT_DATA_OUT));

    //
    // Configure the DES module.
    //
    ROM_DESConfigSet(DES_BASE, (DES_CFG_DIR_ENCRYPT | DES_CFG_TRIPLE |
                                DES_CFG_MODE_CBC));

    //
    // Write the key.
    //
    ROM_DESKeySet(DES_BASE, pui32Key);

    //
    // Write the IV.
    //
    ROM_DESIVSet(DES_BASE, pui32IV);

    //
    // Depending on the argument, perform the encryption
    // with or without uDMA.
    //
    if(bUseDMA)
    {
        //
        // Enable DMA interrupts.
        //
        ROM_DESIntEnable(DES_BASE, (DES_INT_DMA_CONTEXT_IN |
                                    DES_INT_DMA_DATA_IN |
                                    DES_INT_DMA_DATA_OUT));

        //
        // Setup the DMA module to copy data in.
        //
        ROM_uDMAChannelAssign(UDMA_CH21_DES0DIN);
        ROM_uDMAChannelAttributeDisable(UDMA_CH21_DES0DIN,
                                        UDMA_ATTR_ALTSELECT |
                                        UDMA_ATTR_USEBURST |
                                        UDMA_ATTR_HIGH_PRIORITY |
                                        UDMA_ATTR_REQMASK);
        ROM_uDMAChannelControlSet(UDMA_CH21_DES0DIN | UDMA_PRI_SELECT,
                                  UDMA_SIZE_32 | UDMA_SRC_INC_32 |
                                  UDMA_DST_INC_NONE | UDMA_ARB_2 |
                                  UDMA_DST_PROT_PRIV);
        ROM_uDMAChannelTransferSet(UDMA_CH21_DES0DIN | UDMA_PRI_SELECT,
                                   UDMA_MODE_BASIC, (void *)pui32Src,
                                   (void *)(DES_BASE + DES_O_DATA_L),
                                   LengthRoundUp(ui32Length) / 4);
        UARTprintf("Data in DMA request enabled.\n");

        //
        // Setup the DMA module to copy the data out.
        //
        ROM_uDMAChannelAssign(UDMA_CH22_DES0DOUT);
        ROM_uDMAChannelAttributeDisable(UDMA_CH22_DES0DOUT,
                                        UDMA_ATTR_ALTSELECT |
                                        UDMA_ATTR_USEBURST |
                                        UDMA_ATTR_HIGH_PRIORITY |
                                        UDMA_ATTR_REQMASK);
        ROM_uDMAChannelControlSet(UDMA_CH22_DES0DOUT | UDMA_PRI_SELECT,
                                  UDMA_SIZE_32 | UDMA_SRC_INC_NONE |
                                  UDMA_DST_INC_32 | UDMA_ARB_2 |
                                  UDMA_SRC_PROT_PRIV);
        ROM_uDMAChannelTransferSet(UDMA_CH22_DES0DOUT | UDMA_PRI_SELECT,
                                   UDMA_MODE_BASIC,
                                   (void *)(DES_BASE + DES_O_DATA_L),
                                   (void *)pui32Dst,
                                   LengthRoundUp(ui32Length) / 4);
        UARTprintf("Data out DMA request enabled.\n");

        //
        // Enable DMA requests
        //
        ROM_DESDMAEnable(DES_BASE, DES_DMA_DATA_IN | DES_DMA_DATA_OUT);

        //
        // Write the length registers to start the process.
        //
        ROM_DESLengthSet(DES_BASE, ui32Length);
        
        //
        // Enable the DMA channels to start the transfers.  This must be done after
        // writing the length to prevent data from copying before the context is 
        // truly ready.
        // 
        ROM_uDMAChannelEnable(UDMA_CH21_DES0DIN);
        ROM_uDMAChannelEnable(UDMA_CH22_DES0DOUT);

        //
        // Wait for the data in DMA done interrupt.
        //
        while(!g_bDataInDMADoneIntFlag)
        {
        }

        //
        // Wait for the data out DMA done interrupt.
        //
        while(!g_bDataOutDMADoneIntFlag)
        {
        }
    }
    else
    {
        //
        // Perform the encryption.
        //
        ROM_DESDataProcess(DES_BASE, pui32Src, pui32Dst, ui32Length);
    }

    return(true);
}
//*****************************************************************************
//
// Perform an GCM decryption operation.
//
//*****************************************************************************
bool
AESGCMDecrypt(uint32_t ui32Keysize, uint32_t *pui32Src, uint32_t *pui32Dst,
              uint32_t ui32Length, uint32_t *pui32Key, uint32_t *pui32IV,
              uint32_t *pui32AAD, uint32_t ui32AADLength, uint32_t *pui32Tag,
              bool bUseDMA)
{
    //
    // Perform a soft reset.
    //
    ROM_AESReset(AES_BASE);

    //
    // Clear the interrupt flags.
    //
    g_bContextInIntFlag = false;
    g_bDataInIntFlag = false;
    g_bContextOutIntFlag = false;
    g_bDataOutIntFlag = false;
    g_bContextInDMADoneIntFlag = false;
    g_bDataInDMADoneIntFlag = false;
    g_bContextOutDMADoneIntFlag = false;
    g_bDataOutDMADoneIntFlag = false;

    //
    // Enable all interrupts.
    //
    ROM_AESIntEnable(AES_BASE, (AES_INT_CONTEXT_IN | AES_INT_CONTEXT_OUT |
                                AES_INT_DATA_IN | AES_INT_DATA_OUT));

    //
    // Wait for the context in flag.
    //
    while(!g_bContextInIntFlag)
    {
    }

    //
    // Configure the AES module.
    //
    ROM_AESConfigSet(AES_BASE, (ui32Keysize | AES_CFG_DIR_DECRYPT |
                                AES_CFG_MODE_GCM_HY0CALC));

    //
    // Write the initialization value
    //
    ROM_AESIVSet(AES_BASE, pui32IV);

    //
    // Write the keys.
    //
    ROM_AESKey1Set(AES_BASE, pui32Key, ui32Keysize);

    //
    // Depending on the argument, perform the decryption
    // with or without uDMA.
    //
    if(bUseDMA)
    {
        //
        // Enable DMA interrupts.
        //
        ROM_AESIntEnable(AES_BASE, (AES_INT_DMA_CONTEXT_IN |
                                    AES_INT_DMA_DATA_IN |
                                    AES_INT_DMA_CONTEXT_OUT |
                                    AES_INT_DMA_DATA_OUT));

        if(ui32AADLength != 0)
        {
            //
            // Setup the DMA module to copy auth data in.
            //
            ROM_uDMAChannelAssign(UDMA_CH14_AES0DIN);
            ROM_uDMAChannelAttributeDisable(UDMA_CH14_AES0DIN,
                                            UDMA_ATTR_ALTSELECT |
                                            UDMA_ATTR_USEBURST |
                                            UDMA_ATTR_HIGH_PRIORITY |
                                            UDMA_ATTR_REQMASK);
            ROM_uDMAChannelControlSet(UDMA_CH14_AES0DIN | UDMA_PRI_SELECT,
                                      UDMA_SIZE_32 | UDMA_SRC_INC_32 |
                                      UDMA_DST_INC_NONE | UDMA_ARB_4 |
                                      UDMA_DST_PROT_PRIV);
            ROM_uDMAChannelTransferSet(UDMA_CH14_AES0DIN | UDMA_PRI_SELECT,
                                       UDMA_MODE_BASIC, (void *)pui32AAD,
                                       (void *)(AES_BASE + AES_O_DATA_IN_0),
                                       LengthRoundUp(ui32AADLength) / 4);
            UARTprintf("Data in DMA request enabled.\n");
        }

        //
        // Setup the DMA module to copy the data out.
        //
        ROM_uDMAChannelAssign(UDMA_CH15_AES0DOUT);
        ROM_uDMAChannelAttributeDisable(UDMA_CH15_AES0DOUT,
                                        UDMA_ATTR_ALTSELECT |
                                        UDMA_ATTR_USEBURST |
                                        UDMA_ATTR_HIGH_PRIORITY |
                                        UDMA_ATTR_REQMASK);
        ROM_uDMAChannelControlSet(UDMA_CH15_AES0DOUT | UDMA_PRI_SELECT,
                                  UDMA_SIZE_32 | UDMA_SRC_INC_NONE |
                                  UDMA_DST_INC_32 | UDMA_ARB_4 |
                                  UDMA_SRC_PROT_PRIV);
        ROM_uDMAChannelTransferSet(UDMA_CH15_AES0DOUT | UDMA_PRI_SELECT,
                                   UDMA_MODE_BASIC,
                                   (void *)(AES_BASE + AES_O_DATA_IN_0),
                                   (void *)pui32Dst,
                                   LengthRoundUp(ui32Length) / 4);
        UARTprintf("Data out DMA request enabled.\n");

        //
        // Write the plaintext length
        //
        ROM_AESLengthSet(AES_BASE, (uint64_t)ui32Length);

        //
        // Write the auth length registers to start the process.
        //
        ROM_AESAuthLengthSet(AES_BASE, ui32AADLength);
        
        //
        // Enable the DMA channels to start the transfers.  This must be done after
        // writing the length to prevent data from copying before the context is 
        // truly ready.
        // 
        if(ui32AADLength != 0)
        {
            ROM_uDMAChannelEnable(UDMA_CH14_AES0DIN);
        }
        ROM_uDMAChannelEnable(UDMA_CH15_AES0DOUT);

        //
        // Enable DMA requests
        //
        ROM_AESDMAEnable(AES_BASE, AES_DMA_DATA_IN | AES_DMA_DATA_OUT);

        if(ui32AADLength != 0)
        {
            //
            // Wait for the data in DMA done interrupt.
            //
            while(!g_bDataInDMADoneIntFlag)
            {
            }
        }

        if(ui32Length != 0)
        {
            //
            // Setup the uDMA to copy the plaintext data.
            //
            ROM_uDMAChannelAssign(UDMA_CH14_AES0DIN);
            ROM_uDMAChannelAttributeDisable(UDMA_CH14_AES0DIN,
                                            UDMA_ATTR_ALTSELECT |
                                            UDMA_ATTR_USEBURST |
                                            UDMA_ATTR_HIGH_PRIORITY |
                                            UDMA_ATTR_REQMASK);
            ROM_uDMAChannelControlSet(UDMA_CH14_AES0DIN | UDMA_PRI_SELECT,
                                      UDMA_SIZE_32 | UDMA_SRC_INC_32 |
                                      UDMA_DST_INC_NONE | UDMA_ARB_4 |
                                      UDMA_DST_PROT_PRIV);
            ROM_uDMAChannelTransferSet(UDMA_CH14_AES0DIN | UDMA_PRI_SELECT,
                                       UDMA_MODE_BASIC, (void *)pui32Src,
                                       (void *)(AES_BASE + AES_O_DATA_IN_0),
                                       LengthRoundUp(ui32Length) / 4);
            ROM_uDMAChannelEnable(UDMA_CH14_AES0DIN);
            UARTprintf("Data in DMA request enabled.\n");

            //
            // Wait for the data out DMA done interrupt.
            //
            while(!g_bDataOutDMADoneIntFlag)
            {
            }
        }

        //
        // Read out the tag.
        //
        AESTagRead(AES_BASE, pui32Tag);
    }
    else
    {
        //
        // Perform the decryption.
        //
        ROM_AESDataProcessAuth(AES_BASE, pui32Src, pui32Dst, ui32Length,
                               pui32AAD, ui32AADLength, pui32Tag);
    }

    return(true);
}
//*****************************************************************************
//
// Generate a hash for the given data.
//
//*****************************************************************************
void
SHA1HashGenerate(uint32_t *pui32Data, uint32_t ui32DataLength,
                 uint32_t *pui32HashResult, bool bUseDMA)
{
    //
    // Perform a soft reset of the SHA module.
    //
    ROM_SHAMD5Reset(SHAMD5_BASE);

    //
    // Clear the flags
    //
    g_bContextReadyFlag = false;
    g_bInputReadyFlag = false;
    g_bDataInDMADoneFlag = false;
    g_bContextOutDMADoneFlag = false;

    //
    // Enable interrupts.
    //
    ROM_SHAMD5IntEnable(SHAMD5_BASE, (SHAMD5_INT_CONTEXT_READY |
                                      SHAMD5_INT_PARTHASH_READY |
                                      SHAMD5_INT_INPUT_READY |
                                      SHAMD5_INT_OUTPUT_READY));

    //
    // Wait for the context ready flag.
    //
    while(!g_bContextReadyFlag)
    {
    }

    //
    // Configure the SHA/MD5 module.
    //
    ROM_SHAMD5ConfigSet(SHAMD5_BASE, SHAMD5_ALGO_SHA1);

    //
    // Use DMA to write the data into the SHA/MD5 module.
    //
    if(bUseDMA)
    {
        //
        // Enable DMA done interrupts.
        //
        ROM_SHAMD5IntEnable(SHAMD5_BASE, (SHAMD5_INT_DMA_CONTEXT_IN |
                                          SHAMD5_INT_DMA_DATA_IN |
                                          SHAMD5_INT_DMA_CONTEXT_OUT));

        if(ui32DataLength != 0)
        {
            //
            // Setup the DMA module to copy data in.
            //
            ROM_uDMAChannelAssign(UDMA_CH5_SHAMD50DIN);
            ROM_uDMAChannelAttributeDisable(UDMA_CH5_SHAMD50DIN,
                                            UDMA_ATTR_ALTSELECT |
                                            UDMA_ATTR_USEBURST |
                                            UDMA_ATTR_HIGH_PRIORITY |
                                            UDMA_ATTR_REQMASK);
            ROM_uDMAChannelControlSet(UDMA_CH5_SHAMD50DIN | UDMA_PRI_SELECT,
                                      UDMA_SIZE_32 | UDMA_SRC_INC_32 |
                                      UDMA_DST_INC_NONE | UDMA_ARB_16 |
                                      UDMA_DST_PROT_PRIV);
            ROM_uDMAChannelTransferSet(UDMA_CH5_SHAMD50DIN | UDMA_PRI_SELECT,
                                       UDMA_MODE_BASIC, (void *)pui32Data,
                                       (void *)(SHAMD5_BASE +
                                                SHAMD5_O_DATA_0_IN),
                                       ui32DataLength / 4);
            ROM_uDMAChannelEnable(UDMA_CH5_SHAMD50DIN);
            UARTprintf("Data in DMA request enabled.\n");
        }

        //
        // Setup the DMA module to copy the hash out.
        //
        ROM_uDMAChannelAssign(UDMA_CH6_SHAMD50COUT);
        ROM_uDMAChannelAttributeDisable(UDMA_CH6_SHAMD50COUT,
                                        UDMA_ATTR_ALTSELECT |
                                        UDMA_ATTR_USEBURST |
                                        UDMA_ATTR_HIGH_PRIORITY |
                                        UDMA_ATTR_REQMASK);
        ROM_uDMAChannelControlSet(UDMA_CH6_SHAMD50COUT | UDMA_PRI_SELECT,
                                  UDMA_SIZE_32 | UDMA_SRC_INC_32 |
                                  UDMA_DST_INC_32 | UDMA_ARB_8 |
                                  UDMA_SRC_PROT_PRIV);
        ROM_uDMAChannelTransferSet(UDMA_CH6_SHAMD50COUT | UDMA_PRI_SELECT,
                                   UDMA_MODE_BASIC,
                                   (void *)(SHAMD5_BASE + SHAMD5_O_IDIGEST_A),
                                   (void *)pui32HashResult, 5);
        ROM_uDMAChannelEnable(UDMA_CH6_SHAMD50COUT);
        UARTprintf("Context out DMA request enabled.\n");

        //
        // Enable DMA in the SHA/MD5 module.
        //
        ROM_SHAMD5DMAEnable(SHAMD5_BASE);

        //
        // Write the length.
        //
        ROM_SHAMD5HashLengthSet(SHAMD5_BASE, ui32DataLength);

        if(ui32DataLength != 0)
        {
            //
            // Wait for the DMA done interrupt.
            //
            while(!g_bDataInDMADoneFlag)
            {
            }
        }

        //
        // Wait for the next DMA done interrupt.
        //
        while(!g_bContextOutDMADoneFlag)
        {
        }

        //
        // Disable DMA requests.
        //
        ROM_SHAMD5DMADisable(SHAMD5_BASE);
    }

    //
    // Perform hash computation by copying the data with the CPU.
    //
    else
    {
        //
        // Perform the hashing operation
        //
        ROM_SHAMD5DataProcess(SHAMD5_BASE, pui32Data, ui32DataLength,
                              pui32HashResult);
    }
}
// After a certain number of edges are captured, the application prints out
// the results and compares the elapsed time between edges to the expected
// value.
//
// Note that the "B" timer is used because on some devices the "A" timer does
// not work correctly with the uDMA controller.  Refer to the chip errata for
// details.
//
//*****************************************************************************
int
main(void)
{
    unsigned long ulIdx;
    unsigned short usTimerElapsed;
    //unsigned short usTimerErr;

    //
    // Set the clocking to run directly from the crystal.
    //
    ROM_SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
                       SYSCTL_XTAL_16MHZ);

    //
    // Initialize the UART and write a status message.
    //
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
    GPIOPinConfigure(GPIO_PA0_U0RX);
    GPIOPinConfigure(GPIO_PA1_U0TX);
    ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
    ROM_UARTConfigSetExpClk(UART0_BASE, ROM_SysCtlClockGet(), 115200,
                            (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
                             UART_CONFIG_PAR_EVEN));    
    
    //UARTStdioInit(0);
    //UARTprintf("\033[2JuDMA edge capture timer example\n\n");
    //UARTprintf("This example requires that PD0 and PD7 be jumpered together"
    //           "\n\n");

    //
    // Create a signal source that can be used as an input for the CCP1 pin.
    //
    SetupSignalSource();

    //
    // Enable the GPIO port used for the CCP1 input.
    //
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);

    //
    // Configure the Timer0 CCP1 function to use PD7
    //
    GPIOPinConfigure(GPIO_PB2_CCP3);
    GPIOPinTypeTimer(GPIO_PORTB_BASE, GPIO_PIN_2);

    //
    // Set up Timer0B for edge-timer mode, positive edge
    //
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER1);
    TimerConfigure(TIMER1_BASE, TIMER_CFG_16_BIT_PAIR | TIMER_CFG_B_CAP_TIME);
    TimerControlEvent(TIMER1_BASE, TIMER_B, TIMER_EVENT_BOTH_EDGES);
    TimerLoadSet(TIMER1_BASE, TIMER_B, 0xffff);

    //
    // Enable the uDMA peripheral
    //
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);

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

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

    //
    // Point at the control table to use for channel control structures.
    //
    ROM_uDMAControlBaseSet(ucControlTable);

    //
    // Put the attributes in a known state for the uDMA Timer0B channel.  These
    // should already be disabled by default.
    //
    ROM_uDMAChannelAttributeDisable(UDMA_CHANNEL_TMR1B,
                                    UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST |
                                    UDMA_ATTR_HIGH_PRIORITY |
                                    UDMA_ATTR_REQMASK);

    //
    // Configure DMA channel for Timer0B to transfer 16-bit values, 1 at a
    // time.  The source is fixed and the destination increments by 16-bits
    // (2 bytes) at a time.
    //
    ROM_uDMAChannelControlSet(UDMA_CHANNEL_TMR1B | UDMA_PRI_SELECT,
                              UDMA_SIZE_16 | UDMA_SRC_INC_NONE |
                              UDMA_DST_INC_16 | UDMA_ARB_1);

    //
    // Set up the transfer parameters for the Timer0B primary control
    // structure.  The mode is set to basic, the transfer source is the
    // Timer0B register, and the destination is a memory buffer.  The
    // transfer size is set to a fixed number of capture events.
    //
    ROM_uDMAChannelTransferSet(UDMA_CHANNEL_TMR1B | UDMA_PRI_SELECT,
                               UDMA_MODE_BASIC,
                               (void *)(TIMER1_BASE + TIMER_O_TBR),
                               g_usTimerBuf, MAX_TIMER_EVENTS);

    //
    // Enable the timer capture event interrupt.  Note that this signal is
    // used to trigger the DMA request and not an actual interrupt.
    // Start the capture timer running and enable its interrupt channel.
    // The timer interrupt channel is used by the uDMA controller.
    //
    //UARTprintf("Starting timer and uDMA\n");
    TimerIntEnable(TIMER1_BASE, TIMER_CAPB_EVENT);
    TimerEnable(TIMER1_BASE, TIMER_B);
    IntEnable(INT_TIMER1B);

    //
    // Now enable the DMA channel for Timer0B.  It should now start performing
    // transfers whenever there is a rising edge detected on the CCP1 pin.
    //
    ROM_uDMAChannelEnable(UDMA_CHANNEL_TMR1B);

    //
    // Enable processor interrupts.
    //
    ROM_IntMasterEnable();

    //
    // Wait for the transfer to complete.
    //
    //UARTprintf("Waiting for transfers to complete\n");
    while(!g_bDoneFlag)
    {
    }

    //
    // Check for the expected number of occurrences of the interrupt handler,
    // and that there are no DMA errors
    //
    if(g_uluDMAErrCount != 0)
    {
        //UARTprintf("\nuDMA errors were detected!!!\n\n");
    }
    if(g_ulTimer0BIntCount != 1)
    {
        //UARTprintf("\nUnexpected number of interrupts occurrred (%d)!!!\n\n",
        //           g_ulTimer0BIntCount);
    }

    //
    // Display the timer values that were captured using the edge capture timer
    // with uDMA.  Compare the difference between stored values to the PWM
    // period and make sure they match.  This verifies that the edge capture
    // DMA transfers were occurring with the correct timing.
    //
    //UARTprintf("\n      Captured\n");
    //UARTprintf("Event   Value   Difference  Status\n");
    //UARTprintf("----- --------  ----------  ------\n");
    const unsigned char nbColonnes = '1';
    UARTSend(&nbColonnes,1);
    for(ulIdx = 1; ulIdx < MAX_TIMER_EVENTS; ulIdx++)
    {
        //
        // Due to timer erratum, when the timer rolls past 0 as it counts
        // down, it will trigger an additional DMA transfer even though there
        // was not an edge capture.  This will appear in the data buffer as
        // a duplicate value - the value will be the same as the prior capture
        // value.  Therefore, in this example we skip past the duplicated
        // value.
        //
        if(g_usTimerBuf[ulIdx] == g_usTimerBuf[ulIdx - 1])
        {
        	const unsigned char dup = '$';
        	UARTSend(&dup,1);
            //UARTprintf(" %2u    0x%04X   skipped duplicate\n", ulIdx,
            //           g_usTimerBuf[ulIdx]);
            continue;
        }

        //
        // Compute the difference between adjacent captured values, and then
        // compare that to the expected timeout period.
        //
        usTimerElapsed = g_usTimerBuf[ulIdx - 1] - g_usTimerBuf[ulIdx];
        //usTimerErr = usTimerElapsed > TIMEOUT_VAL ?
        //             usTimerElapsed - TIMEOUT_VAL :
        //             TIMEOUT_VAL - usTimerElapsed;

        //
        // Print the captured value and the difference from the previous
        //
        unsigned char data[10];
        itoa(usTimerElapsed,data);
        UARTSend(data,10);
        //UARTprintf(" %2u    0x%04X   %8u   ", ulIdx, g_usTimerBuf[ulIdx],
        //           usTimerElapsed);

        //
        // Print error status based on the deviation from expected difference
        // between samples (calculated above).  Allow for a difference of up
        // to 1 cycle.  Any more than that is considered an error.
        //
        //if(usTimerErr >  1)
        //{
        	
        //    UARTprintf(" ERROR\n");
        //}
        //else
        //{
        //    UARTprintf("   OK\n");
        //}
    }
    const unsigned char fin = '\n';
    UARTSend(&fin,1);
    //
    // End of application
    //
    while(1)
    {
    }
}
Exemple #15
0
//*****************************************************************************
//
// Process data to produce a CRC-32 checksum.
//
//*****************************************************************************
uint32_t
CRC32DataProcess(uint32_t *pui32Data, uint32_t ui32Length, uint32_t ui32Seed,
                 bool bUseDMA)
{
    uint32_t ui32Result;

    //
    // Perform a soft reset.
    //
    ROM_SysCtlPeripheralReset(SYSCTL_PERIPH_CCM0);
    while(!ROM_SysCtlPeripheralReady(SYSCTL_PERIPH_CCM0))
    {
    }

    //
    // Configure the CRC engine.
    //
    ROM_CRCConfigSet(CCM0_BASE, (CRC_CFG_INIT_SEED | CRC_CFG_TYPE_P4C11DB7 |
                                 CRC_CFG_SIZE_32BIT));

    //
    // Write the seed.
    //
    ROM_CRCSeedSet(CCM0_BASE, ui32Seed);

    //
    // Generate CRC using uDMA to copy data.
    //
    if(bUseDMA)
    {
        //
        // Setup the DMA module to copy data in.
        //
        ROM_uDMAChannelAssign(UDMA_CH30_SW);
        ROM_uDMAChannelAttributeDisable(UDMA_CH30_SW,
                                        UDMA_ATTR_ALTSELECT |
                                        UDMA_ATTR_USEBURST |
                                        UDMA_ATTR_HIGH_PRIORITY |
                                        UDMA_ATTR_REQMASK);
        ROM_uDMAChannelControlSet(UDMA_CH30_SW | UDMA_PRI_SELECT,
                                  UDMA_SIZE_32 | UDMA_SRC_INC_32 |
                                  UDMA_DST_INC_NONE | UDMA_ARB_1 |
                                  UDMA_DST_PROT_PRIV);
        ROM_uDMAChannelTransferSet(UDMA_CH30_SW | UDMA_PRI_SELECT,
                                   UDMA_MODE_AUTO, (void *)g_pui32RandomData,
                                   (void *)(CCM0_BASE + CCM_O_CRCDIN),
                                   ui32Length);
        ROM_uDMAChannelEnable(UDMA_CH30_SW);
        UARTprintf(" Data in DMA request enabled.\n");

        //
        // Start the uDMA.
        //
        ROM_uDMAChannelRequest(UDMA_CH30_SW | UDMA_PRI_SELECT);

        //
        // Wait for the transfer to finish.
        //
        while(ROM_uDMAChannelIsEnabled(UDMA_CH30_SW))
        {
        }

        //
        // Read the result.
        //
        ui32Result = ROM_CRCResultRead(CCM0_BASE, false);
    }

    //
    // Generate CRC using CPU to copy data.
    //
    else
    {
        ui32Result = ROM_CRCDataProcess(CCM0_BASE, g_pui32RandomData,
                                        ui32Length, false);
    }

    return(ui32Result);
}
Exemple #16
0
//*****************************************************************************
//
// Initializes the SSI1 peripheral and sets up the TX and RX uDMA channels.
// The SSI is configured for loopback mode so that any data sent on TX will be
// received on RX.  The uDMA channels are configured so that the TX channel
// will copy data from a buffer to the SSI TX output.  And the uDMA RX channel
// will receive any incoming data into a pair of buffers in ping-pong mode.
//
//*****************************************************************************
void
InitSSI2Transfer(void)
{
    unsigned long SysClock=ROM_SysCtlClockGet();

    //
    // Enable the SSI peripheral, and configure it to operate even if the CPU
    // is in sleep.
    //
    
     
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI2);
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
    ROM_SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_SSI2);
    UARTprintf("%u\n",SysClock);
    GPIOPinConfigure(GPIO_PB4_SSI2CLK);
    GPIOPinWrite(GPIO_PORTE_BASE, GPIO_PIN_3, GPIO_PIN_3);
    GPIOPinConfigure(GPIO_PB5_SSI2FSS);
    GPIOPinConfigure(GPIO_PB6_SSI2RX);
    GPIOPinConfigure(GPIO_PB7_SSI2TX);
    GPIOPinTypeSSI(GPIO_PORTB_BASE, GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7);

    //
    // Configure the SSI communication parameters.
    //
    //UARTprintf("%u\n",SysClock);
    
    ROM_SSIConfigSetExpClk(SSI2_BASE, SysClock,
                             SSI_FRF_MOTO_MODE_1,
			     SSI_MODE_SLAVE,
			     1000000,
			     16);

    //
    // Set both the TX and RX trigger thresholds to 4.  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 4
    // bytes in a burst when the SSI is ready to transfer more data.
    //
    //ROM_SSIFIFOLevelSet(SSI2_BASE, SSI_FIFO_TX4_8, SSI_FIFO_RX4_8);
    
    HWREG(SSI2_BASE + SSI_O_CR1) |= 0x00000020; // set Slave Bypass mode

    //
    // Enable the SSI for operation, and enable the uDMA interface for both TX
    // and RX channels.
    //
    ROM_SSIEnable(SSI2_BASE);
    
    ROM_SSIDMAEnable(SSI2_BASE, SSI_DMA_RX | SSI_DMA_TX);

    //
    // This register write will set the SSI to operate in loopback mode.  Any
    // data sent on the TX output will be received on the RX input.
    //
    

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

    //
    // Put the attributes in a known state for the uDMA SSI2RX channel.  These
    // should already be disabled by default.
    //
    ROM_uDMAChannelAttributeDisable(UDMA_CHANNEL_SSI2TX,
                                    UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST |
                                    UDMA_ATTR_HIGH_PRIORITY |
                                    UDMA_ATTR_REQMASK);

    ROM_uDMAChannelAssign(UDMA_CH13_SSI2TX);
    //
    // Configure the control parameters for the primary control structure for
    // the SSI RX channel.  The primary contol structure is used for the "A"
    // part of the ping-pong receive.  The transfer data size is 8 bits, the
    // source address does not increment since it will be reading from a
    // register.  The destination address increment is byte 8-bit bytes.  The
    // arbitration size is set to 4 to match the RX FIFO trigger threshold.
    // The uDMA controller will use a 4 byte burst transfer if possible.  This
    // will be somewhat more effecient that single byte transfers.
    //
    ROM_uDMAChannelControlSet(UDMA_CHANNEL_SSI2TX | UDMA_PRI_SELECT,
                              UDMA_SIZE_16 | UDMA_SRC_INC_16 | UDMA_DST_INC_NONE |
                              UDMA_ARB_4);

    //
    // Configure the control parameters for the alternate control structure for
    // the SSI RX channel.  The alternate contol structure is used for the "B"
    // part of the ping-pong receive.  The configuration is identical to the
    // primary/A control structure.
    //
    ROM_uDMAChannelControlSet(UDMA_CHANNEL_SSI2TX | UDMA_ALT_SELECT,
                              UDMA_SIZE_16 | UDMA_SRC_INC_16 | UDMA_DST_INC_NONE |
                              UDMA_ARB_4);

    //
    // Set up the transfer parameters for the SSI RX primary control
    // structure.  The mode is set to ping-pong, the transfer source is the
    // SSI data register, and the destination is the receive "A" buffer.  The
    // transfer size is set to match the size of the buffer.
    //
    ROM_uDMAChannelTransferSet(UDMA_CHANNEL_SSI2TX | UDMA_PRI_SELECT,
                               UDMA_MODE_PINGPONG,
                               (void *)g_uiSsiTxBufA,
                               (void *)(SSI2_BASE + SSI_O_DR),
			       SSI_TXBUF_SIZE);

    //
    // Set up the transfer parameters for the SSI RX alternate control
    // structure.  The mode is set to ping-pong, the transfer source is the
    // SSI data register, and the destination is the receive "B" buffer.  The
    // transfer size is set to match the size of the buffer.
    //
    ROM_uDMAChannelTransferSet(UDMA_CHANNEL_SSI2TX | UDMA_ALT_SELECT,
                               UDMA_MODE_PINGPONG,
                               (void *)g_uiSsiTxBufB,
                               (void *)(SSI2_BASE + SSI_O_DR),
			       SSI_TXBUF_SIZE);
    
    ROM_uDMAChannelAttributeEnable(UDMA_CHANNEL_SSI2TX, UDMA_ATTR_USEBURST);

    
    
    UARTprintf("A_base: %X \n",(void *)g_uiSsiTxBufA);
    UARTprintf("B_base: %X \n",(void *)(g_uiSsiTxBufB));
    //
    // Put the attributes in a known state for the uDMA SSI2TX channel.  These
    // should already be disabled by default.
    //
    ROM_uDMAChannelAttributeDisable(UDMA_CHANNEL_SSI2RX,
                                    UDMA_ATTR_ALTSELECT |
                                    UDMA_ATTR_HIGH_PRIORITY |
                                    UDMA_ATTR_REQMASK);

    ROM_uDMAChannelAssign(UDMA_CH12_SSI2RX);
    //
    // Set the USEBURST attribute for the uDMA SSI RX channel.  This will
    // force the controller to always use a burst when transferring data from
    // the TX buffer to the SSI.  This is somewhat more effecient bus usage
    // than the default which allows single or burst transfers.
    //
    ROM_uDMAChannelAttributeEnable(UDMA_CHANNEL_SSI2RX, UDMA_ATTR_USEBURST);

    //
    // Configure the control parameters for the SSI TX.  The uDMA SSI TX
    // channel is used to transfer a block of data from a buffer to the SSI.
    // The data size is 8 bits.  The source address increment is 8-bit bytes
    // since the data is coming from a buffer.  The destination increment is
    // none since the data is to be written to the SSI data register.  The
    // arbitration size is set to 4, which matches the SSI TX FIFO trigger
    // threshold.
    //
    ROM_uDMAChannelControlSet(UDMA_CHANNEL_SSI2RX | UDMA_PRI_SELECT,
                              UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 |
                              UDMA_ARB_4);

    //
    // Set up the transfer parameters for the uDMA SSI TX channel.  This will
    // configure the transfer source and destination and the transfer size.
    // Basic mode is used because the peripheral is making the uDMA transfer
    // request.  The source is the TX buffer and the destination is the SSI
    // data register.
    //
    ROM_uDMAChannelTransferSet(UDMA_CHANNEL_SSI2RX | UDMA_PRI_SELECT,
                               UDMA_MODE_BASIC,
                               (void *)(SSI2_BASE + SSI_O_DR),
			       (void *)g_uiSsiRxBuf,
                               SSI_RXBUF_SIZE);

    //
    // Now both the uDMA SSI TX and RX channels are primed to start a
    // transfer.  As soon as the channels are enabled, the peripheral will
    // issue a transfer request and the data transfers will begin.
    //
    ROM_uDMAChannelEnable(UDMA_CHANNEL_SSI2TX);
    ROM_uDMAChannelEnable(UDMA_CHANNEL_SSI2RX);
     GPIOPinWrite(GPIO_PORTE_BASE, GPIO_PIN_3, 0);
}