NmraDcc.h 29 KB

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