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.

Timer controlling ADC



Using:

Tiva 129XNCZAD

TivaWare_C_Series-2.1.2.111

CCS Version: 6.1.3.00033

I am trying to use a timer to trigger an ADC sequence every 128uSec.  Then the ISR for the ADC sequence will read the ADC keeping track of minimum and maximum values detected.

I am iteratively setting up the ADC to monitor one of three different inputs connected to current monitoring hardware on a solenoid driver.

Below is the code that I am currently using with much of the functionality unrelated to the question at hand removed.  This is running under TIRTOS so I am setting up the ISR for the Timer using Hwi_Create.

The function 'Calibrate' is what kicks everything off.

The issue is that if I set a breakpoint in the ADC sequence complete ISR, it never hits it.  So something in the configuration is wrong.

Any help finding the error would be greatly appreciated.

#define CAL_TRIES               3

#define ADC_SEQ_3               3               // Seq 3 used for calibration since FIFO depth is just one so don't have to worry about previous data in FIFO
#define ADC_PRIORITY_HIGHEST    0
#define ADC1_SEQ_3_ISR_VEC      65              // ISR vector number for ADC1 Sequence 3
 
// Solenoids that have their activation waveform monitored
enum ActivationIndex
{
  AI_Kicker,
  AI_Flapper,
  AI_InputGate,
 
  AI_Max
};
 
static struct ActivationMonitorConfig
{
  const char *Name;                 ///< Name of solenoid
  const int duration;               ///< How long to activate solenoid during calibration
  const int minDelta;               ///< Minimum separation between top and bottom of curve
  const short minOffset;            ///< Amount to add to minimum current detected to create minimum threshold
  const short maxOffset;            ///< Amount to subtract from maximum current detected to create maximum threshold
  const int AdcComp;                ///< Mask for comparator configuration in ADC sequence step
  const int AdcSeqPin;              ///< Mask for ADC pin configuration in ADC sequence step
} const ActMonConfig[] =
    {//     Name        Kick Duration    minDelta  minOff  maxOff    Comparator       ADC Pin
        { "Kicker",     100,             100,    100,    100,    ADC_CTL_CMP0,   ADC_CTL_CH17 },
        { "Flapper",    500,             100,    100,    100,    ADC_CTL_CMP1,   ADC_CTL_CH16 },
        { "InputGate",  500,             100,    100,    100,    ADC_CTL_CMP2,   ADC_CTL_CH18 },
    };
 
static int minReading = 0, maxReading = 0;
 
 
 /// Routine to figure out what values should be used to configure the ADCs for solenoid activation monitoring
  static bool Calibrate(CmdLine *cmd)
    {
    bool calError = false;
    ActivationMonitorConfig const *pActMonConfig;
    int attempt, solenoid, minTotal[AI_Max] = {0}, maxTotal[AI_Max] = {0};
    static Hwi_Handle hwi_handle = Hwi_create(ADC1_SEQ_3_ISR_VEC, SolenoidActivationMonitorCalibrationISR, NULL, NULL);
 
    if (TransportElement::CurrentTransportState() == TS_Idle)
      {
                // Configure timer to start ADC conversions every 128uSec
      TimerConfigure(TIMER3_BASE, TIMER_CFG_PERIODIC);
      TimerLoadSet(TIMER3_BASE, TIMER_BOTH, 128 * 120);                   // CPU clock runs at 120MHz
      TimerADCEventSet(TIMER3_BASE, TIMER_ADC_TIMEOUT_A);
      TimerClockSourceSet(TIMER3_BASE, TIMER_CLOCK_SYSTEM);
 
      for (attempt = 0; attempt < CAL_TRIES; attempt++)
        for (solenoid = 0, pActMonConfig = ActMonConfig; solenoid < AI_Max; solenoid++, pActMonConfig++)
          {
          maxReading = 0;
          minReading = 0x1000;
 
                  // Configure ADC sequence to monitor one solenoid at a time
          ADCSequenceConfigure(ADC1_BASE, ADC_SEQ_3, ADC_TRIGGER_TIMER, ADC_PRIORITY_HIGHEST);
          ADCSequenceStepConfigure(ADC1_BASE, ADC_SEQ_3, 0, pActMonConfig->AdcSeqPin | ADC_CTL_IE | ADC_CTL_END);
 
          ADCIntClear(ADC1_BASE, ADC_SEQ_3);                              // Make sure nothing pending from before
          ADCIntEnable(ADC1_BASE, ADC_SEQ_3);
          ADCSequenceEnable(ADC1_BASE, ADC_SEQ_3);
          TimerEnable(TIMER3_BASE, TIMER_BOTH);
 
                // Fire solenoid for time indicated in table
          Solenoid::ActivationSolo[solenoid]->SetDrive(true);
          Task_sleep(pActMonConfig->duration);                          // ISR will monitor min/max current during this time
         
          ADCIntDisable(ADC1_BASE, ADC_SEQ_3);                          // Disable monitoring prior to shutting off solenoid drive
          TimerDisable(TIMER3_BASE, TIMER_BOTH);
          ADCSequenceDisable(ADC1_BASE, ADC_SEQ_3);
          Solenoid::ActivationSolo[solenoid]->SetDrive(false);
 
                // Add current readings to total for later averaging
          minTotal[solenoid] += minReading;
          maxTotal[solenoid] += maxReading;
 
 
                // Check for errors
          Sleep(300);        // Pause a little between activations
          }
      }
 
    return false;
    }
 
/// ISR to find points of interest along solenoid activation waveform during calibration
extern "C" void SolenoidActivationMonitorCalibrationISR(unsigned int ignored)
  {
  uint32_t reading;
 
  ADCIntClear(ADC1_BASE, ADC_SEQ_3);
  ADCSequenceDataGet(ADC1_BASE, ADC_SEQ_3, &reading);
 
  if (reading > maxReading)
    maxReading = reading;
 
  if (reading < maxReading - 100 && reading < minReading)
    minReading = reading;
  }