I've written a user library for the Pi Pico that uses the TaskScheduler library to abstract timing away from the user. The user provides a function in their sketch which the library calls periodically via function pointer passed in the constructor.
When I stick to standard Arduino or functions from my library, everything works fine. If I include a function from the ADC library I'm using, core1 hangs while the comms on core0 continue to respond. If I run the same ADC operation from a non-callback function on the same core it works as expected. What is happening?
The relevant code snippets follow:
Library:
class Card {
public:
typedef void (*ExtCbPtr)(); //pointer type to call sketch code from library
ExtCbPtr _readCB; //function pointer, points at user routine in sketch
ExtCbPtr _writeCB;
Card(ExtCbPtr readFunc, ExtCbPtr writeFunc); //constructor
private:
Task readInputs;
Task writeOutputs;
Scheduler ts1;
};
Card::Card(ExtCbPtr readFunc, ExtCbPtr writeFunc) {
this->_readCB = readFunc; //use to call user's sketch code
this->_writeCB = writeFunc;
}
void Card::begin() {
//init scheduler tasks
ts1.init();
ts1.addTask(readInputs);
ts1.addTask(writeOutputs);
readInputs.setInterval(100);
readInputs.setIterations(10);
readInputs.setCallback(_readCB);
writeOutputs.setInterval(100);
writeOutputs.setIterations(10);
writeOutputs.setCallback(_writeCB);
}
void Card::core1Loop() {
ts1.execute();
}
Sketch:
static void writeOut();
static void readIn();
Card card(readIn, writeOut);
Adafruit_ADS1115 ads; //ADC
void setup(){
rp2040.idleOtherCore();
//setup ADC
if (!ads.begin()) {
Serial.println("Failed to initialize ADS.");
}
ads.setDataRate(0x00E0); //860 samples per second, every conversion takes ~1.2mS
ads.setGain(GAIN_ONE); //0.125mV/LSB
card.begin(); //initialise
rp2040.resumeOtherCore();
Serial.println("Ready 0");
}
void setup1(){
delay(1);
Serial.println("Ready 1");
}
void loop1();
card.core1Loop();
}
void readIn() {
Serial.println("Read start");
uint16_t adc = ads.readADC_SingleEnded(0); //problematic line
Serial.println("Read end");
}
void writeOut(){
//Doesn't matter, task not reached if read fails
}