Tool/software: TI C/C++ Compiler
Hi,
I am trying to use the DMA on my f28379D board. I try to trigger the DMA CH5 interrupt by EOC0 generated at the end of conversion. I do run ADC in continuous mode:
AdcbRegs.ADCINTSEL1N2.bit.INT1CONT = 1; //
I have a check variable in the DMA interrupt routine and I see it is being incremented, however I do not see change in the variable that DMA is supposed to write to. I am also not sure how BURST and TRANSMISSION parameters should be configured, datasheet confuses me here.
I will be very thankful for support. My code is here:
//########################################################################### // // 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" #define BURST (FIFO_LVL-1) // burst size should be less than 8 #define TRANSFER 0 // [(MEM_BUFFER_SIZE/FIFO_LVL)-1] // // Function Prototypes // void ConfigureADC(void); void ConfigureEPWM(void); void SetupADCEpwm(Uint16 channel); __interrupt void adcb1_isr(void); __interrupt void local_D_INTCH5_ISR(void); void dma_init(void); //__interrupt void local_D_INTCH6_ISR(void); // // Defines // #define RESULTS_BUFFER_SIZE 256 // // Globals // Uint16 AdcbResults[RESULTS_BUFFER_SIZE]; Uint16 resultsIndex; volatile Uint16 bufferFull; volatile Uint16 *DMADest; Uint16 rdata; // Receive data buffer Uint16 check; 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(); // // Ensure DMA is connected to Peripheral Frame 2 bridge (EALLOW protected) // EALLOW; CpuSysRegs.SECMSEL.bit.PF2SEL = 1; EDIS; // // Map ISR functions // EALLOW; // PieVectTable.ADCB1_INT = &adcb1_isr; //function for ADCB interrupt 1 PieVectTable.DMA_CH5_INT= &local_D_INTCH5_ISR; EDIS; // // Configure the ADC and power it up // ConfigureADC(); // // Configure the ePWM // ConfigureEPWM(); // // Setup the ADC for ePWM triggered conversions on channel 0 // dma_init(); // Set up DMA for SPI configuration SetupADCEpwm(5); // // Enable global Interrupts and higher priority real-time debug events: // PieCtrlRegs.PIECTRL.bit.ENPIE = 1; // Enable the PIE block PieCtrlRegs.PIEIER7.bit.INTx5 = 1; // Enable PIE Group 7, INT 1 (DMA CH1) IER |= M_INT7; // Enable CPU INT6 // IER |= M_INT1; //Enable group 1 interrupts EINT; // Enable Global interrupt INTM ERTM; // Enable Global realtime interrupt DBGM // // Initialize results buffer // for(resultsIndex = 0; resultsIndex < RESULTS_BUFFER_SIZE; resultsIndex++) { AdcbResults[resultsIndex] = 0; } resultsIndex = 0; bufferFull = 0; // // enable PIE interrupt // // PieCtrlRegs.PIEIER1.bit.INTx2 = 1; // // sync ePWM // EALLOW; CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1; //PWM synchronise EDIS; StartDMACH5(); // Start DMA for(;;) { } } // // ConfigureADC - Write ADC configurations and power up the ADC for both // ADC A and ADC B // void ConfigureADC(void) { EALLOW; // //write configurations // AdcbRegs.ADCCTL2.bit.PRESCALE = 6; //set ADCCLK divider to /4 AdcSetMode(ADC_ADCB, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE); // //Set pulse positions to late // AdcbRegs.ADCCTL1.bit.INTPULSEPOS = 1; // //power up the ADC // AdcbRegs.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; GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 0b01; GpioCtrlRegs.GPAGMUX1.bit.GPIO0 = 0b00; EDIS; EALLOW; // Assumes ePWM clock is already enabled EPwm1Regs.ETSEL.bit.SOCAEN = 1; // Disable SOC on A group EPwm1Regs.ETSEL.bit.SOCASEL = 0b001; // Select SOC on up-count EPwm1Regs.ETPS.bit.SOCAPRD = 1; // Generate pulse on 1st event EPwm1Regs.CMPA.bit.CMPA = 2500; // Set compare A value EPwm1Regs.TBPRD = 5000; // Set period EPwm1Regs.TBCTL.bit.CTRMODE = 0b10; // up-down EPwm1Regs.AQCTLA.bit.ZRO = 0b10; // EPwm1Regs.AQCTLA.bit.PRD = 0b01; // EPwm1Regs.AQCTLA.bit.CAU = 0b01; // EPwm1Regs.AQCTLA.bit.CAD = 0b10; // 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 == AdcbRegs.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; AdcbRegs.ADCSOC0CTL.bit.CHSEL = channel; //SOC0 AdcbRegs.ADCSOC0CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles AdcbRegs.ADCSOC0CTL.bit.TRIGSEL = 5; //trigger on ePWM1 SOCA/C AdcbRegs.ADCINTSEL1N2.bit.INT1SEL = 0; //end of EOC1 will set INT1 flag AdcbRegs.ADCINTSEL1N2.bit.INT1E = 1; //enable INT1 flag AdcbRegs.ADCINTSEL1N2.bit.INT1CONT = 1; // AdcbRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //make sure INT1 flag is cleared EDIS; } void dma_init() { // // Initialize DMA // DMAInitialize(); DMADest = &rdata; // DMACH5AddrConfig(DMADest,&AdcbResultRegs.ADCRESULT0); DMACH5BurstConfig(1,0,1); DMACH5TransferConfig(0,0,1); DMACH5ModeConfig(6,PERINT_ENABLE,ONESHOT_DISABLE,CONT_DISABLE, SYNC_DISABLE,SYNC_SRC,OVRFLOW_DISABLE,SIXTEEN_BIT, CHINT_END,CHINT_ENABLE); } // // local_D_INTCH5_ISR - DMA Channel 5 ISR // __interrupt void local_D_INTCH5_ISR(void) { EALLOW; // NEED TO EXECUTE EALLOW INSIDE ISR !!! DmaRegs.CH5.CONTROL.bit.TRANSFERSTS = 1; DmaRegs.CH5.CONTROL.bit.RUN = 1; PieCtrlRegs.PIEACK.all = PIEACK_GROUP7; // ACK to receive more interrupts // from this PIE group EDIS; check++; return; } // // End of file //