void PWMGen1Handler() { PWMGenIntClear(PWM0_BASE, PWM_GEN_1, PWM_INT_CNT_LOAD); if (!camera_DBSelected) { camera_DBSelected = 1; uDMAChannelTransferSet(UDMA_CHANNEL_ADC3 | UDMA_ALT_SELECT, UDMA_MODE_PINGPONG, (void*) (ADC0_BASE + ADC_O_SSFIFO3), camera_DoubleBuffer[camera_DBSelected], CAMERA_SAMPLES); // switch camera input to near camera ADCSequenceStepConfigure(ADC0_BASE, 3, 0, ADC_CTL_CH1 | ADC_CTL_IE | ADC_CTL_END); current_Camera = FAR; } if (camera_DBSelected) { camera_DBSelected = 0; uDMAChannelTransferSet(UDMA_CHANNEL_ADC3 | UDMA_PRI_SELECT, UDMA_MODE_PINGPONG, (void*) (ADC0_BASE + ADC_O_SSFIFO3), camera_DoubleBuffer[camera_DBSelected], CAMERA_SAMPLES); // switch camera input to far camera ADCSequenceStepConfigure(ADC0_BASE, 3, 0, ADC_CTL_CH0 | ADC_CTL_IE | ADC_CTL_END); current_Camera = NEAR; } }
/** * Initializes the QSSI RTX uDMA to transfer 4 bytes from memory to the QSSI TX FIFO **/ void twe_initQSSIuDMAtx(void) { SSIDMAEnable(twe_QSSI_COMM_BASE, SSI_DMA_TX); uDMAChannelAssign(twe_QSSI_COMM_TX_UDMA_CHANNEL_ASSIGN); // Place the uDMA channel attributes in a known state. These should already be disabled by default. uDMAChannelAttributeDisable(twe_QSSI_COMM_TX_UDMA_CHANNEL, UDMA_ATTR_USEBURST | UDMA_ATTR_ALTSELECT | (UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK)); // Configure the control parameters for the SSI2 RX channel. The channel // will be used to transfer the ADC measurements to memory. uDMAChannelControlSet(twe_QSSI_COMM_TX_UDMA_CHANNEL | UDMA_PRI_SELECT, UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE | UDMA_ARB_4); // Set up the transfer parameters for the SSI2 Rx channel. This will // configure the transfer buffers and the transfer size. uDMAChannelTransferSet(twe_QSSI_COMM_TX_UDMA_CHANNEL | UDMA_PRI_SELECT, UDMA_MODE_BASIC, (void *)(twe_g_QSSItxBuffer), (void *)(TWE_UART_COMM_BASE + UART_O_DR), 4); uDMAChannelAttributeEnable(twe_QSSI_COMM_TX_UDMA_CHANNEL, UDMA_ATTR_HIGH_PRIORITY); //SSIIntEnable(ADC_SSI_BASE, SSI_DMARX); //IntEnable(ADC_SSI_INT); uDMAChannelEnable(twe_QSSI_COMM_TX_UDMA_CHANNEL); }
/** * Initializes the UART uDMA settings **/ void twe_initUARTtxUDMA(void) { #ifdef PART_TM4C1294NCPDT // EK-TM4C1294XL uDMAChannelAssign(UDMA_CH11_UART6TX); #endif UARTIntEnable(TWE_UART_COMM_BASE, UART_INT_TX); // Place the uDMA channel attributes in a known state. These should already be disabled by default. uDMAChannelAttributeDisable(TWE_UART_COMM_UDMA_CHANNEL , UDMA_ATTR_USEBURST | UDMA_ATTR_ALTSELECT | (UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK)); // Configure the control parameters for the UART0 TX channel. The channel // will be used to send the output data uDMAChannelControlSet(TWE_UART_COMM_UDMA_CHANNEL | UDMA_PRI_SELECT, UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE | UDMA_ARB_8); // Set up the transfer parameters for the UART0 Tx channel. This will // configure the transfer buffer and the transfer size. uDMAChannelTransferSet(TWE_UART_COMM_UDMA_CHANNEL | UDMA_PRI_SELECT, UDMA_MODE_AUTO, (void *)twe_g_UARTtxBufferPRI, (void *)(TWE_UART_COMM_BASE + UART_O_DR), TWE_UART_TX_BUFFER_LENGTH); uDMAChannelAttributeEnable(TWE_UART_COMM_UDMA_CHANNEL , UDMA_ATTR_REQMASK); // 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. //uDMAChannelEnable(UDMA_CHANNEL_UART0TX | UART_INT_FE); //IntEnable(INT_UDMA); // Enables the Software channel interrupt that triggers // upon completion of a software transfer. }
void setAgainSampling(void) { // Clear the data ready bit and set up the next DMA transfer adcNode[0].g_ucDataReady = 0; if (NUM_SAMPLES > UDMA_XFER_MAX) { uDMAChannelTransferSet(UDMA_CHANNEL_ADC3 | UDMA_PRI_SELECT, UDMA_MODE_BASIC, (void *) (ADC0_BASE + ADC_O_SSFIFO3 + (0x20 * UDMA_ARB_1)), g_ulADCValues, UDMA_XFER_MAX); } else { uDMAChannelTransferSet(UDMA_CHANNEL_ADC3 | UDMA_PRI_SELECT, UDMA_MODE_BASIC, (void *) (ADC0_BASE + ADC_O_SSFIFO3 + (0x20 * UDMA_ARB_1)), g_ulADCValues, NUM_SAMPLES); } // Enable the timer and start the sampling timer uDMAChannelEnable(UDMA_CHANNEL_ADC3); TimerLoadSet(TIMER0_BASE, TIMER_A, LoadTimer); TimerEnable(TIMER0_BASE, TIMER_A); }
void InitADC3Transfer(void) { // Set data as not ready to be processed adcNode[0].g_ucDataReady = 0; // Init buffers by setting them all to 0 // Should go from 0 to 2048 for (uIdx = 0; uIdx < NUM_SAMPLES ; uIdx++) { g_ulADCValues[uIdx] = 0; } SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA); SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0); SysCtlPeripheralReset(SYSCTL_PERIPH_ADC0); IntEnable(INT_UDMAERR); uDMAEnable(); uDMAControlBaseSet(ucControlTable); // // Configure the ADC to use PLL at 480 MHz divided by 24 to get an ADC // clock of 20 MHz. // //ADCClockConfigSet(ADC0_BASE, ADC_CLOCK_SRC_PLL | ADC_CLOCK_RATE_FULL, 24); ADCSequenceConfigure(ADC0_BASE, SEQUENCER, ADC_TRIGGER_TIMER, 0); #ifdef test_w_internal_temp ADCSequenceStepConfigure(ADC0_BASE, SEQUENCER, 0, ADC_CTL_TS | ADC_CTL_IE | ADC_CTL_END); // internal temperator #endif #ifdef test_w_pe3 ADCSequenceStepConfigure(ADC0_BASE, SEQUENCER, 0, ADC_CTL_CH0 | ADC_CTL_IE | ADC_CTL_END); //PE3 #endif ADCSequenceEnable(ADC0_BASE, SEQUENCER); ADCIntEnable(ADC0_BASE, SEQUENCER); uDMAChannelAttributeDisable(UDMA_CHANNEL_ADC3, UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST | UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK); uDMAChannelControlSet(UDMA_CHANNEL_ADC3 | UDMA_PRI_SELECT, UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1); uDMAChannelTransferSet(UDMA_CHANNEL_ADC3 | UDMA_PRI_SELECT, UDMA_MODE_BASIC, (void *) (ADC0_BASE + ADC_O_SSFIFO3 + (0x20 * UDMA_ARB_1)), g_ulADCValues, UDMA_XFER_MAX); uDMAChannelEnable(UDMA_CHANNEL_ADC3); }
/************************************************************************************************** * @fn npSpiUdmaPrepareRx * * @brief This function is called to set up uDMA for SPI RX. The uDMA and SPI must be * initialized once already. * * input parameters * * None. * * output parameters * * None. * * @return None. ************************************************************************************************** */ static void npSpiUdmaPrepareRx(void) { uint32 ulDummy; /* Flush the RX FIFO */ while(SSIDataGetNonBlocking(BSP_SPI_SSI_BASE, &ulDummy)); /* Prepare for the next one byte RX DMA */ uDMAChannelTransferSet(UDMA_CH10_SSI0RX | UDMA_PRI_SELECT, UDMA_MODE_BASIC, SPI_DATA, npSpiBuf, 1); uDMAChannelEnable(UDMA_CH10_SSI0RX); /* Disable the TX channel in RX */ SSIDMADisable(BSP_SPI_SSI_BASE, SSI_DMA_TX); SSIDMAEnable(BSP_SPI_SSI_BASE, SSI_DMA_RX); }
void UART1IntHandler(void) { const uint32_t dma_rx_primary = UDMA_CHANNEL_UART1RX | UDMA_PRI_SELECT; uint32_t int_status; uint32_t mode; int_status = UARTIntStatus(UART1_BASE, 1); UARTIntClear(UART1_BASE, int_status); mode = uDMAChannelModeGet(dma_rx_primary); // Receive buffer is done. if(mode == UDMA_MODE_STOP) { // Configure the next receive transfer uart_rx_write_index += UART_RX_BLOCK_SIZE; if (uart_rx_write_index == UART_RX_BLOCKS_COUNT * UART_RX_BLOCK_SIZE) { uart_rx_write_index = 0; } uDMAChannelTransferSet(dma_rx_primary, UDMA_MODE_BASIC, (void *)(UART1_BASE + UART_O_DR), &uart_rx_buf[uart_rx_write_index], UART_RX_BLOCK_SIZE); uDMAChannelEnable(UDMA_CHANNEL_UART1RX); } // 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. //ui32Mode = uDMAChannelModeGet(UDMA_CHANNEL_UART1RX | UDMA_ALT_SELECT); // If the UART1 DMA TX channel is disabled, that means the TX DMA transfer // is done. // if(!uDMAChannelIsEnabled(UDMA_CHANNEL_UART1TX)) // { // // Start another DMA transfer to UART1 TX. // uDMAChannelTransferSet(UDMA_CHANNEL_UART1TX | UDMA_PRI_SELECT, // UDMA_MODE_BASIC, g_ui8TxBuf, // (void *)(UART1_BASE + UART_O_DR), // sizeof(g_ui8TxBuf)); // // // The uDMA TX channel must be re-enabled. // uDMAChannelEnable(UDMA_CHANNEL_UART1TX); // } }
/************************************************************************************************** * @fn spi_tx * * @brief This function is called to send an SPI packet * * input parameters * * None. * * output parameters * * None. * * @return None. ************************************************************************************************** */ static void spi_tx(uint8* buf) { uint8 tx_len = buf[0] + 3; osal_memcpy(npSpiBuf, buf, tx_len); /* Disable the RX channel in TX */ SSIDMADisable(BSP_SPI_SSI_BASE, SSI_DMA_RX); SSIDMAEnable(BSP_SPI_SSI_BASE, SSI_DMA_TX); /* The transfer buffers and transfer size are now configured using BASIC mode */ uDMAChannelTransferSet(UDMA_CH11_SSI0TX | UDMA_PRI_SELECT, UDMA_MODE_BASIC, npSpiBuf, SPI_DATA, tx_len); /* Pull the SRDY pin high */ GPIOPinWrite(HAL_SPI_SRDY_BASE, HAL_SPI_SRDY_PIN, HAL_SPI_SRDY_PIN); /* Enable the TX channel. */ uDMAChannelEnable(UDMA_CH11_SSI0TX); }
/************************************************************************************************** * @fn npSpiUdmaCompleteIsr * * @brief This ISR is vectored when uDMA for TX or RX is completed. * * input parameters * * None. * * output parameters * * None. * * @return None. ************************************************************************************************** */ static void npSpiUdmaCompleteIsr(void) { halIntState_t intState; uint32 intStatus; uint8 rx_len; intStatus = uDMAIntStatus(); HAL_ENTER_CRITICAL_SECTION_DEBUG(intState); if((npSpiState == NP_SPI_WAIT_RX) && (intStatus & UDMA_CH10_SSI0RX_MASK)) { uDMAIntClear(UDMA_CH10_SSI0RX_MASK); /* The RX length is known at this point */ rx_len = npSpiBuf[0] + 2; /* Start another RX DMA for the remaining of the bytes */ uDMAChannelTransferSet(UDMA_CH10_SSI0RX | UDMA_PRI_SELECT, UDMA_MODE_BASIC, SPI_DATA, &npSpiBuf[1], rx_len); uDMAChannelEnable(UDMA_CH10_SSI0RX); /* Poll for results. TODO: Add error/timeout */ while (uDMAChannelSizeGet(UDMA_CH10_SSI0RX | UDMA_PRI_SELECT) > 0); /* Process RX packet */ npSpiRxIsr(); } else if((npSpiState == NP_SPI_WAIT_TX) && (intStatus & UDMA_CH11_SSI0TX_MASK)) { uDMAIntClear(UDMA_CH11_SSI0TX_MASK); } else { /* TODO: Add debug. Should never get here! */ uDMAIntClear(UDMA_CH10_SSI0RX_MASK | UDMA_CH11_SSI0TX_MASK); } HAL_EXIT_CRITICAL_SECTION_DEBUG(intState); }
/* * function: ADC3IntHandler * interrupt handler ADC0, sequence 3 * return: none * */ void ADC3IntHandler(void) { unsigned long ulStatus; static unsigned long uluDMACount = 0; static unsigned long ulDataXferd = 0; unsigned long ulNextuDMAXferSize = 0; ADCIntClear(ADC0_BASE, SEQUENCER); // If the channel's not done capturing, we have an error if (uDMAChannelIsEnabled(UDMA_CHANNEL_ADC3)) { // Increment error counter adcNode[0].g_ulBadPeriphIsr2++; ADCIntDisable(ADC0_BASE, SEQUENCER); IntPendClear(INT_ADC0SS3); return; } ulStatus = uDMAChannelSizeGet(UDMA_CHANNEL_ADC3); // If non-zero items are left in the transfer buffer // Something went wrong if (ulStatus) { adcNode[0].g_ulBadPeriphIsr1++; return; } // Disable the sampling timer TimerDisable(TIMER0_BASE, TIMER_A); // how many times the DMA has been full without processing the data uluDMACount++; // The amount of data transferred increments in sets of 1024 ulDataXferd += UDMA_XFER_MAX; if (NUM_SAMPLES > ulDataXferd) { if ((NUM_SAMPLES - ulDataXferd) > UDMA_XFER_MAX) { ulNextuDMAXferSize = UDMA_XFER_MAX; } else { ulNextuDMAXferSize = NUM_SAMPLES - ulDataXferd; } #ifdef USE_TEMPORARY_BUFFER if (currentAdcBuffer == g_ulADCValues_B) { uDMAChannelTransferSet(UDMA_CHANNEL_ADC3 | UDMA_PRI_SELECT, UDMA_MODE_BASIC, (void *) (ADC0_BASE + ADC_O_SSFIFO3 + (0x20 * UDMA_ARB_1)), g_ulADCValues + (UDMA_XFER_MAX * uluDMACount), ulNextuDMAXferSize); } else { uDMAChannelTransferSet(UDMA_CHANNEL_ADC3 | UDMA_PRI_SELECT, UDMA_MODE_BASIC, (void *) (ADC0_BASE + ADC_O_SSFIFO3 + (0x20 * UDMA_ARB_1)), g_ulADCValues_B + (UDMA_XFER_MAX * uluDMACount), ulNextuDMAXferSize); } #endif #ifdef NOT_TEMPORARY_BUFFER uDMAChannelTransferSet(UDMA_CHANNEL_ADC3 | UDMA_PRI_SELECT, UDMA_MODE_BASIC, (void *) (ADC0_BASE + ADC_O_SSFIFO3 + (0x20 * UDMA_ARB_1)), g_ulADCValues + (UDMA_XFER_MAX * uluDMACount), ulNextuDMAXferSize); #endif uDMAChannelEnable(UDMA_CHANNEL_ADC3); TimerLoadSet(TIMER0_BASE, TIMER_A, LoadTimer); TimerEnable(TIMER0_BASE, TIMER_A); } else { uluDMACount = 0; ulDataXferd = 0; ADCIntDisable(ADC0_BASE, SEQUENCER); IntPendClear(INT_ADC0SS3); // Signal that we have new data to be processed adcNode[0].g_ucDataReady = 1; #ifdef USING_BUFFER2 if (adcNode[0].g_ucDataReady) { memcpy(output2, g_ulADCValues, NUM_SAMPLES); countFullData++; } #endif } }
void InitUartInterface(uint32_t sys_clock) { uart_rx_read_index = 0; uart_rx_write_index = 0; const uint32_t dma_rx_primary = UDMA_CHANNEL_UART1RX | UDMA_PRI_SELECT; SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB); SysCtlPeripheralEnable(SYSCTL_PERIPH_UART1); SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_UART1); //921600 //460800 uint32_t uart_config = UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE; UARTConfigSetExpClk(UART1_BASE, sys_clock, 921600, uart_config); GPIOPinConfigure(GPIO_PB0_U1RX); GPIOPinConfigure(GPIO_PB1_U1TX); GPIOPinTypeUART(GPIO_PORTB_BASE, GPIO_PIN_0 | GPIO_PIN_1); UARTFIFOLevelSet(UART1_BASE, UART_FIFO_TX4_8, UART_FIFO_RX4_8); UARTEnable(UART1_BASE); //UARTDMAEnable(UART1_BASE, UART_DMA_RX | UART_DMA_TX); UARTDMAEnable(UART1_BASE, UART_DMA_RX); // Put the attributes in a known state for the uDMA UART1RX channel. These // should already be disabled by default. uint32_t dma_config = UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST | UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK; uDMAChannelAttributeDisable(UDMA_CHANNEL_UART1RX, dma_config); uint32_t dma_control = UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 | UDMA_ARB_4; uDMAChannelControlSet(dma_rx_primary, dma_control); uDMAChannelTransferSet(dma_rx_primary, UDMA_MODE_BASIC, (void *)(UART1_BASE + UART_O_DR), &uart_rx_buf[uart_rx_write_index], UART_RX_BLOCK_SIZE); // Put the attributes in a known state for the uDMA UART1TX channel. These // should already be disabled by default. // uDMAChannelAttributeDisable(UDMA_CHANNEL_UART1TX, // 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. //uDMAChannelAttributeEnable(UDMA_CHANNEL_UART1TX, 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. // uDMAChannelControlSet(UDMA_CHANNEL_UART1TX | 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. // uDMAChannelTransferSet(UDMA_CHANNEL_UART1TX | UDMA_PRI_SELECT, // UDMA_MODE_BASIC, g_ui8TxBuf, // (void *)(UART1_BASE + UART_O_DR), // sizeof(g_ui8TxBuf)); // 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. uDMAChannelEnable(UDMA_CHANNEL_UART1RX); //uDMAChannelEnable(UDMA_CHANNEL_UART1TX); // Enable the UART DMA TX/RX interrupts. //UARTIntEnable(UART1_BASE, UART_INT_DMATX | UART_INT_DMATX); UARTIntEnable(UART1_BASE, UART_INT_DMARX); IntEnable(INT_UART1); MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0); MAP_TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC); MAP_TimerLoadSet(TIMER0_BASE, TIMER_A, sys_clock / 2000); MAP_IntEnable(INT_TIMER0A); MAP_TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT); MAP_TimerEnable(TIMER0_BASE, TIMER_A); MAP_IntPrioritySet(INT_TIMER0A, 0xC0); }
void camera_init() { Serial_puts(UART_DEBUG_MODULE, "inside \"camera_init\"\r\n", 100); // Calculate the PWM clock frequency camera_PWMClockFreq = SysCtlClockGet() / CAMERA_CLOCK_DIV; DEBUG_LINE("camera_init"); // Enable the PWM peripheral SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM0); // Enable the GPIO port SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB); // Configure PD0 as the PWM output for the drive motor GPIOPinTypePWM(GPIO_PORTB_BASE, GPIO_PIN_7); GPIOPinConfigure(GPIO_PB7_M0PWM1); GPIOPinTypePWM(GPIO_PORTB_BASE, GPIO_PIN_4); GPIOPinConfigure(GPIO_PB4_M0PWM2); // Set the camera clock pulse period PWMGenConfigure(PWM0_BASE, PWM_GEN_0, PWM_GEN_MODE_DOWN); PWMGenPeriodSet(PWM0_BASE, PWM_GEN_0, CAMERA_SAMPLE_PERIOD - 1); PWMPulseWidthSet(PWM0_BASE, PWM_OUT_1, (CAMERA_SAMPLE_PERIOD / 2) - 1); // Set the camera enable pulse period PWMGenConfigure(PWM0_BASE, PWM_GEN_1, PWM_GEN_MODE_DOWN); PWMGenPeriodSet(PWM0_BASE, PWM_GEN_1, (CAMERA_SAMPLE_PERIOD * CAMERA_SAMPLES) - 1); PWMPulseWidthSet(PWM0_BASE, PWM_OUT_2, ((CAMERA_SAMPLE_PERIOD / 2) * 2) - 1); DEBUG_LINE("camera_init"); // Enable the PWM output PWMOutputState(PWM0_BASE, PWM_OUT_1_BIT | PWM_OUT_2_BIT, true); PWMGenEnable(PWM0_BASE, PWM_GEN_0); PWMGenEnable(PWM0_BASE, PWM_GEN_1); PWMSyncTimeBase(PWM0_BASE, PWM_GEN_0_BIT | PWM_GEN_1_BIT); // Enable PWM trigger on zero count on Generator 0 PWMGenIntTrigEnable(PWM0_BASE, PWM_GEN_0, PWM_TR_CNT_ZERO); // PWM_TR_CNT_ZERO/PWM_TR_CNT_LOAD // Trigger an interrupt on GEN1 load (to setup the uDMA transfer on a consistent time boundary) PWMGenIntTrigEnable(PWM0_BASE, PWM_GEN_1, PWM_INT_CNT_LOAD); DEBUG_LINE("camera_init"); /******************************************** * ADC CONFIGURATION * ******************************************** */ // Enable ADC0 module SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0); DEBUG_LINE("camera_init"); ADCClockConfigSet(ADC0_BASE, ADC_CLOCK_SRC_PIOSC | ADC_CLOCK_RATE_FULL, 1); DEBUG_LINE("camera_init"); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE); // Camera Far GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_3); // Camera Near GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_2); DEBUG_LINE("camera_init"); // Configure and enable the ADC sequence; single sample ADCSequenceConfigure(ADC0_BASE, 3, ADC_TRIGGER_PWM0, 0); ADCSequenceStepConfigure(ADC0_BASE, 3, 0, ADC_CTL_CH0 | ADC_CTL_IE | ADC_CTL_END); ADCSequenceEnable(ADC0_BASE, 3); DEBUG_LINE("camera_init"); ADCSequenceDMAEnable(ADC0_BASE, 3); DEBUG_LINE("camera_init"); // Start writing into the first buffer camera_DBSelected = 0; current_Camera = FAR; // Expose the other buffer camera_buffer = camera_DoubleBuffer[1]; /******************************************** * uDMA CONFIGURATION * ******************************************** */ // Enable the uDMA for normal and sleep operation SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA); SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_UDMA); uDMAEnable(); DEBUG_LINE("camera_init"); // Set the position of the uDMA control table uDMAControlBaseSet(uDMAControlTable); // Put the uDMA table entry for ADC3 into a known state uDMAChannelAttributeDisable(UDMA_CHANNEL_ADC3, UDMA_ATTR_USEBURST | UDMA_ATTR_ALTSELECT | UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK); // Configure the primary and alternate uDMA channel structures uDMAChannelControlSet(UDMA_CHANNEL_ADC3 | UDMA_PRI_SELECT, UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1); uDMAChannelControlSet(UDMA_CHANNEL_ADC3 | UDMA_ALT_SELECT, UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1); // Configure the primary and alternate transfers for ping-pong operation uDMAChannelTransferSet(UDMA_CHANNEL_ADC3 | UDMA_PRI_SELECT, UDMA_MODE_PINGPONG, (void*) (ADC0_BASE + ADC_O_SSFIFO3), camera_DoubleBuffer[0], CAMERA_SAMPLES); uDMAChannelTransferSet(UDMA_CHANNEL_ADC3 | UDMA_ALT_SELECT, UDMA_MODE_PINGPONG, (void*) (ADC0_BASE + ADC_O_SSFIFO3), camera_DoubleBuffer[1], CAMERA_SAMPLES); DEBUG_LINE("camera_init"); // Enable the ADC3 uDMA channel uDMAChannelEnable(UDMA_CHANNEL_ADC3); // Enable interrupts // IntEnable(INT_ADC0SS3); // ADCIntEnableEx(ADC0_BASE, ADC_INT_DMA_SS3); IntEnable(INT_PWM0_1); PWMIntEnable(PWM0_BASE, PWM_INT_GEN_1); DEBUG_LINE("camera_init"); }
/* * function: ADC3IntHandler * interrupt handler ADC0, sequence 3 * return: none * */ void ADC3IntHandler(void) { unsigned long ulStatus; static unsigned long uluDMACount = 0; static unsigned long ulDataXferd = 0; unsigned long ulNextuDMAXferSize = 0; unsigned short *pusDMABuffer; unsigned short *pusCopyBuffer; int i; ADCIntClear(ADC0_BASE, SEQUENCER); // If the channel's not done capturing, we have an error if (uDMAChannelIsEnabled(UDMA_CHANNEL_ADC3)) { // Increment error counter adcNode[0].g_ulBadPeriphIsr2++; ADCIntDisable(ADC0_BASE, SEQUENCER); IntPendClear(INT_ADC0SS3); return; } ulStatus = uDMAChannelSizeGet(UDMA_CHANNEL_ADC3); // If non-zero items are left in the transfer buffer // Something went wrong if (ulStatus) { adcNode[0].g_ulBadPeriphIsr1++; return; } if (g_ucDMAMethod == DMA_METHOD_SLOW) { // // We are using the slow DMA method, meaning there are not enough // samples in a second to generate a new set of FFT values and still // have data frequent enough to refresh at 15 frames per second // // // when pingpong is 0, uDMA just finished transferring into ping, so next // we transfer into pong. // if (g_ucDMApingpong == 0) { pusDMABuffer = g_usDMApong; pusCopyBuffer = g_usDMAping; g_ucDMApingpong = 1; } else { pusDMABuffer = g_usDMAping; pusCopyBuffer = g_usDMApong; g_ucDMApingpong = 0; } // // Set up the next uDMA transfer // uDMAChannelTransferSet(UDMA_CHANNEL_ADC3 | UDMA_PRI_SELECT, UDMA_MODE_BASIC, (void *) (ADC0_BASE + ADC_O_SSFIFO3),// + (0x20 * UDMA_ARB_1)), pusDMABuffer, DMA_SIZE); uDMAChannelEnable(UDMA_CHANNEL_ADC3); IntPendClear(INT_ADC0SS3); // // Shift everything back DMA_SIZE samples // for (i = 0; i < (NUM_SAMPLES - DMA_SIZE); i++) { g_ulADCValues[i] = g_ulADCValues[i + DMA_SIZE]; } // // Copy the new samples from the copy buffer into the sample array // for (i = 0; i < DMA_SIZE; i++) { g_ulADCValues[i + NUM_SAMPLES - DMA_SIZE] = pusCopyBuffer[i]; } // // Signal that we have new data to be processed // adcNode[0].g_ucDataReady = 1; } else { // Disable the sampling timer TimerDisable(TIMER0_BASE, TIMER_A); // how many times the DMA has been full without processing the data uluDMACount++; // The amount of data transferred increments in sets of 1024 ulDataXferd += UDMA_XFER_MAX; if (NUM_SAMPLES > ulDataXferd) { if ((NUM_SAMPLES - ulDataXferd) > UDMA_XFER_MAX) { ulNextuDMAXferSize = UDMA_XFER_MAX; } else { ulNextuDMAXferSize = NUM_SAMPLES - ulDataXferd; } #ifdef USE_TEMPORARY_BUFFER if (currentAdcBuffer == g_ulADCValues_B) { uDMAChannelTransferSet(UDMA_CHANNEL_ADC3 | UDMA_PRI_SELECT, UDMA_MODE_BASIC, (void *) (ADC0_BASE + ADC_O_SSFIFO3 + (0x20 * UDMA_ARB_1)), g_ulADCValues + (UDMA_XFER_MAX * uluDMACount), ulNextuDMAXferSize); } else { uDMAChannelTransferSet(UDMA_CHANNEL_ADC3 | UDMA_PRI_SELECT, UDMA_MODE_BASIC, (void *) (ADC0_BASE + ADC_O_SSFIFO3 + (0x20 * UDMA_ARB_1)), g_ulADCValues_B + (UDMA_XFER_MAX * uluDMACount), ulNextuDMAXferSize); } #endif uDMAChannelTransferSet(UDMA_CHANNEL_ADC3 | UDMA_PRI_SELECT, UDMA_MODE_BASIC, (void *) (ADC0_BASE + ADC_O_SSFIFO3 + (0x20 * UDMA_ARB_1)), g_ulADCValues + (UDMA_XFER_MAX * uluDMACount), ulNextuDMAXferSize); uDMAChannelEnable(UDMA_CHANNEL_ADC3); TimerLoadSet(TIMER0_BASE, TIMER_A, LoadTimer); TimerEnable(TIMER0_BASE, TIMER_A); } else { uluDMACount = 0; ulDataXferd = 0; ADCIntDisable(ADC0_BASE, SEQUENCER); IntPendClear(INT_ADC0SS3); // Signal that we have new data to be processed adcNode[0].g_ucDataReady = 1; #ifdef USING_BUFFER2 if (adcNode[0].g_ucDataReady) { memcpy(output2, g_ulADCValues, NUM_SAMPLES); countFullData++; } #endif } } }
//***************************************************************************** // // Main function, setup DMA and perform flash write. Verify the transaction. // //***************************************************************************** int main(void) { uint16_t i; int32_t i32Res; // // Set the clocking to run directly from the external crystal/oscillator. // (no ext 32k osc, no internal osc) // SysCtrlClockSet(false, false, SYS_CTRL_SYSDIV_32MHZ); // // Set IO clock to the same as system clock // SysCtrlIOClockSet(SYS_CTRL_SYSDIV_32MHZ); // // Set up the serial console to use for displaying messages. This is // just for this example program and is not needed for Systick operation. // InitConsole(); // // Display the setup on the console. // UARTprintf("Example - Write to Flash using DMA.\n"); // // Erase Flash page that will hold our transferred data // i32Res = FlashMainPageErase(PAGE_TO_ERASE_START_ADDR); ASSERT(i32Res==0); // // Fill Source buffer (to be copied to flash) with some data // for(i=0; i<256; i++) { ucSourceBuffer[i] = '0' + (i % 10); } // // Enable the uDMA controller. // uDMAEnable(); // // Disable the uDMA channel to be used, before modifications are done. // uDMAChannelDisable(UDMA_CH2_FLASH); // // Set the base for the channel control table. // uDMAControlBaseSet(&ucDMAControlTable[0]); // // Assign the DMA channel // uDMAChannelAssign(UDMA_CH2_FLASH); // // Set attributes for the channel. // uDMAChannelAttributeDisable(UDMA_CH2_FLASH, UDMA_ATTR_HIGH_PRIORITY); // // Now set up the characteristics of the transfer. // 32-bit data size, with source increments in words (32 bits), // no destination increment. // A bus arbitration size of 1 must be used. // uDMAChannelControlSet(UDMA_CH2_FLASH, UDMA_SIZE_32 | UDMA_SRC_INC_32 | UDMA_DST_INC_NONE | UDMA_ARB_1); // // Set transfer parameters. // Source address is the location of the data to write // and destination address is the FLASH_CTRL_FWDATA register. // uDMAChannelTransferSet(UDMA_CH2_FLASH, UDMA_MODE_BASIC, ucSourceBuffer, (void *) FLASH_CTRL_FWDATA, sizeof(ucSourceBuffer)); // // Asure that the flash controller is not busy. // while(HWREG(FLASH_CTRL_FCTL) & FLASH_CTRL_FCTL_BUSY) { } // // Initialize Flash control register without changing the cache mode. // HWREG(FLASH_CTRL_FCTL) &= FLASH_CTRL_FCTL_CM_M; // // Setup Flash Address register to address of first data word (32-bit) // HWREG(FLASH_CTRL_FADDR) = PAGE_TO_ERASE_START_ADDR; // // Finally, the DMA channel must be enabled. // uDMAChannelEnable(UDMA_CH2_FLASH); // // Set FCTL.WRITE, to trigger flash write // HWREG(FLASH_CTRL_FCTL) |= FLASH_CTRL_FCTL_WRITE; // // Wait until all words has been programmed. // while( HWREG(FLASH_CTRL_FCTL) & FLASH_CTRL_FCTL_FULL ) { } // // Check if flash write was successfull // if (HWREG(FLASH_CTRL_FCTL) & FLASH_CTRL_FCTL_ABORT) { UARTprintf("Write not successful!\n"); } else { UARTprintf("Write success!\n"); } // // Set control register back to reset value without changing the cache mode. // HWREG(FLASH_CTRL_FCTL) &= FLASH_CTRL_FCTL_CM_M; // // Compare source buffer and destination flash page // if(memcmp(ucSourceBuffer, (void*) PAGE_TO_ERASE_START_ADDR, 256)==0) { UARTprintf("Buffer compares to flash page!\n"); } else { UARTprintf("Buffer does not compare to flash page!\n"); } // // We are done, loop forever // while(1) { } }
//***************************************************************************** // // 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(;;) { } }
//***************************************************************************** // // Configure the SysTick and SysTick interrupt with a period of 1 second. // //***************************************************************************** int main(void) { uint16_t i; // // Set the clocking to run directly from the external crystal/oscillator. // (no ext 32k osc, no internal osc) // SysCtrlClockSet(false, false, SYS_CTRL_SYSDIV_32MHZ); // // Set IO clock to the same as system clock // SysCtrlIOClockSet(SYS_CTRL_SYSDIV_32MHZ); // // Set up the serial console to use for displaying messages. This is // just for this example program and is not needed for Systick operation. // InitConsole(); // // Display the setup on the console. // UARTprintf("DMA SW example mem to mem!\n"); // // Fill Source buffer with some data // for(i=0; i<256; i++) { ucSourceBuffer[i] = '0' + (i % 10); } // // Enable the uDMA controller. // uDMAEnable(); // // Set the base for the channel control table. // uDMAControlBaseSet(&ucDMAControlTable[0]); // // No attributes must be set for a software-based transfer. // The attributes are cleared by default, but are explicitly cleared // here, in case they were set elsewhere. // uDMAChannelAttributeDisable(UDMA_CH30_SW, UDMA_ATTR_ALL); // // Now set up the characteristics of the transfer for // 8-bit data size, with source and destination increments // in bytes, and a byte-wise buffer copy. A bus arbitration // size of 8 is used. // uDMAChannelControlSet(UDMA_CH30_SW | UDMA_PRI_SELECT, UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_8 | UDMA_ARB_8); // // The transfer buffers and transfer size are now configured. // The transfer uses AUTO mode, which means that the // transfer automatically runs to completion after the first // request. // uDMAChannelTransferSet(UDMA_CH30_SW | UDMA_PRI_SELECT, UDMA_MODE_AUTO, ucSourceBuffer, ucDestBuffer, sizeof(ucDestBuffer)); // // Enable Interrupt for DMA // IntEnable(INT_UDMA); // // Finally, the channel must be enabled. Because this is a // software-initiated transfer, a request must also be made. // The request starts the transfer. // uDMAChannelEnable(UDMA_CH30_SW); uDMAChannelRequest(UDMA_CH30_SW); // // Put cpu to sleep and wait for interrupt (when DMA transfer is done) // SysCtrlSleep(); // // Loop forever while the SysTick runs. // while(1) { } }