Added IRAM_ATTR changes for the ESP32 from Hans Tanner

bumped version to 2.0.1
This commit is contained in:
Alex Shepherd
2019-02-16 22:09:19 +13:00
parent ff3e24dff4
commit 865d919802
2 changed files with 69 additions and 26 deletions

View File

@@ -244,8 +244,10 @@ struct countOf_t countOf;
#if defined ( __STM32F1__ ) #if defined ( __STM32F1__ )
static ExtIntTriggerMode ISREdge; static ExtIntTriggerMode ISREdge;
static ExtIntTriggerMode ISRWatch;
#else #else
static byte ISREdge; // RISING or FALLING static byte ISREdge; // Holder of the Next Edge we're looking for: RISING or FALLING
static byte ISRWatch; // Interrupt Handler Edge Filter
#endif #endif
static word bitMax, bitMin; static word bitMax, bitMin;
@@ -301,8 +303,35 @@ DCC_PROCESSOR_STATE ;
DCC_PROCESSOR_STATE DccProcState ; DCC_PROCESSOR_STATE DccProcState ;
#ifdef ESP32
portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED;
void IRAM_ATTR ExternalInterruptHandler(void)
#else
void ExternalInterruptHandler(void) void ExternalInterruptHandler(void)
#endif
{ {
// switch (ISRWatch)
// {
// case RISING: if (digitalRead(DccProcState.ExtIntPinNum)) break;
// case FALLING: if (digitalRead(DccProcState.ExtIntPinNum)) return; break;
// }
// First compare the edge we're looking for to the pin state
switch (ISRWatch)
{
case CHANGE:
break;
case RISING:
if (digitalRead(DccProcState.ExtIntPinNum) != HIGH)
return;
break;
case FALLING:
if (digitalRead(DccProcState.ExtIntPinNum) != LOW)
return;
break;
}
// Bit evaluation without Timer 0 ------------------------------ // Bit evaluation without Timer 0 ------------------------------
uint8_t DccBitVal; uint8_t DccBitVal;
static int8_t bit1, bit2 ; static int8_t bit1, bit2 ;
@@ -350,11 +379,9 @@ void ExternalInterruptHandler(void)
DccRx.State = WAIT_START_BIT ; DccRx.State = WAIT_START_BIT ;
// While waiting for the start bit, detect halfbit lengths. We will detect the correct // While waiting for the start bit, detect halfbit lengths. We will detect the correct
// sync and detect whether we see a false (e.g. motorola) protocol // sync and detect whether we see a false (e.g. motorola) protocol
#if defined ( __STM32F1__ )
detachInterrupt( DccProcState.ExtIntNum );
#endif
attachInterrupt( DccProcState.ExtIntNum, ExternalInterruptHandler, CHANGE);
halfBit = 0; halfBit = 0;
ISRWatch = CHANGE;
bitMax = MAX_ONEBITHALF; bitMax = MAX_ONEBITHALF;
bitMin = MIN_ONEBITHALF; bitMin = MIN_ONEBITHALF;
CLR_TP1; CLR_TP1;
@@ -397,10 +424,9 @@ void ExternalInterruptHandler(void)
bitMin = MIN_ONEBITFULL; bitMin = MIN_ONEBITFULL;
DccRx.BitCount = 0; DccRx.BitCount = 0;
SET_TP4; SET_TP4;
#if defined ( __STM32F1__ )
detachInterrupt( DccProcState.ExtIntNum ); ISRWatch = ISREdge;
#endif
attachInterrupt( DccProcState.ExtIntNum, ExternalInterruptHandler, ISREdge );
SET_TP3; SET_TP3;
CLR_TP4; CLR_TP4;
} }
@@ -436,10 +462,9 @@ void ExternalInterruptHandler(void)
DccRx.TempByte = 0 ; DccRx.TempByte = 0 ;
} }
SET_TP4; SET_TP4;
#if defined ( __STM32F1__ )
detachInterrupt( DccProcState.ExtIntNum ); ISRWatch = ISREdge;
#endif
attachInterrupt( DccProcState.ExtIntNum, ExternalInterruptHandler, ISREdge );
CLR_TP1; CLR_TP1;
CLR_TP4; CLR_TP4;
break; break;
@@ -468,10 +493,9 @@ void ExternalInterruptHandler(void)
CLR_TP1; CLR_TP1;
SET_TP4; SET_TP4;
#if defined ( __STM32F1__ )
detachInterrupt( DccProcState.ExtIntNum ); ISRWatch = ISREdge;
#endif
attachInterrupt( DccProcState.ExtIntNum, ExternalInterruptHandler, ISREdge );
CLR_TP4; CLR_TP4;
break; break;
@@ -509,8 +533,14 @@ void ExternalInterruptHandler(void)
DccRx.State = WAIT_PREAMBLE ; DccRx.State = WAIT_PREAMBLE ;
bitMax = MAX_PRAEAMBEL; bitMax = MAX_PRAEAMBEL;
bitMin = MIN_ONEBITFULL; bitMin = MIN_ONEBITFULL;
#ifdef ESP32
portENTER_CRITICAL_ISR(&mux);
#endif
DccRx.PacketCopy = DccRx.PacketBuf ; DccRx.PacketCopy = DccRx.PacketBuf ;
DccRx.DataReady = 1 ; DccRx.DataReady = 1 ;
#ifdef ESP32
portEXIT_CRITICAL_ISR(&mux);
#endif
SET_TP3; SET_TP3;
} }
else // Get next Byte else // Get next Byte
@@ -1326,16 +1356,18 @@ void NmraDcc::init( uint8_t ManufacturerId, uint8_t VersionId, uint8_t Flags, ui
MODE_TP2; MODE_TP2;
MODE_TP3; MODE_TP3;
MODE_TP4; MODE_TP4;
ISREdge = RISING;
bitMax = MAX_ONEBITFULL; bitMax = MAX_ONEBITFULL;
bitMin = MIN_ONEBITFULL; bitMin = MIN_ONEBITFULL;
attachInterrupt( DccProcState.ExtIntNum, ExternalInterruptHandler, RISING);
DccProcState.Flags = Flags ; DccProcState.Flags = Flags ;
DccProcState.OpsModeAddressBaseCV = OpsModeAddressBaseCV ; DccProcState.OpsModeAddressBaseCV = OpsModeAddressBaseCV ;
DccProcState.myDccAddress = -1; DccProcState.myDccAddress = -1;
DccProcState.inAccDecDCCAddrNextReceivedMode = 0; DccProcState.inAccDecDCCAddrNextReceivedMode = 0;
ISREdge = RISING;
ISRWatch = ISREdge;
attachInterrupt( DccProcState.ExtIntNum, ExternalInterruptHandler, CHANGE);
// Set the Bits that control Multifunction or Accessory behaviour // Set the Bits that control Multifunction or Accessory behaviour
// and if the Accessory decoder optionally handles Output Addressing // and if the Accessory decoder optionally handles Output Addressing
// we need to peal off the top two bits // we need to peal off the top two bits
@@ -1439,10 +1471,21 @@ uint8_t NmraDcc::process()
{ {
// We need to do this check with interrupts disabled // We need to do this check with interrupts disabled
//SET_TP4; //SET_TP4;
#ifdef ESP32
portENTER_CRITICAL(&mux);
#else
noInterrupts(); noInterrupts();
#endif
Msg = DccRx.PacketCopy ; Msg = DccRx.PacketCopy ;
DccRx.DataReady = 0 ; DccRx.DataReady = 0 ;
#ifdef ESP32
portEXIT_CRITICAL(&mux);
#else
interrupts(); interrupts();
#endif
#ifdef DCC_DBGVAR #ifdef DCC_DBGVAR
countOf.Tel++; countOf.Tel++;
#endif #endif

View File

@@ -1,6 +1,6 @@
name=NmraDcc name=NmraDcc
version=2.0.0 version=2.0.1
author=Alex Shepherd, Wolfgang Kuffer, Geoff Bunza, Martin Pischky, Franz-Peter Müller, Sven (littleyoda) author=Alex Shepherd, Wolfgang Kuffer, Geoff Bunza, Martin Pischky, Franz-Peter Müller, Sven (littleyoda), Hans Tanner
maintainer=Alex Shepherd <kiwi64ajs@gmail.com> maintainer=Alex Shepherd <kiwi64ajs@gmail.com>
sentence=Enables NMRA DCC Communication sentence=Enables NMRA DCC Communication
paragraph=This library allows you to interface to a NMRA DCC track signal and receive DCC commands. The library has been tested on AVR ATTiny84/85 & ATMega88/168/328/32u4, ESP8266 and Teensy 3.x using the INT0/1 Hardware Interrupt and micros() ONLY and no longer uses Timer0 Compare Match B, which makes it much more portable to other platforms. paragraph=This library allows you to interface to a NMRA DCC track signal and receive DCC commands. The library has been tested on AVR ATTiny84/85 & ATMega88/168/328/32u4, ESP8266 and Teensy 3.x using the INT0/1 Hardware Interrupt and micros() ONLY and no longer uses Timer0 Compare Match B, which makes it much more portable to other platforms.