made some changes to the handling of Accessory Basic and Extended OPS Mode CV Programming
This commit is contained in:
81
NmraDcc.cpp
81
NmraDcc.cpp
@@ -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
|
||||||
@@ -1337,8 +1337,8 @@ void execDccProcessor (DCC_MSG * pDccMsg)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
BoardAddress = ( ( (~pDccMsg->Data[1]) & 0b01110000) << 2) | (pDccMsg->Data[0] & 0b00111111) ;
|
BoardAddress = ( ( (~pDccMsg->Data[1]) & 0b01110000) << 2) | (pDccMsg->Data[0] & 0b00111111) ;
|
||||||
TurnoutPairIndex = (pDccMsg->Data[1] & 0b00000110) >> 1;
|
TurnoutPairIndex = ( pDccMsg->Data[1] & 0b00000110) >> 1;
|
||||||
DB_PRINT ("eDP: BAddr:%d, Index:%d", BoardAddress, TurnoutPairIndex);
|
DB_PRINT ("eDP: Board Address: %d, Index: %d", BoardAddress, TurnoutPairIndex);
|
||||||
|
|
||||||
// First check for Legacy Accessory Decoder Configuration Variable Access Instruction
|
// First check for Legacy Accessory Decoder Configuration Variable Access Instruction
|
||||||
// as it's got a different format to the others
|
// as it's got a different format to the others
|
||||||
@@ -1354,22 +1354,21 @@ void execDccProcessor (DCC_MSG * pDccMsg)
|
|||||||
|
|
||||||
uint16_t cvAddress = ( (pDccMsg->Data[1] & 0b00000011) << 8) + pDccMsg->Data[2] + 1;
|
uint16_t cvAddress = ( (pDccMsg->Data[1] & 0b00000011) << 8) + pDccMsg->Data[2] + 1;
|
||||||
uint8_t cvValue = pDccMsg->Data[3];
|
uint8_t cvValue = pDccMsg->Data[3];
|
||||||
DB_PRINT ("eDP: CV:%d Value:%d", cvAddress, cvValue);
|
DB_PRINT ("eDP: CV: %d Value: %d", cvAddress, cvValue);
|
||||||
if (validCV (cvAddress, 1))
|
if (validCV (cvAddress, 1))
|
||||||
writeCV (cvAddress, cvValue);
|
writeCV (cvAddress, cvValue);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
OutputAddress = ( ( (BoardAddress - 1) << 2) | TurnoutPairIndex) + 1 ; //decoder output addresses start with 1, packet address range starts with 0
|
OutputAddress = ( ( (BoardAddress - 1) << 2) | TurnoutPairIndex) + 1 ; //decoder output addresses start with 1, packet address range starts with 0
|
||||||
// ( according to NMRA 9.2.2 )
|
// ( according to NMRA 9.2.2 )
|
||||||
DB_PRINT ("eDP: OAddr:%d", OutputAddress);
|
DB_PRINT ("eDP: Output Address: %d", OutputAddress);
|
||||||
|
|
||||||
if (DccProcState.inAccDecDCCAddrNextReceivedMode)
|
if (DccProcState.inAccDecDCCAddrNextReceivedMode)
|
||||||
{
|
{
|
||||||
if (DccProcState.Flags & FLAGS_OUTPUT_ADDRESS_MODE)
|
if (DccProcState.Flags & FLAGS_OUTPUT_ADDRESS_MODE)
|
||||||
{
|
{
|
||||||
DB_PRINT ("eDP: Set OAddr:%d", OutputAddress);
|
DB_PRINT ("eDP: Set Output 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));
|
||||||
@@ -1379,7 +1378,7 @@ void execDccProcessor (DCC_MSG * pDccMsg)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DB_PRINT ("eDP: Set BAddr:%d", BoardAddress);
|
DB_PRINT ("eDP: Set 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,12 +1392,12 @@ void execDccProcessor (DCC_MSG * pDccMsg)
|
|||||||
// If we're filtering addresses, does the address match our address or is it a broadcast address? If NOT then return
|
// If we're filtering addresses, does the address match our address or is it a broadcast address? If NOT then return
|
||||||
if (DccProcState.Flags & FLAGS_MY_ADDRESS_ONLY)
|
if (DccProcState.Flags & FLAGS_MY_ADDRESS_ONLY)
|
||||||
{
|
{
|
||||||
|
DB_PRINT ("eDP: Check if the Address matches");
|
||||||
if (DccProcState.Flags & FLAGS_OUTPUT_ADDRESS_MODE)
|
if (DccProcState.Flags & FLAGS_OUTPUT_ADDRESS_MODE)
|
||||||
{
|
{
|
||||||
DB_PRINT (" AddrChk: OAddr:%d, BAddr:%d, myAddr:%d Chk=%d", OutputAddress, BoardAddress, getMyAddr(), OutputAddress != getMyAddr());
|
|
||||||
if (OutputAddress != getMyAddr() && OutputAddress < 2045)
|
if (OutputAddress != getMyAddr() && OutputAddress < 2045)
|
||||||
{
|
{
|
||||||
DB_PRINT (" eDP: OAddr:%d, myAddr:%d - no match", OutputAddress, getMyAddr());
|
DB_PRINT ("eDP: OAddr: %d, myAddr: %d - no match", OutputAddress, getMyAddr());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1406,10 +1405,11 @@ void execDccProcessor (DCC_MSG * pDccMsg)
|
|||||||
{
|
{
|
||||||
if ( (BoardAddress != getMyAddr()) && (BoardAddress < 511))
|
if ( (BoardAddress != getMyAddr()) && (BoardAddress < 511))
|
||||||
{
|
{
|
||||||
DB_PRINT (" eDP: BAddr:%d, myAddr:%d - no match", BoardAddress, getMyAddr());
|
DB_PRINT ("eDP: BAddr: %d, myAddr: %d - no match", BoardAddress, getMyAddr());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DB_PRINT ("eDP: Address Matched");
|
DB_PRINT ("eDP: Address Matched");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1419,7 +1419,7 @@ void execDccProcessor (DCC_MSG * pDccMsg)
|
|||||||
// According to the NMRA Dcc Spec the Signal State should only use the lower 5 Bits,
|
// According to the NMRA Dcc Spec the Signal State should only use the lower 5 Bits,
|
||||||
// however some manufacturers seem to allow/use all 8 bits, so we'll relax that constraint for now
|
// however some manufacturers seem to allow/use all 8 bits, so we'll relax that constraint for now
|
||||||
uint8_t state = pDccMsg->Data[2] ;
|
uint8_t state = pDccMsg->Data[2] ;
|
||||||
DB_PRINT ("eDP: OAddr:%d Extended State:%0X", OutputAddress, state);
|
DB_PRINT ("eDP: Output Address: %d Extended State: %0X", OutputAddress, state);
|
||||||
if (notifyDccSigOutputState)
|
if (notifyDccSigOutputState)
|
||||||
notifyDccSigOutputState (OutputAddress, state);
|
notifyDccSigOutputState (OutputAddress, state);
|
||||||
|
|
||||||
@@ -1439,13 +1439,13 @@ void execDccProcessor (DCC_MSG * pDccMsg)
|
|||||||
|
|
||||||
if (DccProcState.Flags & FLAGS_OUTPUT_ADDRESS_MODE)
|
if (DccProcState.Flags & FLAGS_OUTPUT_ADDRESS_MODE)
|
||||||
{
|
{
|
||||||
DB_PRINT ("eDP: OAddr:%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)
|
||||||
notifyDccAccTurnoutOutput (OutputAddress, direction, outputPower);
|
notifyDccAccTurnoutOutput (OutputAddress, direction, outputPower);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DB_PRINT ("eDP: Turnout Pair Index:%d Dir:%d Output Power: ", TurnoutPairIndex, direction, outputPower);
|
DB_PRINT ("eDP: Turnout Pair Index: %d Dir: %d Output Power: ", TurnoutPairIndex, direction, outputPower);
|
||||||
if (notifyDccAccTurnoutBoard)
|
if (notifyDccAccTurnoutBoard)
|
||||||
notifyDccAccTurnoutBoard (BoardAddress, TurnoutPairIndex, direction, outputPower);
|
notifyDccAccTurnoutBoard (BoardAddress, TurnoutPairIndex, direction, outputPower);
|
||||||
}
|
}
|
||||||
@@ -1460,19 +1460,21 @@ void execDccProcessor (DCC_MSG * pDccMsg)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if this command is for our address or the broadcast address
|
// If its a "Basic Accessory Decoder Packet" OPS Command
|
||||||
if (DccProcState.Flags & FLAGS_OUTPUT_ADDRESS_MODE)
|
if ((pDccMsg->Data[1] & 0x80) == 0x80)
|
||||||
{
|
{
|
||||||
DB_PRINT ("eDP: Check Output Address:%d", OutputAddress);
|
DB_PRINT ("eDP: Basic Accessory Decoder Packet OPS Command");
|
||||||
if ( (OutputAddress != getMyAddr()) && (OutputAddress < 2045))
|
|
||||||
{
|
// If we're in FLAGS_OUTPUT_ADDRESS_MODE then return as this isn't for us
|
||||||
DB_PRINT ("eDP: Output Address Not Matched");
|
DB_PRINT ("eDP: Check if in Output Address Mode");
|
||||||
return;
|
if(DccProcState.Flags & FLAGS_OUTPUT_ADDRESS_MODE)
|
||||||
}
|
{
|
||||||
}
|
DB_PRINT ("eDP: Ignore Basic Accessory Decoder Packet in Output Address Mode");
|
||||||
else
|
return;
|
||||||
{
|
}
|
||||||
DB_PRINT ("eDP: Check Board Address:%d", BoardAddress);
|
|
||||||
|
// 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");
|
||||||
@@ -1480,12 +1482,33 @@ void execDccProcessor (DCC_MSG * pDccMsg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If its a "Extended Decoder Control Packet" OPS Command
|
||||||
|
else if ((pDccMsg->Data[1] & 0x81) == 0x01)
|
||||||
|
{
|
||||||
|
DB_PRINT ("eDP: Extended Decoder Control Packet OPS Command");
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
{
|
||||||
|
DB_PRINT ("eDP: Ignore Extended Decoder Control Packet in Board Address Mode");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if this command is for our Output Address or the broadcast address
|
||||||
|
DB_PRINT ("eDP: Check Output Address: %d", OutputAddress);
|
||||||
|
if ( (OutputAddress != getMyAddr()) && (OutputAddress < 2045))
|
||||||
|
{
|
||||||
|
DB_PRINT ("eDP: Output Address Not Matched");
|
||||||
|
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];
|
||||||
|
|
||||||
OpsInstructionType insType = (OpsInstructionType) ( (pDccMsg->Data[2] & 0b00001100) >> 2) ;
|
OpsInstructionType insType = (OpsInstructionType) ( (pDccMsg->Data[2] & 0b00001100) >> 2) ;
|
||||||
|
|
||||||
DB_PRINT ("eDP: OPS Mode Instruction:%d", insType);
|
DB_PRINT ("eDP: OPS Mode Instruction: %d", insType);
|
||||||
switch (insType)
|
switch (insType)
|
||||||
{
|
{
|
||||||
case OPS_INS_RESERVED:
|
case OPS_INS_RESERVED:
|
||||||
@@ -1494,7 +1517,7 @@ void execDccProcessor (DCC_MSG * pDccMsg)
|
|||||||
break; // We only support Write Byte or Bit Manipulation
|
break; // We only support Write Byte or Bit Manipulation
|
||||||
|
|
||||||
case OPS_INS_WRITE_BYTE:
|
case OPS_INS_WRITE_BYTE:
|
||||||
DB_PRINT ("eDP: CV:%d Value:%d", cvAddress, cvValue);
|
DB_PRINT ("eDP: CV:%d Value: %d", cvAddress, cvValue);
|
||||||
if (validCV (cvAddress, 1))
|
if (validCV (cvAddress, 1))
|
||||||
writeCV (cvAddress, cvValue);
|
writeCV (cvAddress, cvValue);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
name=NmraDcc
|
name=NmraDcc
|
||||||
version=2.0.10
|
version=2.0.11
|
||||||
author=Alex Shepherd, Wolfgang Kuffer, Geoff Bunza, Martin Pischky, Franz-Peter Müller, Sven (littleyoda), Hans Tanner, bugfixes by Jueff
|
author=Alex Shepherd, Wolfgang Kuffer, Geoff Bunza, Martin Pischky, Franz-Peter Müller, Sven (littleyoda), Hans Tanner, bugfixes by Jueff
|
||||||
maintainer=Alex Shepherd <kiwi64ajs@gmail.com>
|
maintainer=Alex Shepherd <kiwi64ajs@gmail.com>
|
||||||
sentence=Enables NMRA DCC Communication
|
sentence=Enables NMRA DCC Communication
|
||||||
|
|||||||
Reference in New Issue
Block a user