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:
Alex Shepherd
2019-08-06 01:23:12 +12:00
3 changed files with 34 additions and 17 deletions

View File

@@ -290,6 +290,7 @@ typedef struct
uint8_t ExtIntPinNum;
int16_t myDccAddress; // Cached value of DCC Address from CVs
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))

View File

@@ -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
*

View File

@@ -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