Other Parts Discussed in Thread: C2000WARE
Hi,
I'm trying to use the ADC module to read in an analog voltage signal from 3 analog pins (A5, C4, B4). I have used the C2000 workshop code with driverlib to configure the base ADC A, B, and C modules. However, the interrupt service routines I have written are not being executed. Could you please help me here? I'm not sure what I'm doing wrong here? The code I've for ADCinits and ISRs is as follows:
/**********************************************************************
* File: Adc.c
* Devices: TMS320F2837xD
* Author: C2000 Technical Training, Texas Instruments
**********************************************************************/
#include "SONG.h" // Main include file
/**********************************************************************
* Function: InitAdca()
*
* Description: Initializes ADC-A on the F2837xD
**********************************************************************/
void InitAdca(void)
{
//--- Reset the ADC. This is good programming practice.
SysCtl_resetPeripheral(SYSCTL_PERIPH_RES_ADCA); // Reset ADC
//--- Configure the ADC-A base registers
ADC_disableConverter(ADCA_BASE); // Power down ADC for configuration
ADC_setMode(ADCA_BASE, ADC_RESOLUTION_12BIT, ADC_MODE_SINGLE_ENDED); // 12-bit mode, single-ended
ADC_setPrescaler(ADCA_BASE, ADC_CLK_DIV_4_0); // ADC clock prescaler = CPUCLK/4
ADC_setInterruptPulseMode(ADCA_BASE, ADC_PULSE_END_OF_CONV); // INT pulse generation = end of conversion
//--- SOC0 configuration - Trigger using ePWM2-ADCSOCA; Convert channel ADCINA5; Acquisition window = 20 cycles
ADC_setupSOC(ADCA_BASE, ADC_SOC_NUMBER0, ADC_TRIGGER_EPWM2_SOCA, ADC_CH_ADCIN5, 20);
//--- No ADC interrupt triggers SOC0 (TRIGSEL determined by SOC and not ADCINT1 or ADCINT2)
ADC_setInterruptSOCTrigger(ADCA_BASE, ADC_SOC_NUMBER0, ADC_INT_SOC_TRIGGER_NONE);
ADC_setSOCPriority(ADCA_BASE, ADC_PRI_ALL_ROUND_ROBIN); // All SOCs handled in round-robin mode
//--- ADCA1 interrupt configuration
ADC_enableContinuousMode(ADCA_BASE, ADC_INT_NUMBER1); // Interrupt pulses regardless of flag state
ADC_setInterruptSource(ADCA_BASE, ADC_INT_NUMBER1, ADC_SOC_NUMBER0); // EOC0 triggers the interrupt
ADC_enableInterrupt(ADCA_BASE, ADC_INT_NUMBER1); // Enable the interrupt in the ADC
//--- Enable ADCA1 interrupt
Interrupt_register(INT_ADCA1, &adcA5ISR); // Re-map ADCA1 interrupt signal to call the ISR function
Interrupt_enable(INT_ADCA1); // Enable ADCA1 in PIE group 1 and enable INT1 in IER to enable PIE group 1
//--- Finish up
ADC_enableConverter(ADCA_BASE); // Power up the ADC
DEVICE_DELAY_US(1000); // Wait 1 ms after power-up before using the ADC
} // end InitAdca()
void InitAdcb(void)
{
//--- Reset the ADC. This is good programming practice.
SysCtl_resetPeripheral(SYSCTL_PERIPH_RES_ADCB); // Reset ADC
//--- Configure the ADC-A base registers
ADC_disableConverter(ADCB_BASE); // Power down ADC for configuration
ADC_setMode(ADCB_BASE, ADC_RESOLUTION_12BIT, ADC_MODE_SINGLE_ENDED); // 12-bit mode, single-ended
ADC_setPrescaler(ADCB_BASE, ADC_CLK_DIV_4_0); // ADC clock prescaler = CPUCLK/4
ADC_setInterruptPulseMode(ADCB_BASE, ADC_PULSE_END_OF_CONV); // INT pulse generation = end of conversion
//--- SOC0 configuration - Trigger using ePWM2-ADCSOCA; Convert channel ADCINA0; Acquisition window = 20 cycles
ADC_setupSOC(ADCB_BASE, ADC_SOC_NUMBER0, ADC_TRIGGER_EPWM2_SOCA, ADC_CH_ADCIN4, 20);
//--- No ADC interrupt triggers SOC0 (TRIGSEL determined by SOC and not ADCINT1 or ADCINT2)
ADC_setInterruptSOCTrigger(ADCB_BASE, ADC_SOC_NUMBER0, ADC_INT_SOC_TRIGGER_NONE);
ADC_setSOCPriority(ADCB_BASE, ADC_PRI_ALL_ROUND_ROBIN); // All SOCs handled in round-robin mode
//--- ADCA1 interrupt configuration
ADC_enableContinuousMode(ADCB_BASE, ADC_INT_NUMBER1); // Interrupt pulses regardless of flag state
ADC_setInterruptSource(ADCB_BASE, ADC_INT_NUMBER1, ADC_SOC_NUMBER0); // EOC0 triggers the interrupt
ADC_enableInterrupt(ADCB_BASE, ADC_INT_NUMBER1); // Enable the interrupt in the ADC
//--- Enable ADCA1 interrupt
Interrupt_register(INT_ADCB1, &adcB4ISR); // Re-map ADCB1 interrupt signal to call the ISR function
Interrupt_enable(INT_ADCB1); // Enable ADCB1 in PIE group 1 and enable INT1 in IER to enable PIE group 1
//--- Finish up
ADC_enableConverter(ADCB_BASE); // Power up the ADC
DEVICE_DELAY_US(1000); // Wait 1 ms after power-up before using the ADC
} // end InitAdcB()
void InitAdcc(void)
{
//--- Reset the ADC. This is good programming practice.
SysCtl_resetPeripheral(SYSCTL_PERIPH_RES_ADCC); // Reset ADC
//--- Configure the ADC-C base registers
ADC_disableConverter(ADCC_BASE); // Power down ADC for configuration
ADC_setMode(ADCC_BASE, ADC_RESOLUTION_12BIT, ADC_MODE_SINGLE_ENDED); // 12-bit mode, single-ended
ADC_setPrescaler(ADCB_BASE, ADC_CLK_DIV_4_0); // ADC clock prescaler = CPUCLK/4
ADC_setInterruptPulseMode(ADCC_BASE, ADC_PULSE_END_OF_CONV); // INT pulse generation = end of conversion
//--- SOC0 configuration - Trigger using ePWM2-ADCSOCA; Convert channel ADCINA0; Acquisition window = 20 cycles
ADC_setupSOC(ADCC_BASE, ADC_SOC_NUMBER0, ADC_TRIGGER_EPWM2_SOCA, ADC_CH_ADCIN4, 20);
//--- No ADC interrupt triggers SOC0 (TRIGSEL determined by SOC and not ADCINT1 or ADCINT2)
ADC_setInterruptSOCTrigger(ADCC_BASE, ADC_SOC_NUMBER0, ADC_INT_SOC_TRIGGER_NONE);
ADC_setSOCPriority(ADCC_BASE, ADC_PRI_ALL_ROUND_ROBIN); // All SOCs handled in round-robin mode
//--- ADCA1 interrupt configuration
ADC_enableContinuousMode(ADCC_BASE, ADC_INT_NUMBER1); // Interrupt pulses regardless of flag state
ADC_setInterruptSource(ADCC_BASE, ADC_INT_NUMBER1, ADC_SOC_NUMBER0); // EOC0 triggers the interrupt
ADC_enableInterrupt(ADCC_BASE, ADC_INT_NUMBER1); // Enable the interrupt in the ADC
//--- Enable ADCA1 interrupt
Interrupt_register(INT_ADCC1, &adcC4ISR); // Re-map ADCB1 interrupt signal to call the ISR function
Interrupt_enable(INT_ADCC1); // Enable ADCB1 in PIE group 1 and enable INT1 in IER to enable PIE group 1
//--- Finish up
ADC_enableConverter(ADCC_BASE); // Power up the ADC
DEVICE_DELAY_US(1000); // Wait 1 ms after power-up before using the ADC
} // end InitAdcC()
/*
* ADCA_ISR.c
*
* Created on: Apr 6, 2021
* Author: Kartavya Agarwal
*/
#include "SONG.h" //Main include file
interrupt void adcA5ISR(void) {
static uint16_t *AdcABufPtr = AdcABuf;
Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP1); // Must acknowledge the PIE group
//--- Manage the ADC interrupt flag
ADC_clearInterruptStatus(ADCA_BASE, ADC_INT_NUMBER1); // Clear ADCINT1 flag
//--- Read the ADC result
*AdcABufPtr++ = ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER0); // Read the result
//--- Brute-force the circular buffer
if(AdcABufPtr == (AdcABuf + ADC_BUF_LEN))
{
AdcABufPtr = AdcABuf; // Rewind the pointer to beginning
}
v48 = (*AdcABufPtr*3)/4096;
}
interrupt void adcB4ISR(void) {
static uint16_t *AdcBBufPtr = AdcBBuf;
Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP1); // Must acknowledge the PIE group
//--- Manage the ADC interrupt flag
ADC_clearInterruptStatus(ADCB_BASE, ADC_INT_NUMBER1); // Clear ADCINT1 flag
//--- Read the ADC result
*AdcBBufPtr++ = ADC_readResult(ADCBRESULT_BASE, ADC_SOC_NUMBER0); // Read the result
//--- Brute-force the circular buffer
if(AdcBBufPtr == (AdcBBuf + ADC_BUF_LEN))
{
AdcBBufPtr = AdcBBuf; // Rewind the pointer to beginning
}
iout = (*AdcBBufPtr * 3.0)/4096;
}
interrupt void adcC4ISR(void) {
static uint16_t *AdcCBufPtr = AdcCBuf;
Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP1); // Must acknowledge the PIE group
//--- Manage the ADC interrupt flag
ADC_clearInterruptStatus(ADCC_BASE, ADC_INT_NUMBER1); // Clear ADCINT1 flag
//--- Read the ADC result
*AdcCBufPtr++ = ADC_readResult(ADCCRESULT_BASE, ADC_SOC_NUMBER0); // Read the result
//--- Brute-force the circular buffer
if(AdcCBufPtr == (AdcCBuf + ADC_BUF_LEN))
{
AdcCBufPtr = AdcCBuf; // Rewind the pointer to beginning
}
v12 = (*AdcCBufPtr * 3.0)/4096;
}