Commanders
Arduino buttons/bus library
NmraDcc.h
1 //------------------------------------------------------------------------
2 //
3 // Model Railroading with Arduino - NmraDcc.h
4 //
5 // Copyright (c) 2008 - 2018 Alex Shepherd
6 //
7 // This source file is subject of the GNU general public license 2,
8 // that is available at the world-wide-web at
9 // http://www.gnu.org/licenses/gpl.txt
10 //
11 //------------------------------------------------------------------------
12 //
13 // file: NmraDcc.h
14 // author: Alex Shepherd
15 // webpage: http://mrrwa.org/
16 // history: 2008-03-20 Initial Version
17 // 2011-06-26 Migrated into Arduino library from OpenDCC codebase
18 // 2014 Added getAddr to NmraDcc Geoff Bunza
19 // 2015-11-06 Martin Pischky (martin@pischky.de):
20 // Experimental Version to support 14 speed steps
21 // and new signature of notifyDccSpeed and notifyDccFunc
22 // 2017-11-29 Ken West (kgw4449@gmail.com):
23 // Added method and callback headers.
24 //
25 //------------------------------------------------------------------------
26 //
27 // purpose: Provide a simplified interface to decode NMRA DCC packets
28 // and build DCC MutliFunction and Stationary Decoders
29 //
30 //------------------------------------------------------------------------
31 
32 // Uncomment the following Line to Enable Service Mode CV Programming
33 //#define NMRA_DCC_PROCESS_SERVICEMODE
34 
35 // Uncomment the following line to Enable MultiFunction Decoder Operations
36 //#define NMRA_DCC_PROCESS_MULTIFUNCTION
37 
38 // Uncomment the following line to Enable 14 Speed Step Support
39 //#define NMRA_DCC_ENABLE_14_SPEED_STEP_MODE
40 
41 #if defined(ARDUINO) && ARDUINO >= 100
42 #include "Arduino.h"
43 #else
44 #include "WProgram.h"
45 #endif
46 
47 #include "EEPROM.h"
48 
49 #ifndef NMRADCC_IS_IN
50 #define NMRADCC_IS_IN
51 
52 #define NMRADCC_VERSION 200 // Version 2.0.0
53 
54 #define MAX_DCC_MESSAGE_LEN 6 // including XOR-Byte
55 
56 typedef struct
57 {
58  uint8_t Size ;
59  uint8_t PreambleBits ;
60  uint8_t Data[MAX_DCC_MESSAGE_LEN] ;
61 } DCC_MSG ;
62 
63 //--------------------------------------------------------------------------
64 // This section contains the NMRA Assigned DCC Manufacturer Id Codes that
65 // are used in projects
66 //
67 // This value is to be used for CV8
68 //--------------------------------------------------------------------------
69 
70 #define MAN_ID_JMRI 0x12
71 #define MAN_ID_DIY 0x0D
72 #define MAN_ID_SILICON_RAILWAY 0x21
73 
74 //--------------------------------------------------------------------------
75 // This section contains the Product/Version Id Codes for projects
76 //
77 // This value is to be used for CV7
78 //
79 // NOTE: Each Product/Version Id Code needs to be UNIQUE for that particular
80 // the DCC Manufacturer Id Code
81 //--------------------------------------------------------------------------
82 
83 // Product/Version Id Codes allocated under: MAN_ID_JMRI
84 
85 // Product/Version Id Codes allocated under: MAN_ID_DIY
86 
87 // Standard CV Addresses
88 #define CV_ACCESSORY_DECODER_ADDRESS_LSB 1
89 #define CV_ACCESSORY_DECODER_ADDRESS_MSB 9
90 
91 #define CV_MULTIFUNCTION_PRIMARY_ADDRESS 1
92 #define CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB 17
93 #define CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB 18
94 
95 #define CV_VERSION_ID 7
96 #define CV_MANUFACTURER_ID 8
97 #define CV_29_CONFIG 29
98 
99 #if defined(ESP32)
100  #include <esp_log.h>
101  #define MAXCV SPI_FLASH_SEC_SIZE
102 #elif defined(ESP8266)
103  #include <spi_flash.h>
104  #define MAXCV SPI_FLASH_SEC_SIZE
105 #elif defined( __STM32F1__)
106  #define MAXCV (EEPROM_PAGE_SIZE/4 - 1) // number of storage places (CV address could be larger
107  // because STM32 uses virtual addresses)
108 #else
109  #define MAXCV E2END // the upper limit of the CV value currently defined to max memory.
110 #endif
111 
112 typedef enum {
113  CV29_LOCO_DIR = 0b00000001,
114  CV29_F0_LOCATION = 0b00000010,
115  CV29_APS = 0b00000100,
116  CV29_ADV_ACK = 0b00001000,
117  CV29_SPEED_TABLE_ENABLE = 0b00010000,
118  CV29_EXT_ADDRESSING = 0b00100000,
119  CV29_OUTPUT_ADDRESS_MODE = 0b01000000,
120  CV29_ACCESSORY_DECODER = 0b10000000,
121 } CV_29_BITS;
122 
123 typedef enum {
124 #ifdef NMRA_DCC_ENABLE_14_SPEED_STEP_MODE
125  SPEED_STEP_14 = 15,
126 #endif
127  SPEED_STEP_28 = 29,
128  SPEED_STEP_128 = 127
129 } DCC_SPEED_STEPS;
130 
131 typedef enum {
132  DCC_DIR_REV = 0,
133  DCC_DIR_FWD = 1,
134 } DCC_DIRECTION;
135 
136 typedef enum {
137  DCC_ADDR_SHORT,
138  DCC_ADDR_LONG,
139 } DCC_ADDR_TYPE;
140 
141 typedef enum
142 {
143  FN_0_4 = 1,
144  FN_5_8,
145  FN_9_12,
146  FN_13_20,
147  FN_21_28,
148 #ifdef NMRA_DCC_ENABLE_14_SPEED_STEP_MODE
149  FN_0
150 #endif
151 } FN_GROUP;
152 
153 #define FN_BIT_00 0x10
154 #define FN_BIT_01 0x01
155 #define FN_BIT_02 0x02
156 #define FN_BIT_03 0x04
157 #define FN_BIT_04 0x08
158 
159 #define FN_BIT_05 0x01
160 #define FN_BIT_06 0x02
161 #define FN_BIT_07 0x04
162 #define FN_BIT_08 0x08
163 
164 #define FN_BIT_09 0x01
165 #define FN_BIT_10 0x02
166 #define FN_BIT_11 0x04
167 #define FN_BIT_12 0x08
168 
169 #define FN_BIT_13 0x01
170 #define FN_BIT_14 0x02
171 #define FN_BIT_15 0x04
172 #define FN_BIT_16 0x08
173 #define FN_BIT_17 0x10
174 #define FN_BIT_18 0x20
175 #define FN_BIT_19 0x40
176 #define FN_BIT_20 0x80
177 
178 #define FN_BIT_21 0x01
179 #define FN_BIT_22 0x02
180 #define FN_BIT_23 0x04
181 #define FN_BIT_24 0x08
182 #define FN_BIT_25 0x10
183 #define FN_BIT_26 0x20
184 #define FN_BIT_27 0x40
185 #define FN_BIT_28 0x80
186 
187 //#define DCC_DBGVAR
188 #ifdef DCC_DBGVAR
189 typedef struct countOf_t {
190  unsigned long Tel;
191  unsigned long Err;
192 }countOf_t ;
193 
194 extern struct countOf_t countOf;
195 #endif
196 
197 class NmraDcc
198 {
199  private:
200  DCC_MSG Msg ;
201 
202  public:
203  NmraDcc();
204 
205 // Flag values to be logically ORed together and passed into the init() method
206 #define FLAGS_MY_ADDRESS_ONLY 0x01 // Only process DCC Packets with My Address
207 #define FLAGS_AUTO_FACTORY_DEFAULT 0x02 // Call notifyCVResetFactoryDefault() if CV 7 & 8 == 255
208 #define FLAGS_SETCV_CALLED 0x10 // only used internally !!
209 #define FLAGS_OUTPUT_ADDRESS_MODE 0x40 // CV 29/541 bit 6
210 #define FLAGS_DCC_ACCESSORY_DECODER 0x80 // CV 29/541 bit 7
211 
212 // Flag Bits that are cloned from CV29 relating the DCC Accessory Decoder
213 #define FLAGS_CV29_BITS (FLAGS_OUTPUT_ADDRESS_MODE | FLAGS_DCC_ACCESSORY_DECODER)
214 
215 
216  /*+
217  * pin() is called from setup() and sets up the pin used to receive DCC packets.
218  *
219  * Inputs:
220  * ExtIntNum - Interrupt number of the pin. Use digitalPinToInterrupt(ExtIntPinNum).
221  * ExtIntPinNum - Input pin number.
222  * EnablePullup - Set true to enable the pins pullup resistor.
223  *
224  * Returns:
225  * None.
226  */
227  void pin( uint8_t ExtIntNum, uint8_t ExtIntPinNum, uint8_t EnablePullup);
228 
229  /*+
230  * pin() is called from setup() and sets up the pin used to receive DCC packets.
231  * This relies on the internal function: digitalPinToInterrupt() to map the input pin number to the right interrupt
232  *
233  * Inputs:
234  * ExtIntPinNum - Input pin number.
235  * EnablePullup - Set true to enable the pins pullup resistor.
236  *
237  * Returns:
238  * None.
239  */
240 #ifdef digitalPinToInterrupt
241 void pin( uint8_t ExtIntPinNum, uint8_t EnablePullup);
242 #endif
243 
244  /*+
245  * init() is called from setup() after the pin() command is called.
246  * It initializes the NmDcc object and makes it ready to process packets.
247  *
248  * Inputs:
249  * ManufacturerId - Manufacturer ID returned in CV 8.
250  * Commonly MAN_ID_DIY.
251  * VersionId - Version ID returned in CV 7.
252  * Flags - ORed flags beginning with FLAGS_...
253  * FLAGS_MY_ADDRESS_ONLY - Only process packets with My Address.
254  * FLAGS_DCC_ACCESSORY_DECODER - Decoder is an accessory decoder.
255  * FLAGS_OUTPUT_ADDRESS_MODE - This flag applies to accessory decoders only.
256  * Accessory decoders normally have 4 paired outputs
257  * and a single address refers to all 4 outputs.
258  * Setting FLAGS_OUTPUT_ADDRESS_MODE causes each
259  * address to refer to a single output.
260  * OpsModeAddressBaseCV - Ops Mode base address. Set it to 0?
261  *
262  * Returns:
263  * None.
264  */
265  void init( uint8_t ManufacturerId, uint8_t VersionId, uint8_t Flags, uint8_t OpsModeAddressBaseCV );
266 
267  /*+
268  * initAccessoryDecoder() is called from setup() for accessory decoders.
269  * It calls init() with FLAGS_DCC_ACCESSORY_DECODER ORed into Flags.
270  *
271  * Inputs:
272  * ManufacturerId - Manufacturer ID returned in CV 8.
273  * Commonly MAN_ID_DIY.
274  * VersionId - Version ID returned in CV 7.
275  * Flags - ORed flags beginning with FLAGS_...
276  * FLAGS_DCC_ACCESSORY_DECODER will be set for init() call.
277  * OpsModeAddressBaseCV - Ops Mode base address. Set it to 0?
278  *
279  * Returns:
280  * None.
281  */
282  void initAccessoryDecoder( uint8_t ManufacturerId, uint8_t VersionId, uint8_t Flags, uint8_t OpsModeAddressBaseCV );
283 
284  /*+
285  * process() is called from loop() to process DCC packets.
286  * It must be called very frequently to keep up with the packets.
287  *
288  * Inputs:
289  * None.
290  *
291  * Returns:
292  * 1 - Packet successfully parsed on this call to process().
293  * 0 - Packet not ready or received packet had an error.
294  */
295  uint8_t process();
296 
297  /*+
298  * getCV() returns the selected CV value.
299  *
300  * Inputs:
301  * CV - CV number. It must point to a valid CV.
302  *
303  * Returns:
304  * Value - CV value. Invalid CV numbers will return an undefined result
305  * since nothing will have been set in that EEPROM position.
306  * Calls notifyCVRead() if it is defined.
307  */
308  uint8_t getCV( uint16_t CV );
309 
310  /*+
311  * setCV() sets the value of a CV.
312  *
313  * Inputs:
314  * CV - CV number. It must point to a valid CV.
315  * Value - CV value.
316  *
317  * Returns:
318  * Value - CV value set by this call.
319  * since nothing will have been set in that EEPROM position.
320  * Calls notifyCVWrite() if it is defined.
321  * Calls notifyCVChange() if the value is changed by this call.
322  */
323  uint8_t setCV( uint16_t CV, uint8_t Value);
324 
325  /*+
326  * setAccDecDCCAddrNextReceived() enables/disables the setting of the board address from the next received turnout command
327  *
328  * Inputs:
329  * enable- boolean to enable or disable the mode
330  *
331  * Returns:
332  */
333  void setAccDecDCCAddrNextReceived(uint8_t enable);
334 
335  /*+
336  * isSetCVReady() returns 1 if EEPROM is ready to write.
337  *
338  * Inputs:
339  * CV - CV number. It must point to a valid CV.
340  * Value - CV value.
341  *
342  * Returns:
343  * ready - 1 if ready to write, 0 otherwise. AVR processor will block
344  * for several ms. for each write cycle so you should check this to avoid blocks.
345  * Note: It returns the value returned by notifyIsSetCVReady() if it is defined.
346  * Calls notifyIsSetCVReady() if it is defined.
347  */
348  uint8_t isSetCVReady( void );
349 
350  /*+
351  * getAddr() return the currently active decoder address.
352  * based on decoder type and current address size.
353  *
354  * Inputs:
355  * None.
356  *
357  * Returns:
358  * Adr - The current decoder address based on decoder type(Multifunction, Accessory)
359  * and short or long address selection for Multifunction decoders.
360  */
361  uint16_t getAddr(void);
362 
363  /*+
364  * getX() return debugging data if DCC_DEBUG is defined.
365  * You would really need to be modifying the library to need them.
366  *
367  * Inputs:
368  * None.
369  *
370  * Returns:
371  * getIntCount - Init to 0 and apparently never incremented?
372  * getTickCount - Init to 0 and incremented each time interrupt handler
373  * completes without an error.
374  * getBitCount - Bit count of valid packet, 0 otherwise. Only valid until
375  * start of the next packet.
376  * getState - Current WAIT_... state as defined by DccRxWaitState in NmraDcc.cpp.
377  * getNestedIrqCount - Init to 0 and incremented each time the interrupt handler
378  * is called before the previous interrupt was complete.
379  * This is an error indication and may indicate the system
380  * is not handling packets fast enough or some other error is occurring.
381  */
382 // #define DCC_DEBUG
383 #ifdef DCC_DEBUG
384  uint8_t getIntCount(void);
385  uint8_t getTickCount(void);
386  uint8_t getBitCount(void);
387  uint8_t getState(void);
388  uint8_t getNestedIrqCount(void);
389 #endif
390 
391 };
392 
393 /************************************************************************************
394  Call-back functions
395 ************************************************************************************/
396 
397 #if defined (__cplusplus)
398  extern "C" {
399 #endif
400 
401 /*+
402  * notifyDccReset(uint8_t hardReset) Callback for a DCC reset command.
403  *
404  * Inputs:
405  * hardReset - 0 normal reset command.
406  * 1 hard reset command.
407  *
408  * Returns:
409  * None
410  */
411 extern void notifyDccReset(uint8_t hardReset ) __attribute__ ((weak));
412 
413 /*+
414  * notifyDccIdle() Callback for a DCC idle command.
415  *
416  * Inputs:
417  * None
418  *
419  * Returns:
420  * None
421  */
422 extern void notifyDccIdle(void) __attribute__ ((weak));
423 
424 
425 /*+
426  * notifyDccSpeed() Callback for a multifunction decoder speed command.
427  * The received speed and direction are unpacked to separate values.
428  *
429  * Inputs:
430  * Addr - Active decoder address.
431  * AddrType - DCC_ADDR_SHORT or DCC_ADDR_LONG.
432  * Speed - Decoder speed. 0 = Emergency stop
433  * 1 = Regular stop
434  * 2 to SpeedSteps = Speed step 1 to max.
435  * Dir - DCC_DIR_REV or DCC_DIR_FWD
436  * SpeedSteps - Highest speed, SPEED_STEP_14 = 15
437  * SPEED_STEP_28 = 29
438  * SPEED_STEP_128 = 127
439  *
440  * Returns:
441  * None
442  */
443 extern void notifyDccSpeed( uint16_t Addr, DCC_ADDR_TYPE AddrType, uint8_t Speed, DCC_DIRECTION Dir, DCC_SPEED_STEPS SpeedSteps ) __attribute__ ((weak));
444 
445 /*+
446  * notifyDccSpeedRaw() Callback for a multifunction decoder speed command.
447  * The value in Raw is the unpacked speed command.
448  *
449  * Inputs:
450  * Addr - Active decoder address.
451  * AddrType - DCC_ADDR_SHORT or DCC_ADDR_LONG.
452  * Raw - Raw decoder speed command.
453  *
454  * Returns:
455  * None
456  */
457 extern void notifyDccSpeedRaw( uint16_t Addr, DCC_ADDR_TYPE AddrType, uint8_t Raw) __attribute__ ((weak));
458 
459 /*+
460  * notifyDccFunc() Callback for a multifunction decoder function command.
461  *
462  * Inputs:
463  * Addr - Active decoder address.
464  * AddrType - DCC_ADDR_SHORT or DCC_ADDR_LONG.
465  * FuncGrp - Function group. FN_0 - 14 speed step headlight function.
466  * Mask FN_BIT_00.
467  * FN_0_4 - Functions 0 to 4. Mask FN_BIT_00 - FN_BIT_04
468  * FN_5_8 - Functions 5 to 8. Mask FN_BIT_05 - FN_BIT_08
469  * FN_9_12 - Functions 9 to 12. Mask FN_BIT_09 - FN_BIT_12
470  * FN_13_20 - Functions 13 to 20. Mask FN_BIT_13 - FN_BIT_20
471  * FN_21_28 - Functions 21 to 28. Mask FN_BIT_21 - FN_BIT_28
472  * FuncState - Function state. Bitmask where active functions have a 1 at that bit.
473  * You must & FuncState with the appropriate
474  * FN_BIT_nn value to isolate a given bit.
475  *
476  * Returns:
477  * None
478  */
479 extern void notifyDccFunc( uint16_t Addr, DCC_ADDR_TYPE AddrType, FN_GROUP FuncGrp, uint8_t FuncState) __attribute__ ((weak));
480 
481 /*+
482  * notifyDccAccTurnoutBoard() Board oriented callback for a turnout accessory decoder.
483  * Most useful when CV29_OUTPUT_ADDRESS_MODE is not set.
484  * Decoders of this type have 4 paired turnout outputs per board.
485  * OutputPower is 1 if the power is on, and 0 otherwise.
486  *
487  * Inputs:
488  * BoardAddr - Per board address. Equivalent to CV 1 LSB & CV 9 MSB.
489  * OutputPair - Output pair number. It has a range of 0 to 3.
490  * Equivalent to upper 2 bits of the 3 DDD bits in the accessory packet.
491  * Direction - Turnout direction. It has a value of 0 or 1.
492  * It is equivalent to bit 0 of the 3 DDD bits in the accessory packet.
493  * OutputPower - Output On/Off. Equivalent to packet C bit. It has these values:
494  * 0 - Output pair is off.
495  * 1 - Output pair is on.
496  *
497  * Returns:
498  * None
499  */
500 
501 extern void notifyDccAccTurnoutBoard( uint16_t BoardAddr, uint8_t OutputPair, uint8_t Direction, uint8_t OutputPower ) __attribute__ ((weak));
502 /*+
503  * notifyDccAccTurnoutOutput() Output oriented callback for a turnout accessory decoder.
504  * Most useful when CV29_OUTPUT_ADDRESS_MODE is not set.
505  * Decoders of this type have 4 paired turnout outputs per board.
506  * OutputPower is 1 if the power is on, and 0 otherwise.
507  *
508  * Inputs:
509  * Addr - Per output address. There will be 4 Addr addresses
510  * per board for a standard accessory decoder with 4 output pairs.
511  * Direction - Turnout direction. It has a value of 0 or 1.
512  * Equivalent to bit 0 of the 3 DDD bits in the accessory packet.
513  * OutputPower - Output On/Off. Equivalent to packet C bit. It has these values:
514  * 0 - Output is off.
515  * 1 - Output is on.
516  *
517  * Returns:
518  * None
519  */
520 extern void notifyDccAccTurnoutOutput( uint16_t Addr, uint8_t Direction, uint8_t OutputPower ) __attribute__ ((weak));
521 
522 /*+
523  * notifyDccAccBoardAddrSet() Board oriented callback for a turnout accessory decoder.
524  * This notification is when a new Board Address is set to the
525  * address of the next DCC Turnout Packet that is received
526  *
527  * This is enabled via the setAccDecDCCAddrNextReceived() method above
528  *
529  * Inputs:
530  * BoardAddr - Per board address. Equivalent to CV 1 LSB & CV 9 MSB.
531  * per board for a standard accessory decoder with 4 output pairs.
532  *
533  * Returns:
534  * None
535  */
536 extern void notifyDccAccBoardAddrSet( uint16_t BoardAddr) __attribute__ ((weak));
537 
538 /*+
539  * notifyDccAccOutputAddrSet() Output oriented callback for a turnout accessory decoder.
540  * This notification is when a new Output Address is set to the
541  * address of the next DCC Turnout Packet that is received
542  *
543  * This is enabled via the setAccDecDCCAddrNextReceived() method above
544  *
545  * Inputs:
546  * Addr - Per output address. There will be 4 Addr addresses
547  * per board for a standard accessory decoder with 4 output pairs.
548  *
549  * Returns:
550  * None
551  */
552 extern void notifyDccAccOutputAddrSet( uint16_t Addr) __attribute__ ((weak));
553 
554 /*+
555  * notifyDccSigOutputState() Callback for a signal aspect accessory decoder.
556  * Defined in S-9.2.1 as the Extended Accessory Decoder Control Packet.
557  *
558  * Inputs:
559  * Addr - Decoder address.
560  * State - 6 bit command equivalent to S-9.2.1 00XXXXXX.
561  *
562  * Returns:
563  * None
564  */
565 extern void notifyDccSigOutputState( uint16_t Addr, uint8_t State) __attribute__ ((weak));
566 
567 /*+
568  * notifyDccMsg() Raw DCC packet callback.
569  * Called with raw DCC packet bytes.
570  *
571  * Inputs:
572  * Msg - Pointer to DCC_MSG structure. The values are:
573  * Msg->Size - Number of Data bytes in the packet.
574  * Msg->PreambleBits - Number of preamble bits in the packet.
575  * Msg->Data[] - Array of data bytes in the packet.
576  *
577  * Returns:
578  * None
579  */
580 extern void notifyDccMsg( DCC_MSG * Msg ) __attribute__ ((weak));
581 
582 /*+
583  * notifyCVValid() Callback to determine if a given CV is valid.
584  * This is called when the library needs to determine
585  * if a CV is valid. Note: If defined, this callback
586  * MUST determine if a CV is valid and return the
587  * appropriate value. If this callback is not defined,
588  * the library will determine validity.
589  *
590  * Inputs:
591  * CV - CV number.
592  * Writable - 1 for CV writes. 0 for CV reads.
593  *
594  * Returns:
595  * 1 - CV is valid.
596  * 0 - CV is not valid.
597  */
598 extern uint8_t notifyCVValid( uint16_t CV, uint8_t Writable ) __attribute__ ((weak));
599 
600 /*+
601  * notifyCVRead() Callback to read a CV.
602  * This is called when the library needs to read
603  * a CV. Note: If defined, this callback
604  * MUST return the value of the CV.
605  * If this callback is not defined,
606  * the library will read the CV from EEPROM.
607  *
608  * Inputs:
609  * CV - CV number.
610  *
611  * Returns:
612  * Value - Value of the CV.
613  */
614 extern uint8_t notifyCVRead( uint16_t CV) __attribute__ ((weak));
615 
616 /*+
617  * notifyCVWrite() Callback to write a value to a CV.
618  * This is called when the library needs to write
619  * a CV. Note: If defined, this callback
620  * MUST write the Value to the CV and return the value of the CV.
621  * If this callback is not defined,
622  * the library will read the CV from EEPROM.
623  *
624  * Inputs:
625  * CV - CV number.
626  * Value - Value of the CV.
627  *
628  * Returns:
629  * Value - Value of the CV.
630  */
631 extern uint8_t notifyCVWrite( uint16_t CV, uint8_t Value) __attribute__ ((weak));
632 
633 /*+
634  * notifyIsSetCVReady() Callback to to determine if CVs can be written.
635  * This is called when the library needs to determine
636  * is ready to write without blocking or failing.
637  * Note: If defined, this callback
638  * MUST determine if a CV write would block or fail
639  * return the appropriate value.
640  * If this callback is not defined,
641  * the library determines if a write to the EEPROM
642  * would block.
643  *
644  * Inputs:
645  * None
646  *
647  * Returns:
648  * 1 - CV is ready to be written.
649  * 0 - CV is not ready to be written.
650  */
651 extern uint8_t notifyIsSetCVReady(void) __attribute__ ((weak));
652 
653 /*+
654  * notifyCVChange() Called when a CV value is changed.
655  * This is called whenever a CV's value is changed.
656  * notifyDccCVChange() Called only when a CV value is changed by a Dcc packet or a internal lib function.
657  * it is NOT called if the CV is changed by means of the setCV() method.
658  * Note: It is not called if notifyCVWrite() is defined
659  * or if the value in the EEPROM is the same as the value
660  * in the write command.
661  *
662  * Inputs:
663  * CV - CV number.
664  * Value - Value of the CV.
665  *
666  * Returns:
667  * None
668  */
669 extern void notifyCVChange( uint16_t CV, uint8_t Value) __attribute__ ((weak));
670 extern void notifyDccCVChange( uint16_t CV, uint8_t Value) __attribute__ ((weak));
671 
672 /*+
673  * notifyCVResetFactoryDefault() Called when CVs must be reset.
674  * This is called when CVs must be reset
675  * to their factory defaults. This callback
676  * should write the factory default value of
677  * relevent CVs using the setCV() method.
678  * setCV() must not block whens this is called.
679  * Test with isSetCVReady() prior to calling setCV()
680  *
681  * Inputs:
682  * None
683  * *
684  * Returns:
685  * None
686  */
687 extern void notifyCVResetFactoryDefault(void) __attribute__ ((weak));
688 
689 /*+
690  * notifyCVAck() Called when a CV write must be acknowledged.
691  * This callback must increase the current drawn by this
692  * decoder by at least 60mA for 6ms +/- 1ms.
693  *
694  * Inputs:
695  * None
696  * *
697  * Returns:
698  * None
699  */
700 extern void notifyCVAck(void) __attribute__ ((weak));
701 /*+
702  * notifyServiceMode(bool) Called when state of 'inServiceMode' changes
703  *
704  * Inputs:
705  * bool state of inServiceMode
706  * *
707  * Returns:
708  * None
709  */
710 extern void notifyServiceMode(bool) __attribute__ ((weak));
711 
712 // Deprecated, only for backward compatibility with version 1.4.2.
713 // Don't use in new designs. These functions may be dropped in future versions
714 extern void notifyDccAccState( uint16_t Addr, uint16_t BoardAddr, uint8_t OutputAddr, uint8_t State ) __attribute__ ((weak));
715 extern void notifyDccSigState( uint16_t Addr, uint8_t OutputIndex, uint8_t State) __attribute__ ((weak));
716 
717 #if defined (__cplusplus)
718 }
719 #endif
720 
721 #endif