Merge branch 'master' into MicroBahner-Without-use-of-HW-timers

This commit is contained in:
Alex Shepherd
2016-03-24 18:51:12 +13:00
20 changed files with 626 additions and 64 deletions

View File

@@ -888,8 +888,17 @@ void execDccProcessor( DCC_MSG * pDccMsg )
if(pDccMsg->Data[1] & 0b10000000)
{
uint8_t direction = OutputAddress & 0x01;
uint8_t outputPower = (pDccMsg->Data[1] & 0b00001000) >> 3;
if( notifyDccAccState )
notifyDccAccState( Address, BoardAddress, OutputAddress, pDccMsg->Data[1] & 0b00001000 ) ;
if( notifyDccAccTurnoutBoard )
notifyDccAccTurnoutBoard( BoardAddress, OutputIndex, direction, outputPower );
if( notifyDccAccTurnoutOutput )
notifyDccAccTurnoutOutput( Address, direction, outputPower );
}
else

View File

@@ -223,6 +223,8 @@ extern void notifyDccSpeedRaw( uint16_t Addr, DCC_ADDR_TYPE AddrType, uint8_t Ra
extern void notifyDccFunc( uint16_t Addr, DCC_ADDR_TYPE AddrType, FN_GROUP FuncGrp, uint8_t FuncState) __attribute__ ((weak));
extern void notifyDccAccState( uint16_t Addr, uint16_t BoardAddr, uint8_t OutputAddr, uint8_t State ) __attribute__ ((weak));
extern void notifyDccAccTurnoutBoard( uint16_t BoardAddr, uint8_t OutputPair, uint8_t Direction, uint8_t OutputPower ) __attribute__ ((weak));
extern void notifyDccAccTurnoutOutput( uint16_t Addr, uint8_t Direction, uint8_t OutputPower ) __attribute__ ((weak));
extern void notifyDccSigState( uint16_t Addr, uint8_t OutputIndex, uint8_t State) __attribute__ ((weak));

View File

@@ -69,6 +69,30 @@ void notifyDccAccState( uint16_t Addr, uint16_t BoardAddr, uint8_t OutputAddr, u
Serial.println(State, HEX) ;
}
// This function is called whenever a normal DCC Turnout Packet is received
void notifyDccAccTurnoutBoard( uint16_t BoardAddr, uint8_t OutputPair, uint8_t Direction, uint8_t OutputPower )
{
Serial.print("notifyDccAccTurnoutBoard: ") ;
Serial.print(BoardAddr,DEC) ;
Serial.print(',');
Serial.print(OutputPair,DEC) ;
Serial.print(',');
Serial.print(Direction,DEC) ;
Serial.print(',');
Serial.println(OutputPower, HEX) ;
}
// This function is called whenever a normal DCC Turnout Packet is received
void notifyDccAccTurnoutOutput( uint16_t Addr, uint8_t Direction, uint8_t OutputPower )
{
Serial.print("notifyDccAccTurnoutOutput: ") ;
Serial.print(Addr,DEC) ;
Serial.print(',');
Serial.print(Direction,DEC) ;
Serial.print(',');
Serial.println(OutputPower, HEX) ;
}
// This function is called whenever a DCC Signal Aspect Packet is received
void notifyDccSigState( uint16_t Addr, uint8_t OutputIndex, uint8_t State)
{

View File

@@ -0,0 +1,214 @@
#include <NmraDcc.h>
#include "PinPulser.h"
// This Example shows how to use the library as a DCC Accessory Decoder to drive 8 Pulsed Turnouts
// You can print every DCC packet by un-commenting the line below
//#define NOTIFY_DCC_MSG
// You can print every notifyDccAccTurnoutOutput call-back by un-commenting the line below
#define NOTIFY_TURNOUT_MSG
// You can also print other Debug Messages uncommenting the line below
#define DEBUG_MSG
// Un-Comment the line below to force CVs to be written to the Factory Default values
// defined in the FactoryDefaultCVs below on Start-Up
#define FORCE_RESET_FACTORY_DEFAULT_CV
// Un-Comment the line below to Enable DCC ACK for Service Mode Programming Read CV Capablilty
//#define ENABLE_DCC_ACK 15 // This is A1 on the Iowa Scaled Engineering ARD-DCCSHIELD DCC Shield
#define NUM_TURNOUTS 8 // Set Number of Turnouts (Pairs of Pins)
#define ACTIVE_OUTPUT_STATE LOW // Set the ACTIVE State of the output to Drive the Turnout motor electronics HIGH or LOW
#define DCC_DECODER_VERSION_NUM 11 // Set the Decoder Version - Used by JMRI to Identify the decoder
struct CVPair
{
uint16_t CV;
uint8_t Value;
};
#define CV_ACCESSORY_DECODER_OUTPUT_PULSE_TIME 2 // CV for the Output Pulse ON ms
#define CV_ACCESSORY_DECODER_CDU_RECHARGE_TIME 3 // CV for the delay in ms to allow a CDU to recharge
#define CV_ACCESSORY_DECODER_ACTIVE_STATE 4 // CV to define the ON Output State
// To set the Turnout Addresses for this board you need to change the CV values for CV1 (CV_ACCESSORY_DECODER_ADDRESS_LSB) and
// CV9 (CV_ACCESSORY_DECODER_ADDRESS_MSB) in the FactoryDefaultCVs structure below. The Turnout Addresses are defined as:
// Base Turnout Address is: ((((CV9 * 64) + CV1) - 1) * 4) + 1
// With NUM_TURNOUTS 8 (above) a CV1 = 1 and CV9 = 0, the Turnout Addresses will be 1..8, for CV1 = 2 the Turnout Address is 5..12
CVPair FactoryDefaultCVs [] =
{
{CV_ACCESSORY_DECODER_ADDRESS_LSB, 1}, // CV 1 Board Address (lower 6 bits)
{CV_ACCESSORY_DECODER_ADDRESS_MSB, 0}, // CV 9 Board Address (Upper 3 bits)
{CV_ACCESSORY_DECODER_OUTPUT_PULSE_TIME, 50}, // x 10mS for the output pulse duration
{CV_ACCESSORY_DECODER_CDU_RECHARGE_TIME, 30}, // x 10mS for the CDU recharge delay time
{CV_ACCESSORY_DECODER_ACTIVE_STATE, ACTIVE_OUTPUT_STATE},
};
uint8_t FactoryDefaultCVIndex = 0;
// This is the Arduino Pin Mapping to Turnout Addresses with 2 pins per turnout
// A1 is missing in the sequence as it is used for the DCC ACK
// The Pins are defined in Pairs T=Thrown, C=Closed (Digitrax Notation)
// base address 1T 1C 2T 2C 3T 3C 4T 4C 5T 5C 6T 6C 7T 7C 8T 8C
byte outputs[] = { 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 18, 19};
// pins D3 D4 D5 D6 D7 D8 D9 D10 D11 D12 D13 A0 A2 A3 A4 A5
NmraDcc Dcc ;
DCC_MSG Packet ;
PinPulser pinPulser;
uint16_t BaseTurnoutAddress;
// This function is called whenever a normal DCC Turnout Packet is received
void notifyDccAccTurnoutOutput( uint16_t Addr, uint8_t Direction, uint8_t OutputPower )
{
#ifdef NOTIFY_TURNOUT_MSG
Serial.print("notifyDccAccTurnoutOutput: Turnout: ") ;
Serial.print(Addr,DEC) ;
Serial.print(" Direction: ");
Serial.print(Direction ? "Closed" : "Thrown") ;
Serial.print(" Output: ");
Serial.print(OutputPower ? "On" : "Off") ;
#endif
if(( Addr >= BaseTurnoutAddress ) && ( Addr < (BaseTurnoutAddress + NUM_TURNOUTS )) && OutputPower )
{
uint16_t pinIndex = ( (Addr - BaseTurnoutAddress) << 1 ) + Direction ;
pinPulser.addPin(outputs[pinIndex]);
#ifdef NOTIFY_TURNOUT_MSG
Serial.print(" Pin Index: ");
Serial.print(pinIndex,DEC);
Serial.print(" Pin: ");
Serial.print(outputs[pinIndex],DEC);
#endif
}
#ifdef NOTIFY_TURNOUT_MSG
Serial.println();
#endif
}
void initPinPulser(void)
{
BaseTurnoutAddress = (((Dcc.getCV(CV_ACCESSORY_DECODER_ADDRESS_MSB) * 64) + Dcc.getCV(CV_ACCESSORY_DECODER_ADDRESS_LSB) - 1) * 4) + 1 ;
uint16_t onMs = Dcc.getCV(CV_ACCESSORY_DECODER_OUTPUT_PULSE_TIME) * 10;
uint16_t cduRechargeMs = Dcc.getCV(CV_ACCESSORY_DECODER_CDU_RECHARGE_TIME) * 10;
uint8_t activeOutputState = Dcc.getCV(CV_ACCESSORY_DECODER_ACTIVE_STATE);
#ifdef DEBUG_MSG
Serial.print("initPinPulser: DCC Turnout Base Address: "); Serial.print(BaseTurnoutAddress, DEC);
Serial.print(" Active Pulse: "); Serial.print(onMs);
Serial.print("ms CDU Recharge: "); Serial.print(cduRechargeMs);
Serial.print("ms Active Output State: "); Serial.println(activeOutputState ? "HIGH" : "LOW" );
#endif
// Step through all the Turnout Driver pins setting them to OUTPUT and NOT Active State
for(uint8_t i = 0; i < (NUM_TURNOUTS * 2); i++)
{
digitalWrite(outputs[i], !activeOutputState); // Set the Output Inactive before the direction so the
pinMode( outputs[i], OUTPUT ); // Pin doesn't momentarily pulse the wrong state
}
// Init the PinPulser with the new settings
pinPulser.init(onMs, cduRechargeMs, activeOutputState);
}
void setup()
{
Serial.begin(115200);
// Setup which External Interrupt, the Pin it's associated with that we're using and enable the Pull-Up
Dcc.pin(0, 2, 1);
// Call the main DCC Init function to enable the DCC Receiver
Dcc.init( MAN_ID_DIY, DCC_DECODER_VERSION_NUM, CV29_ACCESSORY_DECODER, 0 );
#ifdef DEBUG_MSG
Serial.print("\nNMRA DCC 8-Turnout Accessory Decoder. Ver: "); Serial.println(DCC_DECODER_VERSION_NUM,DEC);
#endif
#ifdef FORCE_RESET_FACTORY_DEFAULT_CV
Serial.println("Resetting CVs to Factory Defaults");
notifyCVResetFactoryDefault();
#endif
if( FactoryDefaultCVIndex == 0) // Not forcing a reset CV Reset to Factory Defaults so initPinPulser
initPinPulser();
}
void loop()
{
// You MUST call the NmraDcc.process() method frequently from the Arduino loop() function for correct library operation
Dcc.process();
pinPulser.process();
if( FactoryDefaultCVIndex && Dcc.isSetCVReady())
{
FactoryDefaultCVIndex--; // Decrement first as initially it is the size of the array
uint16_t cv = FactoryDefaultCVs[FactoryDefaultCVIndex].CV;
uint8_t val = FactoryDefaultCVs[FactoryDefaultCVIndex].Value;
#ifdef DEBUG_MSG
Serial.print("loop: Write Default CV: "); Serial.print(cv,DEC); Serial.print(" Value: "); Serial.println(val,DEC);
#endif
Dcc.setCV( cv, val );
if( FactoryDefaultCVIndex == 0) // Is this the last Default CV to set? if so re-initPinPulser
initPinPulser();
}
}
void notifyCVChange(uint16_t CV, uint8_t Value)
{
#ifdef DEBUG_MSG
Serial.print("notifyCVChange: CV: ") ;
Serial.print(CV,DEC) ;
Serial.print(" Value: ") ;
Serial.println(Value, DEC) ;
#endif
Value = Value; // Silence Compiler Warnings...
if((CV == CV_ACCESSORY_DECODER_ADDRESS_MSB) || (CV == CV_ACCESSORY_DECODER_ADDRESS_LSB) ||
(CV == CV_ACCESSORY_DECODER_OUTPUT_PULSE_TIME) || (CV == CV_ACCESSORY_DECODER_CDU_RECHARGE_TIME) || (CV == CV_ACCESSORY_DECODER_ACTIVE_STATE))
initPinPulser(); // Some CV we care about changed so re-init the PinPulser with the new CV settings
}
void notifyCVResetFactoryDefault()
{
// Make FactoryDefaultCVIndex non-zero and equal to num CV's to be reset
// to flag to the loop() function that a reset to Factory Defaults needs to be done
FactoryDefaultCVIndex = sizeof(FactoryDefaultCVs)/sizeof(CVPair);
};
// This function is called by the NmraDcc library when a DCC ACK needs to be sent
// Calling this function should cause an increased 60ma current drain on the power supply for 6ms to ACK a CV Read
#ifdef ENABLE_DCC_ACK
void notifyCVAck(void)
{
#ifdef DEBUG_MSG
Serial.println("notifyCVAck") ;
#endif
// Configure the DCC CV Programing ACK pin for an output
pinMode( ENABLE_DCC_ACK, OUTPUT );
// Generate the DCC ACK 60mA pulse
digitalWrite( ENABLE_DCC_ACK, HIGH );
delay( 10 ); // The DCC Spec says 6ms but 10 makes sure... ;)
digitalWrite( ENABLE_DCC_ACK, LOW );
}
#endif
#ifdef NOTIFY_DCC_MSG
void notifyDccMsg( DCC_MSG * Msg)
{
Serial.print("notifyDccMsg: ") ;
for(uint8_t i = 0; i < Msg->Size; i++)
{
Serial.print(Msg->Data[i], HEX);
Serial.write(' ');
}
Serial.println();
}
#endif

View File

@@ -0,0 +1,92 @@
#include "PinPulser.h"
#define PIN_PULSER_SLOT_EMPTY 255
void PinPulser::init(uint16_t onMs, uint16_t cduRechargeMs, uint8_t activeOutputState)
{
this->onMs = onMs;
this->cduRechargeMs = cduRechargeMs;
this->activeOutputState = activeOutputState;
state = PP_IDLE;
targetMs = 0;
memset(pinQueue, PIN_PULSER_SLOT_EMPTY, PIN_PULSER_MAX_PINS + 1);
}
uint8_t PinPulser::addPin(uint8_t Pin)
{
// Serial.print(" PinPulser::addPin: "); Serial.print(Pin,DEC);
for(uint8_t i = 0; i < PIN_PULSER_MAX_PINS; i++)
{
if(pinQueue[i] == Pin)
{
// Serial.print(" Already in Index: "); Serial.println(i,DEC);
return i;
}
else if(pinQueue[i] == PIN_PULSER_SLOT_EMPTY)
{
// Serial.print(" pinQueue Index: "); Serial.println(i,DEC);
pinQueue[i] = Pin;
process();
return i;
}
}
// Serial.println();
return PIN_PULSER_SLOT_EMPTY;
}
PP_State PinPulser::process(void)
{
unsigned long now;
switch(state)
{
case PP_IDLE:
if(pinQueue[0] != PIN_PULSER_SLOT_EMPTY)
{
// Serial.print(" PinPulser::process: PP_IDLE: Pin: "); Serial.println(pinQueue[0],DEC);
digitalWrite(pinQueue[0], activeOutputState);
targetMs = millis() + onMs;
state = PP_OUTPUT_ON_DELAY;
}
break;
case PP_OUTPUT_ON_DELAY:
now = millis();
if(now >= targetMs)
{
// Serial.print(" PinPulser::process: PP_OUTPUT_ON_DELAY: Done Deactivate Pin: "); Serial.println(pinQueue[0],DEC);
digitalWrite(pinQueue[0], !activeOutputState);
targetMs = now + cduRechargeMs;
memmove(pinQueue, pinQueue + 1, PIN_PULSER_MAX_PINS);
state = PP_CDU_RECHARGE_DELAY;
}
break;
case PP_CDU_RECHARGE_DELAY:
now = millis();
if(now >= targetMs)
{
if(pinQueue[0] != PIN_PULSER_SLOT_EMPTY)
{
// Serial.print(" PinPulser::process: PIN_PULSER_SLOT_EMPTY: Done Deactivate Pin: "); Serial.println(pinQueue[0],DEC);
digitalWrite(pinQueue[0], activeOutputState);
targetMs = now + onMs;
state = PP_OUTPUT_ON_DELAY;
}
else
{
// Serial.println(" PinPulser::process: PP_CDU_RECHARGE_DELAY - Now PP_IDLE");
state = PP_IDLE;
}
}
break;
}
return state;
}

View File

@@ -0,0 +1,27 @@
#include <Arduino.h>
#define PIN_PULSER_MAX_PINS 16
enum PP_State
{
PP_IDLE = 0,
PP_OUTPUT_ON_DELAY,
PP_CDU_RECHARGE_DELAY,
};
class PinPulser
{
private:
uint16_t onMs;
uint16_t cduRechargeMs;
PP_State state = PP_IDLE;
unsigned long targetMs = 0;
uint8_t activeOutputState = HIGH;
uint8_t pinQueue[PIN_PULSER_MAX_PINS + 1];
public:
void init(uint16_t onMs, uint16_t cduRechargeMs, uint8_t activeOutputState);
uint8_t addPin(uint8_t pin);
PP_State process(void);
};

View File

@@ -0,0 +1,195 @@
#include <NmraDcc.h>
#define This_Decoder_Address 3
struct CVPair
{
uint16_t CV;
uint8_t Value;
};
CVPair FactoryDefaultCVs [] =
{
// The CV Below defines the Short DCC Address
{CV_MULTIFUNCTION_PRIMARY_ADDRESS, This_Decoder_Address},
// These two CVs define the Long DCC Address
{CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB, 0},
{CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB, This_Decoder_Address},
// ONLY uncomment 1 CV_29_CONFIG line below as approprate
// {CV_29_CONFIG, 0}, // Short Address 14 Speed Steps
{CV_29_CONFIG, CV29_F0_LOCATION}, // Short Address 28/128 Speed Steps
// {CV_29_CONFIG, CV29_EXT_ADDRESSING | CV29_F0_LOCATION}, // Long Address 28/128 Speed Steps
};
NmraDcc Dcc ;
uint8_t FactoryDefaultCVIndex = 0;
// Uncomment this line below to force resetting the CVs back to Factory Defaults
// FactoryDefaultCVIndex = sizeof(FactoryDefaultCVs)/sizeof(CVPair);
void notifyCVResetFactoryDefault()
{
// Make FactoryDefaultCVIndex non-zero and equal to num CV's to be reset
// to flag to the loop() function that a reset to Factory Defaults needs to be done
FactoryDefaultCVIndex = sizeof(FactoryDefaultCVs)/sizeof(CVPair);
};
// Uncomment the #define below to print all Speed Packets
#define NOTIFY_DCC_SPEED
#ifdef NOTIFY_DCC_SPEED
void notifyDccSpeed( uint16_t Addr, DCC_ADDR_TYPE AddrType, uint8_t Speed, DCC_DIRECTION Dir, DCC_SPEED_STEPS SpeedSteps )
{
Serial.print("notifyDccSpeed: Addr: ");
Serial.print(Addr,DEC);
Serial.print( (AddrType == DCC_ADDR_SHORT) ? "-S" : "-L" );
Serial.print(" Speed: ");
Serial.print(Speed,DEC);
Serial.print(" Steps: ");
Serial.print(SpeedSteps,DEC);
Serial.print(" Dir: ");
Serial.println( (Dir == DCC_DIR_FWD) ? "Forward" : "Reverse" );
};
#endif
// Uncomment the #define below to print all Function Packets
#define NOTIFY_DCC_FUNC
#ifdef NOTIFY_DCC_FUNC
void notifyDccFunc(uint16_t Addr, DCC_ADDR_TYPE AddrType, FN_GROUP FuncGrp, uint8_t FuncState)
{
Serial.print("notifyDccFunc: Addr: ");
Serial.print(Addr,DEC);
Serial.print( (AddrType == DCC_ADDR_SHORT) ? 'S' : 'L' );
Serial.print(" Function Group: ");
Serial.print(FuncGrp,DEC);
switch( FuncGrp )
{
#ifdef NMRA_DCC_ENABLE_14_SPEED_STEP_MODE
case FN_0:
Serial.print(" FN0: ");
Serial.println((FuncState & FN_BIT_00) ? "1 " : "0 ");
break;
#endif
case FN_0_4:
if(Dcc.getCV(CV_29_CONFIG) & CV29_F0_LOCATION) // Only process Function 0 in this packet if we're not in Speed Step 14 Mode
{
Serial.print(" FN 0: ");
Serial.print((FuncState & FN_BIT_00) ? "1 ": "0 ");
}
Serial.print(" FN 1-4: ");
Serial.print((FuncState & FN_BIT_01) ? "1 ": "0 ");
Serial.print((FuncState & FN_BIT_02) ? "1 ": "0 ");
Serial.print((FuncState & FN_BIT_03) ? "1 ": "0 ");
Serial.println((FuncState & FN_BIT_04) ? "1 ": "0 ");
break;
case FN_5_8:
Serial.print(" FN 5-8: ");
Serial.print((FuncState & FN_BIT_05) ? "1 ": "0 ");
Serial.print((FuncState & FN_BIT_06) ? "1 ": "0 ");
Serial.print((FuncState & FN_BIT_07) ? "1 ": "0 ");
Serial.println((FuncState & FN_BIT_08) ? "1 ": "0 ");
break;
case FN_9_12:
Serial.print(" FN 9-12: ");
Serial.print((FuncState & FN_BIT_09) ? "1 ": "0 ");
Serial.print((FuncState & FN_BIT_10) ? "1 ": "0 ");
Serial.print((FuncState & FN_BIT_11) ? "1 ": "0 ");
Serial.println((FuncState & FN_BIT_12) ? "1 ": "0 ");
break;
case FN_13_20:
Serial.print(" FN 13-20: ");
Serial.print((FuncState & FN_BIT_13) ? "1 ": "0 ");
Serial.print((FuncState & FN_BIT_14) ? "1 ": "0 ");
Serial.print((FuncState & FN_BIT_15) ? "1 ": "0 ");
Serial.print((FuncState & FN_BIT_16) ? "1 ": "0 ");
Serial.print((FuncState & FN_BIT_17) ? "1 ": "0 ");
Serial.print((FuncState & FN_BIT_18) ? "1 ": "0 ");
Serial.print((FuncState & FN_BIT_19) ? "1 ": "0 ");
Serial.println((FuncState & FN_BIT_20) ? "1 ": "0 ");
break;
case FN_21_28:
Serial.print(" FN 21-28: ");
Serial.print((FuncState & FN_BIT_21) ? "1 ": "0 ");
Serial.print((FuncState & FN_BIT_22) ? "1 ": "0 ");
Serial.print((FuncState & FN_BIT_23) ? "1 ": "0 ");
Serial.print((FuncState & FN_BIT_24) ? "1 ": "0 ");
Serial.print((FuncState & FN_BIT_25) ? "1 ": "0 ");
Serial.print((FuncState & FN_BIT_26) ? "1 ": "0 ");
Serial.print((FuncState & FN_BIT_27) ? "1 ": "0 ");
Serial.println((FuncState & FN_BIT_28) ? "1 ": "0 ");
break;
}
}
#endif
// Uncomment the #define below to print all DCC Packets
#define NOTIFY_DCC_MSG
#ifdef NOTIFY_DCC_MSG
void notifyDccMsg( DCC_MSG * Msg)
{
Serial.print("notifyDccMsg: ") ;
for(uint8_t i = 0; i < Msg->Size; i++)
{
Serial.print(Msg->Data[i], HEX);
Serial.write(' ');
}
Serial.println();
}
#endif
// This function is called by the NmraDcc library when a DCC ACK needs to be sent
// Calling this function should cause an increased 60ma current drain on the power supply for 6ms to ACK a CV Read
const int DccAckPin = 15 ;
void notifyCVAck(void)
{
Serial.println("notifyCVAck") ;
digitalWrite( DccAckPin, HIGH );
delay( 8 );
digitalWrite( DccAckPin, LOW );
}
void setup()
{
Serial.begin(115200);
Serial.println("NMRA Dcc Multifunction Decoder Demo 1");
// Configure the DCC CV Programing ACK pin for an output
pinMode( DccAckPin, OUTPUT );
digitalWrite( DccAckPin, LOW );
// Setup which External Interrupt, the Pin it's associated with that we're using and enable the Pull-Up
Dcc.pin(0, 2, 0);
// Call the main DCC Init function to enable the DCC Receiver
//Dcc.init( MAN_ID_DIY, 10, CV29_ACCESSORY_DECODER | CV29_OUTPUT_ADDRESS_MODE, 0 );
Dcc.init( MAN_ID_DIY, 10, FLAGS_MY_ADDRESS_ONLY, 0 );
// Uncomment to force CV Reset to Factory Defaults
notifyCVResetFactoryDefault();
}
void loop()
{
// You MUST call the NmraDcc.process() method frequently from the Arduino loop() function for correct library operation
Dcc.process();
if( FactoryDefaultCVIndex && Dcc.isSetCVReady())
{
FactoryDefaultCVIndex--; // Decrement first as initially it is the size of the array
Dcc.setCV( FactoryDefaultCVs[FactoryDefaultCVIndex].CV, FactoryDefaultCVs[FactoryDefaultCVIndex].Value);
}
}

View File

@@ -68,7 +68,6 @@ struct QUEUE
};
QUEUE *ftn_queue = new QUEUE[16];
extern uint8_t Decoder_Address = This_Decoder_Address;
struct CVPair
{
uint16_t CV;
@@ -407,7 +406,7 @@ void loop() //****************************************************************
}
}
extern void notifyDccFunc( uint16_t Addr, FN_GROUP FuncGrp, uint8_t FuncState) {
void notifyDccFunc( uint16_t Addr, DCC_ADDR_TYPE AddrType, FN_GROUP FuncGrp, uint8_t FuncState) {
switch(FuncGrp)
{
case FN_0_4: //Function Group 1 F0 F4 F3 F2 F1

View File

@@ -68,7 +68,6 @@ struct QUEUE
};
QUEUE *ftn_queue = new QUEUE[16];
extern uint8_t Decoder_Address = This_Decoder_Address;
struct CVPair
{
uint16_t CV;
@@ -407,7 +406,7 @@ void loop() //****************************************************************
}
}
extern void notifyDccFunc( uint16_t Addr, FN_GROUP FuncGrp, uint8_t FuncState) {
void notifyDccFunc( uint16_t Addr, DCC_ADDR_TYPE AddrType, FN_GROUP FuncGrp, uint8_t FuncState) {
switch(FuncGrp)
{
case FN_0_4: //Function Group 1 F0 F4 F3 F2 F1

View File

@@ -68,7 +68,6 @@ struct QUEUE
};
QUEUE *ftn_queue = new QUEUE[16];
extern uint8_t Decoder_Address = This_Decoder_Address;
struct CVPair
{
uint16_t CV;
@@ -407,7 +406,7 @@ void loop() //****************************************************************
}
}
extern void notifyDccFunc( uint16_t Addr, FN_GROUP FuncGrp, uint8_t FuncState) {
void notifyDccFunc( uint16_t Addr, DCC_ADDR_TYPE AddrType, FN_GROUP FuncGrp, uint8_t FuncState) {
switch(FuncGrp)
{
case FN_0_4: //Function Group 1 F0 F4 F3 F2 F1

View File

@@ -33,7 +33,6 @@ DCC_MSG Packet ;
#define This_Decoder_Address 17
extern uint8_t Decoder_Address = This_Decoder_Address;
struct CVPair
{
uint16_t CV;
@@ -89,7 +88,7 @@ void loop()
}
}
extern void notifyDccFunc( uint16_t Addr, FN_GROUP FuncGrp, uint8_t FuncState)
void notifyDccFunc( uint16_t Addr, DCC_ADDR_TYPE AddrType, FN_GROUP FuncGrp, uint8_t FuncState)
{
switch(FuncGrp)
{

View File

@@ -68,7 +68,6 @@ struct QUEUE
};
QUEUE *ftn_queue = new QUEUE[16];
extern uint8_t Decoder_Address = This_Decoder_Address;
struct CVPair
{
uint16_t CV;
@@ -407,7 +406,7 @@ void loop() //****************************************************************
}
}
extern void notifyDccFunc( uint16_t Addr, FN_GROUP FuncGrp, uint8_t FuncState) {
void notifyDccFunc( uint16_t Addr, DCC_ADDR_TYPE AddrType, FN_GROUP FuncGrp, uint8_t FuncState) {
switch(FuncGrp)
{
case FN_0_4: //Function Group 1 F0 F4 F3 F2 F1

View File

@@ -67,7 +67,6 @@ struct QUEUE
};
QUEUE *ftn_queue = new QUEUE[16];
extern uint8_t Decoder_Address = This_Decoder_Address;
struct CVPair
{
uint16_t CV;
@@ -416,7 +415,7 @@ void loop() //****************************************************************
}
}
extern void notifyDccFunc( uint16_t Addr, uint8_t FuncNum, uint8_t FuncState) {
void notifyDccFunc( uint16_t Addr, DCC_ADDR_TYPE AddrType, FN_GROUP FuncGrp, uint8_t FuncState) {
if (FuncNum==1) { //Function Group 1 F0 F4 F3 F2 F1
exec_function( 0, FunctionPin0, (FuncState&0x10)>>4 );
exec_function( 1, FunctionPin1, (FuncState&0x01 ));

View File

@@ -71,7 +71,6 @@ struct QUEUE
};
QUEUE *ftn_queue = new QUEUE[16];
extern uint8_t Decoder_Address = This_Decoder_Address;
struct CVPair
{
uint16_t CV;
@@ -420,7 +419,7 @@ void loop() //****************************************************************
}
}
extern void notifyDccFunc( uint16_t Addr, FN_GROUP FuncGrp, uint8_t FuncState) {
void notifyDccFunc( uint16_t Addr, DCC_ADDR_TYPE AddrType, FN_GROUP FuncGrp, uint8_t FuncState) {
switch(FuncGrp)
{
case FN_0_4: //Function Group 1 F0 F4 F3 F2 F1

View File

@@ -85,7 +85,6 @@ struct QUEUE
};
QUEUE *ftn_queue = new QUEUE[16];
extern uint8_t Decoder_Address = This_Decoder_Address;
struct CVPair
{
uint16_t CV;
@@ -470,7 +469,7 @@ void gobwd2(int bcnt,int bcycle) {
icnt++;
}
}
extern void notifyDccSpeed( uint16_t Addr, uint8_t Speed, uint8_t ForwardDir, uint8_t MaxSpeed ) {
void notifyDccSpeed( uint16_t Addr, uint8_t Speed, uint8_t ForwardDir, uint8_t MaxSpeed ) {
if (Function13_value==1) {
Motor1Speed = Speed;
Motor1ForwardDir = ForwardDir;
@@ -482,7 +481,7 @@ extern void notifyDccSpeed( uint16_t Addr, uint8_t Speed, uint8_t ForwardDir, ui
Motor2MaxSpeed = MaxSpeed;
}
}
extern void notifyDccFunc( uint16_t Addr, FN_GROUP FuncGrp, uint8_t FuncState) {
void notifyDccFunc( uint16_t Addr, DCC_ADDR_TYPE AddrType, FN_GROUP FuncGrp, uint8_t FuncState) {
switch(FuncGrp)
{
case FN_0_4: //Function Group 1 F0 F4 F3 F2 F1
@@ -669,4 +668,5 @@ void detach_servo (int servo_num) {
default:
break;
}
}
}

View File

@@ -68,7 +68,6 @@ struct QUEUE
};
QUEUE *ftn_queue = new QUEUE[16];
extern uint8_t Decoder_Address = This_Decoder_Address;
struct CVPair
{
uint16_t CV;
@@ -407,7 +406,7 @@ void loop() //****************************************************************
}
}
extern void notifyDccFunc( uint16_t Addr, FN_GROUP FuncGrp, uint8_t FuncState) {
void notifyDccFunc( uint16_t Addr, DCC_ADDR_TYPE AddrType, FN_GROUP FuncGrp, uint8_t FuncState) {
switch(FuncGrp)
{
case FN_0_4: //Function Group 1 F0 F4 F3 F2 F1

View File

@@ -101,7 +101,8 @@ void loop()
// You MUST call the NmraDcc.process() method frequently from the Arduino loop() function for correct library operation
Dcc.process();
}
extern void notifyDccFunc( uint16_t Addr, FN_GROUP FuncGrp, uint8_t FuncState) {
void notifyDccFunc( uint16_t Addr, DCC_ADDR_TYPE AddrType, FN_GROUP FuncGrp, uint8_t FuncState) {
int f_index;
switch (FuncGrp) {
case FN_0_4: //Function Group 1 F0 F4 F3 F2 F1
@@ -145,7 +146,8 @@ void exec_function (int f_index, int FuncState) {
Set_LED (f_index,false);
}
}
extern void notifyDccSpeed( uint16_t Addr, uint8_t Speed, uint8_t ForwardDir, uint8_t MaxSpeed ) {
void notifyDccSpeed( uint16_t Addr, uint8_t Speed, uint8_t ForwardDir, uint8_t MaxSpeed ) {
Last_Decoder_direction = Decoder_direction;
Decoder_direction = ForwardDir;
if ( Decoder_direction==Last_Decoder_direction) return;
@@ -196,4 +198,5 @@ void Switch_LED (int Function) {
delayMicroseconds (1000.*time_fraction);
}
led_last_state[Function] = end_state;
}
}

View File

@@ -123,7 +123,7 @@ void loop()
Dcc.process();
}
extern void notifyDccFunc( uint16_t Addr, FN_GROUP FuncGrp, uint8_t FuncState) {
void notifyDccFunc( uint16_t Addr, DCC_ADDR_TYPE AddrType, FN_GROUP FuncGrp, uint8_t FuncState) {
int f_index;
switch (FuncGrp) {
case FN_0_4: //Function Group 1 F0 F4 F3 F2 F1
@@ -172,4 +172,5 @@ void exec_function (int f_index, int FuncState) {
Last_Function_State[f_index] = false;
}
}

View File

@@ -6,54 +6,57 @@
# Datatypes (KEYWORD1)
#######################################
DCC_MSG KEYWORD1
NmraDcc KEYWORD1
DCC_MSG KEYWORD1
NmraDcc KEYWORD1
#######################################
# Methods and Functions (KEYWORD2)
#######################################
NmraDcc KEYWORD2
pin KEYWORD2
init KEYWORD2
process KEYWORD2
getCV KEYWORD2
setCV KEYWORD2
isSetCVReady KEYWORD2
notifyDccReset KEYWORD2
notifyDccIdle KEYWORD2
notifyDccSpeed KEYWORD2
notifyDccFunc KEYWORD2
notifyDccAccState KEYWORD2
notifyDccSigState KEYWORD2
notifyDccMsg KEYWORD2
notifyCVValid KEYWORD2
notifyCVRead KEYWORD2
notifyCVWrite KEYWORD2
notifyIsSetCVReady KEYWORD2
notifyCVChange KEYWORD2
notifyCVAck KEYWORD2
notifyCVResetFactoryDefault KEYWORD2
NmraDcc KEYWORD2
pin KEYWORD2
init KEYWORD2
process KEYWORD2
getCV KEYWORD2
setCV KEYWORD2
isSetCVReady KEYWORD2
notifyDccReset KEYWORD2
notifyDccIdle KEYWORD2
notifyDccSpeed KEYWORD2
notifyDccSpeedRaw
notifyDccFunc KEYWORD2
notifyDccAccState KEYWORD2
notifyDccAccTurnoutBoard
notifyDccAccTurnoutOutput
notifyDccSigState KEYWORD2
notifyDccMsg KEYWORD2
notifyCVValid KEYWORD2
notifyCVRead KEYWORD2
notifyCVWrite KEYWORD2
notifyIsSetCVReady KEYWORD2
notifyCVChange KEYWORD2
notifyCVAck KEYWORD2
notifyCVResetFactoryDefault KEYWORD2
#######################################
# Constants (LITERAL1)
MAN_ID_JMRI LITERAL1
MAN_ID_DIY LITERAL1
MAN_ID_SILICON_RAILWAY LITERAL1
FLAGS_MY_ADDRESS_ONLY LITERAL1
FLAGS_OUTPUT_ADDRESS_MODE LITERAL1
FLAGS_DCC_ACCESSORY_DECODER LITERAL1
MAN_ID_JMRI LITERAL1
MAN_ID_DIY LITERAL1
MAN_ID_SILICON_RAILWAY LITERAL1
FLAGS_MY_ADDRESS_ONLY LITERAL1
FLAGS_OUTPUT_ADDRESS_MODE LITERAL1
FLAGS_DCC_ACCESSORY_DECODER LITERAL1
CV_ACCESSORY_DECODER_ADDRESS_LSB LITERAL1
CV_ACCESSORY_DECODER_ADDRESS_MSB LITERAL1
CV_ACCESSORY_DECODER_ADDRESS_LSB LITERAL1
CV_ACCESSORY_DECODER_ADDRESS_MSB LITERAL1
CV_MULTIFUNCTION_PRIMARY_ADDRESS LITERAL1
CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB LITERAL1
CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB LITERAL1
CV_MULTIFUNCTION_PRIMARY_ADDRESS LITERAL1
CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB LITERAL1
CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB LITERAL1
CV_VERSION_ID LITERAL1
CV_MANUFACTURER_ID LITERAL1
CV_29_CONFIG LITERAL1
CV_OPS_MODE_ADDRESS_LSB LITERAL1
CV_VERSION_ID LITERAL1
CV_MANUFACTURER_ID LITERAL1
CV_29_CONFIG LITERAL1
CV_OPS_MODE_ADDRESS_LSB LITERAL1
#######################################

View File

@@ -1,5 +1,5 @@
name=NmraDcc
version=1.1.0
version=1.2.0
author=Alex Shepherd, Wolfgang Kuffer, Geoff Bunza, Martin Pischky
maintainer=Alex Shepherd <kiwi64ajs@gmail.com>
sentence=Enables NMRA DCC Communication