Reworked the handling of Accessory OPS Mode CV writing to handle the difference of 11-bit Basic Extended Commands and 11-bit Signal Commands

This commit is contained in:
Alex Shepherd
2021-09-12 01:22:21 +12:00
parent 6333abf691
commit f59048383f
2 changed files with 59 additions and 39 deletions

View File

@@ -50,7 +50,7 @@
#include "EEPROM.h" #include "EEPROM.h"
// Uncomment to print DEBUG messages // Uncomment to print DEBUG messages
#define DEBUG_PRINT // #define DEBUG_PRINT
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// DCC Receive Routine // DCC Receive Routine
@@ -889,7 +889,7 @@ uint16_t getMyAddr (void)
if (DccProcState.cv29Value & CV29_ACCESSORY_DECODER) // Accessory Decoder? if (DccProcState.cv29Value & CV29_ACCESSORY_DECODER) // Accessory Decoder?
{ {
if (DccProcState.cv29Value & CV29_OUTPUT_ADDRESS_MODE) if (DccProcState.cv29Value & (CV29_OUTPUT_ADDRESS_MODE | CV29_EXT_ADDRESSING))
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) ;
@@ -1366,9 +1366,9 @@ void execDccProcessor (DCC_MSG * pDccMsg)
if (DccProcState.inAccDecDCCAddrNextReceivedMode) if (DccProcState.inAccDecDCCAddrNextReceivedMode)
{ {
if (DccProcState.Flags & FLAGS_OUTPUT_ADDRESS_MODE) if (DccProcState.Flags & (FLAGS_OUTPUT_ADDRESS_MODE | FLAGS_EXTENDED_ADDRESS_MODE))
{ {
DB_PRINT ("eDP: Set Output Address: %d", OutputAddress); DB_PRINT ("eDP: 11-bit Accessory Address: %d", OutputAddress);
//uint16_t storedOutputAddress = OutputAddress + 1; // The value stored in CV1 & 9 for Output Addressing Mode is + 1 //uint16_t storedOutputAddress = OutputAddress + 1; // The value stored in CV1 & 9 for Output Addressing Mode is + 1
writeCV (CV_ACCESSORY_DECODER_ADDRESS_LSB, (uint8_t) (OutputAddress % 256)); writeCV (CV_ACCESSORY_DECODER_ADDRESS_LSB, (uint8_t) (OutputAddress % 256));
writeCV (CV_ACCESSORY_DECODER_ADDRESS_MSB, (uint8_t) (OutputAddress / 256)); writeCV (CV_ACCESSORY_DECODER_ADDRESS_MSB, (uint8_t) (OutputAddress / 256));
@@ -1378,7 +1378,7 @@ void execDccProcessor (DCC_MSG * pDccMsg)
} }
else else
{ {
DB_PRINT ("eDP: Set Board Address: %d", BoardAddress); DB_PRINT ("eDP: Set 9-bit Board Address: %d", BoardAddress);
writeCV (CV_ACCESSORY_DECODER_ADDRESS_LSB, (uint8_t) (BoardAddress % 64)); writeCV (CV_ACCESSORY_DECODER_ADDRESS_LSB, (uint8_t) (BoardAddress % 64));
writeCV (CV_ACCESSORY_DECODER_ADDRESS_MSB, (uint8_t) (BoardAddress / 64)); writeCV (CV_ACCESSORY_DECODER_ADDRESS_MSB, (uint8_t) (BoardAddress / 64));
@@ -1393,7 +1393,7 @@ void execDccProcessor (DCC_MSG * pDccMsg)
if (DccProcState.Flags & FLAGS_MY_ADDRESS_ONLY) if (DccProcState.Flags & FLAGS_MY_ADDRESS_ONLY)
{ {
DB_PRINT ("eDP: Check if the Address matches"); DB_PRINT ("eDP: Check if the Address matches");
if (DccProcState.Flags & FLAGS_OUTPUT_ADDRESS_MODE) if (DccProcState.Flags & (FLAGS_OUTPUT_ADDRESS_MODE | FLAGS_EXTENDED_ADDRESS_MODE))
{ {
if (OutputAddress != getMyAddr() && OutputAddress < 2045) if (OutputAddress != getMyAddr() && OutputAddress < 2045)
{ {
@@ -1437,7 +1437,7 @@ void execDccProcessor (DCC_MSG * pDccMsg)
if (notifyDccAccState) if (notifyDccAccState)
notifyDccAccState (OutputAddress, BoardAddress, pDccMsg->Data[1] & 0b00000111, outputPower); notifyDccAccState (OutputAddress, BoardAddress, pDccMsg->Data[1] & 0b00000111, outputPower);
if (DccProcState.Flags & FLAGS_OUTPUT_ADDRESS_MODE) if (DccProcState.Flags & FLAGS_EXTENDED_ADDRESS_MODE)
{ {
DB_PRINT ("eDP: Output Address: %d Turnout Dir: %d Output Power: %d", OutputAddress, direction, outputPower); DB_PRINT ("eDP: Output Address: %d Turnout Dir: %d Output Power: %d", OutputAddress, direction, outputPower);
if (notifyDccAccTurnoutOutput) if (notifyDccAccTurnoutOutput)
@@ -1452,56 +1452,70 @@ void execDccProcessor (DCC_MSG * pDccMsg)
} }
else if (pDccMsg->Size == 6) // Accessory Decoder OPS Mode Programming else if (pDccMsg->Size == 6) // Accessory Decoder OPS Mode Programming
{ {
DB_PRINT ("eDP: OPS Mode CV Programming Command"); DB_PRINT ("eDP: Accessory OPS Mode CV Programming Command");
// Check for unsupported OPS Mode Addressing mode
if ( ( (pDccMsg->Data[1] & 0b10001001) != 1) && ( (pDccMsg->Data[1] & 0b10001111) != 0x80))
{
DB_PRINT ("eDP: Unsupported OPS Mode CV Addressing Mode");
return;
}
// If its a "Basic Accessory Decoder Packet" OPS Command // If its a "Basic Accessory Decoder Packet" OPS Command
if ((pDccMsg->Data[1] & 0x80) == 0x80) if (pDccMsg->Data[1] & 0x80)
{ {
DB_PRINT ("eDP: Basic Accessory Decoder Packet OPS Command"); DB_PRINT ("eDP: Handle Basic OPS Command");
// If we're in FLAGS_OUTPUT_ADDRESS_MODE then return as this isn't for us
DB_PRINT ("eDP: Check if in Output Address Mode");
if(DccProcState.Flags & FLAGS_OUTPUT_ADDRESS_MODE) if(DccProcState.Flags & FLAGS_OUTPUT_ADDRESS_MODE)
{ {
DB_PRINT ("eDP: Ignore Basic Accessory Decoder Packet in Output Address Mode"); DB_PRINT ("eDP: Ignore Basic OPS Command in Signal Address Mode");
return;
}
if(pDccMsg->Data[1] & 0b00001111)
{
DB_PRINT ("eDP: Handle 11-bit Basic OPS Command");
if((DccProcState.Flags & FLAGS_EXTENDED_ADDRESS_MODE) == 0)
{
DB_PRINT ("eDP: Ignore 11-bit Basic OPS Command in Board Address Mode");
return;
}
if((OutputAddress != getMyAddr()) && (OutputAddress < 2045))
{
DB_PRINT ("eDP: Extended Address Not Matched");
return;
}
}
else
{
DB_PRINT ("eDP: Handle 9-bit Basic OPS Command");
if(DccProcState.Flags & FLAGS_EXTENDED_ADDRESS_MODE)
{
DB_PRINT ("eDP: Ignore 9-bit Basic OPS Command in Extended Address Mode");
return; return;
} }
// Check if this command is for our Board Address or the broadcast address
DB_PRINT ("eDP: Check Board Address: %d", BoardAddress);
if ( (BoardAddress != getMyAddr()) && (BoardAddress < 511)) if ( (BoardAddress != getMyAddr()) && (BoardAddress < 511))
{ {
DB_PRINT ("eDP: Board Address Not Matched"); DB_PRINT ("eDP: Board Address Not Matched");
return; return;
} }
} }
}
// If its a "Extended Decoder Control Packet" OPS Command // If its a "Extended (Signal) Decoder OPS Command
else if ((pDccMsg->Data[1] & 0x81) == 0x01) else if ((pDccMsg->Data[1] & 0x81) == 0x01)
{ {
DB_PRINT ("eDP: Extended Decoder Control Packet OPS Command"); DB_PRINT ("eDP: Handle Signal Decoder OPS Command");
// If we're not in FLAGS_OUTPUT_ADDRESS_MODE then return as this isn't for us // If we're not in FLAGS_OUTPUT_ADDRESS_MODE then return as this isn't for us
DB_PRINT ("eDP: Check if in Board Address Mode");
if ((DccProcState.Flags & FLAGS_OUTPUT_ADDRESS_MODE) == 0) if ((DccProcState.Flags & FLAGS_OUTPUT_ADDRESS_MODE) == 0)
{ {
DB_PRINT ("eDP: Ignore Extended Decoder Control Packet in Board Address Mode"); DB_PRINT ("eDP: Ignore Signal Decoder OPS Command in Board or Extended Address Mode");
return; return;
} }
// Check if this command is for our Output Address or the broadcast address // Check if this command is for our Output Address or the broadcast address
DB_PRINT ("eDP: Check Output Address: %d", OutputAddress); DB_PRINT ("eDP: Compare Signal Address: %d to MyAddr: %d", OutputAddress, getMyAddr());
if ( (OutputAddress != getMyAddr()) && (OutputAddress < 2045)) if ( (OutputAddress != getMyAddr()) && (OutputAddress < 2045))
{ {
DB_PRINT ("eDP: Output Address Not Matched"); DB_PRINT ("eDP: Signal Address Not Matched");
return; return;
} } }
}
uint16_t cvAddress = ( (pDccMsg->Data[2] & 0b00000011) << 8) + pDccMsg->Data[3] + 1; uint16_t cvAddress = ( (pDccMsg->Data[2] & 0b00000011) << 8) + pDccMsg->Data[3] + 1;
uint8_t cvValue = pDccMsg->Data[4]; uint8_t cvValue = pDccMsg->Data[4];

View File

@@ -234,11 +234,17 @@ public:
#define FLAGS_MY_ADDRESS_ONLY 0x01 // Only process DCC Packets with My Address #define FLAGS_MY_ADDRESS_ONLY 0x01 // Only process DCC Packets with My Address
#define FLAGS_AUTO_FACTORY_DEFAULT 0x02 // Call notifyCVResetFactoryDefault() if CV 7 & 8 == 255 #define FLAGS_AUTO_FACTORY_DEFAULT 0x02 // Call notifyCVResetFactoryDefault() if CV 7 & 8 == 255
#define FLAGS_SETCV_CALLED 0x10 // only used internally !! #define FLAGS_SETCV_CALLED 0x10 // only used internally !!
#define FLAGS_OUTPUT_ADDRESS_MODE 0x40 // CV 29/541 bit 6 #define FLAGS_EXTENDED_ADDRESS_MODE 0x20 // CV 29/541 bit 5 0 = 9-bit Board or Decoder Addressing mode, 1 = 11-bit Extended Address using middle 2 DD of the CDDD bits for the extra 2 bits
#define FLAGS_DCC_ACCESSORY_DECODER 0x80 // CV 29/541 bit 7 #define FLAGS_OUTPUT_ADDRESS_MODE 0x40 // CV 29/541 bit 6 0 = Board or Extended Addressing Mode, 1 = Signal Decoder Output Addressing Mode
#define FLAGS_DCC_ACCESSORY_DECODER 0x80 // CV 29/541 bit 7 0 = Multifunction Decoder, 1 = Accessory Decoder
#define FLAGS_MULTIFUNCTION_DECODER ()
#define FLAGS_BASIC_ACCESSORY_DECODER (FLAGS_DCC_ACCESSORY_DECODER)
#define FLAGS_EXTENDED_ACCESSORY_DECODER (FLAGS_DCC_ACCESSORY_DECODER | FLAGS_EXTENDED_ADDRESS_MODE)
#define FLAGS_SIGNAL_ACCESSORY_DECODER (FLAGS_DCC_ACCESSORY_DECODER | FLAGS_OUTPUT_ADDRESS_MODE)
// Flag Bits that are cloned from CV29 relating the DCC Accessory Decoder // Flag Bits that are cloned from CV29 relating the DCC Accessory Decoder
#define FLAGS_CV29_BITS (FLAGS_OUTPUT_ADDRESS_MODE | FLAGS_DCC_ACCESSORY_DECODER) #define FLAGS_CV29_BITS (FLAGS_EXTENDED_ACCESSORY_DECODER | FLAGS_OUTPUT_ADDRESS_MODE | FLAGS_DCC_ACCESSORY_DECODER)
/*+ /*+