TinyT TinyT - 1 year ago 84
C Question

driverlib ADC trigger does not get invoked

The description is lengthy, sorry for that. I highlighted the problems in bold type.

I am currently trying to set up a driverlib mechanism that does the following:

  • on roughly every 20th RTC prescaler 1 event, check if an ADC measurement should take place.

  • if it should, set the number of measurements to perform.

  • then start the actual measurement.

  • on measurement callback, decrement the measurement counter. if not zero, run another.

That I'm doing for all four channels. The code looks about like this (can't post the original here):

file adccapture.c:


uint8_t start_each[NUMBER_OF_CHANNELS];
uint8_t start_ctd[NUMBER_OF_CHANNELS];
uint8_t run_for[NUMBER_OF_CHANNELS];
uint8_t rem_runs[NUMBER_OF_CHANNELS];

// some code setting run_for and start_each

void timerISR() {
// this checker is invoked every odd time
// by the actual prescaler event handler
for (int i=0; i<NUMBER_OF_CHANNELS; ++i) {
if (!start_ctd[i]) {
// start ADC
uint8_t adc_busy = 0;
for (int j=0; j < NUMBER_OF_CHANNELS; ++j) {
// start critical section
if (rem_runs[i])
// end critical section
rem_runs[i] += run_for[i];
if (!adc_busy) {
// start ADC
start_ctd[i] = start_each[i];

void ADCISR() {
// this method is registered in the startup_diddly.c file
// for ADC_ISR and the port that provides data to the ADC.

The error I encounter is: If I leave the critical section in the code, the ISR never triggers. If I don't, or if I use something independent from
there, everything works fine.

I've tried different data types, setting the
before the loop (and unsetting it if I happen to start anything), but nothing worked. Strangely enough, setting
has no influence. In the first run, there is always only one channel triggering, and I don't get into
before I would expect any results (
triggers only three or four times a second, while measurements are limited by datasheet to take something in microsecond range to complete).

The ADC registers have been checked, too. When the functioning code starts the measurement, all ten or twelve of them (plus MCTL/MEM arrays) have the same values they have when the malfunctioning code has run. Which fits with the code working in general.

I do run into
again, so the code does not seem to hang in an infloop blocking
from triggering.

I've tried to use other storage classes for
without success, too. Semaphores won't work because they're disabled during ISR. Attempts to obtain a semaphore in another task results in a reproducible crash reset.

Another observation was that at some point,
routines didn't modify the registers we could be checking any more, and we had to resort to using
routines from code instead. At first we thought it might be that we were mixing them, but even if using
... all the way, our clock timers didn't trigger

defines point to
according to driverlib's
. They are defined to memory addresses in
(surprise!). We don't have any changes to driverlib in our records, but at some point they stopped working.

Can the two issues be related? They both seem like memory shenanigans. Any ideas on how to diagnose that stuff further are highly appreciated.

Answer Source

The problem was solved by typing the (non-functional) patch again. Seems there was some sort of macro-breaking marauding space error going on.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download