/* * ======== CameraCC3200DMA_configDMA ======== */ static void CameraCC3200DMA_configDMA(Camera_Handle handle) { CameraCC3200DMA_Object *object = handle->object; CameraCC3200DMA_HWAttrs const *hwAttrs = handle->hwAttrs; unsigned long **bufferPtr = (unsigned long**)&object->captureBuf; /* Setup ping-pong transfer */ MAP_uDMAChannelControlSet(hwAttrs->channelIndex, UDMA_SIZE_32 | UDMA_SRC_INC_32 | UDMA_DST_INC_32 | UDMA_ARB_8); MAP_uDMAChannelAttributeEnable(hwAttrs->channelIndex,UDMA_ATTR_USEBURST); MAP_uDMAChannelTransferSet(hwAttrs->channelIndex, UDMA_MODE_PINGPONG, (void *)CAM_BUFFER_ADDR, (void *)*bufferPtr, CameraCC3200DMA_DMA_TRANSFER_SIZE); MAP_uDMAChannelEnable(hwAttrs->channelIndex); /* Pong Buffer */ *bufferPtr += CameraCC3200DMA_DMA_TRANSFER_SIZE; MAP_uDMAChannelControlSet(hwAttrs->channelIndex | UDMA_ALT_SELECT, UDMA_SIZE_32 | UDMA_SRC_INC_32 | UDMA_DST_INC_32 | UDMA_ARB_8); MAP_uDMAChannelAttributeEnable(hwAttrs->channelIndex | UDMA_ALT_SELECT, UDMA_ATTR_USEBURST); MAP_uDMAChannelTransferSet(hwAttrs->channelIndex | UDMA_ALT_SELECT, UDMA_MODE_PINGPONG, (void *)CAM_BUFFER_ADDR, (void *)*bufferPtr, CameraCC3200DMA_DMA_TRANSFER_SIZE); MAP_uDMAChannelEnable(hwAttrs->channelIndex | UDMA_ALT_SELECT); /* Ping Buffer */ *bufferPtr += CameraCC3200DMA_DMA_TRANSFER_SIZE; DebugP_log1("Camera:(%p) DMA transfer enabled", hwAttrs->baseAddr); /* Set mode to Ping buffer initially */ object->cameraDMA_PingPongMode = 0; /* Clear any pending interrupt */ MAP_CameraIntClear(hwAttrs->baseAddr, CAM_INT_DMA); /* DMA Interrupt unmask from apps config */ MAP_CameraIntEnable(hwAttrs->baseAddr, CAM_INT_DMA); DebugP_log3("Camera:(%p) DMA receive, " "CaptureBuf: %p; Count: %d", hwAttrs->baseAddr, (uintptr_t)*bufferPtr, (uintptr_t)object->bufferlength); }
static void SetupSGMemTransfer(unsigned long ulChannel,void *pvSrcBuf0, void *pvSrcBuf1,void *pvDstBuf,unsigned long size) { // // Create task0 // tDMAControlTable task0=uDMATaskStructEntry(size, UDMA_SIZE_8, UDMA_SRC_INC_8, pvSrcBuf0, UDMA_DST_INC_8,pvDstBuf, UDMA_ARB_8, UDMA_MODE_MEM_SCATTER_GATHER); // // create task1 // tDMAControlTable task1=uDMATaskStructEntry(size, UDMA_SIZE_8, UDMA_SRC_INC_8, pvSrcBuf1, UDMA_DST_INC_8, (char *)pvDstBuf+size, UDMA_ARB_8, UDMA_MODE_AUTO); // // Copy to TaskList // memcpy(&TaskList[0],&task0,sizeof(tDMAControlTable)); memcpy(&TaskList[1],&task1,sizeof(tDMAControlTable)); memset(pvDstBuf,0,size); // // Setup Scatter Gather with two tasks // MAP_uDMAChannelScatterGatherSet(ulChannel, 2,TaskList,0); MAP_uDMAChannelEnable(ulChannel); }
void DMASetupTransfer(unsigned long ulChannel, unsigned long ulMode, unsigned long ulItemCount, unsigned long ulItemSize, unsigned long ulArbSize, void *pvSrcBuf, unsigned long ulSrcInc, void *pvDstBuf, unsigned long ulDstInc) { MAP_uDMAChannelControlSet(ulChannel, ulItemSize | ulSrcInc | ulDstInc | ulArbSize); MAP_uDMAChannelAttributeEnable(ulChannel,UDMA_ATTR_USEBURST); MAP_uDMAChannelTransferSet(ulChannel, ulMode, pvSrcBuf, pvDstBuf, ulItemCount); MAP_uDMAChannelEnable(ulChannel); }
//***************************************************************************** // // USBLibDMAChannelEnable() for USB controllers that use uDMA. // //***************************************************************************** static void uDMAUSBChannelEnable(tUSBDMAInstance *psUSBDMAInst, uint32_t ui32Channel) { uint32_t ui32IntEnabled; // // Save if the interrupt was enabled or not. // ui32IntEnabled = IntIsEnabled(psUSBDMAInst->ui32IntNum); // // Disable the USB interrupt if it was enabled. // if(ui32IntEnabled) { OS_INT_DISABLE(psUSBDMAInst->ui32IntNum); } // // Mark this channel as pending and not complete. // psUSBDMAInst->ui32Pending |= (1 << (ui32Channel - 1)); psUSBDMAInst->ui32Complete &= ~(1 << (ui32Channel - 1)); // // Enable DMA for the endpoint. // if(UDMAConfigIsRx(psUSBDMAInst->pui32Config[ui32Channel - 1])) { MAP_USBEndpointDMAEnable(psUSBDMAInst->ui32Base, psUSBDMAInst->pui8Endpoint[ui32Channel - 1], USB_EP_DEV_OUT | USB_EP_HOST_IN); } else { MAP_USBEndpointDMAEnable(psUSBDMAInst->ui32Base, psUSBDMAInst->pui8Endpoint[ui32Channel - 1], USB_EP_DEV_IN | USB_EP_HOST_OUT); } // // Enable the DMA in the uDMA controller. // MAP_uDMAChannelEnable(ui32Channel - 1); // // Enable the USB interrupt if it was enabled before. // if(ui32IntEnabled) { OS_INT_ENABLE(psUSBDMAInst->ui32IntNum); } }
inline void kickoff_transfer(unsigned int channel, unsigned int bus, int base) { const int transfer = sizeof(busbuffer) / 2; _Static_assert(BUS_SIZE/2<=1024, "DMA Transfer must not be more than 1024"); MAP_uDMAChannelTransferSet(channel | UDMA_PRI_SELECT, UDMA_MODE_BASIC, (unsigned char*)(&framebuffer_output[bus]), (void *)(base + SSI_O_DR), transfer); MAP_uDMAChannelEnable(channel); }
//***************************************************************************** //! //! The interrupt handler for UART0. This interrupt will occur when a DMA //! transfer is complete using the UART0 uDMA channel.This interrupt handler will //! switch between receive ping-pong buffers A and B. It will also restart a TX //! uDMA transfer if the prior transfer is complete. This will keep the UART //! running continuously (looping TX data back to RX). //! //! \param None //! //! \return None //***************************************************************************** void UART0IntHandler(void) { unsigned long ulStatus; unsigned long ulMode; // // Read the interrupt status of the UART. // ulStatus = MAP_UARTIntStatus(UARTA0_BASE, 1); // // Clear any pending status, even though there should be none since no UART // interrupts were enabled. // MAP_UARTIntClear(UARTA0_BASE, ulStatus); if(uiCount<6) { // // Check the DMA control table to see if the ping-pong "A" transfer is // complete. The "A" transfer uses receive buffer "A", and the primary // control structure. // ulMode = MAP_uDMAChannelModeGet(UDMA_CH8_UARTA0_RX | UDMA_PRI_SELECT); // // If the primary control structure indicates stop, that means the "A" // receive buffer is done. The uDMA controller should still be receiving // data into the "B" buffer. // if(ulMode == UDMA_MODE_STOP) { // // Increment a counter to indicate data was received into buffer A. // g_ulRxBufACount++; // // Set up the next transfer for the "A" buffer, using the primary // control structure. When the ongoing receive into the "B" buffer is // done, the uDMA controller will switch back to this one. // UDMASetupTransfer(UDMA_CH8_UARTA0_RX | UDMA_PRI_SELECT, UDMA_MODE_PINGPONG, sizeof(g_ucRxBufA),UDMA_SIZE_8, UDMA_ARB_4, (void *)(UARTA0_BASE + UART_O_DR), UDMA_SRC_INC_NONE, g_ucRxBufA, UDMA_DST_INC_8); } // // Check the DMA control table to see if the ping-pong "B" transfer is // complete. The "B" transfer uses receive buffer "B", and the alternate // control structure. // ulMode = MAP_uDMAChannelModeGet(UDMA_CH8_UARTA0_RX | UDMA_ALT_SELECT); // // If the alternate control structure indicates stop, that means the "B" // receive buffer is done. The uDMA controller should still be receiving // data into the "A" buffer. // if(ulMode == UDMA_MODE_STOP) { // // Increment a counter to indicate data was received into buffer A. // g_ulRxBufBCount++; // // Set up the next transfer for the "B" buffer, using the alternate // control structure. When the ongoing receive into the "A" buffer is // done, the uDMA controller will switch back to this one. // UDMASetupTransfer(UDMA_CH8_UARTA0_RX | UDMA_ALT_SELECT, UDMA_MODE_PINGPONG, sizeof(g_ucRxBufB),UDMA_SIZE_8, UDMA_ARB_4,(void *)(UARTA0_BASE + UART_O_DR), UDMA_SRC_INC_NONE, g_ucRxBufB, UDMA_DST_INC_8); } // // If the UART0 DMA TX channel is disabled, that means the TX DMA transfer // is done. // if(!MAP_uDMAChannelIsEnabled(UDMA_CH9_UARTA0_TX)) { g_ulTxCount++; // // Start another DMA transfer to UART0 TX. // UDMASetupTransfer(UDMA_CH9_UARTA0_TX| UDMA_PRI_SELECT, UDMA_MODE_BASIC, sizeof(g_ucTxBuf),UDMA_SIZE_8, UDMA_ARB_4,g_ucTxBuf, UDMA_SRC_INC_8, (void *)(UARTA0_BASE + UART_O_DR), UDMA_DST_INC_NONE); // // The uDMA TX channel must be re-enabled. // MAP_uDMAChannelEnable(UDMA_CH9_UARTA0_TX); } } else { UARTDone=1; MAP_UARTIntUnregister(UARTA0_BASE); } }
/* * ======== CameraCC3200DMA_hwiIntFxn ======== * Hwi function that processes Camera interrupts. * * The Frame end,DMA interrupts is enabled for the camera. * The DMA interrupt is triggered for every 64 elements. * The ISR will check for Frame end interrupt to trigger the callback * in the non-blocking mode/post a semaphore in the blocking mode to * indicate capture complete. * * @param(arg) The Camera_Handle for this Hwi. */ static void CameraCC3200DMA_hwiIntFxn(uintptr_t arg) { uint32_t status; CameraCC3200DMA_Object *object = ((Camera_Handle)arg)->object; CameraCC3200DMA_HWAttrs const *hwAttrs = ((Camera_Handle)arg)->hwAttrs; unsigned long **bufferPtr = (unsigned long**)&object->captureBuf; status = MAP_CameraIntStatus(hwAttrs->baseAddr); if ((object->cameraDMAxIntrRcvd > 1) && (status & (CAM_INT_FE))) { DebugP_log2("Camera:(%p) Interrupt with mask 0x%x", hwAttrs->baseAddr,status); MAP_CameraIntClear(hwAttrs->baseAddr, CAM_INT_FE); object->captureCallback((Camera_Handle)arg, *bufferPtr, object->frameLength); DebugP_log2("Camera:(%p) capture finished, %d bytes written", hwAttrs->baseAddr, object->frameLength); object->inUse = 0; MAP_CameraCaptureStop(hwAttrs->baseAddr, true); Power_releaseConstraint(PowerCC3200_DISALLOW_DEEPSLEEP); } if (status & CAM_INT_DMA) { // Camera DMA Done clear MAP_CameraIntClear(hwAttrs->baseAddr, CAM_INT_DMA); object->cameraDMAxIntrRcvd++; object->frameLength += (CameraCC3200DMA_DMA_TRANSFER_SIZE*sizeof(unsigned long)); if (object->frameLength < object->bufferlength) { if (object->cameraDMA_PingPongMode == 0) { MAP_uDMAChannelControlSet(hwAttrs->channelIndex, UDMA_SIZE_32 | UDMA_SRC_INC_32 | UDMA_DST_INC_32 | UDMA_ARB_8); MAP_uDMAChannelAttributeEnable(hwAttrs->channelIndex, UDMA_ATTR_USEBURST); MAP_uDMAChannelTransferSet(hwAttrs->channelIndex, UDMA_MODE_PINGPONG, (void *)CAM_BUFFER_ADDR, (void *)*bufferPtr, CameraCC3200DMA_DMA_TRANSFER_SIZE); MAP_uDMAChannelEnable(hwAttrs->channelIndex); *bufferPtr += CameraCC3200DMA_DMA_TRANSFER_SIZE; object->cameraDMA_PingPongMode = 1; } else { MAP_uDMAChannelControlSet(hwAttrs->channelIndex | UDMA_ALT_SELECT, UDMA_SIZE_32 | UDMA_SRC_INC_32 | UDMA_DST_INC_32 | UDMA_ARB_8); MAP_uDMAChannelAttributeEnable( hwAttrs->channelIndex | UDMA_ALT_SELECT, UDMA_ATTR_USEBURST); MAP_uDMAChannelTransferSet( hwAttrs->channelIndex | UDMA_ALT_SELECT, UDMA_MODE_PINGPONG, (void *)CAM_BUFFER_ADDR, (void *)*bufferPtr, CameraCC3200DMA_DMA_TRANSFER_SIZE); MAP_uDMAChannelEnable(hwAttrs->channelIndex | UDMA_ALT_SELECT); *bufferPtr += CameraCC3200DMA_DMA_TRANSFER_SIZE; object->cameraDMA_PingPongMode = 0; } } else { // Disable DMA MAP_UtilsDelay(20000); MAP_uDMAChannelDisable(hwAttrs->channelIndex); MAP_CameraIntDisable(hwAttrs->baseAddr, CAM_INT_DMA); object->cameraDMA_PingPongMode = 0; object->captureCallback((Camera_Handle)arg, *bufferPtr, object->frameLength); DebugP_log2("Camera:(%p) capture finished, %d bytes written", hwAttrs->baseAddr, object->frameLength); MAP_CameraCaptureStop(hwAttrs->baseAddr, true); Power_releaseConstraint(PowerCC3200_DISALLOW_DEEPSLEEP); } } }
/* * ======== SPICC3200DMA_configDMA ======== * This functions configures the transmit and receive DMA channels for a given * SPI_Handle and SPI_Transaction * * @pre Function assumes that the handle and transaction is not NULL */ static void SPICC3200DMA_configDMA(SPI_Handle handle, SPI_Transaction *transaction) { uintptr_t key; SPIDataType dummy; void *buf; uint32_t channelControlOptions; SPICC3200DMA_Object *object = handle->object; SPICC3200DMA_HWAttrs const *hwAttrs = handle->hwAttrs; /* Clear out the FIFO */ while (MAP_SPIDataGetNonBlocking(hwAttrs->baseAddr, &dummy)) {} /* Configure DMA for RX */ MAP_uDMAChannelAssign(hwAttrs->rxChannelIndex); MAP_uDMAChannelAttributeDisable(hwAttrs->rxChannelIndex, UDMA_ATTR_ALTSELECT); if (transaction->rxBuf) { channelControlOptions = dmaRxConfig[object->frameSize]; buf = transaction->rxBuf; } else { channelControlOptions = dmaNullConfig[object->frameSize]; buf = hwAttrs->scratchBufPtr; } MAP_uDMAChannelControlSet(hwAttrs->rxChannelIndex | UDMA_PRI_SELECT, channelControlOptions); MAP_uDMAChannelTransferSet(hwAttrs->rxChannelIndex | UDMA_PRI_SELECT, UDMA_MODE_BASIC, (void *)(hwAttrs->baseAddr + MCSPI_O_RX0), buf, transaction->count); /* Configure DMA for TX */ MAP_uDMAChannelAssign(hwAttrs->txChannelIndex); MAP_uDMAChannelAttributeDisable(hwAttrs->txChannelIndex, UDMA_ATTR_ALTSELECT); if (transaction->txBuf) { channelControlOptions = dmaTxConfig[object->frameSize]; buf = transaction->txBuf; } else { channelControlOptions = dmaNullConfig[object->frameSize]; *hwAttrs->scratchBufPtr = hwAttrs->defaultTxBufValue; buf = hwAttrs->scratchBufPtr; } MAP_uDMAChannelControlSet(hwAttrs->txChannelIndex | UDMA_PRI_SELECT, channelControlOptions); MAP_uDMAChannelTransferSet(hwAttrs->txChannelIndex | UDMA_PRI_SELECT, UDMA_MODE_BASIC, buf, (void *)(hwAttrs->baseAddr + MCSPI_O_TX0), transaction->count); DebugP_log1("SPI:(%p) DMA transfer enabled", hwAttrs->baseAddr); DebugP_log4("SPI: DMA transaction: %p, rxBuf: %p; txBuf: %p; Count: %d", (uintptr_t)transaction, (uintptr_t)transaction->rxBuf, (uintptr_t)transaction->txBuf, (uintptr_t)transaction->count); key = HwiP_disable(); MAP_uDMAChannelEnable(hwAttrs->rxChannelIndex); MAP_uDMAChannelEnable(hwAttrs->txChannelIndex); HwiP_restore(key); MAP_SPIWordCountSet(hwAttrs->baseAddr, transaction->count); }
//***************************************************************************** // // The main function sets up the peripherals for the example, then enters // a wait loop until the DMA transfers are complete. At the end some // information is printed for the user. // //***************************************************************************** int main(void) { unsigned long ulIdx; // // Set the clocking to run directly from the PLL at 50 MHz. // MAP_SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ); // // Initialize the console UART and write a message to the terminal. // MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); MAP_GPIOPinConfigure(GPIO_PA0_U0RX); MAP_GPIOPinConfigure(GPIO_PA1_U0TX); MAP_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1); UARTStdioInit(0); UARTprintf("\033[2JMemory/UART scatter-gather uDMA example\n\n"); // // Configure UART1 to be used for the loopback peripheral // MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART1); // // Configure the UART communication parameters. // MAP_UARTConfigSetExpClk(UART1_BASE, MAP_SysCtlClockGet(), 115200, UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE); // // Set both the TX and RX trigger thresholds to one-half (8 bytes). This // will be used by the uDMA controller to signal when more data should be // transferred. The uDMA TX and RX channels will be configured so that it // can transfer 8 bytes in a burst when the UART is ready to transfer more // data. // MAP_UARTFIFOLevelSet(UART1_BASE, UART_FIFO_TX4_8, UART_FIFO_RX4_8); // // Enable the UART for operation, and enable the uDMA interface for both TX // and RX channels. // MAP_UARTEnable(UART1_BASE); MAP_UARTDMAEnable(UART1_BASE, UART_DMA_RX | UART_DMA_TX); // // This register write will set the UART to operate in loopback mode. Any // data sent on the TX output will be received on the RX input. // HWREG(UART1_BASE + UART_O_CTL) |= UART_CTL_LBE; // // Enable the UART peripheral interrupts. Note that no UART interrupts // were enabled, but the uDMA controller will cause an interrupt on the // UART interrupt signal when a uDMA transfer is complete. // MAP_IntEnable(INT_UART1); // // Enable the uDMA peripheral clocking. // MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA); // // Enable the uDMA controller. // MAP_uDMAEnable(); // // Point at the control table to use for channel control structures. // MAP_uDMAControlBaseSet(sControlTable); // // Configure the UART TX channel for scatter-gather // Peripheral scatter-gather is used because transfers are gated by // requests from the peripheral // UARTprintf("Configuring UART TX uDMA channel for scatter-gather\n"); #ifndef USE_SGSET_API // // Use the original method for configuring the scatter-gather transfer // uDMAChannelControlSet(UDMA_CHANNEL_UART1TX, UDMA_SIZE_32 | UDMA_SRC_INC_32 | UDMA_DST_INC_32 | UDMA_ARB_4); uDMAChannelTransferSet(UDMA_CHANNEL_UART1TX, UDMA_MODE_PER_SCATTER_GATHER, g_TaskTableSrc, &sControlTable[UDMA_CHANNEL_UART1TX], 6 * 4); #else // // Use the simplified API for configuring the scatter-gather transfer // uDMAChannelScatterGatherSet(UDMA_CHANNEL_UART1TX, 6, g_TaskTableSrc, 1); #endif // // Configure the UART RX channel for scatter-gather task list. // This is set to peripheral s-g because it starts by receiving data // from the UART // UARTprintf("Configuring UART RX uDMA channel for scatter-gather\n"); #ifndef USE_SGSET_API // // Use the original method for configuring the scatter-gather transfer // uDMAChannelControlSet(UDMA_CHANNEL_UART1RX, UDMA_SIZE_32 | UDMA_SRC_INC_32 | UDMA_DST_INC_32 | UDMA_ARB_4); uDMAChannelTransferSet(UDMA_CHANNEL_UART1RX, UDMA_MODE_PER_SCATTER_GATHER, g_TaskTableDst, &sControlTable[UDMA_CHANNEL_UART1RX], 7 * 4); #else // // Use the simplified API for configuring the scatter-gather transfer // uDMAChannelScatterGatherSet(UDMA_CHANNEL_UART1RX, 7, g_TaskTableDst, 1); #endif // // Fill the source buffer with a pattern // for(ulIdx = 0; ulIdx < 1024; ulIdx++) { g_ucSrcBuf[ulIdx] = ulIdx + (ulIdx / 256); } // // Enable the uDMA controller error interrupt. This interrupt will occur // if there is a bus error during a transfer. // IntEnable(INT_UDMAERR); // // Enable the UART RX DMA channel. It will wait for data to be available // from the UART. // UARTprintf("Enabling uDMA channel for UART RX\n"); MAP_uDMAChannelEnable(UDMA_CHANNEL_UART1RX); // // Enable the UART TX DMA channel. Since the UART TX will be asserting // a DMA request (since the TX FIFO is empty), this will cause this // DMA channel to start running. // UARTprintf("Enabling uDMA channel for UART TX\n"); MAP_uDMAChannelEnable(UDMA_CHANNEL_UART1TX); // // Wait for the TX task list to be finished // UARTprintf("Waiting for TX task list to finish ... "); while(!g_bTXdone) { } UARTprintf("done\n"); // // Wait for the RX task list to be finished // UARTprintf("Waiting for RX task list to finish ... "); while(!g_bRXdone) { } UARTprintf("done\n"); // // Verify that all the counters are in the expected state // UARTprintf("Verifying counters\n"); if(g_ulDMAIntCount != 2) { UARTprintf("ERROR in interrupt count, found %d, expected 2\n", g_ulDMAIntCount); } if(g_uluDMAErrCount != 0) { UARTprintf("ERROR in error counter, found %d, expected 0\n", g_uluDMAErrCount); } // // Now verify the contents of the final destination buffer. Compare it // to the original source buffer. // UARTprintf("Verifying buffer contents ... "); for(ulIdx = 0; ulIdx < 1024; ulIdx++) { if(g_ucDstBuf[ulIdx] != g_ucSrcBuf[ulIdx]) { UARTprintf("ERROR\n @ index %d: expected 0x%02X, found 0x%02X\n", ulIdx, g_ucSrcBuf[ulIdx], g_ucDstBuf[ulIdx]); UARTprintf("Checking stopped. There may be additional errors\n"); break; } } if(ulIdx == 1024) { UARTprintf("OK\n"); } // // End of program, loop forever // for(;;) { } }