TinyT TinyT - 1 month ago 15
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:

# define NUMBER_OF_CHANNELS 4

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) {
--start_ctd[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])
++adc_busy;
// 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
rem_runs
there, everything works fine.


I've tried different data types, setting the
adc_busy
before the loop (and unsetting it if I happen to start anything), but nothing worked. Strangely enough, setting
rem_runs
has no influence. In the first run, there is always only one channel triggering, and I don't get into
timerISR
before I would expect any results (
timerISR
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
timerISR
again, so the code does not seem to hang in an infloop blocking
ADC_ISR
from triggering.

I've tried to use other storage classes for
rem_runs
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,
MAP_RTC_whatsitsface
routines didn't modify the registers we could be checking any more, and we had to resort to using
RTC_whatsitsface
routines from code instead. At first we thought it might be that we were mixing them, but even if using
MAP_RTC_
... all the way, our clock timers didn't trigger
.

MAP_RTC_function
defines point to
ROM_RTC_function
according to driverlib's
rom_map.h
. They are defined to memory addresses in
rom.h
(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

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