//########################################################################### // // FILE: adc_soc_epwm_cpu01.c // // TITLE: ADC triggering via epwm for F2837xD. // //! \addtogroup cpu01_example_list //!

ADC ePWM Triggering (adc_soc_epwm)

//! //! 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" #include "stdio.h" #include "math.h" #include #include #include // // Function Prototypes // void ConfigureADC(void); void ConfigureEPWM(void); void SetupADCEpwm(Uint16 channel); interrupt void adca1_isr(void); void scia_echoback_init(void); void scia_fifo_init(void); void scia_xmit(int a); void scia_msg(char *msg); void send_result(Uint16 res); // // Defines // #define RESULTS_BUFFER_SIZE 64 // the buffer size was 256 FILE *myFile; //#define ADC_SAMPLE_PERIOD 0x1000 // 1999 = 50 kHz sampling w/ 100 MHz ePWM clock // // Globals // Uint16 AdcaResults[RESULTS_BUFFER_SIZE]; Uint16 AdcaResults1[RESULTS_BUFFER_SIZE]; //float32 AdcaResults1[RESULTS_BUFFER_SIZE]; Uint16 resultsIndex; Uint16 resultsIndex1; //Uint16 LoopCount; // from sci example volatile Uint16 bufferFull; volatile Uint16 bufferFull1; Uint16 Vin; int z; char *msg; 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 EDIS; // // Configure the ADC and power it up // ConfigureADC(); // // Configure the ePWM // // ConfigureEPWM(); // // Setup the ADC for ePWM triggered conversions on channel 0 // SetupADCEpwm(0); // // Enable global Interrupts and higher priority real-time debug events: // 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++) { AdcaResults[resultsIndex] = 0; // AdcbResults[resultsIndex] = 0; // AdcdResults[resultsIndex] = 0; } resultsIndex = 0; bufferFull = 0; for(resultsIndex1 = 0; resultsIndex1 < RESULTS_BUFFER_SIZE; resultsIndex1++) { AdcaResults1[resultsIndex1] = 0; // AdcbResults[resultsIndex] = 0; // AdcdResults[resultsIndex] = 0; } resultsIndex1 = 0; bufferFull1 = 0; // // enable PIE interrupt // PieCtrlRegs.PIEIER1.bit.INTx1 = 1; // // For this example, only init the pins for the SCI-A port. // GPIO_SetupPinMux() - Sets the GPxMUX1/2 and GPyMUX1/2 register bits // GPIO_SetupPinOptions() - Sets the direction and configuration of the GPIOS // These functions are found in the F2837xD_Gpio.c file. // GPIO_SetupPinMux(28, GPIO_MUX_CPU1, 1); GPIO_SetupPinOptions(28, GPIO_INPUT, GPIO_PUSHPULL); GPIO_SetupPinMux(29, GPIO_MUX_CPU1, 1); GPIO_SetupPinOptions(29, GPIO_OUTPUT, GPIO_ASYNC); scia_fifo_init(); // Initialize the SCI FIFO scia_echoback_init(); // Initialize SCI for echoback //msg = "\r\n\n\nHello World!\n\0"; msg = "\r\n\nStart of Conversion: \n\n"; scia_msg(msg); // msg = "\r\nYou will enter a character, and the DSP will echo it back! \n\0"; // scia_msg(msg); // // sync ePWM // EALLOW; CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1; // // //take conversions indefinitely in loop, this loop is used with the pwm trigger // do { // //start ePWM // EPwm1Regs.ETSEL.bit.SOCAEN = 1; //enable SOCA EPwm1Regs.TBCTL.bit.CTRMODE = 0; //unfreeze, and enter up count mode // AdcaRegs.ADCSOCFRC1.all = 0x0001; // //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 while(!bufferFull1); bufferFull1 = 0; //clear the buffer full flag // //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 // msg = "\r\n\n\nConversion finished!\n\n"; scia_msg(msg); // //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 was 6 AdcSetMode(ADC_ADCA, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE); // //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 = 0x0800; // Set compare A value to 2048 counts, it was 0x0800 EPwm1Regs.TBPRD = 0x1000; // Set period to 4096 counts, it was 0x1000 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 A0 AdcaRegs.ADCSOC0CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles AdcaRegs.ADCSOC0CTL.bit.TRIGSEL = 1; //trigger on ePWM1 SOCA/C = 5, OR = 1 for cpu.timer0 trigger 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 AdcaRegs.ADCSOC1CTL.bit.CHSEL = 1; //SOC1 will convert pin A1 AdcaRegs.ADCSOC1CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles AdcaRegs.ADCSOC1CTL.bit.TRIGSEL = 1; //trigger on ePWM1 SOCA/C = 5, OR = 1 for cpu.timer0 trigger 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; if(RESULTS_BUFFER_SIZE == resultsIndex) { for (z=0;z