Merge branch 'AdvancedCVAck' into ESP32-IRAM_ATTR
* AdvancedCVAck: split out ServiceMode ackCV from Ops Mode AdvancedCVAck as doing a ackCV in Ops Mode is wrong and adds 6ms busy delay add cache of CV29 value bumped version to 2.0.2 reverted changes around lastMicros added conditional compilation for ESP8266 to add ICACHE_RAM_ATTR to ExternalInterruptHandler changed storage for Micros to unsigned long changed the version to 201 in the header # Conflicts: # NmraDcc.cpp reverted to unsigned int
This commit is contained in:
35
NmraDcc.cpp
35
NmraDcc.cpp
@@ -289,7 +289,8 @@ typedef struct
|
||||
uint8_t ExtIntNum;
|
||||
uint8_t ExtIntPinNum;
|
||||
int16_t myDccAddress; // Cached value of DCC Address from CVs
|
||||
uint8_t inAccDecDCCAddrNextReceivedMode;
|
||||
uint8_t inAccDecDCCAddrNextReceivedMode;
|
||||
uint8_t cv29Value;
|
||||
#ifdef DCC_DEBUG
|
||||
uint8_t IntCount;
|
||||
uint8_t TickCount;
|
||||
@@ -601,6 +602,13 @@ void ackCV(void)
|
||||
notifyCVAck() ;
|
||||
}
|
||||
|
||||
void ackAdvancedCV(void)
|
||||
{
|
||||
if( notifyAdvancedCVAck && (DccProcState.cv29Value & CV29_ADV_ACK) )
|
||||
notifyAdvancedCVAck() ;
|
||||
}
|
||||
|
||||
|
||||
uint8_t readEEPROM( unsigned int CV ) {
|
||||
return EEPROM.read(CV) ;
|
||||
}
|
||||
@@ -660,6 +668,7 @@ uint8_t writeCV( unsigned int CV, uint8_t Value)
|
||||
{
|
||||
case CV_29_CONFIG:
|
||||
// copy addressmode Bit to Flags
|
||||
DccProcState.cv29Value = Value;
|
||||
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
|
||||
@@ -688,23 +697,19 @@ uint8_t writeCV( unsigned int CV, uint8_t Value)
|
||||
|
||||
uint16_t getMyAddr(void)
|
||||
{
|
||||
uint8_t CV29Value ;
|
||||
|
||||
if( DccProcState.myDccAddress != -1 ) // See if we can return the cached value
|
||||
return( DccProcState.myDccAddress );
|
||||
|
||||
CV29Value = readCV( CV_29_CONFIG ) ;
|
||||
|
||||
if( CV29Value & CV29_ACCESSORY_DECODER ) // Accessory Decoder?
|
||||
if( DccProcState.cv29Value & CV29_ACCESSORY_DECODER ) // Accessory Decoder?
|
||||
{
|
||||
if( CV29Value & CV29_OUTPUT_ADDRESS_MODE )
|
||||
if( DccProcState.cv29Value & CV29_OUTPUT_ADDRESS_MODE )
|
||||
DccProcState.myDccAddress = ( readCV( CV_ACCESSORY_DECODER_ADDRESS_MSB ) << 8 ) | readCV( CV_ACCESSORY_DECODER_ADDRESS_LSB );
|
||||
else
|
||||
DccProcState.myDccAddress = ( ( readCV( CV_ACCESSORY_DECODER_ADDRESS_MSB ) & 0b00000111) << 6 ) | ( readCV( CV_ACCESSORY_DECODER_ADDRESS_LSB ) & 0b00111111) ;
|
||||
}
|
||||
else // Multi-Function Decoder?
|
||||
{
|
||||
if( CV29Value & CV29_EXT_ADDRESSING ) // Two Byte Address?
|
||||
if( DccProcState.cv29Value & CV29_EXT_ADDRESSING ) // Two Byte Address?
|
||||
DccProcState.myDccAddress = ( ( readCV( CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB ) - 192 ) << 8 ) | readCV( CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB ) ;
|
||||
|
||||
else
|
||||
@@ -725,7 +730,7 @@ void processDirectOpsOperation( uint8_t Cmd, uint16_t CVAddr, uint8_t Value )
|
||||
if( validCV( CVAddr, 1 ) )
|
||||
{
|
||||
if( writeCV( CVAddr, Value ) == Value )
|
||||
ackCV();
|
||||
ackAdvancedCV();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -734,7 +739,7 @@ void processDirectOpsOperation( uint8_t Cmd, uint16_t CVAddr, uint8_t Value )
|
||||
if( validCV( CVAddr, 0 ) )
|
||||
{
|
||||
if( readCV( CVAddr ) == Value )
|
||||
ackCV();
|
||||
ackAdvancedCV();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -759,7 +764,7 @@ void processDirectOpsOperation( uint8_t Cmd, uint16_t CVAddr, uint8_t Value )
|
||||
tempValue &= ~BitMask ; // Turn the Bit Off
|
||||
|
||||
if( writeCV( CVAddr, tempValue ) == tempValue )
|
||||
ackCV() ;
|
||||
ackAdvancedCV() ;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -771,12 +776,12 @@ void processDirectOpsOperation( uint8_t Cmd, uint16_t CVAddr, uint8_t Value )
|
||||
if( BitValue )
|
||||
{
|
||||
if( tempValue & BitMask )
|
||||
ackCV() ;
|
||||
ackAdvancedCV() ;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( !( tempValue & BitMask) )
|
||||
ackCV() ;
|
||||
ackAdvancedCV() ;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -870,7 +875,7 @@ void processMultiFunctionMessage( uint16_t Addr, DCC_ADDR_TYPE AddrType, uint8_t
|
||||
case 0b01100000:
|
||||
//TODO should we cache this info in DCC_PROCESSOR_STATE.Flags ?
|
||||
#ifdef NMRA_DCC_ENABLE_14_SPEED_STEP_MODE
|
||||
speedSteps = (readCV( CV_29_CONFIG ) & CV29_F0_LOCATION) ? SPEED_STEP_28 : SPEED_STEP_14 ;
|
||||
speedSteps = (DccProcState.cv29Value & CV29_F0_LOCATION) ? SPEED_STEP_28 : SPEED_STEP_14 ;
|
||||
#else
|
||||
speedSteps = SPEED_STEP_28 ;
|
||||
#endif
|
||||
@@ -1417,7 +1422,7 @@ 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
|
||||
// we need to peal off the top two bits
|
||||
writeCV( CV_29_CONFIG, ( readCV( CV_29_CONFIG ) & ~FLAGS_CV29_BITS ) | (Flags & FLAGS_CV29_BITS) ) ;
|
||||
DccProcState.cv29Value = 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))
|
||||
|
14
NmraDcc.h
14
NmraDcc.h
@@ -99,7 +99,7 @@ typedef struct
|
||||
#define CV_29_CONFIG 29
|
||||
|
||||
#if defined(ESP32)
|
||||
#include <esp_log.h>
|
||||
#include <esp_spi_flash.h>
|
||||
#define MAXCV SPI_FLASH_SEC_SIZE
|
||||
#elif defined(ESP8266)
|
||||
#include <spi_flash.h>
|
||||
@@ -703,6 +703,18 @@ extern void notifyCVResetFactoryDefault(void) __attribute__ ((weak));
|
||||
* None
|
||||
*/
|
||||
extern void notifyCVAck(void) __attribute__ ((weak));
|
||||
/*+
|
||||
* notifyAdvancedCVAck() Called when a CV write must be acknowledged.
|
||||
* This callback must increase the current drawn by this
|
||||
* decoder by at least 60mA for 6ms +/- 1ms.
|
||||
*
|
||||
* Inputs:
|
||||
* None
|
||||
* *
|
||||
* Returns:
|
||||
* None
|
||||
*/
|
||||
extern void notifyAdvancedCVAck(void) __attribute__ ((weak));
|
||||
/*+
|
||||
* notifyServiceMode(bool) Called when state of 'inServiceMode' changes
|
||||
*
|
||||
|
@@ -1,5 +1,5 @@
|
||||
name=NmraDcc
|
||||
version=2.0.1
|
||||
version=2.0.2
|
||||
author=Alex Shepherd, Wolfgang Kuffer, Geoff Bunza, Martin Pischky, Franz-Peter Müller, Sven (littleyoda), Hans Tanner
|
||||
maintainer=Alex Shepherd <kiwi64ajs@gmail.com>
|
||||
sentence=Enables NMRA DCC Communication
|
||||
|
Reference in New Issue
Block a user