mrrwa / NmraDcc

NMRA Digital Command Control (DCC) Library
GNU Lesser General Public License v2.1
137 stars 53 forks source link

ESP32 version stops working when loosing interrupts or signal is bad #48

Closed Jueff closed 3 years ago

Jueff commented 3 years ago

sometimes ESP32 runs into the problem, that no DCC data are processed anymore.

I found out that in error state we have

so this code if ( bitMicros < bitMin || ( DccRx.State != WAIT_START_BIT && digitalRead( DccProcState.ExtIntPinNum ) != (ISRLevel) ) ) { will always detect a short bit, because when interrupt filter is RISING the ExtIntPinNum will never be 0. This fault situation needs a reboot.

It seems that the problems comes from this code

#ifdef ESP32
    ISRWatch = ISREdge;
#else
attachInterrupt( DccProcState.ExtIntNum, ExternalInterruptHandler, ISREdge );
// enable level checking ( with direct port reading @ AVR )
ISRChkMask = DccProcState.ExtIntMask;       
ISRLevel = (ISREdge==RISING)? DccProcState.ExtIntMask : 0 ;
#endif

because ISRChkMask and ISRLevel are not set correctly (in ESP32 case)

The fixed code could look like this - but maybe it's not the only location where levels aren't set correctly.

#ifdef ESP32
    ISRWatch = ISREdge;
#else
    attachInterrupt( DccProcState.ExtIntNum, ExternalInterruptHandler, ISREdge );
#endif
// enable level checking ( with direct port reading @ AVR )
ISRChkMask = DccProcState.ExtIntMask;       
ISRLevel = (ISREdge==RISING)? DccProcState.ExtIntMask : 0 ;
MicroBahner commented 3 years ago

Hi Jueff, You are right. The two lines of code after // enable level checking should be active for all processors. So the #endif must be shifted 3 lines up.

In all other cases where the ISR edge is changed and this two variables are set it is correct.

Regards Franz-Peter

kiwi64ajs commented 3 years ago

I've committed this change - thanks