pierremolinaro / acan2515

MCP2515 CAN Controller Driver for Arduino
MIT License
74 stars 29 forks source link

Error and Wake-up interrupt handling #7

Closed framet closed 5 years ago

framet commented 5 years ago

Using this with MKR Zero and MKR Can Shield. My program freezes randomly without crashing. I've tested on SRAM overflow, memory corruption etc and everything should work fine.

I'm currently suspecting it has todo with the ACAN2515::isr_core routine MCP2515 Datasheet says that one have to set every intflag to zero with BIT_MODIFY command. But in the isr_core routine if an Error Interrupt or Wake-Up Interrupt flag is set. It will never bet unset so the while loop will never exit.

I've probably missed something on why you do that. But can you explain me on how the while loop in ACAN2515::isr_core will exit when Error or Wakeup Intflag is set?

pierremolinaro commented 5 years ago

Hello,

I can't reproduce the bug with my hardware. Have you checked interrupt pin number, quartz frequency?

"Error Interrupt" and "Wake-up interrupt" are not handled in the isr_core function, but they are not activated: the bits 5 and 6 of the CANINTE register are not set (lines 350 to 359 of ACAN2515.cpp: //--- Register CANINTE: activate interrupts // Bit 7 --> 0: MERRE // Bit 6 --> 0: WAKIE // Bit 5 --> 0: ERRIE // Bit 4 --> 1: TX2IE // Bit 3 --> 1: TX1IE // Bit 2 --> 1: TX0IE // Bit 1 --> 1: RX1IE // Bit 0 --> 1: RX0IE mSPI.transfer (0x1F) ;

But I agree, it would be cleaner to acknowledge these interruptions. I suggest the following modified isr_core function: bool ACAN2515::isr_core (void) { bool handled = false ; mSPI.beginTransaction (mSPISettings) ; uint8_t itStatus = read2515Register (CANSTAT_REGISTER) & 0x0E ; while (itStatus != 0) { handled = true ; switch (itStatus) { case 0 : // No interrupt break ; case 1 << 1 : // Error interrupt bitModify2515Register (CANINTF_REGISTER, 0x20, 0) ; // Ack interrupt break ; case 2 << 1 : // Wake-up interrupt bitModify2515Register (CANINTF_REGISTER, 0x40, 0) ; // Ack interrupt break ; case 3 << 1 : // TXB0 interrupt handleTXBInterrupt (0) ; break ; case 4 << 1 : // TXB1 interrupt handleTXBInterrupt (1) ; break ; case 5 << 1 : // TXB2 interrupt handleTXBInterrupt (2) ; break ; case 6 << 1 : // RXB0 interrupt case 7 << 1 : // RXB1 interrupt handleRXBInterrupt () ; break ; } itStatus = read2515Register (CANSTAT_REGISTER) & 0x0E ; } mSPI.endTransaction () ; return handled ; }

Pierre

Le 22 févr. 2019 à 11:45, framet notifications@github.com a écrit :

Using this with MKR Zero and MKR Can Shield. My program freezes randomly without crashing. I've tested on SRAM overflow, memory corruption etc and everything should work fine.

I'm currently suspecting it has todo with the ACAN2515::isr_core routine MCP2515 Datasheet says that one have to set every intflag to zero with BIT_MODIFY command. But in the isr_core routine if an Error Interrupt or Wake-Up Interrupt flag is set. It will never bet unset so the while loop will never exit.

I've probably missed something on why you do that. But can you explain me on how the while loop in ACAN2515::isr_core will exit when Error or Wakeup Intflag is set?

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/pierremolinaro/acan2515/issues/7, or mute the thread https://github.com/notifications/unsubscribe-auth/ASys1FrMTv_jfi7YpuO5SPw_LIEpn7r5ks5vP8o5gaJpZM4bJVjN.

framet commented 5 years ago

Thank you very much!