Tool/software: Code Composer Studio
Hi,
I am using the TI delfino Launchpad. I am using ADC1 to trigger DMA. I have successfully implemented DMA data transfer. But this only work if I keep the ADC ISR and Clear the ADC interrupt flag. If I disable the ISR and it`s respective PIE group, the DMA only transfer ONE word and after that nothing. So I guess the problem is regarding clearing of interrupt flag.
The datasheet says, " Upon receipt of a peripheral interrupt event signal, the DMA will automatically send a clear signal to the interrupt source so that subsequent interrupt events will occur".
So is it actually possible that the DMA and ADC keep transferring data, without my CPU interference?
#include "F28x_Project.h"
#define _LAUNCHXL_F28377S
//
// DMA Related
//
#pragma DATA_SECTION(rdata, "ramgs0");
#define BURST 0 // write 0 to the register for a burst size of 1
#define TRANSFER (512*6)-1 // [(MEM_BUFFER_SIZE/(BURST + 1)) - 1]
Uint16 rdata[TRANSFER+1];
volatile Uint16 *DMADest;
volatile Uint16 *DMASource;
__interrupt void local_D_INTCH6_ISR(void);
void dma_init(void);
//
// Defines
void ConfigureADC(void);
void SetupADCEpwm(Uint16 channel);
//interrupt void adca1_isr(void);
//
// DMA PROTOTYPE
//
__interrupt void local_D_INTCH6_ISR(void);
void dma_init(void);
//
// Main
//
void main(void)
{
//
// Step 1. Initialize System Control:
// PLL, WatchDog, enable Peripheral Clocks
// This example function is found in the F2837xS_SysCtrl.c file.
//
InitSysCtrl();
//
// Step 2. Initialize GPIO:
// This example function is found in the F2837xS_Gpio.c file and
// illustrates how to set the GPIO to it's default state.
//
InitGpio();
/* GPIO_SetupPinMux(TOGGLE, GPIO_MUX_CPU1, 0);
GPIO_SetupPinOptions(TOGGLE, GPIO_OUTPUT, GPIO_PUSHPULL); /
GPIO_SetupPinMux(CHECK, GPIO_MUX_CPU1, 0); //
GPIO_SetupPinOptions(CHECK, GPIO_OUTPUT, GPIO_PUSHPULL);
*/
//
// Enable PWM2 and PWM7
//
CpuSysRegs.PCLKCR2.bit.EPWM8=1;
CpuSysRegs.PCLKCR2.bit.EPWM7=1;
CpuSysRegs.PCLKCR2.bit.EPWM3=1;
//
// For this case just init GPIO pins for ePWM1, ePWM2, ePWM3
// These functions are in the F2837xS_EPwm.c file
//
//InitEPwm2Gpio();
InitEPwm8Gpio();
InitEPwm7Gpio();
InitEPwm3Gpio();
/* EALLOW;
GpioCtrlRegs.GPCPUD.bit.GPIO73=1; // XCLKOUT code to check the PLLSYSCLK, clock is divided by 8.
ClkCfgRegs.CLKSRCCTL3.bit.XCLKOUTSEL=0;
GpioCtrlRegs.GPCGMUX1.bit.GPIO73=0;
GpioCtrlRegs.GPCMUX1.bit.GPIO73=3;
EDIS;
*/
//
//
// 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 F2837xS_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 F2837xS_DefaultIsr.c.
// This function is found in F2837xS_PieVect.c.
//
InitPieVectTable();
dma_init(); // set up the dma
//
// Interrupts that are used in this example are re-mapped to
// ISR functions found within this file.
//
EALLOW; // This is needed to write to EALLOW protected registers
PieVectTable.EPWM7_INT = &epwm7_isr; // ROUTINE SET FOR THE PWM7 module.
PieVectTable.EPWM8_INT = &epwm8_isr;
PieVectTable.EPWM3_INT = &epwm3_isr;
// PieVectTable.ADCA1_INT = &adca1_isr;
PieVectTable.DMA_CH6_INT= &local_D_INTCH6_ISR; // ^^^^^^^^^^^^^^^^^^^^-------------^^^^^^^^^^^^^^^^^^^
EDIS; // This is needed to disable write to EALLOW protected registers
//
// For this example, only initialize the ePWM
//
EALLOW;
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 0;
CpuSysRegs.SECMSEL.bit.PF2SEL = 1; // DMA Dual Ported Bridge connected
EDIS;
// GPIO_WritePin(TOGGLE, 1);
ConfigureADC(); // CONFIGURE ADC,
InitEPwm7Example();
InitEPwm8Example();
InitEPwm3Example();
EALLOW;
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 0;
EDIS;
//EALLOW;
// CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1;
// EDIS;
int i;
for(i = 0; i < TRANSFER+1; i++)
{
rdata[i] = 10;
}
SetupADCEpwm(0);
//
// Step 4. User specific code, enable interrupts:
//
// Enable CPU INT3 which is connected to EPWM1-3 INT:
//
IER |= M_INT3; //---------------------> Enables EPWM1-12
//IER |= M_INT1; //Enable group 1 interrupts
IER |= M_INT7; // Enable Group 7, DMA interrupt group
//
// Enable EPWM INTn in the PIE: Group 3 interrupt 1-3
//PieCtrlRegs.PIEIER1.bit.INTx1 = 1; // ADC1
PieCtrlRegs.PIEIER3.bit.INTx8 = 1;
PieCtrlRegs.PIEIER3.bit.INTx7 = 1;
PieCtrlRegs.PIEIER3.bit.INTx3 = 1;
PieCtrlRegs.PIEIER7.bit.INTx6 = 1; // Enable PIE Group 7, INT 2 (DMA CH6)
//
// Enable global Interrupts and higher priority real-time debug events:
//
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM
EALLOW;
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1;
EDIS;
StartDMACH6();
while(1)
{
}
}
void ConfigureADC(void)
{
EALLOW;
//
//write configurations
//
AdcaRegs.ADCCTL2.bit.PRESCALE = 6; //set ADCCLK divider to /4
AdcSetMode(ADC_ADCA, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE);
//
//Set pulse positions to late
//
AdcaRegs.ADCCTL1.bit.INTPULSEPOS = 1; // Interrupt just one cycle before Result being loaded into the ADC RESULT Register
//
//power up the ADC
//
AdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1;
//
//delay for 1ms to allow ADC time to power up
//
DELAY_US(1000);
EDIS;
}
void dma_init()
{
//
// Refer to dma.c for the descriptions of the following functions.
//
//
//Initialize DMA
//
DMAInitialize();
DMASource = &AdcaResultRegs.ADCRESULT0;
DMADest = ((volatile Uint16 *)rdata);
//
// configure DMA CH6
//
DMACH6AddrConfig(DMADest,DMASource);
DMACH6BurstConfig(BURST,0,1);
DMACH6TransferConfig(TRANSFER,0,1);
DMACH6ModeConfig(DMA_ADCAINT1 ,PERINT_ENABLE,ONESHOT_DISABLE,CONT_DISABLE,
SYNC_DISABLE,SYNC_SRC,OVRFLOW_DISABLE,SIXTEEN_BIT,
CHINT_END,CHINT_ENABLE);
}
__interrupt void local_D_INTCH6_ISR(void)
{
COUNT= DmaRegs.CH6.SRC_ADDR_SHADOW ;
m= DmaRegs.CH6.DST_ADDR_SHADOW;
//x[1]= DmaRegs.CH6.DST_ADDR_SHADOW>>16;
EALLOW; // NEED TO EXECUTE EALLOW INSIDE ISR !!!
DmaRegs.CH6.CONTROL.bit.HALT = 1;
PieCtrlRegs.PIEACK.all = PIEACK_GROUP7; // ACK to receive more interrupts
// from this PIE group
EDIS;
asm(" ESTOP0");
}
ADC SOC is being triggered by EPwm7.