Part Number: TMS320F28388D
Hello,
I am trying to have DMA reading ADC data at the end of SOC15. SOC is triggered by ePWM. The example of "adc_ex6_soc_continuous_dma" only runs once, so I modified the DMA configuration from DMA_CFG_CONTINUOUS_DISABLE to DMA_CFG_CONTINUOUS_ENABLE. I also removed the trigger disable in dma interrupt. I also would like to have all SOC triggered by epwm1, so I changed the software tigger in the example.
I get correct data if the DMA_CFG_CONTINUOUS_DISABLE is set:

But the data reading is incorrect if I changed it to DMA_CFG_CONTINUOUS_ENABLE:

I have my modified c file attached. I am not sure what configuration I missed.
//###########################################################################
//
// FILE: adc_ex6_soc_continuous_dma.c
//
// TITLE: ADC continuous conversions read by DMA.
//
//! \addtogroup driver_example_list
//! <h1> ADC Continuous Conversions Read by DMA (adc_soc_continuous_dma)</h1>
//!
//! This example sets up two ADC channels to convert simultaneously. The
//! results will be transferred by the DMA into a buffer in RAM.
//!
//! \b External \b Connections \n
//! - A3 & B3 pins should be connected to signals to convert
//!
//! \b Watch \b Variables \n
//! - \b adcADataBuffer \b: a digital representation of the voltage on pin A3\n
//! - \b adcBDataBuffer \b: a digital representation of the voltage on pin B3\n
//!
//
//###########################################################################
// $TI Release: F2838x Support Library v3.03.00.00 $
// $Release Date: Sun Oct 4 16:00:36 IST 2020 $
// $Copyright:
// Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the
// distribution.
//
// Neither the name of Texas Instruments Incorporated nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// $
//###########################################################################
//
// Included Files
//
#include "driverlib.h"
#include "device.h"
//
// Function Prototypes
//
__interrupt void dmach1ISR(void);
void configureEPWM(uint32_t epwmBase);
void configureADC(uint32_t adcBase);
void setupADCContinuous(uint32_t adcBase, uint16_t channel);
void initializeDMA(void);
void configureDMAChannels(void);
//
// Defines0
//
#define RESULTS_BUFFER_SIZE 256 // Buffer for storing conversion results
// (size must be multiple of 16)
#define EX_ADC_RESOLUTION 16
//
// Globals
//
#pragma DATA_SECTION(adcADataBuffer, "ramgs0");
#pragma DATA_SECTION(adcBDataBuffer, "ramgs0");
uint16_t adcADataBuffer[RESULTS_BUFFER_SIZE];
uint16_t adcBDataBuffer[RESULTS_BUFFER_SIZE];
volatile uint16_t dma_done;
void main(void)
{
uint16_t resultsIndex;
//
// Initialize device clock and peripherals
//
Device_init();
//
// Disable pin locks and enable internal pullups.
//
Device_initGPIO();
//
// Initialize PIE and clear PIE registers. Disables CPU interrupts.
//
Interrupt_initModule();
//
// Initialize the PIE vector table with pointers to the shell Interrupt
// Service Routines (ISR).
//
Interrupt_initVectorTable();
//
// Set up ISRs used by this example
//
// ISR for DMA ch1 - occurs when DMA transfer is complete
//
Interrupt_register(INT_DMA_CH1, &dmach1ISR);
//
// Enable specific PIE & CPU interrupts:
// DMA interrupt - Group 7, interrupt 1
Interrupt_enable(INT_DMA_CH1);
//
// Stop the ePWM clock
//
SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
//
// Call the set up function for ePWM 2
//
configureEPWM(EPWM1_BASE);
//
// Start the ePWM clock
//
SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
//
// Configure the ADCA & ADCB and power it up
//
configureADC(ADCA_BASE);
configureADC(ADCB_BASE);
//
// Setup the ADC for continuous conversions on channels A3 and B3
//
setupADCContinuous(ADCA_BASE, 2);
setupADCContinuous(ADCB_BASE, 2);
//
// Initialize the DMA & configure DMA channels 1 & 2
//
initializeDMA();
configureDMAChannels();
//
// Initialize results buffer
//
for(resultsIndex = 0; resultsIndex < RESULTS_BUFFER_SIZE; resultsIndex++)
{
adcADataBuffer[resultsIndex] = 0;
adcBDataBuffer[resultsIndex] = 0;
}
//
// Clearing all pending interrupt flags
//
DMA_clearTriggerFlag(DMA_CH1_BASE); // DMA channel 1
DMA_clearTriggerFlag(DMA_CH2_BASE); // DMA channel 2
HWREGH(ADCA_BASE + ADC_O_INTFLGCLR) = 0x3U; // ADCA
HWREGH(ADCB_BASE + ADC_O_INTFLGCLR) = 0x3U; // ADCB
EPWM_forceADCTriggerEventCountInit(EPWM1_BASE, EPWM_SOC_A); // EPWM1 SOCA
EPWM_clearADCTriggerFlag(EPWM1_BASE, EPWM_SOC_A); // EPWM1 SOCA
//
// Enable global Interrupts and higher priority real-time debug events:
//
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM
//
// Start DMA
//
dma_done = 0;
DMA_startChannel(DMA_CH1_BASE);
DMA_startChannel(DMA_CH2_BASE);
//
// Finally, enable the SOCA trigger from ePWM. This will kick off
// conversions at the next ePWM event.
//
EPWM_enableADCTrigger(EPWM1_BASE, EPWM_SOC_A);
//
// Loop until the ISR signals the transfer is complete
//
while(1)
{
if (dma_done == 1){
//dsp
dma_done=0;
}
__asm(" NOP");
}
}
//
// dmach1ISR - This is called at the end of the DMA transfer.
//
#pragma CODE_SECTION(dmach1ISR, ".TI.ramfunc");
__interrupt void dmach1ISR(void)
{
dma_done=1;
//
// Acknowledge interrupt
//
Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP7);
}
//
// configureEPWM - Set up the ePWM module so that the A output has a period
// of 5us with a 50% duty. The SOCA signal is coincident with
// the rising edge of this.
//
void configureEPWM(uint32_t epwmBase)
{
//
// Make the timer count up with a period of 5us
//
HWREGH(epwmBase + EPWM_O_TBCTL) = 0x0000U;
EPWM_setTimeBasePeriod(epwmBase, 500U);
//
// Set the A output on zero and reset on CMPA
//
EPWM_setActionQualifierAction(epwmBase, EPWM_AQ_OUTPUT_A,
EPWM_AQ_OUTPUT_HIGH,
EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
EPWM_setActionQualifierAction(epwmBase, EPWM_AQ_OUTPUT_A,
EPWM_AQ_OUTPUT_LOW,
EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
//
// Set CMPA to 2.5us to get a 50% duty
//
EPWM_setCounterCompareValue(epwmBase, EPWM_COUNTER_COMPARE_A, 250U);
//
// Start ADC when timer equals zero (note: don't enable yet)
//
EPWM_setADCTriggerSource(epwmBase, EPWM_SOC_A, EPWM_SOC_TBCTR_ZERO);
EPWM_setADCTriggerEventPrescale(epwmBase, EPWM_SOC_A, 1U);
//
// Enable initialization of the SOCA event counter. Since we are
// disabling the ETSEL.SOCAEN bit, we need a way to reset the SOCACNT.
// Hence, enable the counter initialize control.
//
EPWM_enableADCTriggerEventCountInit(epwmBase, EPWM_SOC_A);
}
//
// configureADC - Write ADC configurations and power up the ADC for both
// ADC A and ADC B
//
void configureADC(uint32_t adcBase)
{
//
// Set ADCCLK divider to /4
//
ADC_setPrescaler(adcBase, ADC_CLK_DIV_4_0);
//
// Set resolution and signal mode (see #defines above) and load
// corresponding trims.
//
#if(EX_ADC_RESOLUTION == 12)
ADC_setMode(adcBase, ADC_RESOLUTION_12BIT, ADC_MODE_SINGLE_ENDED);
#elif(EX_ADC_RESOLUTION == 16)
ADC_setMode(adcBase, ADC_RESOLUTION_16BIT, ADC_MODE_DIFFERENTIAL);
#endif
//
// Set pulse positions to late
//
ADC_setInterruptPulseMode(adcBase, ADC_PULSE_END_OF_CONV);
//
// Power up the ADCs and then delay for 1 ms
//
ADC_enableConverter(adcBase);
//
// Delay for 1ms to allow ADC time to power up
//
DEVICE_DELAY_US(1000);
}
//
// setupADCContinuous - setup the ADC to continuously convert on one channel
//
void setupADCContinuous(uint32_t adcBase, uint16_t channel)
{
uint16_t acqps=63;
//
// Configure SOCs channel no. & acquisition window.
// Trigger SCO0-15 from EPWM1SOCA.
//
ADC_setupSOC(adcBase, ADC_SOC_NUMBER0, ADC_TRIGGER_EPWM1_SOCA,
(ADC_Channel)channel, acqps);
ADC_setupSOC(adcBase, ADC_SOC_NUMBER1, ADC_TRIGGER_EPWM1_SOCA,
(ADC_Channel)channel, acqps);
ADC_setupSOC(adcBase, ADC_SOC_NUMBER2, ADC_TRIGGER_EPWM1_SOCA,
(ADC_Channel)channel, acqps);
ADC_setupSOC(adcBase, ADC_SOC_NUMBER3, ADC_TRIGGER_EPWM1_SOCA,
(ADC_Channel)channel, acqps);
ADC_setupSOC(adcBase, ADC_SOC_NUMBER4, ADC_TRIGGER_EPWM1_SOCA,
(ADC_Channel)channel, acqps);
ADC_setupSOC(adcBase, ADC_SOC_NUMBER5, ADC_TRIGGER_EPWM1_SOCA,
(ADC_Channel)channel, acqps);
ADC_setupSOC(adcBase, ADC_SOC_NUMBER6, ADC_TRIGGER_EPWM1_SOCA,
(ADC_Channel)channel, acqps);
ADC_setupSOC(adcBase, ADC_SOC_NUMBER7, ADC_TRIGGER_EPWM1_SOCA,
(ADC_Channel)channel, acqps);
ADC_setupSOC(adcBase, ADC_SOC_NUMBER8, ADC_TRIGGER_EPWM1_SOCA,
(ADC_Channel)channel, acqps);
ADC_setupSOC(adcBase, ADC_SOC_NUMBER9, ADC_TRIGGER_EPWM1_SOCA,
(ADC_Channel)channel, acqps);
ADC_setupSOC(adcBase, ADC_SOC_NUMBER10, ADC_TRIGGER_EPWM1_SOCA,
(ADC_Channel)channel, acqps);
ADC_setupSOC(adcBase, ADC_SOC_NUMBER11, ADC_TRIGGER_EPWM1_SOCA,
(ADC_Channel)channel, acqps);
ADC_setupSOC(adcBase, ADC_SOC_NUMBER12, ADC_TRIGGER_EPWM1_SOCA,
(ADC_Channel)channel, acqps);
ADC_setupSOC(adcBase, ADC_SOC_NUMBER13, ADC_TRIGGER_EPWM1_SOCA,
(ADC_Channel)channel, acqps);
ADC_setupSOC(adcBase, ADC_SOC_NUMBER14, ADC_TRIGGER_EPWM1_SOCA,
(ADC_Channel)channel, acqps);
ADC_setupSOC(adcBase, ADC_SOC_NUMBER15, ADC_TRIGGER_EPWM1_SOCA,
(ADC_Channel)channel, acqps);
//
// Enable ADCINT1 & ADCINT2. Disable ADCINT3 & ADCINT4.
//
ADC_disableInterrupt(adcBase, ADC_INT_NUMBER1);
ADC_enableInterrupt(adcBase, ADC_INT_NUMBER2);
ADC_disableInterrupt(adcBase, ADC_INT_NUMBER3);
ADC_disableInterrupt(adcBase, ADC_INT_NUMBER4);
//
// Enable continuous mode
//
//ADC_enableContinuousMode(adcBase, ADC_INT_NUMBER1);
ADC_enableContinuousMode(adcBase, ADC_INT_NUMBER2);
//
// Configure interrupt triggers
//
//ADC_setInterruptSource(adcBase, ADC_INT_NUMBER1, ADC_SOC_NUMBER0);
ADC_setInterruptSource(adcBase, ADC_INT_NUMBER2, ADC_SOC_NUMBER15);
}
//
// initializeDMA - Initialize DMA through hard reset
//
void initializeDMA(void)
{
//
// Perform a hard reset on DMA
//
DMA_initController();
//
// Allow DMA to run free on emulation suspend
//
DMA_setEmulationMode(DMA_EMULATION_FREE_RUN);
}
//
// configureDMAChannels - Initialize DMA ch 1 to transfer ADCA results
// and DMA ch 2 to transfer ADCB results
//
void configureDMAChannels(void)
{
//
// DMA channel 1 set up for ADCA
//
DMA_configAddresses(DMA_CH1_BASE, (uint16_t *)&adcADataBuffer,
(uint16_t *)ADCARESULT_BASE);
//
// Perform enough 16-word bursts to fill the results buffer. Data will be
// transferred 32 bits at a time hence the address steps below.
//
DMA_configBurst(DMA_CH1_BASE, 16, 2, 2);
DMA_configTransfer(DMA_CH1_BASE, (RESULTS_BUFFER_SIZE >> 4), -14, 2);
DMA_configMode(DMA_CH1_BASE, DMA_TRIGGER_ADCA2,
(DMA_CFG_ONESHOT_DISABLE | DMA_CFG_CONTINUOUS_ENABLE |
DMA_CFG_SIZE_32BIT));
DMA_enableTrigger(DMA_CH1_BASE);
DMA_disableOverrunInterrupt(DMA_CH1_BASE);
DMA_setInterruptMode(DMA_CH1_BASE, DMA_INT_AT_END);
DMA_enableInterrupt(DMA_CH1_BASE);
//
// DMA channel 2 set up for ADCB
//
DMA_configAddresses(DMA_CH2_BASE, (uint16_t *)&adcBDataBuffer,
(uint16_t *)ADCBRESULT_BASE);
//
// Perform enough 16-word bursts to fill the results buffer. Data will be
// transferred 32 bits at a time hence the address steps below.
//
DMA_configBurst(DMA_CH2_BASE, 16, 2, 2);
DMA_configTransfer(DMA_CH2_BASE, (RESULTS_BUFFER_SIZE >> 4), -14, 2);
DMA_configMode(DMA_CH2_BASE, DMA_TRIGGER_ADCA2,
(DMA_CFG_ONESHOT_DISABLE | DMA_CFG_CONTINUOUS_ENABLE |
DMA_CFG_SIZE_32BIT));
DMA_enableTrigger(DMA_CH2_BASE);
DMA_disableOverrunInterrupt(DMA_CH2_BASE);
DMA_setInterruptMode(DMA_CH2_BASE, DMA_INT_AT_END);
DMA_enableInterrupt(DMA_CH2_BASE);
}
//
// End of file
//
//###########################################################################
//
// FILE: adc_ex6_soc_continuous_dma.c
//
// TITLE: ADC continuous conversions read by DMA.
//
//! \addtogroup driver_example_list
//! <h1> ADC Continuous Conversions Read by DMA (adc_soc_continuous_dma)</h1>
//!
//! This example sets up two ADC channels to convert simultaneously. The
//! results will be transferred by the DMA into a buffer in RAM.
//!
//! \b External \b Connections \n
//! - A3 & B3 pins should be connected to signals to convert
//!
//! \b Watch \b Variables \n
//! - \b adcADataBuffer \b: a digital representation of the voltage on pin A3\n
//! - \b adcBDataBuffer \b: a digital representation of the voltage on pin B3\n
//!
//
//###########################################################################
// $TI Release: F2838x Support Library v3.03.00.00 $
// $Release Date: Sun Oct 4 16:00:36 IST 2020 $
// $Copyright:
// Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the
// distribution.
//
// Neither the name of Texas Instruments Incorporated nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// $
//###########################################################################
//
// Included Files
//
#include "driverlib.h"
#include "device.h"
//
// Function Prototypes
//
__interrupt void dmach1ISR(void);
void configureEPWM(uint32_t epwmBase);
void configureADC(uint32_t adcBase);
void setupADCContinuous(uint32_t adcBase, uint16_t channel);
void initializeDMA(void);
void configureDMAChannels(void);
//
// Defines0
//
#define RESULTS_BUFFER_SIZE 256 // Buffer for storing conversion results
// (size must be multiple of 16)
#define EX_ADC_RESOLUTION 16
//
// Globals
//
#pragma DATA_SECTION(adcADataBuffer, "ramgs0");
#pragma DATA_SECTION(adcBDataBuffer, "ramgs0");
uint16_t adcADataBuffer[RESULTS_BUFFER_SIZE];
uint16_t adcBDataBuffer[RESULTS_BUFFER_SIZE];
volatile uint16_t dma_done;
void main(void)
{
uint16_t resultsIndex;
//
// Initialize device clock and peripherals
//
Device_init();
//
// Disable pin locks and enable internal pullups.
//
Device_initGPIO();
//
// Initialize PIE and clear PIE registers. Disables CPU interrupts.
//
Interrupt_initModule();
//
// Initialize the PIE vector table with pointers to the shell Interrupt
// Service Routines (ISR).
//
Interrupt_initVectorTable();
//
// Set up ISRs used by this example
//
// ISR for DMA ch1 - occurs when DMA transfer is complete
//
Interrupt_register(INT_DMA_CH1, &dmach1ISR);
//
// Enable specific PIE & CPU interrupts:
// DMA interrupt - Group 7, interrupt 1
Interrupt_enable(INT_DMA_CH1);
//
// Stop the ePWM clock
//
SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
//
// Call the set up function for ePWM 2
//
configureEPWM(EPWM1_BASE);
//
// Start the ePWM clock
//
SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
//
// Configure the ADCA & ADCB and power it up
//
configureADC(ADCA_BASE);
configureADC(ADCB_BASE);
//
// Setup the ADC for continuous conversions on channels A3 and B3
//
setupADCContinuous(ADCA_BASE, 2);
setupADCContinuous(ADCB_BASE, 2);
//
// Initialize the DMA & configure DMA channels 1 & 2
//
initializeDMA();
configureDMAChannels();
//
// Initialize results buffer
//
for(resultsIndex = 0; resultsIndex < RESULTS_BUFFER_SIZE; resultsIndex++)
{
adcADataBuffer[resultsIndex] = 0;
adcBDataBuffer[resultsIndex] = 0;
}
//
// Clearing all pending interrupt flags
//
DMA_clearTriggerFlag(DMA_CH1_BASE); // DMA channel 1
DMA_clearTriggerFlag(DMA_CH2_BASE); // DMA channel 2
HWREGH(ADCA_BASE + ADC_O_INTFLGCLR) = 0x3U; // ADCA
HWREGH(ADCB_BASE + ADC_O_INTFLGCLR) = 0x3U; // ADCB
EPWM_forceADCTriggerEventCountInit(EPWM1_BASE, EPWM_SOC_A); // EPWM1 SOCA
EPWM_clearADCTriggerFlag(EPWM1_BASE, EPWM_SOC_A); // EPWM1 SOCA
//
// Enable global Interrupts and higher priority real-time debug events:
//
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM
//
// Start DMA
//
dma_done = 0;
DMA_startChannel(DMA_CH1_BASE);
DMA_startChannel(DMA_CH2_BASE);
//
// Finally, enable the SOCA trigger from ePWM. This will kick off
// conversions at the next ePWM event.
//
EPWM_enableADCTrigger(EPWM1_BASE, EPWM_SOC_A);
//
// Loop until the ISR signals the transfer is complete
//
while(1)
{
if (dma_done == 1){
//dsp
dma_done=0;
}
__asm(" NOP");
}
}
//
// dmach1ISR - This is called at the end of the DMA transfer.
//
#pragma CODE_SECTION(dmach1ISR, ".TI.ramfunc");
__interrupt void dmach1ISR(void)
{
dma_done=1;
//
// Acknowledge interrupt
//
Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP7);
}
//
// configureEPWM - Set up the ePWM module so that the A output has a period
// of 5us with a 50% duty. The SOCA signal is coincident with
// the rising edge of this.
//
void configureEPWM(uint32_t epwmBase)
{
//
// Make the timer count up with a period of 5us
//
HWREGH(epwmBase + EPWM_O_TBCTL) = 0x0000U;
EPWM_setTimeBasePeriod(epwmBase, 500U);
//
// Set the A output on zero and reset on CMPA
//
EPWM_setActionQualifierAction(epwmBase, EPWM_AQ_OUTPUT_A,
EPWM_AQ_OUTPUT_HIGH,
EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
EPWM_setActionQualifierAction(epwmBase, EPWM_AQ_OUTPUT_A,
EPWM_AQ_OUTPUT_LOW,
EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
//
// Set CMPA to 2.5us to get a 50% duty
//
EPWM_setCounterCompareValue(epwmBase, EPWM_COUNTER_COMPARE_A, 250U);
//
// Start ADC when timer equals zero (note: don't enable yet)
//
EPWM_setADCTriggerSource(epwmBase, EPWM_SOC_A, EPWM_SOC_TBCTR_ZERO);
EPWM_setADCTriggerEventPrescale(epwmBase, EPWM_SOC_A, 1U);
//
// Enable initialization of the SOCA event counter. Since we are
// disabling the ETSEL.SOCAEN bit, we need a way to reset the SOCACNT.
// Hence, enable the counter initialize control.
//
EPWM_enableADCTriggerEventCountInit(epwmBase, EPWM_SOC_A);
}
//
// configureADC - Write ADC configurations and power up the ADC for both
// ADC A and ADC B
//
void configureADC(uint32_t adcBase)
{
//
// Set ADCCLK divider to /4
//
ADC_setPrescaler(adcBase, ADC_CLK_DIV_4_0);
//
// Set resolution and signal mode (see #defines above) and load
// corresponding trims.
//
#if(EX_ADC_RESOLUTION == 12)
ADC_setMode(adcBase, ADC_RESOLUTION_12BIT, ADC_MODE_SINGLE_ENDED);
#elif(EX_ADC_RESOLUTION == 16)
ADC_setMode(adcBase, ADC_RESOLUTION_16BIT, ADC_MODE_DIFFERENTIAL);
#endif
//
// Set pulse positions to late
//
ADC_setInterruptPulseMode(adcBase, ADC_PULSE_END_OF_CONV);
//
// Power up the ADCs and then delay for 1 ms
//
ADC_enableConverter(adcBase);
//
// Delay for 1ms to allow ADC time to power up
//
DEVICE_DELAY_US(1000);
}
//
// setupADCContinuous - setup the ADC to continuously convert on one channel
//
void setupADCContinuous(uint32_t adcBase, uint16_t channel)
{
uint16_t acqps=63;
//
// Configure SOCs channel no. & acquisition window.
// Trigger SCO0-15 from EPWM1SOCA.
//
ADC_setupSOC(adcBase, ADC_SOC_NUMBER0, ADC_TRIGGER_EPWM1_SOCA,
(ADC_Channel)channel, acqps);
ADC_setupSOC(adcBase, ADC_SOC_NUMBER1, ADC_TRIGGER_EPWM1_SOCA,
(ADC_Channel)channel, acqps);
ADC_setupSOC(adcBase, ADC_SOC_NUMBER2, ADC_TRIGGER_EPWM1_SOCA,
(ADC_Channel)channel, acqps);
ADC_setupSOC(adcBase, ADC_SOC_NUMBER3, ADC_TRIGGER_EPWM1_SOCA,
(ADC_Channel)channel, acqps);
ADC_setupSOC(adcBase, ADC_SOC_NUMBER4, ADC_TRIGGER_EPWM1_SOCA,
(ADC_Channel)channel, acqps);
ADC_setupSOC(adcBase, ADC_SOC_NUMBER5, ADC_TRIGGER_EPWM1_SOCA,
(ADC_Channel)channel, acqps);
ADC_setupSOC(adcBase, ADC_SOC_NUMBER6, ADC_TRIGGER_EPWM1_SOCA,
(ADC_Channel)channel, acqps);
ADC_setupSOC(adcBase, ADC_SOC_NUMBER7, ADC_TRIGGER_EPWM1_SOCA,
(ADC_Channel)channel, acqps);
ADC_setupSOC(adcBase, ADC_SOC_NUMBER8, ADC_TRIGGER_EPWM1_SOCA,
(ADC_Channel)channel, acqps);
ADC_setupSOC(adcBase, ADC_SOC_NUMBER9, ADC_TRIGGER_EPWM1_SOCA,
(ADC_Channel)channel, acqps);
ADC_setupSOC(adcBase, ADC_SOC_NUMBER10, ADC_TRIGGER_EPWM1_SOCA,
(ADC_Channel)channel, acqps);
ADC_setupSOC(adcBase, ADC_SOC_NUMBER11, ADC_TRIGGER_EPWM1_SOCA,
(ADC_Channel)channel, acqps);
ADC_setupSOC(adcBase, ADC_SOC_NUMBER12, ADC_TRIGGER_EPWM1_SOCA,
(ADC_Channel)channel, acqps);
ADC_setupSOC(adcBase, ADC_SOC_NUMBER13, ADC_TRIGGER_EPWM1_SOCA,
(ADC_Channel)channel, acqps);
ADC_setupSOC(adcBase, ADC_SOC_NUMBER14, ADC_TRIGGER_EPWM1_SOCA,
(ADC_Channel)channel, acqps);
ADC_setupSOC(adcBase, ADC_SOC_NUMBER15, ADC_TRIGGER_EPWM1_SOCA,
(ADC_Channel)channel, acqps);
//
// Enable ADCINT1 & ADCINT2. Disable ADCINT3 & ADCINT4.
//
ADC_disableInterrupt(adcBase, ADC_INT_NUMBER1);
ADC_enableInterrupt(adcBase, ADC_INT_NUMBER2);
ADC_disableInterrupt(adcBase, ADC_INT_NUMBER3);
ADC_disableInterrupt(adcBase, ADC_INT_NUMBER4);
//
// Enable continuous mode
//
//ADC_enableContinuousMode(adcBase, ADC_INT_NUMBER1);
ADC_enableContinuousMode(adcBase, ADC_INT_NUMBER2);
//
// Configure interrupt triggers
//
//ADC_setInterruptSource(adcBase, ADC_INT_NUMBER1, ADC_SOC_NUMBER0);
ADC_setInterruptSource(adcBase, ADC_INT_NUMBER2, ADC_SOC_NUMBER15);
}
//
// initializeDMA - Initialize DMA through hard reset
//
void initializeDMA(void)
{
//
// Perform a hard reset on DMA
//
DMA_initController();
//
// Allow DMA to run free on emulation suspend
//
DMA_setEmulationMode(DMA_EMULATION_FREE_RUN);
}
//
// configureDMAChannels - Initialize DMA ch 1 to transfer ADCA results
// and DMA ch 2 to transfer ADCB results
//
void configureDMAChannels(void)
{
//
// DMA channel 1 set up for ADCA
//
DMA_configAddresses(DMA_CH1_BASE, (uint16_t *)&adcADataBuffer,
(uint16_t *)ADCARESULT_BASE);
//
// Perform enough 16-word bursts to fill the results buffer. Data will be
// transferred 32 bits at a time hence the address steps below.
//
DMA_configBurst(DMA_CH1_BASE, 16, 2, 2);
DMA_configTransfer(DMA_CH1_BASE, (RESULTS_BUFFER_SIZE >> 4), -14, 2);
DMA_configMode(DMA_CH1_BASE, DMA_TRIGGER_ADCA2,
(DMA_CFG_ONESHOT_DISABLE | DMA_CFG_CONTINUOUS_ENABLE |
DMA_CFG_SIZE_32BIT));
DMA_enableTrigger(DMA_CH1_BASE);
DMA_disableOverrunInterrupt(DMA_CH1_BASE);
DMA_setInterruptMode(DMA_CH1_BASE, DMA_INT_AT_END);
DMA_enableInterrupt(DMA_CH1_BASE);
//
// DMA channel 2 set up for ADCB
//
DMA_configAddresses(DMA_CH2_BASE, (uint16_t *)&adcBDataBuffer,
(uint16_t *)ADCBRESULT_BASE);
//
// Perform enough 16-word bursts to fill the results buffer. Data will be
// transferred 32 bits at a time hence the address steps below.
//
DMA_configBurst(DMA_CH2_BASE, 16, 2, 2);
DMA_configTransfer(DMA_CH2_BASE, (RESULTS_BUFFER_SIZE >> 4), -14, 2);
DMA_configMode(DMA_CH2_BASE, DMA_TRIGGER_ADCA2,
(DMA_CFG_ONESHOT_DISABLE | DMA_CFG_CONTINUOUS_ENABLE |
DMA_CFG_SIZE_32BIT));
DMA_enableTrigger(DMA_CH2_BASE);
DMA_disableOverrunInterrupt(DMA_CH2_BASE);
DMA_setInterruptMode(DMA_CH2_BASE, DMA_INT_AT_END);
DMA_enableInterrupt(DMA_CH2_BASE);
}
//
// End of file
//