Hi,
My interrupt handling function randomly crash. I can't capture its crashlog as well, it always show as corrupted. My chip is ESP32
16:19:02.996 -> Guru Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled.
16:19:03.037 ->
16:19:03.037 -> Core 1 register dump:
16:19:03.037 -> PC : 0x40084934 PS : 0x00050d31 A0 : 0x80081300 A1 : 0x3ffbf31c
16:19:03.037 -> A2 : 0x00000040 A3 : 0x00018040 A4 : 0x000637ff A5 : 0x3ffbf2ec
16:19:03.037 -> A6 : 0x00000000 A7 : 0x3ffbdbd4 A8 : 0x00000001 A9 : 0x4008821a
16:19:03.037 -> A10 : 0x3ffc40ac A11 : 0x80000001 A12 : 0x00000001 A13 : 0x3ffbf2cc
16:19:03.037 -> A14 : 0x00000000 A15 : 0x00000000 SAR : 0x00000004 EXCCAUSE: 0x0000001c
16:19:03.078 -> EXCVADDR: 0x8008130c LBEG : 0x40086030 LEND : 0x4008603a LCOUNT : 0x00000000
16:19:03.078 ->
16:19:03.078 ->
16:19:03.078 -> Backtrace: 0x40084931:0x3ffbf31c |<-CORRUPTED
Here's the function which is called when interrupt occurred:
#define BUFFER_SIZE 16//16
volatile uint8_t byte_buffer[BUFFER_SIZE];
volatile byte buffer_idx = 0;
volatile byte sig_seen = 0;
volatile unsigned short shift_register = 0;
volatile byte bit_count = 0;
volatile int scount=1;
volatile bool crcpass=false;
volatile int device_id=0;
volatile int teststep=0;
volatile int collectedcount=0;
volatile bool parseDone=false;
void rfInterruptProcessor(unsigned long ctime,unsigned long ltime){
unsigned long ccount = 0;
int duration=ctime-ltime;
int newVal=0;
if(duration>=5){
ccount++;
newVal += digitalRead(RXPIN) ? 1 : 0;
if(ccount==10 || duration>50){
newVal=(newVal+ccount/2)/(ccount);
ccount=0;
}else{
ccount++;
return;
}
}else{
return;
}
now = micros();
if(transition_t <= now)
duration = now - transition_t;
else
duration = (~transition_t) + now;
if(newVal != val) { // then transitioning state
/*
* We update the transition time for the pulse, and
* change the current state of the input value.
*/
transition_t = now;
val = newVal;
//teststep=duration;
if(duration < (SHORT_PULSE - SHORT_MARGIN)
|| duration > (LONG_PULSE + LONG_MARGIN)) {
// Meaningless pulse
return;
}
/*
* If we reach here, then we have seen a potentially
* valid pulse. Shift the bit into the register.
*/
if(newVal == 1) {
// rising edge of a pulse (0 -> 1)
} else {
// falling edge of a pulse (1 -> 0)
if( duration >= (SHORT_PULSE - SHORT_MARGIN) && duration <= (SHORT_PULSE + SHORT_MARGIN) ) {
// short pulse is binary '1'
shift_register = (shift_register << 1) | 0x01;
bit_count++;
} else if(duration >= (LONG_PULSE - LONG_MARGIN) && duration <= (LONG_PULSE + LONG_MARGIN)) {
// long pulse is binary '0'
shift_register = (shift_register << 1);
bit_count++;
}
}
// Look for signature of 0xfa (4 bits 0xf0 pre-amble + 0xa)
if((shift_register & 0xff) == 0xfa && buffer_idx == 0) {
// Found signature - discard pre-amble and leave 0x0a.
shift_register = 0x0a;
bit_count = 4;
sig_seen = 1; // Flag that the signature has been seen.
} else if(bit_count == 8 && sig_seen) {
// Got a byte, so store it if we have room.
if(buffer_idx < BUFFER_SIZE)
byte_buffer[buffer_idx++] = (byte)(shift_register & 0xff);
else{
// Serial.println("Overflow on byte");
}
shift_register = 0;
bit_count = 0;
}
} else {
/*
* Have we reached timeout on duration? If so, process any
* bytes present in the buffer and then reset the state
* variables.
*/
if(duration > 5000) {
if (buffer_idx > 0) {
/*
* Dump the bytes to the Serial.
*/
/*
* If we have enough bytes, then verify the checksum.
*/
crcpass=false;
if(buffer_idx >= 10 && _crc8(byte_buffer, 9) == byte_buffer[9]) {
crcpass=true;
scount++;
}
device_id = (byte_buffer[0] << 4 & 0xf0) | (byte_buffer[1] >> 4);
int battery_low = (byte_buffer[8] >> 4) == 1;
temp_raw = ((byte_buffer[1] & 0x03) << 8) | byte_buffer[2]; // only 10 bits, discard top bits
temperature = (temp_raw - 400) * 0.1f;
humidity = byte_buffer[3];
int direction_deg = wind_dir_degr[byte_buffer[8] & 0x0f];
buffer_idx = 0;
parseDone=true;
String dataString = "";
// read three sensors and append to the string:
dataString=dataString+"Device ID="+String(device_id);
dataString += ",";
}
shift_register = 0;
bit_count = 0;
sig_seen = 0;
}
}
}
void RECEIVE_ATTR handleInterrupt2() {
static unsigned long lastTime2 = 0;
const long time = micros();
rfInterruptProcessor(time,lastTime2);
lastTime2 = time;
}
void setup() {
attachInterrupt(digitalPinToInterrupt(RXPIN), handleInterrupt2, CHANGE);
}