From 1717a2efb06a0482b950d872417bfe2269e73d07 Mon Sep 17 00:00:00 2001 From: Alex Shepherd Date: Sat, 7 Jul 2018 19:21:48 +1200 Subject: [PATCH] Made some minor tweaks / tidy-ups after committing Franz-Peter's changes --- NmraDcc.cpp | 33 ++++++++++++++++++++++++--------- NmraDcc.h | 23 ++++++++++++++++++++++- library.properties | 2 +- 3 files changed, 47 insertions(+), 11 deletions(-) diff --git a/NmraDcc.cpp b/NmraDcc.cpp index 29ab28d..2d49e41 100644 --- a/NmraDcc.cpp +++ b/NmraDcc.cpp @@ -583,7 +583,7 @@ uint8_t writeCV( unsigned int CV, uint8_t Value) { case CV_29_CONFIG: // copy addressmode Bit to Flags - DccProcState.Flags = ( DccProcState.Flags & ~FLAGS_OUTPUT_ADDRESS_MODE) | (Value & FLAGS_OUTPUT_ADDRESS_MODE); + DccProcState.Flags = ( DccProcState.Flags & ~FLAGS_CV29_BITS) | (Value & FLAGS_CV29_BITS); // no break, because myDccAdress must also be reset case CV_ACCESSORY_DECODER_ADDRESS_LSB: // Also same CV for CV_MULTIFUNCTION_PRIMARY_ADDRESS case CV_ACCESSORY_DECODER_ADDRESS_MSB: @@ -601,11 +601,11 @@ uint8_t writeCV( unsigned int CV, uint8_t Value) if( notifyCVChange ) notifyCVChange( CV, Value) ; + if( notifyDccCVChange && !(DccProcState.Flags & FLAGS_SETCV_CALLED) ) notifyDccCVChange( CV, Value ); - - DccProcState.Flags &= ~FLAGS_SETCV_CALLED; } + return readEEPROM( CV ) ; } @@ -934,7 +934,8 @@ void processServiceModeOperation( DCC_MSG * pDccMsg ) } else if( pDccMsg->Size == 4) // 4 Byte Packets are for Direct Byte & Bit Mode - { DB_PRINT("BB-Mode"); + { + DB_PRINT("BB-Mode"); CVAddr = ( ( ( pDccMsg->Data[0] & 0x03 ) << 8 ) | pDccMsg->Data[1] ) + 1 ; Value = pDccMsg->Data[2] ; @@ -1056,7 +1057,7 @@ void execDccProcessor( DCC_MSG * pDccMsg ) { int16_t BoardAddress ; int16_t OutputAddress ; - uint8_t TurnoutPairIndex ; + uint8_t TurnoutPairIndex ; #ifdef DEBUG_PRINT SerialPrintPacketHex(F( "eDP: AccCmd: "), pDccMsg); @@ -1137,7 +1138,9 @@ void execDccProcessor( DCC_MSG * pDccMsg ) if((pDccMsg->Size == 4) && ((pDccMsg->Data[1] & 0b10001001) == 1)) // Extended Accessory Decoder Control Packet Format { - uint8_t state = pDccMsg->Data[2] ;// & 0b00011111; + // According to the NMRA Dcc Spec the Signal State should only use the lower 5 Bits, + // however some manufacturers seem to allow/use all 8 bits, so we'll relax that constraint for now + uint8_t state = pDccMsg->Data[2] ; DB_PRINT("eDP: OAddr:%d Extended State:%0X", OutputAddress, state); if( notifyDccSigOutputState ) notifyDccSigOutputState(OutputAddress, state); @@ -1262,6 +1265,13 @@ NmraDcc::NmraDcc() { } +#ifdef digitalPinToInterrupt +void NmraDcc::pin( uint8_t ExtIntPinNum, uint8_t EnablePullup) +{ + pin(digitalPinToInterrupt(ExtIntPinNum), ExtIntPinNum, EnablePullup); +} +#endif + void NmraDcc::pin( uint8_t ExtIntNum, uint8_t ExtIntPinNum, uint8_t EnablePullup) { #if defined ( __STM32F1__ ) @@ -1308,8 +1318,8 @@ void NmraDcc::init( uint8_t ManufacturerId, uint8_t VersionId, uint8_t Flags, ui // Set the Bits that control Multifunction or Accessory behaviour // and if the Accessory decoder optionally handles Output Addressing - uint8_t cv29Mask = CV29_ACCESSORY_DECODER | CV29_OUTPUT_ADDRESS_MODE ; // peal off the top two bits - writeCV( CV_29_CONFIG, ( readCV( CV_29_CONFIG ) & ~cv29Mask ) | (Flags & cv29Mask) ) ; + // we need to peal off the top two bits + writeCV( CV_29_CONFIG, ( readCV( CV_29_CONFIG ) & ~FLAGS_CV29_BITS ) | (Flags & FLAGS_CV29_BITS) ) ; uint8_t doAutoFactoryDefault = 0; if((Flags & FLAGS_AUTO_FACTORY_DEFAULT) && (readCV(CV_VERSION_ID) == 255) && (readCV(CV_MANUFACTURER_ID) == 255)) @@ -1334,7 +1344,12 @@ uint8_t NmraDcc::getCV( uint16_t CV ) uint8_t NmraDcc::setCV( uint16_t CV, uint8_t Value) { DccProcState.Flags |= FLAGS_SETCV_CALLED; - return writeCV(CV,Value); + + uint8_t returnValue = writeCV(CV,Value); + + DccProcState.Flags &= ~FLAGS_SETCV_CALLED; + + return returnValue; } //////////////////////////////////////////////////////////////////////// diff --git a/NmraDcc.h b/NmraDcc.h index ed2191d..9f2cb62 100644 --- a/NmraDcc.h +++ b/NmraDcc.h @@ -44,6 +44,8 @@ #include "WProgram.h" #endif +#include "pins_arduino.h" + #include "EEPROM.h" #ifndef NMRADCC_IS_IN @@ -109,7 +111,7 @@ typedef struct typedef enum { CV29_LOCO_DIR = 0b00000001, /** bit 0: Locomotive Direction: "0" = normal, "1" = reversed */ CV29_F0_LOCATION = 0b00000010, /** bit 1: F0 location: "0" = bit 4 in Speed and Direction instructions, "1" = bit 4 in function group one instruction */ - CV29_APS = 0b00000100, /** bit 2: Alternate Power Source (APS) "0" = NMRA Digital only, "1" = Alternate power source set by CV12 */ + CV29_APS = 0b00000100, /** bit 2: Alternate Power Source (APS) "0" = NMRA Digital only, "1" = Alternate power source set by CV12 */ CV29_ADV_ACK = 0b00001000, /** bit 3: ACK, Advanced Acknowledge mode enabled if 1, disabled if 0 */ CV29_SPEED_TABLE_ENABLE = 0b00010000, /** bit 4: STE, Speed Table Enable, "0" = values in CVs 2, 4 and 6, "1" = Custom table selected by CV 25 */ CV29_EXT_ADDRESSING = 0b00100000, /** bit 5: "0" = one byte addressing, "1" = two byte addressing */ @@ -206,6 +208,10 @@ class NmraDcc #define FLAGS_OUTPUT_ADDRESS_MODE 0x40 // CV 29/541 bit 6 #define FLAGS_DCC_ACCESSORY_DECODER 0x80 // CV 29/541 bit 7 +// Flag Bits that are cloned from CV29 relating the DCC Accessory Decoder +#define FLAGS_CV29_BITS (FLAGS_OUTPUT_ADDRESS_MODE | FLAGS_DCC_ACCESSORY_DECODER) + + /*+ * pin() is called from setup() and sets up the pin used to receive DCC packets. * @@ -219,6 +225,21 @@ class NmraDcc */ void pin( uint8_t ExtIntNum, uint8_t ExtIntPinNum, uint8_t EnablePullup); + /*+ + * pin() is called from setup() and sets up the pin used to receive DCC packets. + * This relies on the internal function: digitalPinToInterrupt() to map the input pin number to the right interrupt + * + * Inputs: + * ExtIntPinNum - Input pin number. + * EnablePullup - Set true to enable the pins pullup resistor. + * + * Returns: + * None. + */ +#ifdef digitalPinToInterrupt +void pin( uint8_t ExtIntPinNum, uint8_t EnablePullup); +#endif + /*+ * init() is called from setup() after the pin() command is called. * It initializes the NmDcc object and makes it ready to process packets. diff --git a/library.properties b/library.properties index c81337b..35818c6 100644 --- a/library.properties +++ b/library.properties @@ -3,7 +3,7 @@ version=2.0.0 author=Alex Shepherd, Wolfgang Kuffer, Geoff Bunza, Martin Pischky, Franz-Peter Müller, Sven (littleyoda) maintainer=Alex Shepherd sentence=Enables NMRA DCC Communication -paragraph=This library allows you to interface to a NMRA DCC track signal and receive DCC commands. The library currently supports the AVR ATTiny84/85 & ATMega88/168/328/32u4 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. WARNING as of version 1.4.4 support for the call-back functions notifyDccAccState() and notifyDccSigState() has been removed, please check and update your sketches, as they will silently fail. +paragraph=This library allows you to interface to a NMRA DCC track signal and receive DCC commands. The library currently supports the 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. category=Communication url=https://github.com/mrrwa/NmraDcc architectures=avr,esp8266,STM32F1