//***************************************************************************** // // 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); }
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; }
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) { } }
//***************************************************************************** // // 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) { } }
//***************************************************************************** // // 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); }
//***************************************************************************** // // 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); }