GuzLightyear
Member
Hello.
I have a program that continuously reads the ADCs using interrupts, and upon request through can relays the data back through CANbus. I'm using collin80's flexcan lib, and pedvide's ADC library.
The problem i'm currently having is that, after receiving a CAN frame and triggering the CAN frame interrupt, the ADC interrupt stops executing, so the values don't get updated. The rest of the interrupts (timing interrupts, CAN interrupts) seem to work fine. Resetting the ADC interrupts doesn't seem to work, as it still remains stuck. When it locks, the NVIC status is as follows:
Do you have any idea on what could cause this behaviour? I have already tried reenabling the global interrupts after receiving a CAN msg, and it does nothing.
Thank you very much for your help
This is the CAN ISR
This is the ADC ISR
I also have the PDB ISR set:
And this is the code that initialises the ADCs
I have a program that continuously reads the ADCs using interrupts, and upon request through can relays the data back through CANbus. I'm using collin80's flexcan lib, and pedvide's ADC library.
The problem i'm currently having is that, after receiving a CAN frame and triggering the CAN frame interrupt, the ADC interrupt stops executing, so the values don't get updated. The rest of the interrupts (timing interrupts, CAN interrupts) seem to work fine. Resetting the ADC interrupts doesn't seem to work, as it still remains stuck. When it locks, the NVIC status is as follows:
Code:
NVIC_IS_ENABLED(IRQ_PDB) 0
NVIC_IS_ACTIVE(IRQ_PDB) 0
NVIC_IS_PENDING(IRQ_PDB) 100000000000000000000
NVIC_IS_ENABLED(IRQ_ADC0) 10000000
NVIC_IS_ACTIVE(IRQ_ADC0) 0
NVIC_IS_PENDING(IRQ_ADC0) 0
NVIC_IS_ENABLED(IRQ_ADC1) 10000000000
NVIC_IS_ACTIVE(IRQ_ADC1) 0
NVIC_IS_PENDING(IRQ_ADC1) 0
Do you have any idea on what could cause this behaviour? I have already tried reenabling the global interrupts after receiving a CAN msg, and it does nothing.
Thank you very much for your help
This is the CAN ISR
Code:
bool CAN_reader::frameHandler(CAN_message_t & frame, int mailbox, uint8_t controller) {
struct CAN_extendedID* received_id_ptr;
//memcpy(&received_id, &frame.id, sizeof(received_id));
received_id_ptr = (struct CAN_extendedID*) & frame.id;
#ifdef CAN_DEBUG
Serial.print("MSG received, mailbox: ");
Serial.println(mailbox);
Serial.println(frame.id, HEX);
Serial.print(received_id_ptr->dest_uscb_flag, HEX);
Serial.print(" ");
Serial.print(received_id_ptr->board_id, HEX);
Serial.print(" ");
Serial.print(received_id_ptr->msg, HEX);
Serial.println();
#endif
if (mailbox == 0) {
if (received_id_ptr->msg == RPI_REQUEST_START_LOGGING) {
#ifdef RX_DEBUG
Serial.println("Starting logging");
#endif
uscb_ptr->createLogFile();
uscb_ptr->logging = true;
}
else if (received_id_ptr->msg == RPI_REQUEST_CONFIG) {
#ifdef RX_DEBUG
Serial.println("Sending Config");
#endif
uscb_ptr->sendConfigToCAN();
}
else if (received_id_ptr->msg == RPI_REQUEST_LOGGING_STATUS) {
#ifdef RX_DEBUG
Serial.println("Sending Log Status");
#endif
uscb_ptr->sendLoggingStatus();
}
}
else if (mailbox == 1) {
if (received_id_ptr->msg == CANmsg_id_timeset) {
time_set = true;
time_t teensy_time;
memcpy(&teensy_time, &frame.buf, sizeof(time_t));
setTime(teensy_time);
#ifdef RX_DEBUG
Serial.print("Time syncronised. New time: ");
Serial.println(teensy_time);
#endif
}
}
}
This is the ADC ISR
Code:
void adc0_isr() {
static int k = 0;
k++;
if (k % 1000 == 0) {
Serial.println("ADC0_ISR");
}
ADC0_measurements[current_ADC0_index] = adc->adc0->readSingle();
current_ADC0_index++;
if (current_ADC0_index > 11) {
current_ADC0_index = 0;
}
adc->adc0->startSingleRead(ADC0_pins[current_ADC0_index]);
}
I also have the PDB ISR set:
Code:
void pdb_isr(void) {
PDB0_SC &= ~PDB_SC_PDBIF; // clear interrupt
}
And this is the code that initialises the ADCs
Code:
void USCB::initADCs() {
adc->adc0->disableInterrupts();
adc->adc1->disableInterrupts();
adc->setReference(ADC_REFERENCE::REF_3V3, ADC_0);
adc->setReference(ADC_REFERENCE::REF_3V3, ADC_1);
adc->adc0->setResolution(ADC_RESOLUTION);
adc->adc1->setResolution(ADC_RESOLUTION);
adc->setAveraging(ADC_AVERAGING, ADC_0);
adc->setAveraging(ADC_AVERAGING, ADC_1);
#ifndef HIGH_SPEED_BOARD
adc->setConversionSpeed(ADC_CONVERSION_SPEED::HIGH_SPEED_16BITS, ADC_0);
adc->setSamplingSpeed(ADC_SAMPLING_SPEED::LOW_SPEED, ADC_0);
adc->setConversionSpeed(ADC_CONVERSION_SPEED::HIGH_SPEED_16BITS, ADC_1);
adc->setSamplingSpeed(ADC_SAMPLING_SPEED::LOW_SPEED, ADC_1);
#else // !HIGH_SPEED_BOARD
adc->setConversionSpeed(ADC_CONVERSION_SPEED::HIGH_SPEED_16BITS, ADC_0);
adc->setSamplingSpeed(ADC_SAMPLING_SPEED::HIGH_SPEED, ADC_0);
adc->setConversionSpeed(ADC_CONVERSION_SPEED::HIGH_SPEED_16BITS, ADC_1);
adc->setSamplingSpeed(ADC_SAMPLING_SPEED::HIGH_SPEED, ADC_1);
#endif
adc->adc0->stopPDB();
adc->adc0->startSingleRead(A0); // call this to setup everything before the pdb starts, differential is also possible
adc->enableInterrupts(ADC_0);
adc->adc0->startPDB(MAX_SAMPLING_FREQ*MAX_PINS_PER_ADC); //frequency in Hz
adc->adc1->stopPDB();
adc->adc1->startSingleRead(A2); // call this to setup everything before the pdb starts
adc->enableInterrupts(ADC_1);
adc->adc1->startPDB(MAX_SAMPLING_FREQ * MAX_PINS_PER_ADC); //frequency in Hz
// enable PDB
interrupts();
}