Part Number: TMS320F28377D
Other Parts Discussed in Thread: CONTROLSUITE
Tool/software: Code Composer Studio
This is the adc+dma I changed from epwm_adc.c and dma_tranfer.c on ti controlsuite. Previously used controlsuite new adc+dma.c changed for a long time has not been able to meet the requirements, it's this is a single change to continuous sampling, I changed to continuous sampling after the total lack of data, sine image is not complete, Then I changed myself on epwm_adc myself. This program I want to make it through a round of sampling after the data is passed to the DMA from AdcaResults [] to rdata [], through the DmaRegs.CH1.CONTROL.bit.PERINTFRC = 1 directly in the ADC interrupt or loop in the software Trigger DMA. However, it seems to have no effect. At present, only AdcaResults have the correct data. And rdata which is all 0, I see dma_transfer.c is doing so, I do not seem to find which parts missing, so I feel very foolish, do not know how to engage, here are some of the code I changed,thanks for you reply.
//###########################################################################
//
// FILE: adc_soc_epwm_cpu01.c
//
// TITLE: ADC triggering via epwm for F2837xD.
//
//! \addtogroup cpu01_example_list
//! <h1> ADC ePWM Triggering (adc_soc_epwm)</h1>
//!
//! This example sets up the ePWM to periodically trigger the ADC.
//!
//! After the program runs, the memory will contain:\n
//! - \b AdcaResults \b: A sequence of analog-to-digital conversion samples from
//! pin A0. The time between samples is determined based on the period
//! of the ePWM timer.
//
//###########################################################################
// $TI Release: F2837xD Support Library v210 $
// $Release Date: Tue Nov 1 14:46:15 CDT 2016 $
// $Copyright: Copyright (C) 2013-2016 Texas Instruments Incorporated -
// http://www.ti.com/ ALL RIGHTS RESERVED $
//###########################################################################
//
// Included Files
//
#include "F28x_Project.h"
//
// Function Prototypes
//
void ConfigureADC(void);
void ConfigureEPWM(void);
void SetupADCEpwm(Uint16 channel);
interrupt void adca1_isr(void);
interrupt void local_D_INTCH1_ISR(void);
void dma_init(void);
//
// Defines
//
#define RESULTS_BUFFER_SIZE 512
//
// Globals
//
Uint16 AdcaResults[RESULTS_BUFFER_SIZE];
Uint16 rdata[RESULTS_BUFFER_SIZE];
Uint16 resultsIndex;
volatile Uint16 bufferFull;
volatile Uint16 *DMADest;
volatile Uint16 *DMASource;
void main(void)
{
//
// Step 1. Initialize System Control:
// PLL, WatchDog, enable Peripheral Clocks
// This example function is found in the F2837xD_SysCtrl.c file.
//
InitSysCtrl();
//
// Step 2. Initialize GPIO:
// This example function is found in the F2837xD_Gpio.c file and
// illustrates how to set the GPIO to it's default state.
//
InitGpio(); // Skipped for this example
//
// Step 3. Clear all interrupts and initialize PIE vector table:
// Disable CPU interrupts
//
DINT;
//
// Initialize the PIE control registers to their default state.
// The default state is all PIE interrupts disabled and flags
// are cleared.
// This function is found in the F2837xD_PieCtrl.c file.
//
InitPieCtrl();
//
// Disable CPU interrupts and clear all CPU interrupt flags:
//
IER = 0x0000;
IFR = 0x0000;
//
// Initialize the PIE vector table with pointers to the shell Interrupt
// Service Routines (ISR).
// This will populate the entire table, even if the interrupt
// is not used in this example. This is useful for debug purposes.
// The shell ISR routines are found in F2837xD_DefaultIsr.c.
// This function is found in F2837xD_PieVect.c.
//
InitPieVectTable();
//
// Map ISR functions
//
EALLOW;
PieVectTable.ADCA1_INT = &adca1_isr; //function for ADCA interrupt 1
PieVectTable.DMA_CH1_INT= &local_D_INTCH1_ISR;//中断入口函数
EDIS;
// Enable global Interrupts and higher priority real-time debug events:
//
IER |= M_INT1; //Enable group 1 interrupts
IER|= M_INT7;//Enable group 1 interrupts
//
PieCtrlRegs.PIECTRL.bit.ENPIE = 1; // Enable the PIE block
PieCtrlRegs.PIEIER1.bit.INTx1 = 1;
PieCtrlRegs.PIEIER7.bit.INTx1 = 1; // Enable PIE Group 7, INT 2 (DMA CH2)
// Enable CPU INT6
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM
//
// Configure the ADC and power it up
//
ConfigureADC();
//
// Configure the ePWM
//
ConfigureEPWM();
//
// Setup the ADC for ePWM triggered conversions on channel 0
//
SetupADCEpwm(2);
dma_init(); // set up the dma
// Ensure DMA is connected to Peripheral Frame 2 bridge (EALLOW protected)
//
EALLOW;
CpuSysRegs.SECMSEL.bit.PF2SEL = 1;
EDIS;
//
DmaRegs.CH1.CONTROL.bit.PERINTCLR = 1;
// StartDMACH1(); // Start DMA channel
//
// Initialize results buffer
//
for(resultsIndex = 0; resultsIndex < RESULTS_BUFFER_SIZE; resultsIndex++)
{
AdcaResults[resultsIndex] = 0;
rdata[resultsIndex]=0;
}
resultsIndex = 0;
bufferFull = 0;
//
// enable PIE interrupt
//
StartDMACH1(); // Start DMA channel
//
// sync ePWM
//
EALLOW;
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1;
EDIS;
//
//take conversions indefinitely in loop
//
do
{
//
//start ePWM
//
EPwm1Regs.ETSEL.bit.SOCAEN = 1; //enable SOCA
EPwm1Regs.TBCTL.bit.CTRMODE = 0; //unfreeze, and enter up count mode
//
//wait while ePWM causes ADC conversions, which then cause interrupts,
//which fill the results buffer, eventually setting the bufferFull
//flag
//
while(!bufferFull);
bufferFull = 0; //clear the buffer full flag
EALLOW;
// DmaRegs.CH1.CONTROL.bit.PERINTFRC = 1;
EDIS;
//
//stop ePWM
//
EPwm1Regs.ETSEL.bit.SOCAEN = 0; //disable SOCA
EPwm1Regs.TBCTL.bit.CTRMODE = 3; //freeze counter
//
//at this point, AdcaResults[] contains a sequence of conversions
//from the selected channel
//
//
//software breakpoint, hit run again to get updated conversions
//
asm(" ESTOP0");
}while(1);
}
//
// ConfigureADC - Write ADC configurations and power up the ADC for both
// ADC A and ADC B
//
void ConfigureADC(void)
{
EALLOW;
//
//write configurations
//
AdcaRegs.ADCCTL2.bit.PRESCALE = 6; //set ADCCLK divider to /4
AdcSetMode(ADC_ADCA, ADC_RESOLUTION_16BIT, ADC_SIGNALMODE_DIFFERENTIAL);
//
//Set pulse positions to late
//
AdcaRegs.ADCCTL1.bit.INTPULSEPOS = 1;
//
//power up the ADC
//
AdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1;
//
//delay for 1ms to allow ADC time to power up
//
DELAY_US(1000);
EDIS;
}
//
// ConfigureEPWM - Configure EPWM SOC and compare values
//
void ConfigureEPWM(void)
{
EALLOW;
// Assumes ePWM clock is already enabled
EPwm1Regs.ETSEL.bit.SOCAEN = 0; // Disable SOC on A group
EPwm1Regs.ETSEL.bit.SOCASEL = 4; // Select SOC on up-count
EPwm1Regs.ETPS.bit.SOCAPRD = 1; // Generate pulse on 1st event
EPwm1Regs.CMPA.bit.CMPA = 2000; // Set compare A value to 2000 counts
EPwm1Regs.TBPRD =4000; // Set period to 4000 counts
EPwm1Regs.TBCTL.bit.CTRMODE = 3; // freeze counter
EDIS;
}
//
// SetupADCEpwm - Setup ADC EPWM acquisition window
//
void SetupADCEpwm(Uint16 channel)
{
Uint16 acqps;
//
//determine minimum acquisition window (in SYSCLKS) based on resolution
//
if(ADC_RESOLUTION_12BIT == AdcaRegs.ADCCTL2.bit.RESOLUTION)
{
acqps = 14; //75ns
}
else //resolution is 16-bit
{
acqps = 63; //320ns
}
//
//Select the channels to convert and end of conversion flag
//
EALLOW;
AdcaRegs.ADCSOC0CTL.bit.CHSEL = channel; //SOC0 will convert pin A2
AdcaRegs.ADCSOC0CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles
AdcaRegs.ADCSOC0CTL.bit.TRIGSEL = 5; //trigger on ePWM1 SOCA/C
AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 0; //end of SOC0 will set INT1 flag
AdcaRegs.ADCINTSEL1N2.bit.INT1E = 1; //enable INT1 flag
AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //make sure INT1 flag is cleared
EDIS;
}
//
// adca1_isr - Read ADC Buffer in ISR
//
interrupt void adca1_isr(void)
{
AdcaResults[resultsIndex++] = AdcaResultRegs.ADCRESULT0;
// DmaRegs.CH1.CONTROL.bit.PERINTFRC = 1;
if(RESULTS_BUFFER_SIZE <= resultsIndex)
{
resultsIndex = 0;
bufferFull=1;
}
EALLOW;
DmaRegs.CH1.CONTROL.bit.PERINTFRC = 1;
EDIS;
AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //clear INT1 flag
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}
// dma_init - DMA setup for both TX and RX channels.
//
void dma_init()
{
//
// Refer to dma.c for the descriptions of the following functions.
//
//
//Initialize DMA
//
DMAInitialize();
DMASource = AdcaResults;
DMADest = rdata;
//
// configure DMA CH1
//
DMACH1AddrConfig(DMADest,DMASource);
DMACH1BurstConfig(15,1,1);
DMACH1TransferConfig(31,1,1);
DMACH1ModeConfig(0,PERINT_ENABLE,ONESHOT_DISABLE,CONT_ENABLE,
SYNC_DISABLE,SYNC_SRC,OVRFLOW_DISABLE,SIXTEEN_BIT,
CHINT_BEGIN,CHINT_ENABLE);
}
// local_D_INTCH6_ISR - DMA Channel6 ISR
//
interrupt void local_D_INTCH1_ISR(void)
{
PieCtrlRegs.PIEACK.all = PIEACK_GROUP7; // ACK to receive more interrupts
// from this PIE group
}
//
// End of file
//
.