/************************************************************************************************** * @fn npSpiUdmaInit * * @brief This function is called to set up uDMA for SPI interface. * * input parameters * * None. * * output parameters * * None. * * @return None. ************************************************************************************************** */ static void npSpiUdmaInit(void) { /* Enable the uDMA controller. */ uDMAEnable(); /* Set the base for the channel control table. */ uDMAControlBaseSet(&ucDMAControlTable[0]); /* No attributes need to be set for a perpheral-based transfer. * The attributes are cleared by default, but are explicitly cleared * here, in case they were set elsewhere. */ uDMAChannelAttributeDisable(UDMA_CH10_SSI0RX, UDMA_ATTR_ALL); uDMAChannelAttributeDisable(UDMA_CH11_SSI0TX, UDMA_ATTR_ALL); /* Now set up the characteristics of the transfer for * 8-bit data size, with source and destination increments * accordingly, and a byte-wise buffer copy. A bus arbitration * size of 1 is used. */ uDMAChannelControlSet(UDMA_CH10_SSI0RX | UDMA_PRI_SELECT, UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 | UDMA_ARB_4); uDMAChannelControlSet(UDMA_CH11_SSI0TX | UDMA_PRI_SELECT, UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE | UDMA_ARB_4); /* Prepare SPI RX using uDMA */ npSpiUdmaPrepareRx(); }
/** * 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. }
static void initDMA() { // Init DMA ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA); ROM_uDMAEnable(); ROM_uDMAControlBaseSet(g_sDMAControlTable); uDMAChannelAttributeDisable(UDMA_CHANNEL_ETH0TX, UDMA_ATTR_ALL); uDMAChannelControlSet(UDMA_CHANNEL_ETH0TX, UDMA_SIZE_32 | UDMA_SRC_INC_32 | UDMA_DST_INC_NONE | UDMA_ARB_8); }
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); }
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); }
//***************************************************************************** // //! Configures the I2S peripheral for the given audio data format. //! //! \param ulSampleRate is the sample rate of the audio to be played in //! samples per second. //! \param usBitsPerSample is the number of bits in each audio sample. //! \param usChannels is the number of audio channels, 1 for mono, 2 for stereo. //! //! This function configures the I2S peripheral in preparation for playing //! and recording audio data of a particular format. //! //! \note This function has a work around for the I2SMCLKCFG register errata. //! This errata limits the low end of the MCLK at some bit sizes. The absolute //! limit is a divide of the System PLL by 256 or an MCLK minimum of //! 400MHz/256 or 1.5625MHz. This is overcome by increasing the number of //! bits shifted out per sample and thus increasing the MCLK needed for a given //! sample rate. This uses the fact that the I2S codec used on the development //! board s that will toss away extra bits that go to or from the codec. //! //! \return None. // //***************************************************************************** void SoundSetFormat(unsigned long ulSampleRate, unsigned short usBitsPerSample, unsigned short usChannels) { unsigned long ulFormat; unsigned long ulDMASetting; unsigned long ulI2SErrata; // // Save these values for use when configuring I2S. // g_usChannels = usChannels; g_usBitsPerSample = usBitsPerSample; I2SMasterClockSelect(I2S0_BASE, 0); // // Always use have the controller be an I2S Master. // ulFormat = I2S_CONFIG_FORMAT_I2S | I2S_CONFIG_CLK_MASTER; // // Check if the missing divisor bits need to be taken into account. // if(CLASS_IS_TEMPEST && REVISION_IS_B1) { ulI2SErrata = 1; } else { ulI2SErrata = 0; } // // Mono or Stereo formats. // if(g_usChannels == 1) { // // 8 bit formats. // if(g_usBitsPerSample == 8) { // // On Tempest class devices rev B parts the divisor is // limited for lower samples rates (see errata). // if((ulI2SErrata != 0) && (ulSampleRate < 24400)) { ulFormat |= I2S_CONFIG_WIRE_SIZE_32 | I2S_CONFIG_MODE_MONO | I2S_CONFIG_SAMPLE_SIZE_8; usBitsPerSample = 32; } else { ulFormat |= I2S_CONFIG_WIRE_SIZE_8 | I2S_CONFIG_MODE_MONO | I2S_CONFIG_SAMPLE_SIZE_8; } } else if(g_usBitsPerSample == 16) { // // On Tempest class devices rev B parts the divisor is // limited for lower samples rates (see errata). // if((ulI2SErrata != 0) && (ulSampleRate < 12200)) { ulFormat |= I2S_CONFIG_WIRE_SIZE_32 | I2S_CONFIG_MODE_MONO | I2S_CONFIG_SAMPLE_SIZE_16; usBitsPerSample = 32; } else { ulFormat |= I2S_CONFIG_WIRE_SIZE_16 | I2S_CONFIG_MODE_MONO | I2S_CONFIG_SAMPLE_SIZE_16; } } else if(g_usBitsPerSample == 24) { ulFormat |= (I2S_CONFIG_WIRE_SIZE_24 | I2S_CONFIG_MODE_MONO | I2S_CONFIG_SAMPLE_SIZE_24); } else { ulFormat |= (I2S_CONFIG_WIRE_SIZE_32 | I2S_CONFIG_MODE_MONO | I2S_CONFIG_SAMPLE_SIZE_32); } } else { if(g_usBitsPerSample == 8) { // // On Tempest class devices rev B parts the divisor is // limited for lower samples rates (see errata). // if((ulI2SErrata != 0) && (ulSampleRate < 12200)) { ulFormat |= I2S_CONFIG_WIRE_SIZE_32 | I2S_CONFIG_MODE_COMPACT_8 | I2S_CONFIG_SAMPLE_SIZE_8; usBitsPerSample = 32; } else { ulFormat |= I2S_CONFIG_WIRE_SIZE_8 | I2S_CONFIG_MODE_COMPACT_8 | I2S_CONFIG_SAMPLE_SIZE_8; } } else if(g_usBitsPerSample == 16) { if((ulI2SErrata != 0) && (ulSampleRate < 12200)) { ulFormat |= I2S_CONFIG_WIRE_SIZE_32 | I2S_CONFIG_MODE_COMPACT_16 | I2S_CONFIG_SAMPLE_SIZE_16; usBitsPerSample = 32; } else { ulFormat |= I2S_CONFIG_WIRE_SIZE_16 | I2S_CONFIG_MODE_COMPACT_16 | I2S_CONFIG_SAMPLE_SIZE_16; } } else if(g_usBitsPerSample == 24) { ulFormat |= (I2S_CONFIG_WIRE_SIZE_24 | I2S_CONFIG_MODE_DUAL | I2S_CONFIG_SAMPLE_SIZE_24); } else { ulFormat |= (I2S_CONFIG_WIRE_SIZE_32 | I2S_CONFIG_MODE_DUAL | I2S_CONFIG_SAMPLE_SIZE_32); } } // // Configure the I2S TX format. // I2STxConfigSet(I2S0_BASE, ulFormat); // // This is needed on Rev B parts due to errata. // if(ulI2SErrata) { ulFormat = (ulFormat & ~I2S_CONFIG_FORMAT_MASK) | I2S_CONFIG_FORMAT_LEFT_JUST; } // // Configure the I2S RX format. // I2SRxConfigSet(I2S0_BASE, ulFormat); // // Internally both are masters but the pins may not be driven out. // I2SMasterClockSelect(I2S0_BASE, I2S_TX_MCLK_INT | I2S_RX_MCLK_INT); // // Set the MCLK rate and save it for conversion back to sample rate. // The multiply by 8 is due to a 4X oversample rate plus a factor of two // since the data is always stereo on the I2S interface. // g_ulSampleRate = SysCtlI2SMClkSet(0, ulSampleRate * usBitsPerSample * 8); // // Convert the MCLK rate to sample rate. // g_ulSampleRate = g_ulSampleRate / (usBitsPerSample * 8); // // Configure the I2S TX DMA channel to use high priority burst transfer. // uDMAChannelAttributeEnable(UDMA_CHANNEL_I2S0TX, UDMA_ATTR_USEBURST | UDMA_ATTR_HIGH_PRIORITY); // // Set the DMA channel configuration. // if(g_usChannels == 1) { // // Handle Mono formats. // if(g_usBitsPerSample == 8) { // // The transfer size is 8 bits from the TX buffer to the TX FIFO. // ulDMASetting = (UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE | UDMA_ARB_2); } else { // // The transfer size is 16 bits from the TX buffer to the TX FIFO. // ulDMASetting = (UDMA_SIZE_16 | UDMA_SRC_INC_16 | UDMA_DST_INC_NONE | UDMA_ARB_2); } } else { // // Handle Stereo formats. // if(g_usBitsPerSample == 8) { // // The transfer size is 16 bits(stereo 8 bits) from the TX buffer // to the TX FIFO. // ulDMASetting = (UDMA_SIZE_16 | UDMA_SRC_INC_16 | UDMA_DST_INC_NONE | UDMA_ARB_2); } else { // // The transfer size is 32 bits(stereo 16 bits) from the TX buffer // to the TX FIFO. // ulDMASetting = (UDMA_SIZE_32 | UDMA_SRC_INC_32 | UDMA_DST_INC_NONE | UDMA_ARB_2); } } // // Configure the DMA settings for this channel. // uDMAChannelControlSet(UDMA_CHANNEL_I2S0TX | UDMA_PRI_SELECT, ulDMASetting); uDMAChannelControlSet(UDMA_CHANNEL_I2S0TX | UDMA_ALT_SELECT, ulDMASetting); // // Set the DMA channel configuration. // if(g_usChannels == 1) { // // Handle stereo recording. // if(g_usBitsPerSample == 8) { // // The transfer size is 8 bits from the RX FIFO to // RX buffer. // ulDMASetting = (UDMA_SIZE_8 | UDMA_DST_INC_8 | UDMA_SRC_INC_NONE | UDMA_ARB_2); // // Only read the most significant byte of the I2S FIFO. // g_pvFIFORecord = (void *)(I2S0_BASE + I2S_O_RXFIFO + 3); } else { // // The transfer size is 16 bits from the RX FIFO to // RX buffer. // ulDMASetting = (UDMA_SIZE_16 | UDMA_DST_INC_16 | UDMA_SRC_INC_NONE | UDMA_ARB_2); // // Only read the most significant 16 bits of the I2S FIFO. // g_pvFIFORecord = (void *)(I2S0_BASE + I2S_O_RXFIFO + 2); } } else { // // Handle stereo recording. // if(g_usBitsPerSample == 8) { // // The transfer size is 16 bits(stereo 8 bits) from the RX FIFO to // RX buffer. // ulDMASetting = (UDMA_SIZE_16 | UDMA_DST_INC_16 | UDMA_SRC_INC_NONE | UDMA_ARB_2); // // Only read the most significant 16 bits of the I2S FIFO. // g_pvFIFORecord = (void *)(I2S0_BASE + I2S_O_RXFIFO); } else { // // The transfer size is 32 bits(stereo 16 bits) from the RX FIFO to // RX buffer. // ulDMASetting = (UDMA_SIZE_32 | UDMA_DST_INC_32 | UDMA_SRC_INC_NONE | UDMA_ARB_2); // // Only read the most significant byte of the I2S FIFO. // g_pvFIFORecord = (void *)(I2S0_BASE + I2S_O_RXFIFO); } } // // Configure the DMA settings for this channel. // uDMAChannelControlSet(UDMA_CHANNEL_I2S0RX | UDMA_PRI_SELECT, ulDMASetting); uDMAChannelControlSet(UDMA_CHANNEL_I2S0RX | UDMA_ALT_SELECT, ulDMASetting); }
//***************************************************************************** // //! Configures the I2S peripheral to play audio in a given format. //! //! \param ulSampleRate is the sample rate of the audio to be played in //! samples per second. //! \param usBitsPerSample is the number of bits in each audio sample. //! \param usChannels is the number of audio channels, 1 for mono, 2 for stereo. //! //! This function configures the I2S peripheral in preparation for playing //! or recording audio data in a particular format. //! //! \return None. // //***************************************************************************** void SoundSetFormat(unsigned long ulSampleRate, unsigned short usBitsPerSample, unsigned short usChannels) { unsigned long ulFormat; unsigned long ulDMASetting; unsigned long ulI2SErrata; // // Save these values for use when configuring I2S. // g_usChannels = usChannels; g_usBitsPerSample = usBitsPerSample; // // Configure the I2S master clock for internal. // I2SMasterClockSelect(I2S0_BASE, I2S_TX_MCLK_INT); // // Configure the I2S to be a master. // ulFormat = I2S_CONFIG_FORMAT_I2S | I2S_CONFIG_CLK_MASTER; // // Check if the missing divisor bits need to be taken into account. // if(CLASS_IS_TEMPEST && REVISION_IS_B1) { ulI2SErrata = 1; } else { ulI2SErrata = 0; } // // Mono or Stereo formats. // if(g_usChannels == 1) { // // 8 bit formats. // if(g_usBitsPerSample == 8) { // // On Tempest class devices rev B parts the divisor is // limited for lower samples rates (see erratum). // if((ulI2SErrata != 0) && (ulSampleRate < 24400)) { ulFormat |= I2S_CONFIG_WIRE_SIZE_32 | I2S_CONFIG_MODE_MONO | I2S_CONFIG_SAMPLE_SIZE_8; usBitsPerSample = 32; } else { ulFormat |= I2S_CONFIG_WIRE_SIZE_8 | I2S_CONFIG_MODE_MONO | I2S_CONFIG_SAMPLE_SIZE_8; } } // // 16-bit format // else if(g_usBitsPerSample == 16) { // // On Tempest class devices rev B parts the divisor is // limited for lower samples rates (see errata). // if((ulI2SErrata != 0) && (ulSampleRate < 12200)) { ulFormat |= I2S_CONFIG_WIRE_SIZE_32 | I2S_CONFIG_MODE_MONO | I2S_CONFIG_SAMPLE_SIZE_16; usBitsPerSample = 32; } else { ulFormat |= I2S_CONFIG_WIRE_SIZE_16 | I2S_CONFIG_MODE_MONO | I2S_CONFIG_SAMPLE_SIZE_16; } } // // 24-bit format // else if(g_usBitsPerSample == 24) { ulFormat |= I2S_CONFIG_WIRE_SIZE_24 | I2S_CONFIG_MODE_MONO | I2S_CONFIG_SAMPLE_SIZE_24; } else { ulFormat |= I2S_CONFIG_WIRE_SIZE_32 | I2S_CONFIG_MODE_MONO | I2S_CONFIG_SAMPLE_SIZE_32; } } // // Stereo formats // else { // // 8-bit format // if(g_usBitsPerSample == 8) { // // On Tempest class devices rev B parts the divisor is // limited for lower samples rates (see errata). // if((ulI2SErrata != 0) && (ulSampleRate < 12200)) { ulFormat |= I2S_CONFIG_WIRE_SIZE_32 | I2S_CONFIG_MODE_COMPACT_8 | I2S_CONFIG_SAMPLE_SIZE_8; usBitsPerSample = 32; } else { ulFormat |= I2S_CONFIG_WIRE_SIZE_8 | I2S_CONFIG_MODE_COMPACT_8 | I2S_CONFIG_SAMPLE_SIZE_8; } } // // 16-bit format // else if(g_usBitsPerSample == 16) { if((ulI2SErrata != 0) && (ulSampleRate < 12200)) { ulFormat |= I2S_CONFIG_WIRE_SIZE_32 | I2S_CONFIG_MODE_COMPACT_16 | I2S_CONFIG_SAMPLE_SIZE_16; usBitsPerSample = 32; } else { ulFormat |= I2S_CONFIG_WIRE_SIZE_16 | I2S_CONFIG_MODE_COMPACT_16 | I2S_CONFIG_SAMPLE_SIZE_16; } } // // 24-bit format // else if(g_usBitsPerSample == 24) { ulFormat |= I2S_CONFIG_WIRE_SIZE_24 | I2S_CONFIG_MODE_DUAL | I2S_CONFIG_SAMPLE_SIZE_24; } else { ulFormat |= I2S_CONFIG_WIRE_SIZE_32 | I2S_CONFIG_MODE_DUAL | I2S_CONFIG_SAMPLE_SIZE_32; } } // // Configure the I2S TX format. // I2STxConfigSet(I2S0_BASE, ulFormat); // // Set the MCLK rate and save it for conversion back to sample rate. // The multiply by 8 is due to a 4X oversample rate plus a factor of two // since the data is always stereo on the I2S interface. // g_ulSampleRate = SysCtlI2SMClkSet(0, (ulSampleRate * usBitsPerSample * 8)); // // Convert the MCLK rate to sample rate. // g_ulSampleRate = g_ulSampleRate / (usBitsPerSample * 8); // // Configure the I2S TX DMA channel to use high priority burst transfer. // uDMAChannelAttributeEnable(UDMA_CHANNEL_I2S0TX, (UDMA_ATTR_USEBURST | UDMA_ATTR_HIGH_PRIORITY)); // // Set the DMA channel configuration. // if(g_usChannels == 1) { // // Handle Mono formats. // if(g_usBitsPerSample == 8) { // // The transfer size is 8 bits from the TX buffer to the TX FIFO. // ulDMASetting = UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE | UDMA_ARB_2; } else { // // The transfer size is 16 bits from the TX buffer to the TX FIFO. // ulDMASetting = UDMA_SIZE_16 | UDMA_SRC_INC_16 | UDMA_DST_INC_NONE | UDMA_ARB_2; } } else { // // Handle Stereo formats. // if(g_usBitsPerSample == 8) { // // The transfer size is 16 bits(stereo 8 bits) from the TX buffer // to the TX FIFO. // ulDMASetting = UDMA_SIZE_16 | UDMA_SRC_INC_16 | UDMA_DST_INC_NONE | UDMA_ARB_2; } else { // // The transfer size is 32 bits(stereo 16 bits) from the TX buffer // to the TX FIFO. // ulDMASetting = UDMA_SIZE_32 | UDMA_SRC_INC_32 | UDMA_DST_INC_NONE | UDMA_ARB_2; } } // // Configure the DMA settings for this channel. // uDMAChannelControlSet(UDMA_CHANNEL_I2S0TX | UDMA_PRI_SELECT, ulDMASetting); uDMAChannelControlSet(UDMA_CHANNEL_I2S0TX | UDMA_ALT_SELECT, ulDMASetting); }
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"); }
//***************************************************************************** // // 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) { } }