This commit is contained in:
MicroBahner
2019-02-22 14:52:23 +01:00
2 changed files with 73 additions and 4 deletions

View File

@@ -26,6 +26,7 @@
// 2017-11-29 Ken West (kgw4449@gmail.com): // 2017-11-29 Ken West (kgw4449@gmail.com):
// Minor fixes to pass NMRA Baseline Conformance Tests. // Minor fixes to pass NMRA Baseline Conformance Tests.
// 2018-12-17 added ESP32 support by Trusty (thierry@lapajaparis.net) // 2018-12-17 added ESP32 support by Trusty (thierry@lapajaparis.net)
// 2019-02-17 added ESP32 specific changes by Hans Tanner
// //
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// //
@@ -244,6 +245,9 @@ struct countOf_t countOf;
#if defined ( __STM32F1__ ) #if defined ( __STM32F1__ )
static ExtIntTriggerMode ISREdge; static ExtIntTriggerMode ISREdge;
#elif defined ( ESP32 )
static byte ISREdge; // Holder of the Next Edge we're looking for: RISING or FALLING
static byte ISRWatch; // Interrupt Handler Edge Filter
#else #else
static byte ISREdge; // RISING or FALLING static byte ISREdge; // RISING or FALLING
#endif #endif
@@ -301,8 +305,37 @@ 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
{ {
#ifdef ESP32
// 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;
}
#endif
// 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 ;
@@ -353,7 +386,11 @@ void ExternalInterruptHandler(void)
#if defined ( __STM32F1__ ) #if defined ( __STM32F1__ )
detachInterrupt( DccProcState.ExtIntNum ); detachInterrupt( DccProcState.ExtIntNum );
#endif #endif
#ifdef ESP32
ISRWatch = CHANGE;
#else
attachInterrupt( DccProcState.ExtIntNum, ExternalInterruptHandler, CHANGE); attachInterrupt( DccProcState.ExtIntNum, ExternalInterruptHandler, CHANGE);
#endif
halfBit = 0; halfBit = 0;
bitMax = MAX_ONEBITHALF; bitMax = MAX_ONEBITHALF;
bitMin = MIN_ONEBITHALF; bitMin = MIN_ONEBITHALF;
@@ -400,7 +437,11 @@ void ExternalInterruptHandler(void)
#if defined ( __STM32F1__ ) #if defined ( __STM32F1__ )
detachInterrupt( DccProcState.ExtIntNum ); detachInterrupt( DccProcState.ExtIntNum );
#endif #endif
#ifdef ESP32
ISRWatch = ISREdge;
#else
attachInterrupt( DccProcState.ExtIntNum, ExternalInterruptHandler, ISREdge ); attachInterrupt( DccProcState.ExtIntNum, ExternalInterruptHandler, ISREdge );
#endif
SET_TP3; SET_TP3;
CLR_TP4; CLR_TP4;
} }
@@ -439,7 +480,11 @@ void ExternalInterruptHandler(void)
#if defined ( __STM32F1__ ) #if defined ( __STM32F1__ )
detachInterrupt( DccProcState.ExtIntNum ); detachInterrupt( DccProcState.ExtIntNum );
#endif #endif
#ifdef ESP32
ISRWatch = ISREdge;
#else
attachInterrupt( DccProcState.ExtIntNum, ExternalInterruptHandler, ISREdge ); attachInterrupt( DccProcState.ExtIntNum, ExternalInterruptHandler, ISREdge );
#endif
CLR_TP1; CLR_TP1;
CLR_TP4; CLR_TP4;
break; break;
@@ -471,7 +516,11 @@ void ExternalInterruptHandler(void)
#if defined ( __STM32F1__ ) #if defined ( __STM32F1__ )
detachInterrupt( DccProcState.ExtIntNum ); detachInterrupt( DccProcState.ExtIntNum );
#endif #endif
#ifdef ESP32
ISRWatch = ISREdge;
#else
attachInterrupt( DccProcState.ExtIntNum, ExternalInterruptHandler, ISREdge ); attachInterrupt( DccProcState.ExtIntNum, ExternalInterruptHandler, ISREdge );
#endif
CLR_TP4; CLR_TP4;
break; break;
@@ -509,8 +558,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 +1381,22 @@ 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;
#ifdef ESP32
ISRWatch = ISREdge;
attachInterrupt( DccProcState.ExtIntNum, ExternalInterruptHandler, CHANGE);
#else
attachInterrupt( DccProcState.ExtIntNum, ExternalInterruptHandler, RISING);
#endif
// 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 +1500,18 @@ 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.