Merge remote-tracking branch 'mrrwa/master'
This commit is contained in:
78
NmraDcc.cpp
78
NmraDcc.cpp
@@ -93,7 +93,7 @@
|
|||||||
#define MAX_ONEBITHALF 82
|
#define MAX_ONEBITHALF 82
|
||||||
#define MIN_ONEBITFULL 82
|
#define MIN_ONEBITFULL 82
|
||||||
#define MIN_ONEBITHALF 35
|
#define MIN_ONEBITHALF 35
|
||||||
#define MAX_BITDIFF 18
|
#define MAX_BITDIFF 24
|
||||||
|
|
||||||
|
|
||||||
// Debug-Ports
|
// Debug-Ports
|
||||||
@@ -217,18 +217,12 @@
|
|||||||
#define MODE_TP2
|
#define MODE_TP2
|
||||||
#define SET_TP2
|
#define SET_TP2
|
||||||
#define CLR_TP2
|
#define CLR_TP2
|
||||||
//#define MODE_TP2 DDRC |= (1<<2) // A2
|
|
||||||
//#define SET_TP2 PORTC |= (1<<2)
|
|
||||||
//#define CLR_TP2 PORTC &= ~(1<<2)
|
|
||||||
#define MODE_TP3
|
#define MODE_TP3
|
||||||
#define SET_TP3
|
#define SET_TP3
|
||||||
#define CLR_TP3
|
#define CLR_TP3
|
||||||
#define MODE_TP4
|
#define MODE_TP4
|
||||||
#define SET_TP4
|
#define SET_TP4
|
||||||
#define CLR_TP4
|
#define CLR_TP4
|
||||||
//#define MODE_TP4 DDRC |= (1<<4) //A4
|
|
||||||
//#define SET_TP4 PORTC |= (1<<4)
|
|
||||||
//#define CLR_TP4 PORTC &= ~(1<<4)
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#ifdef DEBUG_PRINT
|
#ifdef DEBUG_PRINT
|
||||||
@@ -296,6 +290,7 @@ typedef struct
|
|||||||
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;
|
||||||
@@ -310,6 +305,8 @@ DCC_PROCESSOR_STATE DccProcState ;
|
|||||||
portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED;
|
portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED;
|
||||||
|
|
||||||
void IRAM_ATTR ExternalInterruptHandler(void)
|
void IRAM_ATTR ExternalInterruptHandler(void)
|
||||||
|
#elif defined(ESP8266)
|
||||||
|
void ICACHE_RAM_ATTR ExternalInterruptHandler(void)
|
||||||
#else
|
#else
|
||||||
void ExternalInterruptHandler(void)
|
void ExternalInterruptHandler(void)
|
||||||
#endif
|
#endif
|
||||||
@@ -340,9 +337,10 @@ void ExternalInterruptHandler(void)
|
|||||||
// Bit evaluation without Timer 0 ------------------------------
|
// Bit evaluation without Timer 0 ------------------------------
|
||||||
uint8_t DccBitVal;
|
uint8_t DccBitVal;
|
||||||
static int8_t bit1, bit2 ;
|
static int8_t bit1, bit2 ;
|
||||||
static word lastMicros;
|
static unsigned int lastMicros = 0;
|
||||||
static byte halfBit, DCC_IrqRunning;
|
static byte halfBit, DCC_IrqRunning;
|
||||||
unsigned int actMicros, bitMicros;
|
unsigned int actMicros, bitMicros;
|
||||||
|
#ifdef ALLOW_NESTED_IRQ
|
||||||
if ( DCC_IrqRunning ) {
|
if ( DCC_IrqRunning ) {
|
||||||
// nested DCC IRQ - obviously there are glitches
|
// nested DCC IRQ - obviously there are glitches
|
||||||
// ignore this interrupt and increment glitchcounter
|
// ignore this interrupt and increment glitchcounter
|
||||||
@@ -353,6 +351,7 @@ void ExternalInterruptHandler(void)
|
|||||||
SET_TP3;
|
SET_TP3;
|
||||||
return; //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> abort IRQ
|
return; //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> abort IRQ
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
SET_TP3;
|
SET_TP3;
|
||||||
actMicros = micros();
|
actMicros = micros();
|
||||||
bitMicros = actMicros-lastMicros;
|
bitMicros = actMicros-lastMicros;
|
||||||
@@ -364,11 +363,12 @@ void ExternalInterruptHandler(void)
|
|||||||
}
|
}
|
||||||
DccBitVal = ( bitMicros < bitMax );
|
DccBitVal = ( bitMicros < bitMax );
|
||||||
lastMicros = actMicros;
|
lastMicros = actMicros;
|
||||||
#ifdef debug
|
|
||||||
if(DccBitVal) {SET_TP2;} else {CLR_TP2;};
|
#ifdef ALLOW_NESTED_IRQ
|
||||||
#endif
|
|
||||||
DCC_IrqRunning = true;
|
DCC_IrqRunning = true;
|
||||||
interrupts(); // time critical is only the micros() command,so allow nested irq's
|
interrupts(); // time critical is only the micros() command,so allow nested irq's
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef DCC_DEBUG
|
#ifdef DCC_DEBUG
|
||||||
DccProcState.TickCount++;
|
DccProcState.TickCount++;
|
||||||
#endif
|
#endif
|
||||||
@@ -429,13 +429,10 @@ void ExternalInterruptHandler(void)
|
|||||||
DccRx.BitCount++;
|
DccRx.BitCount++;
|
||||||
if( abs(bit2-bit1) > MAX_BITDIFF ) {
|
if( abs(bit2-bit1) > MAX_BITDIFF ) {
|
||||||
// the length of the 2 halfbits differ too much -> wrong protokoll
|
// the length of the 2 halfbits differ too much -> wrong protokoll
|
||||||
CLR_TP2;
|
|
||||||
CLR_TP3;
|
|
||||||
DccRx.State = WAIT_PREAMBLE;
|
DccRx.State = WAIT_PREAMBLE;
|
||||||
bitMax = MAX_PRAEAMBEL;
|
bitMax = MAX_PRAEAMBEL;
|
||||||
bitMin = MIN_ONEBITFULL;
|
bitMin = MIN_ONEBITFULL;
|
||||||
DccRx.BitCount = 0;
|
DccRx.BitCount = 0;
|
||||||
SET_TP4;
|
|
||||||
|
|
||||||
#if defined ( __STM32F1__ )
|
#if defined ( __STM32F1__ )
|
||||||
detachInterrupt( DccProcState.ExtIntNum );
|
detachInterrupt( DccProcState.ExtIntNum );
|
||||||
@@ -562,6 +559,7 @@ void ExternalInterruptHandler(void)
|
|||||||
{
|
{
|
||||||
CLR_TP3;
|
CLR_TP3;
|
||||||
DccRx.State = WAIT_PREAMBLE ;
|
DccRx.State = WAIT_PREAMBLE ;
|
||||||
|
DccRx.BitCount = 0 ;
|
||||||
bitMax = MAX_PRAEAMBEL;
|
bitMax = MAX_PRAEAMBEL;
|
||||||
bitMin = MIN_ONEBITFULL;
|
bitMin = MIN_ONEBITFULL;
|
||||||
#ifdef ESP32
|
#ifdef ESP32
|
||||||
@@ -591,9 +589,11 @@ void ExternalInterruptHandler(void)
|
|||||||
DccRx.TempByte = 0 ;
|
DccRx.TempByte = 0 ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#ifdef ALLOW_NESTED_IRQ
|
||||||
|
DCC_IrqRunning = false;
|
||||||
|
#endif
|
||||||
CLR_TP1;
|
CLR_TP1;
|
||||||
CLR_TP3;
|
CLR_TP3;
|
||||||
DCC_IrqRunning = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ackCV(void)
|
void ackCV(void)
|
||||||
@@ -602,6 +602,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) ;
|
||||||
}
|
}
|
||||||
@@ -661,6 +668,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
|
||||||
@@ -689,23 +697,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
|
||||||
@@ -726,7 +730,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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -735,7 +739,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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -760,7 +764,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() ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -772,12 +776,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() ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -871,7 +875,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
|
||||||
@@ -1094,12 +1098,13 @@ void execDccProcessor( DCC_MSG * pDccMsg )
|
|||||||
{
|
{
|
||||||
resetServiceModeTimer( 1 ) ;
|
resetServiceModeTimer( 1 ) ;
|
||||||
|
|
||||||
if( memcmp( pDccMsg, &DccProcState.LastMsg, sizeof( DCC_MSG ) ) )
|
//Only check the DCC Packet "Size" and "Data" fields and ignore the "PreambleBits" as they can be different to the previous packet
|
||||||
|
if(pDccMsg->Size != DccProcState.LastMsg.Size || memcmp( pDccMsg->Data, &DccProcState.LastMsg.Data, pDccMsg->Size ) != 0 )
|
||||||
{
|
{
|
||||||
DccProcState.DuplicateCount = 0 ;
|
DccProcState.DuplicateCount = 0 ;
|
||||||
memcpy( &DccProcState.LastMsg, pDccMsg, sizeof( DCC_MSG ) ) ;
|
memcpy( &DccProcState.LastMsg, pDccMsg, sizeof( DCC_MSG ) ) ;
|
||||||
}
|
}
|
||||||
// Wait until you see 2 identicle packets before acting on a Service Mode Packet
|
// Wait until you see 2 identical packets before acting on a Service Mode Packet
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DccProcState.DuplicateCount++ ;
|
DccProcState.DuplicateCount++ ;
|
||||||
@@ -1355,6 +1360,17 @@ void NmraDcc::pin( uint8_t ExtIntNum, uint8_t ExtIntPinNum, uint8_t EnablePullup
|
|||||||
#if defined ( __STM32F1__ )
|
#if defined ( __STM32F1__ )
|
||||||
// with STM32F1 the interuptnumber is equal the pin number
|
// with STM32F1 the interuptnumber is equal the pin number
|
||||||
DccProcState.ExtIntNum = ExtIntPinNum;
|
DccProcState.ExtIntNum = ExtIntPinNum;
|
||||||
|
// because STM32F1 has a NVIC we must set interuptpriorities
|
||||||
|
const nvic_irq_num irqNum2nvic[] = { NVIC_EXTI0, NVIC_EXTI1, NVIC_EXTI2, NVIC_EXTI3, NVIC_EXTI4,
|
||||||
|
NVIC_EXTI_9_5, NVIC_EXTI_9_5, NVIC_EXTI_9_5, NVIC_EXTI_9_5, NVIC_EXTI_9_5,
|
||||||
|
NVIC_EXTI_15_10, NVIC_EXTI_15_10, NVIC_EXTI_15_10, NVIC_EXTI_15_10, NVIC_EXTI_15_10, NVIC_EXTI_15_10 };
|
||||||
|
exti_num irqNum = (exti_num)(PIN_MAP[ExtIntPinNum].gpio_bit);
|
||||||
|
|
||||||
|
// DCC-Input IRQ must be able to interrupt other long low priority ( level15 ) IRQ's
|
||||||
|
nvic_irq_set_priority ( irqNum2nvic[irqNum], PRIO_DCC_IRQ);
|
||||||
|
|
||||||
|
// Systic must be able to interrupt DCC-IRQ to always get correct micros() values
|
||||||
|
nvic_irq_set_priority(NVIC_SYSTICK, PRIO_SYSTIC);
|
||||||
#else
|
#else
|
||||||
DccProcState.ExtIntNum = ExtIntNum;
|
DccProcState.ExtIntNum = ExtIntNum;
|
||||||
#endif
|
#endif
|
||||||
@@ -1407,7 +1423,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))
|
||||||
|
18
NmraDcc.h
18
NmraDcc.h
@@ -53,6 +53,8 @@
|
|||||||
|
|
||||||
#define MAX_DCC_MESSAGE_LEN 6 // including XOR-Byte
|
#define MAX_DCC_MESSAGE_LEN 6 // including XOR-Byte
|
||||||
|
|
||||||
|
//#define ALLOW_NESTED_IRQ // uncomment to enable nested IRQ's ( only for AVR! )
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
uint8_t Size ;
|
uint8_t Size ;
|
||||||
@@ -97,7 +99,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>
|
||||||
@@ -105,6 +107,9 @@ typedef struct
|
|||||||
#elif defined( __STM32F1__)
|
#elif defined( __STM32F1__)
|
||||||
#define MAXCV (EEPROM_PAGE_SIZE/4 - 1) // number of storage places (CV address could be larger
|
#define MAXCV (EEPROM_PAGE_SIZE/4 - 1) // number of storage places (CV address could be larger
|
||||||
// because STM32 uses virtual adresses)
|
// because STM32 uses virtual adresses)
|
||||||
|
#undef ALLOW_NESTED_IRQ // This is done with NVIC on STM32
|
||||||
|
#define PRIO_DCC_IRQ 9
|
||||||
|
#define PRIO_SYSTIC 8 // MUST be higher priority than DCC Irq
|
||||||
#else
|
#else
|
||||||
#define MAXCV E2END // the upper limit of the CV value currently defined to max memory.
|
#define MAXCV E2END // the upper limit of the CV value currently defined to max memory.
|
||||||
#endif
|
#endif
|
||||||
@@ -698,6 +703,17 @@ 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 via Advanced Acknowledgement.
|
||||||
|
* This callback must send the Advanced Acknowledgement via RailComm.
|
||||||
|
*
|
||||||
|
* 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
|
||||||
*
|
*
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
name=NmraDcc
|
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
|
author=Alex Shepherd, Wolfgang Kuffer, Geoff Bunza, Martin Pischky, Franz-Peter Müller, Sven (littleyoda), Hans Tanner
|
||||||
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