/** * 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); }
/** * Send the data p over interface netif * * @param netif the netif to send the data * @param p the pbuf containing the data * @return An error code */ static err_t eth_output(struct netif *netif, struct pbuf *p) { /* Wait for previous DMA (one could also implement queueing here...) */ while (dma_running) ; /* * Free the memory */ if (active_dma != NULL) { pbuf_free(active_dma); #ifdef DEBUG_MALLOC UARTprintf("%x %d free, %s:%d;\r\n", active_dma, debug_ctr++, __FILE__, __LINE__); #endif } active_dma = p; dma_running = 1; /* Reserve the pbuf so that it is not free()d */ pbuf_ref(p); char *buf = p->payload; int len = p->len; uint16_t *len_buf = (uint16_t*)buf; *len_buf = len - PBUF_LINK_HLEN; len += 2; /** * If this enters the infinite loop, the buffer is not correctly aligned! */ if (((unsigned long) buf & 3) != 0) for (;;) ; /* Ensure that DMA sends all the data (and up to 3 bytes garbage extra) */ while ((len & 3) != 0) len++; /* * Configure the TX DMA channel to transfer the packet buffer. */ uDMAChannelTransferSet(UDMA_CHANNEL_ETH0TX, UDMA_MODE_AUTO, buf, (void *) (ETH_BASE + MAC_O_DATA), len >> 2); /* * Enable the Ethernet Transmit DMA channel. */ uDMAChannelEnable(UDMA_CHANNEL_ETH0TX); /* * Issue a software request to start the channel running. */ uDMAChannelRequest(UDMA_CHANNEL_ETH0TX); return ERR_OK; }
void setAgainSampling(void) { // Clear the data ready bit and set up the next DMA transfer adcNode[0].g_ucDataReady = 0; 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); // 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); }
//***************************************************************************** // // 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) { } }
/* * 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) { } }
//***************************************************************************** // // 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) { } }