6 Commits

Author SHA1 Message Date
Alex Shepherd
4b175e9229 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
2019-08-06 01:23:12 +12:00
Alex Shepherd
f3a2b87693 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
2019-08-06 00:22:04 +12:00
Alex Shepherd
e06f6b3bce bumped version to 2.0.2 2019-08-05 21:34:48 +12:00
Alex Shepherd
6a7e206032 reverted changes around lastMicros 2019-08-05 21:30:39 +12:00
Alex Shepherd
6d12e6cd3f added conditional compilation for ESP8266 to add ICACHE_RAM_ATTR to ExternalInterruptHandler
changed storage for Micros to unsigned long
2019-05-25 15:52:55 +12:00
Alex Shepherd
b249762550 changed the version to 201 in the header 2019-05-02 21:42:59 +12:00
3 changed files with 34 additions and 17 deletions

View File

@@ -289,7 +289,8 @@ typedef struct
uint8_t ExtIntNum; uint8_t ExtIntNum;
uint8_t ExtIntPinNum; uint8_t ExtIntPinNum;
int16_t myDccAddress; // Cached value of DCC Address from CVs int16_t myDccAddress; // Cached value of DCC Address from CVs
uint8_t inAccDecDCCAddrNextReceivedMode; uint8_t inAccDecDCCAddrNextReceivedMode;
uint8_t cv29Value;
#ifdef DCC_DEBUG #ifdef DCC_DEBUG
uint8_t IntCount; uint8_t IntCount;
uint8_t TickCount; uint8_t TickCount;
@@ -601,6 +602,13 @@ void ackCV(void)
notifyCVAck() ; notifyCVAck() ;
} }
void ackAdvancedCV(void)
{
if( notifyAdvancedCVAck && (DccProcState.cv29Value & CV29_ADV_ACK) )
notifyAdvancedCVAck() ;
}
uint8_t readEEPROM( unsigned int CV ) { uint8_t readEEPROM( unsigned int CV ) {
return EEPROM.read(CV) ; return EEPROM.read(CV) ;
} }
@@ -660,6 +668,7 @@ uint8_t writeCV( unsigned int CV, uint8_t Value)
{ {
case CV_29_CONFIG: case CV_29_CONFIG:
// copy addressmode Bit to Flags // copy addressmode Bit to Flags
DccProcState.cv29Value = Value;
DccProcState.Flags = ( DccProcState.Flags & ~FLAGS_CV29_BITS) | (Value & FLAGS_CV29_BITS); DccProcState.Flags = ( DccProcState.Flags & ~FLAGS_CV29_BITS) | (Value & FLAGS_CV29_BITS);
// no break, because myDccAdress must also be reset // 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_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) uint16_t getMyAddr(void)
{ {
uint8_t CV29Value ;
if( DccProcState.myDccAddress != -1 ) // See if we can return the cached value if( DccProcState.myDccAddress != -1 ) // See if we can return the cached value
return( DccProcState.myDccAddress ); return( DccProcState.myDccAddress );
CV29Value = readCV( CV_29_CONFIG ) ; if( DccProcState.cv29Value & CV29_ACCESSORY_DECODER ) // Accessory Decoder?
if( 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 ); DccProcState.myDccAddress = ( readCV( CV_ACCESSORY_DECODER_ADDRESS_MSB ) << 8 ) | readCV( CV_ACCESSORY_DECODER_ADDRESS_LSB );
else else
DccProcState.myDccAddress = ( ( readCV( CV_ACCESSORY_DECODER_ADDRESS_MSB ) & 0b00000111) << 6 ) | ( readCV( CV_ACCESSORY_DECODER_ADDRESS_LSB ) & 0b00111111) ; DccProcState.myDccAddress = ( ( readCV( CV_ACCESSORY_DECODER_ADDRESS_MSB ) & 0b00000111) << 6 ) | ( readCV( CV_ACCESSORY_DECODER_ADDRESS_LSB ) & 0b00111111) ;
} }
else // Multi-Function Decoder? 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 ) ; DccProcState.myDccAddress = ( ( readCV( CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB ) - 192 ) << 8 ) | readCV( CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB ) ;
else else
@@ -725,7 +730,7 @@ void processDirectOpsOperation( uint8_t Cmd, uint16_t CVAddr, uint8_t Value )
if( validCV( CVAddr, 1 ) ) if( validCV( CVAddr, 1 ) )
{ {
if( writeCV( CVAddr, Value ) == Value ) 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( validCV( CVAddr, 0 ) )
{ {
if( readCV( CVAddr ) == Value ) 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 tempValue &= ~BitMask ; // Turn the Bit Off
if( writeCV( CVAddr, tempValue ) == tempValue ) 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( BitValue )
{ {
if( tempValue & BitMask ) if( tempValue & BitMask )
ackCV() ; ackAdvancedCV() ;
} }
else else
{ {
if( !( tempValue & BitMask) ) if( !( tempValue & BitMask) )
ackCV() ; ackAdvancedCV() ;
} }
} }
} }
@@ -870,7 +875,7 @@ void processMultiFunctionMessage( uint16_t Addr, DCC_ADDR_TYPE AddrType, uint8_t
case 0b01100000: case 0b01100000:
//TODO should we cache this info in DCC_PROCESSOR_STATE.Flags ? //TODO should we cache this info in DCC_PROCESSOR_STATE.Flags ?
#ifdef NMRA_DCC_ENABLE_14_SPEED_STEP_MODE #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 #else
speedSteps = SPEED_STEP_28 ; speedSteps = SPEED_STEP_28 ;
#endif #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 // 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
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; uint8_t doAutoFactoryDefault = 0;
if((Flags & FLAGS_AUTO_FACTORY_DEFAULT) && (readCV(CV_VERSION_ID) == 255) && (readCV(CV_MANUFACTURER_ID) == 255)) if((Flags & FLAGS_AUTO_FACTORY_DEFAULT) && (readCV(CV_VERSION_ID) == 255) && (readCV(CV_MANUFACTURER_ID) == 255))

View File

@@ -99,7 +99,7 @@ typedef struct
#define CV_29_CONFIG 29 #define CV_29_CONFIG 29
#if defined(ESP32) #if defined(ESP32)
#include <esp_log.h> #include <esp_spi_flash.h>
#define MAXCV SPI_FLASH_SEC_SIZE #define MAXCV SPI_FLASH_SEC_SIZE
#elif defined(ESP8266) #elif defined(ESP8266)
#include <spi_flash.h> #include <spi_flash.h>
@@ -703,6 +703,18 @@ extern void notifyCVResetFactoryDefault(void) __attribute__ ((weak));
* None * None
*/ */
extern void notifyCVAck(void) __attribute__ ((weak)); 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 * notifyServiceMode(bool) Called when state of 'inServiceMode' changes
* *

View File

@@ -1,5 +1,5 @@
name=NmraDcc 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 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