This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Hi,
I have changed the adc trigger in the example " adc_soc_epwm_cpu01.c" from the epwm1 to the software. when I debug and run the project the project stay in the conversion loop specifically in the (while(!bufferFull);) and I don't get anything in the result buffer.
the project work fine with epwm trigger. the full code is given below. The system Clock is 100 MHz and The ADCCLK is 25 MHz.
What else should I change in the conversion loop so it work correctly?
Regards
Hayder
//
// Included Files
//
#include "F28x_Project.h"
#include "stdio.h"
#include "math.h"
//
// Function Prototypes
//
void ConfigureADC(void);
void ConfigureEPWM(void);
void SetupADCEpwm(Uint16 channel);
interrupt void adca1_isr(void);
//interrupt void adcb1_isr(void);
//interrupt void adcd1_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
//#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 AdcbResults[RESULTS_BUFFER_SIZE];
//Uint16 AdcdResults[RESULTS_BUFFER_SIZE];
Uint16 resultsIndex;
Uint16 resultsIndex1;
volatile Uint16 bufferFull;
volatile Uint16 bufferFull1;
Uint16 Vin;
char sprintf_msg[5];
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
// PieVectTable.ADCB1_INT = &adcb1_isr; //function for ADCB interrupt 1
// PieVectTable.ADCD1_INT = &adcd1_isr; //function for ADCD 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;
// sprintf(sprintf_msg,"%d",AdcaResults[resultsIndex]);
// scia_msg(sprintf_msg);
}
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;
// PieCtrlRegs.PIEIER1.bit.INTx2 = 1;
// PieCtrlRegs.PIEIER1.bit.INTx6 = 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\nStart of Conversion!\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
//
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
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");
//InitSci(AdcaResults);
}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_12BIT, ADC_SIGNALMODE_SINGLE);
/*
AdcbRegs.ADCCTL2.bit.PRESCALE = 6; //set ADCCLK divider to /4
AdcSetMode(ADC_ADCB, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE);
AdcdRegs.ADCCTL2.bit.PRESCALE = 6; //set ADCCLK divider to /4
AdcSetMode(ADC_ADCD, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE);*/
//
//Set pulse positions to late
//
AdcaRegs.ADCCTL1.bit.INTPULSEPOS = 1;
// AdcbRegs.ADCCTL1.bit.INTPULSEPOS = 1;
// AdcdRegs.ADCCTL1.bit.INTPULSEPOS = 1;
//
//power up the ADC
//
AdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1;
// AdcbRegs.ADCCTL1.bit.ADCPWDNZ = 1;
// AdcdRegs.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 = 0; //trigger on ePWM1 SOCA/C = 5
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 = 0; //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;
//for (z=0;z<RESULTS_BUFFER_SIZE;z++)
if(RESULTS_BUFFER_SIZE == resultsIndex){
for (z=0;z<RESULTS_BUFFER_SIZE;z++)
{
Vin = AdcaResults[z];
send_result(Vin);
}
}
if(RESULTS_BUFFER_SIZE <= resultsIndex)
{
resultsIndex = 0;
bufferFull = 1;
// InitSci(AdcaResults);
}
//sprintf(sprintf_msg,"%d",AdcaResults);
// msg = "\r\n\n\nHello Hayder!\n\0";
//scia_msg(sprintf_msg);
// AdcaResults1[resultsIndex1++] = (float32) AdcaResultRegs.ADCRESULT1 * (float32)(3/3096);
AdcaResults1[resultsIndex1++] = AdcaResultRegs.ADCRESULT1;
if(RESULTS_BUFFER_SIZE <= resultsIndex1)
{
resultsIndex1 = 0;
bufferFull1 = 1;
}
AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //clear INT1 flag
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}
//
// scia_echoback_init - Test 1,SCIA DLB, 8-bit word, baud rate 0x000F,
// default, 1 STOP bit, no parity
//
void scia_echoback_init()
{
//
// Note: Clocks were turned on to the SCIA peripheral
// in the InitSysCtrl() function
//
SciaRegs.SCICCR.all = 0x0007; // 1 stop bit, No loopback
// No parity,8 char bits,
// async mode, idle-line protocol
SciaRegs.SCICTL1.all = 0x0003; // enable TX, RX, internal SCICLK,
// Disable RX ERR, SLEEP, TXWAKE
SciaRegs.SCICTL2.all = 0x0003;
SciaRegs.SCICTL2.bit.TXINTENA = 1;
SciaRegs.SCICTL2.bit.RXBKINTENA = 1;
//
// SCIA at 9600 baud
// @LSPCLK = 50 MHz (200 MHz SYSCLK) HBAUD = 0x02 and LBAUD = 0x8B.
// @LSPCLK = 30 MHz (120 MHz SYSCLK) HBAUD = 0x01 and LBAUD = 0x86.
//
SciaRegs.SCIHBAUD.all = 0x0002; // was 0x0002
SciaRegs.SCILBAUD.all = 0x008A; // was 0x008B
SciaRegs.SCICTL1.all = 0x0023; // Relinquish SCI from Reset
}
//
// scia_xmit - Transmit a character from the SCI
//
void scia_xmit(int a)
{
while (SciaRegs.SCIFFTX.bit.TXFFST != 0) {}
SciaRegs.SCITXBUF.all =a;
}
//
// scia_msg - Transmit message via SCIA
//
void scia_msg(char * msg)
{
int i;
i = 0;
while(msg[i] != '\0')
{
scia_xmit(msg[i]);
i++;
}
}
// scia_fifo_init - Initialize the SCI FIFO
//
void scia_fifo_init()
{
SciaRegs.SCIFFTX.all = 0xE040;
SciaRegs.SCIFFRX.all = 0x2044;
SciaRegs.SCIFFCT.all = 0x0;
}
void send_result(Uint16 res)
{
int b3,b2,b1,b0;
b3 = (res/1000)+48;
b2 = ((res%1000)/100)+48;
b1 = ((res%100)/10)+48;
b0 = (res%10)+48;
scia_xmit(b3);
scia_xmit(b2);
scia_xmit(b1);
scia_xmit(b0);
msg = ", ";
scia_msg (msg);
/*
float32 print_value;
int d1, d2;
print_value= (3*Vin)/4096;
d1 = print_value;
print_value=print_value-d1;
d2 = trunc(print_value*1000); //print_value*10^(no. of decimal place)
sprintf(sprintf_msg,"%d.%d",d1,d2);
scia_msg(sprintf_msg);
// msg = "V\r\n"; //this is to add the Unit "V" to the value as well as adding new line
msg = "V, "; //this is to add the Unit "V" to the value as well as adding new line
scia_msg (msg);
*/
return;
}
//
// End of file
//
Hi Devin,
Thanks for replying. I used your recommended example as a reference to do some changes to the project posted. I amended the conversion loop as following and the rest of the code posted above is the same:
/*******************************************************************************************************************************
do
{
//
//start ePWM
//
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(RESULTS_BUFFER_SIZE < resultsIndex){
AdcaResults[resultsIndex++]=AdcaResultRegs.ADCRESULT0;
}
//
//stop ePWM
//
// AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;
//
//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);
}
When I debug and run the project, the adc work but not LIKE the epwm was the trigger. With the epwm as the trigger, when I run the project the code run continuously till the adcaResults buffer array get fill, while with above changes, when I run the project the buffer receive the first sample and the run halt, so I need to run it 64 time to fill the buffer of size 64. The second problem is the conversion result is incorrect or my be because each time I run the project I receive a different value from the external signal generator I use.
I really appreciate any advise to solve this issue.
regards
Hayder