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
This commit is contained in:
Alex Shepherd
2019-08-06 00:22:04 +12:00
parent e06f6b3bce
commit f3a2b87693
2 changed files with 33 additions and 16 deletions

View File

@@ -295,7 +295,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;
@@ -604,6 +605,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) ;
} }
@@ -663,6 +671,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
@@ -691,23 +700,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
@@ -728,7 +733,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();
} }
} }
@@ -737,7 +742,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();
} }
} }
} }
@@ -762,7 +767,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() ;
} }
} }
@@ -774,12 +779,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() ;
} }
} }
} }
@@ -873,7 +878,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
@@ -1409,7 +1414,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

@@ -97,7 +97,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>
@@ -698,6 +698,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
* *