NmraDcc.c 61 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920
  1. //------------------------------------------------------------------------
  2. //
  3. // Model Railroading with Arduino - NmraDcc.cpp
  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.cpp
  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. // 2015-12-16 Version without use of Timer0 by Franz-Peter Müller
  33. // 2016-07-16 handle glitches on DCC line
  34. // 2016-08-20 added ESP8266 support by Sven (littleyoda)
  35. // 2017-01-19 added STM32F1 support by Franz-Peter
  36. // 2017-11-29 Ken West (kgw4449@gmail.com):
  37. // Minor fixes to pass NMRA Baseline Conformance Tests.
  38. // 2018-12-17 added ESP32 support by Trusty (thierry@lapajaparis.net)
  39. // 2019-02-17 added ESP32 specific changes by Hans Tanner
  40. // 2020-05-15 changes to pass NMRA Tests ( always search for preamble )
  41. //------------------------------------------------------------------------
  42. //
  43. // purpose: Provide a simplified interface to decode NMRA DCC packets
  44. // and build DCC Mobile and Stationary Decoders
  45. //
  46. //------------------------------------------------------------------------
  47. // NodeMCU Lua port by @voborsky
  48. // #define NODE_DEBUG
  49. #define NODEMCUDCC
  50. #ifdef NODEMCUDCC
  51. #include <stdint.h>
  52. #include <stdlib.h>
  53. #include <stdio.h>
  54. #include "platform.h"
  55. #include "user_interface.h"
  56. #include "task/task.h"
  57. #include "driver/NmraDcc.h"
  58. #define BYTE_TO_BINARY_PATTERN "%c%c%c%c%c%c%c%c"
  59. #define BYTE_TO_BINARY(byte) \
  60. (byte & 0x80 ? '1' : '0'), \
  61. (byte & 0x40 ? '1' : '0'), \
  62. (byte & 0x20 ? '1' : '0'), \
  63. (byte & 0x10 ? '1' : '0'), \
  64. (byte & 0x08 ? '1' : '0'), \
  65. (byte & 0x04 ? '1' : '0'), \
  66. (byte & 0x02 ? '1' : '0'), \
  67. (byte & 0x01 ? '1' : '0')
  68. #define byte uint8_t
  69. #define word int16_t
  70. #define abs(a) ((a) > 0 ? (a) : (0-a))
  71. #define RISING GPIO_PIN_INTR_POSEDGE
  72. #define FALLING GPIO_PIN_INTR_NEGEDGE
  73. #define CHANGE GPIO_PIN_INTR_ANYEDGE
  74. static uint32_t last_time_overflow_millis;
  75. static uint32_t last_system_time;
  76. uint32_t millis() {
  77. uint32_t now = system_get_time();
  78. if (now < last_system_time) {
  79. // we have an overflow situation
  80. // assume only one overflow
  81. last_time_overflow_millis += (1 << 29) / 125; // (1 << 32) / 1000
  82. }
  83. last_system_time = now;
  84. return last_time_overflow_millis + now / 1000;
  85. }
  86. #else
  87. #include "NmraDcc.h"
  88. #include "EEPROM.h"
  89. #endif
  90. // Uncomment to print DEBUG messages
  91. // #define DEBUG_PRINT
  92. //------------------------------------------------------------------------
  93. // DCC Receive Routine
  94. //
  95. // Howto: uses two interrupts: a rising edge in DCC polarity triggers INTx
  96. // in INTx handler, Timer0 CompareB with a delay of 80us is started.
  97. // On Timer0 CompareB Match the level of DCC is evaluated and
  98. // parsed.
  99. //
  100. // |<-----116us----->|
  101. //
  102. // DCC 1: _________XXXXXXXXX_________XXXXXXXXX_________
  103. // ^-INTx
  104. // |----87us--->|
  105. // ^Timer-INT: reads zero
  106. //
  107. // DCC 0: _________XXXXXXXXXXXXXXXXXX__________________
  108. // ^-INTx
  109. // |----------->|
  110. // ^Timer-INT: reads one
  111. //
  112. // new DCC Receive Routine without Timer0 ........................................................
  113. //
  114. // Howto: uses only one interrupt at the rising or falling edge of the DCC signal
  115. // The time between two edges is measured to determine the bit value
  116. // Synchronising to the edge of the first part of a bit is done after recognizing the start bit
  117. // During synchronizing each part of a bit is detected ( Interruptmode 'change' )
  118. //
  119. // |<-----116us----->|
  120. // DCC 1: _________XXXXXXXXX_________XXXXXXXXX_________
  121. // |<--------146us------>|
  122. // ^-INTx ^-INTx
  123. // less than 146us: its a one-Bit
  124. //
  125. //
  126. // |<-----------------232us----------->|
  127. // DCC 0: _________XXXXXXXXXXXXXXXXXX__________________XXXXXXXX__________
  128. // |<--------146us------->|
  129. // ^-INTx ^-INTx
  130. // greater than 146us: its a zero bit
  131. //
  132. //
  133. //
  134. //
  135. //------------------------------------------------------------------------
  136. // if this is commented out, bit synchronisation is only done after a wrong checksum
  137. #define SYNC_ALWAYS
  138. // if this is commented out, Zero-Bit_Stretching is not supported
  139. // ( Bits longer than 2* MAX ONEBIT are treated as error )
  140. #define SUPPORT_ZERO_BIT_STRETCHING
  141. #define MAX_ONEBITFULL 146
  142. #define MAX_PRAEAMBEL 146
  143. #define MAX_ONEBITHALF 82
  144. #define MIN_ONEBITFULL 82
  145. #define MIN_ONEBITHALF 35
  146. #define MAX_BITDIFF 24
  147. // Debug-Ports
  148. //#define debug // Testpulse for logic analyser
  149. #ifdef NODE_DEBUG
  150. #define debug
  151. #endif
  152. #ifdef debug
  153. #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
  154. #define MODE_TP1 DDRF |= (1<<2) //pinA2
  155. #define SET_TP1 PORTF |= (1<<2)
  156. #define CLR_TP1 PORTF &= ~(1<<2)
  157. #define MODE_TP2 DDRF |= (1<<3) //pinA3
  158. #define SET_TP2 PORTF |= (1<<3)
  159. #define CLR_TP2 PORTF &= ~(1<<3)
  160. #define MODE_TP3 DDRF |= (1<<4) //pinA4
  161. #define SET_TP3 PORTF |= (1<<4)
  162. #define CLR_TP3 PORTF &= ~(1<<4)
  163. #define MODE_TP4 DDRF |= (1<<5) //pinA5
  164. #define SET_TP4 PORTF |= (1<<5)
  165. #define CLR_TP4 PORTF &= ~(1<<5)
  166. #elif defined(__AVR_ATmega32U4__)
  167. #define MODE_TP1 DDRF |= (1<<4) //A3
  168. #define SET_TP1 PORTF |= (1<<4)
  169. #define CLR_TP1 PORTF &= ~(1<<4)
  170. #define MODE_TP2 DDRF |= (1<<5) //A2
  171. #define SET_TP2 PORTF |= (1<<5)
  172. #define CLR_TP2 PORTF &= ~(1<<5)
  173. #define MODE_TP3
  174. #define SET_TP3
  175. #define CLR_TP3
  176. #define MODE_TP4
  177. #define SET_TP4
  178. #define CLR_TP4
  179. #elif defined(__AVR_ATmega328P__)
  180. #define MODE_TP1 DDRC |= (1<<1) //A1
  181. #define SET_TP1 PORTC |= (1<<1)
  182. #define CLR_TP1 PORTC &= ~(1<<1)
  183. #define MODE_TP2 DDRC |= (1<<2) // A2
  184. #define SET_TP2 PORTC |= (1<<2)
  185. #define CLR_TP2 PORTC &= ~(1<<2)
  186. #define MODE_TP3 DDRC |= (1<<3) //A3
  187. #define SET_TP3 PORTC |= (1<<3)
  188. #define CLR_TP3 PORTC &= ~(1<<3)
  189. #define MODE_TP4 DDRC |= (1<<4) //A4
  190. #define SET_TP4 PORTC |= (1<<4)
  191. #define CLR_TP4 PORTC &= ~(1<<4)
  192. #elif defined(__arm__) && (defined(__MK20DX128__) || defined(__MK20DX256__))
  193. // Teensys 3.x
  194. #define MODE_TP1 pinMode( A1,OUTPUT ) // A1= PortC, Bit0
  195. #define SET_TP1 GPIOC_PSOR = 0x01
  196. #define CLR_TP1 GPIOC_PCOR = 0x01
  197. #define MODE_TP2 pinMode( A2,OUTPUT ) // A2= PortB Bit0
  198. #define SET_TP2 GPIOB_PSOR = 0x01
  199. #define CLR_TP2 GPIOB_PCOR = 0x01
  200. #define MODE_TP3 pinMode( A3,OUTPUT ) // A3 = PortB Bit1
  201. #define SET_TP3 GPIOB_PSOR = 0x02
  202. #define CLR_TP3 GPIOB_PCOR = 0x02
  203. #define MODE_TP4 pinMode( A4,OUTPUT ) // A4 = PortB Bit3
  204. #define SET_TP4 GPIOB_PSOR = 0x08
  205. #define CLR_TP4 GPIOB_PCOR = 0x08
  206. #elif defined (__STM32F1__)
  207. // STM32F103...
  208. #define MODE_TP1 pinMode( PB12,OUTPUT ) // TP1= PB12
  209. #define SET_TP1 gpio_write_bit( GPIOB,12, HIGH );
  210. #define CLR_TP1 gpio_write_bit( GPIOB,12, LOW );
  211. #define MODE_TP2 pinMode( PB13,OUTPUT ) // TP2= PB13
  212. #define SET_TP2 gpio_write_bit( GPIOB,13, HIGH );
  213. #define CLR_TP2 gpio_write_bit( GPIOB,13, LOW );
  214. #define MODE_TP3 pinMode( PB14,OUTPUT ) // TP3 = PB14
  215. #define SET_TP3 gpio_write_bit( GPIOB,14, HIGH );
  216. #define CLR_TP3 gpio_write_bit( GPIOB,14, LOW );
  217. #define MODE_TP4 pinMode( PB15,OUTPUT ) // TP4 = PB15
  218. #define SET_TP4 gpio_write_bit( GPIOB,15, HIGH );
  219. #define CLR_TP4 gpio_write_bit( GPIOB,15, LOW );
  220. #elif defined(ESP8266)
  221. #define MODE_TP1 pinMode( D5,OUTPUT ) ; // GPIO 14
  222. #define SET_TP1 GPOS = (1 << D5);
  223. #define CLR_TP1 GPOC = (1 << D5);
  224. #define MODE_TP2 pinMode( D6,OUTPUT ) ; // GPIO 12
  225. #define SET_TP2 GPOS = (1 << D6);
  226. #define CLR_TP2 GPOC = (1 << D6);
  227. #define MODE_TP3 pinMode( D7,OUTPUT ) ; // GPIO 13
  228. #define SET_TP3 GPOS = (1 << D7);
  229. #define CLR_TP3 GPOC = (1 << D7);
  230. #define MODE_TP4 pinMode( D8,OUTPUT ) ; // GPIO 15
  231. #define SET_TP4 GPOS = (1 << D8);
  232. #define CLR_TP4 GPOC = (1 << D8);
  233. #elif defined(ESP32)
  234. #define MODE_TP1 pinMode( 33,OUTPUT ) ; // GPIO 33
  235. #define SET_TP1 GPOS = (1 << 33);
  236. #define CLR_TP1 GPOC = (1 << 33);
  237. #define MODE_TP2 pinMode( 25,OUTPUT ) ; // GPIO 25
  238. #define SET_TP2 GPOS = (1 << 25);
  239. #define CLR_TP2 GPOC = (1 << 25);
  240. #define MODE_TP3 pinMode( 26,OUTPUT ) ; // GPIO 26
  241. #define SET_TP3 GPOS = (1 << 26);
  242. #define CLR_TP3 GPOC = (1 << 26);
  243. #define MODE_TP4 pinMode( 27,OUTPUT ) ; // GPIO 27
  244. #define SET_TP4 GPOS = (1 << 27);
  245. #define CLR_TP4 GPOC = (1 << 27);
  246. //#elif defined(__AVR_ATmega128__) ||defined(__AVR_ATmega1281__)||defined(__AVR_ATmega2561__)
  247. #elif defined(NODE_DEBUG)
  248. #define PULLUP PLATFORM_GPIO_PULLUP
  249. #define OUTPUT PLATFORM_GPIO_OUTPUT
  250. #define HIGH PLATFORM_GPIO_HIGH
  251. #define LOW PLATFORM_GPIO_LOW
  252. #define MODE_TP1 platform_gpio_mode( 5, OUTPUT, PULLUP ); // GPIO 14
  253. #define SET_TP1 platform_gpio_write(5, HIGH);
  254. #define CLR_TP1 platform_gpio_write(5, LOW);
  255. #define MODE_TP2 platform_gpio_mode( 6, OUTPUT, PULLUP ); // GPIO 12
  256. #define SET_TP2 platform_gpio_write(6, HIGH);
  257. #define CLR_TP2 platform_gpio_write(6, LOW);
  258. #define MODE_TP3 platform_gpio_mode( 7, OUTPUT, PULLUP ); // GPIO 13
  259. #define SET_TP3 platform_gpio_write(7, HIGH);
  260. #define CLR_TP3 platform_gpio_write(7, LOW);
  261. #define MODE_TP4 platform_gpio_mode( 8, OUTPUT, PULLUP ); // GPIO 15
  262. #define SET_TP4 platform_gpio_write(8, HIGH);
  263. #define CLR_TP4 platform_gpio_write(8, LOW);
  264. #else
  265. #define MODE_TP1
  266. #define SET_TP1
  267. #define CLR_TP1
  268. #define MODE_TP2
  269. #define SET_TP2
  270. #define CLR_TP2
  271. #define MODE_TP3
  272. #define SET_TP3
  273. #define CLR_TP3
  274. #define MODE_TP4
  275. #define SET_TP4
  276. #define CLR_TP4
  277. #endif
  278. #else
  279. #define MODE_TP1
  280. #define SET_TP1
  281. #define CLR_TP1
  282. #define MODE_TP2
  283. #define SET_TP2
  284. #define CLR_TP2
  285. #define MODE_TP3
  286. #define SET_TP3
  287. #define CLR_TP3
  288. #define MODE_TP4
  289. #define SET_TP4
  290. #define CLR_TP4
  291. #endif
  292. #ifdef DEBUG_PRINT
  293. #ifdef NODEMCUDCC
  294. #define DB_PRINT NODE_DBG
  295. #else
  296. #define DB_PRINT( x, ... ) { char dbgbuf[80]; sprintf_P( dbgbuf, (const char*) F( x ) , ##__VA_ARGS__ ) ; Serial.println( dbgbuf ); }
  297. #define DB_PRINT_( x, ... ) { char dbgbuf[80]; sprintf_P( dbgbuf, (const char*) F( x ) , ##__VA_ARGS__ ) ; Serial.print( dbgbuf ); }
  298. #endif
  299. #else
  300. #define DB_PRINT( x, ... ) ;
  301. #define DB_PRINT_( x, ... ) ;
  302. #endif
  303. #ifdef DCC_DBGVAR
  304. struct countOf_t countOf;
  305. #endif
  306. #if defined ( __STM32F1__ )
  307. static ExtIntTriggerMode ISREdge;
  308. #elif defined ( ESP32 )
  309. static byte ISREdge; // Holder of the Next Edge we're looking for: RISING or FALLING
  310. static byte ISRWatch; // Interrupt Handler Edge Filter
  311. #elif defined ( NODEMCUDCC )
  312. static uint8_t ISREdge; // Holder of the Next Edge we're looking for: RISING or FALLING
  313. static int16_t bitMax, bitMin;
  314. DCC_MSG Msg ;
  315. #else
  316. static byte ISREdge; // Holder of the Next Edge we're looking for: RISING or FALLING
  317. static byte ISRWatch; // Interrupt Handler Edge Filter
  318. #endif
  319. byte ISRLevel; // expected Level at DCC input during ISR ( to detect glitches )
  320. byte ISRChkMask; // Flag if Level must be checked
  321. static word bitMax, bitMin;
  322. typedef enum
  323. {
  324. WAIT_PREAMBLE = 0,
  325. WAIT_START_BIT,
  326. #ifndef SYNC_ALWAYS
  327. WAIT_START_BIT_FULL,
  328. #endif
  329. WAIT_DATA,
  330. WAIT_END_BIT
  331. }
  332. DccRxWaitState ;
  333. typedef enum
  334. {
  335. OPS_INS_RESERVED = 0,
  336. OPS_INS_VERIFY_BYTE,
  337. OPS_INS_BIT_MANIPULATION,
  338. OPS_INS_WRITE_BYTE
  339. }
  340. OpsInstructionType;
  341. struct DccRx_t
  342. {
  343. DccRxWaitState State ;
  344. uint8_t DataReady ;
  345. uint8_t BitCount ;
  346. uint8_t TempByte ;
  347. uint8_t chkSum;
  348. DCC_MSG PacketBuf;
  349. DCC_MSG PacketCopy;
  350. }
  351. DccRx ;
  352. typedef struct
  353. {
  354. uint8_t Flags ;
  355. uint8_t OpsModeAddressBaseCV ;
  356. uint8_t inServiceMode ;
  357. long LastServiceModeMillis ;
  358. uint8_t PageRegister ; // Used for Paged Operations in Service Mode Programming
  359. uint8_t DuplicateCount ;
  360. DCC_MSG LastMsg ;
  361. #ifdef NODEMCUDCC
  362. uint8_t IntPin;
  363. uint8_t IntBitmask;
  364. #else
  365. uint8_t ExtIntNum;
  366. uint8_t ExtIntPinNum;
  367. volatile uint8_t *ExtIntPort; // use port and bitmask to read input at AVR in ISR
  368. uint8_t ExtIntMask; // digitalRead is too slow on AVR
  369. #endif
  370. int16_t myDccAddress; // Cached value of DCC Address from CVs
  371. uint8_t inAccDecDCCAddrNextReceivedMode;
  372. uint8_t cv29Value;
  373. #ifdef DCC_DEBUG
  374. uint8_t IntCount;
  375. uint8_t TickCount;
  376. uint8_t NestedIrqCount;
  377. #endif
  378. }
  379. DCC_PROCESSOR_STATE ;
  380. DCC_PROCESSOR_STATE DccProcState ;
  381. #ifdef ESP32
  382. portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED;
  383. void IRAM_ATTR ExternalInterruptHandler(void)
  384. #elif defined(ESP8266)
  385. void ICACHE_RAM_ATTR ExternalInterruptHandler(void)
  386. #elif defined(NODEMCUDCC)
  387. task_handle_t DataReady_taskid;
  388. static uint32_t ICACHE_RAM_ATTR InterruptHandler (uint32_t ret_gpio_status)
  389. #else
  390. void ExternalInterruptHandler(void)
  391. #endif
  392. {
  393. SET_TP3;
  394. #ifdef NODEMCUDCC
  395. // This function really is running at interrupt level with everything
  396. // else masked off. It should take as little time as necessary.
  397. uint32 gpio_status = GPIO_REG_READ(GPIO_STATUS_ADDRESS);
  398. if ((gpio_status & DccProcState.IntBitmask) == 0) {
  399. return ret_gpio_status;
  400. }
  401. GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, gpio_status & DccProcState.IntBitmask);
  402. ret_gpio_status &= ~(DccProcState.IntBitmask);
  403. #endif
  404. #ifdef ESP32
  405. // switch (ISRWatch)
  406. // {
  407. // case RISING: if (digitalRead(DccProcState.ExtIntPinNum)) break;
  408. // case FALLING: if (digitalRead(DccProcState.ExtIntPinNum)) return; break;
  409. // }
  410. // First compare the edge we're looking for to the pin state
  411. switch (ISRWatch)
  412. {
  413. case CHANGE:
  414. break;
  415. case RISING:
  416. if (digitalRead(DccProcState.ExtIntPinNum) != HIGH)
  417. return;
  418. break;
  419. case FALLING:
  420. if (digitalRead(DccProcState.ExtIntPinNum) != LOW)
  421. return;
  422. break;
  423. }
  424. #endif
  425. // Bit evaluation without Timer 0 ------------------------------
  426. uint8_t DccBitVal;
  427. static int8_t bit1, bit2 ;
  428. static unsigned int lastMicros = 0;
  429. #ifdef NODEMCUDCC
  430. static byte halfBit, preambleBitCount;
  431. #else
  432. static byte halfBit, DCC_IrqRunning, preambleBitCount;
  433. #endif
  434. unsigned int actMicros, bitMicros;
  435. #ifdef ALLOW_NESTED_IRQ
  436. if ( DCC_IrqRunning ) {
  437. // nested DCC IRQ - obviously there are glitches
  438. // ignore this interrupt and increment glitchcounter
  439. CLR_TP3;
  440. #ifdef DCC_DEBUG
  441. DccProcState.NestedIrqCount++;
  442. #endif
  443. SET_TP3;
  444. return; //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> abort IRQ
  445. }
  446. #endif
  447. #ifdef NODEMCUDCC
  448. actMicros = system_get_time();
  449. #else
  450. actMicros = micros();
  451. #endif
  452. bitMicros = actMicros-lastMicros;
  453. CLR_TP3; SET_TP3;
  454. #ifdef __AVR_MEGA__
  455. if ( bitMicros < bitMin || ( DccRx.State != WAIT_START_BIT && (*DccProcState.ExtIntPort & DccProcState.ExtIntMask) != (ISRLevel) ) ) {
  456. #elif defined(NODEMCUDCC)
  457. if ( bitMicros < bitMin ) {
  458. #else
  459. if ( bitMicros < bitMin || ( DccRx.State != WAIT_START_BIT && digitalRead( DccProcState.ExtIntPinNum ) != (ISRLevel) ) ) {
  460. #endif
  461. // too short - my be false interrupt due to glitch or false protocol or level does not match RISING / FALLING edge -> ignore this IRQ
  462. CLR_TP3;
  463. SET_TP4; /*delayMicroseconds(1); */ CLR_TP4;
  464. #ifdef NODEMCUDCC
  465. return ret_gpio_status; //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> abort IRQ
  466. #else
  467. return; //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> abort IRQ
  468. #endif
  469. }
  470. CLR_TP3; SET_TP3;
  471. lastMicros = actMicros;
  472. #ifndef SUPPORT_ZERO_BIT_STRETCHING
  473. //if ( bitMicros > MAX_ZEROBITFULL ) {
  474. if ( bitMicros > (bitMax*2) ) {
  475. // too long - my be false protocol -> start over
  476. DccRx.State = WAIT_PREAMBLE ;
  477. DccRx.BitCount = 0 ;
  478. preambleBitCount = 0;
  479. // SET_TP2; CLR_TP2;
  480. bitMax = MAX_PRAEAMBEL;
  481. bitMin = MIN_ONEBITFULL;
  482. #if defined ( __STM32F1__ )
  483. detachInterrupt( DccProcState.ExtIntNum );
  484. #endif
  485. #ifdef ESP32
  486. ISRWatch = ISREdge;
  487. #elif defined(NODEMCUDCC)
  488. gpio_pin_intr_state_set(GPIO_ID_PIN(pin_num[DccProcState.IntPin]), ISREdge );
  489. #else
  490. attachInterrupt( DccProcState.ExtIntNum, ExternalInterruptHandler, ISREdge );
  491. #endif
  492. // enable level-checking
  493. ISRChkMask = DccProcState.ExtIntMask;
  494. ISRLevel = (ISREdge==RISING)? DccProcState.ExtIntMask : 0 ;
  495. CLR_TP3;
  496. //CLR_TP3;
  497. return; //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> abort IRQ
  498. }
  499. CLR_TP3;
  500. SET_TP3;
  501. #endif
  502. DccBitVal = ( bitMicros < bitMax );
  503. #ifdef ALLOW_NESTED_IRQ
  504. DCC_IrqRunning = true;
  505. interrupts(); // time critical is only the micros() command,so allow nested irq's
  506. #endif
  507. #ifdef DCC_DEBUG
  508. DccProcState.TickCount++;
  509. #endif
  510. switch( DccRx.State )
  511. {
  512. case WAIT_PREAMBLE:
  513. // We don't have to do anything special - looking for a preamble condition is done always
  514. SET_TP2;
  515. break;
  516. #ifndef SYNC_ALWAYS
  517. case WAIT_START_BIT_FULL:
  518. // wait for startbit without level checking
  519. if ( !DccBitVal ) {
  520. // we got the startbit
  521. CLR_TP2;CLR_TP1;
  522. DccRx.State = WAIT_DATA ;
  523. CLR_TP1;
  524. // initialize packet buffer
  525. DccRx.PacketBuf.Size = 0;
  526. /*for(uint8_t i = 0; i< MAX_DCC_MESSAGE_LEN; i++ )
  527. DccRx.PacketBuf.Data[i] = 0;*/
  528. DccRx.PacketBuf.PreambleBits = preambleBitCount;
  529. DccRx.BitCount = 0 ;
  530. DccRx.chkSum = 0 ;
  531. DccRx.TempByte = 0 ;
  532. //SET_TP1;
  533. }
  534. break;
  535. #endif
  536. case WAIT_START_BIT:
  537. // we are looking for first half "0" bit after preamble
  538. switch ( halfBit ) {
  539. case 0:
  540. // check first part
  541. if ( DccBitVal ) {
  542. // is still 1-bit (Preamble)
  543. halfBit=1;
  544. bit1=bitMicros;
  545. } else {
  546. // was "0" half bit, maybe the startbit
  547. halfBit = 4;
  548. }
  549. break;
  550. case 1: // previous halfbit was '1'
  551. if ( DccBitVal ) {
  552. // its a '1' halfBit -> we are still in the preamble
  553. halfBit = 0;
  554. bit2=bitMicros;
  555. preambleBitCount++;
  556. if( abs(bit2-bit1) > MAX_BITDIFF ) {
  557. // the length of the 2 halfbits differ too much -> wrong protokoll
  558. DccRx.State = WAIT_PREAMBLE;
  559. bitMax = MAX_PRAEAMBEL;
  560. bitMin = MIN_ONEBITFULL;
  561. preambleBitCount = 0;
  562. // SET_TP2; CLR_TP2;
  563. #if defined ( __STM32F1__ )
  564. detachInterrupt( DccProcState.ExtIntNum );
  565. #endif
  566. #ifdef ESP32
  567. ISRWatch = ISREdge;
  568. #elif defined(NODEMCUDCC)
  569. gpio_pin_intr_state_set(GPIO_ID_PIN(pin_num[DccProcState.IntPin]), ISREdge);
  570. #else
  571. attachInterrupt( DccProcState.ExtIntNum, ExternalInterruptHandler, ISREdge );
  572. // enable level checking ( with direct port reading @ AVR )
  573. ISRChkMask = DccProcState.ExtIntMask;
  574. ISRLevel = (ISREdge==RISING)? DccProcState.ExtIntMask : 0 ;
  575. #endif
  576. SET_TP3;
  577. CLR_TP4;
  578. }
  579. } else {
  580. // first '0' half detected in second halfBit
  581. // wrong sync or not a DCC protokoll
  582. CLR_TP3;
  583. halfBit = 3;
  584. SET_TP3;
  585. }
  586. break;
  587. case 3: // previous halfbit was '0' in second halfbit
  588. if ( DccBitVal ) {
  589. // its a '1' halfbit -> we got only a half '0' bit -> cannot be DCC
  590. DccRx.State = WAIT_PREAMBLE;
  591. bitMax = MAX_PRAEAMBEL;
  592. bitMin = MIN_ONEBITFULL;
  593. preambleBitCount = 0;
  594. // SET_TP2; CLR_TP2;
  595. } else {
  596. // we got two '0' halfbits -> it's the startbit
  597. // but sync is NOT ok, change IRQ edge.
  598. CLR_TP2;CLR_TP1;
  599. if ( ISREdge == RISING ) ISREdge = FALLING; else ISREdge = RISING;
  600. DccRx.State = WAIT_DATA ;
  601. CLR_TP1;
  602. bitMax = MAX_ONEBITFULL;
  603. bitMin = MIN_ONEBITFULL;
  604. DccRx.PacketBuf.Size = 0;
  605. /*for(uint8_t i = 0; i< MAX_DCC_MESSAGE_LEN; i++ )
  606. DccRx.PacketBuf.Data[i] = 0;*/
  607. DccRx.PacketBuf.PreambleBits = preambleBitCount;
  608. DccRx.BitCount = 0 ;
  609. DccRx.chkSum = 0 ;
  610. DccRx.TempByte = 0 ;
  611. //SET_TP1;
  612. }
  613. //SET_TP4;
  614. #if defined ( __STM32F1__ )
  615. detachInterrupt( DccProcState.ExtIntNum );
  616. #endif
  617. #ifdef ESP32
  618. ISRWatch = ISREdge;
  619. #elif defined(NODEMCUDCC)
  620. gpio_pin_intr_state_set(GPIO_ID_PIN(pin_num[DccProcState.IntPin]), ISREdge);
  621. #else
  622. attachInterrupt( DccProcState.ExtIntNum, ExternalInterruptHandler, ISREdge );
  623. #endif
  624. #ifndef NODEMCUDCC
  625. // enable level-checking
  626. ISRChkMask = DccProcState.ExtIntMask;
  627. ISRLevel = (ISREdge==RISING)? DccProcState.ExtIntMask : 0 ;
  628. //CLR_TP4;
  629. #endif
  630. break;
  631. case 4: // previous (first) halfbit was 0
  632. // if this halfbit is 0 too, we got the startbit
  633. if ( DccBitVal ) {
  634. // second halfbit is 1 -> unknown protokoll
  635. DccRx.State = WAIT_PREAMBLE;
  636. bitMax = MAX_PRAEAMBEL;
  637. bitMin = MIN_ONEBITFULL;
  638. preambleBitCount = 0;
  639. CLR_TP2;CLR_TP1;
  640. DccRx.BitCount = 0;
  641. } else {
  642. // we got the startbit
  643. CLR_TP2;CLR_TP1;
  644. DccRx.State = WAIT_DATA ;
  645. CLR_TP1;
  646. bitMax = MAX_ONEBITFULL;
  647. bitMin = MIN_ONEBITFULL;
  648. // initialize packet buffer
  649. DccRx.PacketBuf.Size = 0;
  650. /*for(uint8_t i = 0; i< MAX_DCC_MESSAGE_LEN; i++ )
  651. DccRx.PacketBuf.Data[i] = 0;*/
  652. DccRx.PacketBuf.PreambleBits = preambleBitCount;
  653. DccRx.BitCount = 0 ;
  654. DccRx.chkSum = 0 ;
  655. DccRx.TempByte = 0 ;
  656. //SET_TP1;
  657. }
  658. //SET_TP4;
  659. #if defined ( __STM32F1__ )
  660. detachInterrupt( DccProcState.ExtIntNum );
  661. #endif
  662. #ifdef ESP32
  663. ISRWatch = ISREdge;
  664. #elif defined(NODEMCUDCC)
  665. gpio_pin_intr_state_set(GPIO_ID_PIN(pin_num[DccProcState.IntPin]), ISREdge);
  666. #else
  667. attachInterrupt( DccProcState.ExtIntNum, ExternalInterruptHandler, ISREdge );
  668. #endif
  669. #ifndef NODEMCUDCC
  670. // enable level-checking
  671. ISRChkMask = DccProcState.ExtIntMask;
  672. ISRLevel = (ISREdge==RISING)? DccProcState.ExtIntMask : 0 ;
  673. //CLR_TP4;
  674. #endif
  675. break;
  676. }
  677. break;
  678. case WAIT_DATA:
  679. CLR_TP2;
  680. DccRx.BitCount++;
  681. DccRx.TempByte = ( DccRx.TempByte << 1 ) ;
  682. if( DccBitVal )
  683. DccRx.TempByte |= 1 ;
  684. if( DccRx.BitCount == 8 )
  685. {
  686. if( DccRx.PacketBuf.Size == MAX_DCC_MESSAGE_LEN ) // Packet is too long - abort
  687. {
  688. DccRx.State = WAIT_PREAMBLE ;
  689. bitMax = MAX_PRAEAMBEL;
  690. bitMin = MIN_ONEBITFULL;
  691. DccRx.BitCount = 0 ;
  692. }
  693. else
  694. {
  695. DccRx.State = WAIT_END_BIT ;
  696. DccRx.PacketBuf.Data[ DccRx.PacketBuf.Size++ ] = DccRx.TempByte ;
  697. DccRx.chkSum ^= DccRx.TempByte;
  698. }
  699. }
  700. break;
  701. case WAIT_END_BIT:
  702. SET_TP2;CLR_TP2;
  703. DccRx.BitCount++;
  704. if( DccBitVal ) { // End of packet?
  705. CLR_TP3; SET_TP4;
  706. DccRx.State = WAIT_PREAMBLE ;
  707. DccRx.BitCount = 0 ;
  708. bitMax = MAX_PRAEAMBEL;
  709. bitMin = MIN_ONEBITFULL;
  710. SET_TP1;
  711. if ( DccRx.chkSum == 0 ) {
  712. // Packet is valid
  713. #ifdef ESP32
  714. portENTER_CRITICAL_ISR(&mux);
  715. #endif
  716. DccRx.PacketCopy = DccRx.PacketBuf ;
  717. DccRx.DataReady = 1 ;
  718. #ifdef ESP32
  719. portEXIT_CRITICAL_ISR(&mux);
  720. #elif defined(NODEMCUDCC)
  721. task_post_high(DataReady_taskid, (os_param_t) 0);
  722. #endif
  723. // SET_TP2; CLR_TP2;
  724. preambleBitCount = 0 ;
  725. } else {
  726. // Wrong checksum
  727. CLR_TP1;
  728. #ifdef DCC_DBGVAR
  729. DB_PRINT("Cerr");
  730. countOf.Err++;
  731. #endif
  732. }
  733. SET_TP3; CLR_TP4;
  734. } else { // Get next Byte
  735. // KGW - Abort immediately if packet is too long.
  736. if( DccRx.PacketBuf.Size == MAX_DCC_MESSAGE_LEN ) // Packet is too long - abort
  737. {
  738. DccRx.State = WAIT_PREAMBLE ;
  739. bitMax = MAX_PRAEAMBEL;
  740. bitMin = MIN_ONEBITFULL;
  741. DccRx.BitCount = 0 ;
  742. }
  743. else
  744. {
  745. DccRx.State = WAIT_DATA ;
  746. DccRx.BitCount = 0 ;
  747. DccRx.TempByte = 0 ;
  748. }
  749. }
  750. }
  751. // unless we're already looking for the start bit
  752. // we always search for a preamble ( ( 10 or more consecutive 1 bits )
  753. // if we found it within a packet, the packet decoding is aborted because
  754. // that much one bits cannot be valid in a packet.
  755. if ( DccRx.State != WAIT_START_BIT ) {
  756. if( DccBitVal )
  757. {
  758. preambleBitCount++;
  759. //SET_TP2;
  760. if( preambleBitCount > 10 ) {
  761. CLR_TP2;
  762. #ifndef SYNC_ALWAYS
  763. if ( DccRx.chkSum == 0 ) {
  764. // sync must be correct if chksum was ok, no need to check sync
  765. DccRx.State = WAIT_START_BIT_FULL;
  766. } else {
  767. #endif
  768. DccRx.State = WAIT_START_BIT ;
  769. SET_TP2;
  770. // While waiting for the start bit, detect halfbit lengths. We will detect the correct
  771. // sync and detect whether we see a false (e.g. motorola) protocol
  772. #if defined ( __STM32F1__ )
  773. detachInterrupt( DccProcState.ExtIntNum );
  774. #endif
  775. #ifdef ESP32
  776. ISRWatch = CHANGE;
  777. #elif defined(NODEMCUDCC)
  778. gpio_pin_intr_state_set(GPIO_ID_PIN(pin_num[DccProcState.IntPin]), CHANGE);
  779. #else
  780. attachInterrupt( DccProcState.ExtIntNum, ExternalInterruptHandler, CHANGE);
  781. #endif
  782. ISRChkMask = 0; // AVR level check is always true with this settings
  783. ISRLevel = 0; // ( there cannot be false edge IRQ's with CHANGE )
  784. halfBit = 0;
  785. bitMax = MAX_ONEBITHALF;
  786. bitMin = MIN_ONEBITHALF;
  787. //CLR_TP1;
  788. #ifndef SYNC_ALWAYS
  789. }
  790. #endif
  791. }
  792. } else {
  793. CLR_TP1;
  794. preambleBitCount = 0 ;
  795. // SET_TP2; CLR_TP2;
  796. }
  797. }
  798. #ifdef ALLOW_NESTED_IRQ
  799. DCC_IrqRunning = false;
  800. #endif
  801. //CLR_TP1;
  802. CLR_TP3;
  803. #ifdef NODEMCUDCC
  804. return ret_gpio_status;
  805. #endif
  806. }
  807. void ackCV(void)
  808. {
  809. if( notifyCVAck )
  810. {
  811. DB_PRINT("ackCV: Send Basic ACK");
  812. notifyCVAck() ;
  813. }
  814. }
  815. void ackAdvancedCV(void)
  816. {
  817. if( notifyAdvancedCVAck && (DccProcState.cv29Value & CV29_RAILCOM_ENABLE) )
  818. {
  819. DB_PRINT("ackAdvancedCV: Send RailCom ACK");
  820. notifyAdvancedCVAck() ;
  821. }
  822. }
  823. #ifndef NODEMCUDCC
  824. uint8_t readEEPROM( unsigned int CV )
  825. {
  826. return EEPROM.read(CV) ;
  827. }
  828. void writeEEPROM( unsigned int CV, uint8_t Value )
  829. {
  830. EEPROM.write(CV, Value) ;
  831. #if defined(ESP8266)
  832. EEPROM.commit();
  833. #endif
  834. #if defined(ESP32)
  835. EEPROM.commit();
  836. #endif
  837. }
  838. bool readyEEPROM()
  839. {
  840. #if defined ARDUINO_ARCH_MEGAAVR
  841. return bit_is_clear(NVMCTRL.STATUS,NVMCTRL_EEBUSY_bp);
  842. #elif defined __AVR_MEGA__
  843. return eeprom_is_ready();
  844. #else
  845. return true;
  846. #endif
  847. }
  848. #endif
  849. uint8_t validCV( uint16_t CV, uint8_t Writable )
  850. {
  851. if( notifyCVResetFactoryDefault && (CV == CV_MANUFACTURER_ID ) && Writable )
  852. notifyCVResetFactoryDefault();
  853. if( notifyCVValid )
  854. return notifyCVValid( CV, Writable ) ;
  855. #ifdef NODEMCUDCC
  856. return 0;
  857. #else
  858. uint8_t Valid = 1 ;
  859. if( CV > MAXCV )
  860. Valid = 0 ;
  861. if( Writable && ( ( CV ==CV_VERSION_ID ) || (CV == CV_MANUFACTURER_ID ) ) )
  862. Valid = 0 ;
  863. return Valid ;
  864. #endif
  865. }
  866. #ifdef NODEMCUDCC
  867. uint16_t readCV( unsigned int CV )
  868. #else
  869. uint8_t readCV( unsigned int CV )
  870. #endif
  871. {
  872. #ifndef NODEMCUDCC
  873. uint8_t Value ;
  874. #endif
  875. if( notifyCVRead )
  876. return notifyCVRead( CV ) ;
  877. #ifndef NODEMCUDCC
  878. Value = readEEPROM(CV);
  879. return Value ;
  880. #else
  881. return 0;
  882. #endif
  883. }
  884. uint8_t writeCV( unsigned int CV, uint8_t Value)
  885. {
  886. switch( CV )
  887. {
  888. case CV_29_CONFIG:
  889. // copy addressmode Bit to Flags
  890. Value = Value & ~CV29_RAILCOM_ENABLE; // Bidi (RailCom) Bit must not be enabled,
  891. // because you cannot build a Bidi decoder with this lib.
  892. DccProcState.cv29Value = Value;
  893. DccProcState.Flags = ( DccProcState.Flags & ~FLAGS_CV29_BITS) | (Value & FLAGS_CV29_BITS);
  894. // no break, because myDccAdress must also be reset
  895. case CV_ACCESSORY_DECODER_ADDRESS_LSB: // Also same CV for CV_MULTIFUNCTION_PRIMARY_ADDRESS
  896. case CV_ACCESSORY_DECODER_ADDRESS_MSB:
  897. case CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB:
  898. case CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB:
  899. DccProcState.myDccAddress = -1; // Assume any CV Write Operation might change the Address
  900. }
  901. if( notifyCVWrite )
  902. return notifyCVWrite( CV, Value ) ;
  903. #ifdef NODEMCUDCC
  904. return 0;
  905. #else
  906. if( readEEPROM( CV ) != Value )
  907. {
  908. writeEEPROM( CV, Value ) ;
  909. if( notifyCVChange )
  910. notifyCVChange( CV, Value) ;
  911. if( notifyDccCVChange && !(DccProcState.Flags & FLAGS_SETCV_CALLED) )
  912. notifyDccCVChange( CV, Value );
  913. }
  914. return readEEPROM( CV ) ;
  915. #endif
  916. }
  917. uint16_t getMyAddr(void)
  918. {
  919. if( DccProcState.myDccAddress != -1 ) // See if we can return the cached value
  920. return( DccProcState.myDccAddress );
  921. if( DccProcState.cv29Value & CV29_ACCESSORY_DECODER ) // Accessory Decoder?
  922. {
  923. if( DccProcState.cv29Value & CV29_OUTPUT_ADDRESS_MODE )
  924. DccProcState.myDccAddress = ( readCV( CV_ACCESSORY_DECODER_ADDRESS_MSB ) << 8 ) | readCV( CV_ACCESSORY_DECODER_ADDRESS_LSB );
  925. else
  926. DccProcState.myDccAddress = ( ( readCV( CV_ACCESSORY_DECODER_ADDRESS_MSB ) & 0b00000111) << 6 ) | ( readCV( CV_ACCESSORY_DECODER_ADDRESS_LSB ) & 0b00111111) ;
  927. }
  928. else // Multi-Function Decoder?
  929. {
  930. if( DccProcState.cv29Value & CV29_EXT_ADDRESSING ) // Two Byte Address?
  931. DccProcState.myDccAddress = ( ( readCV( CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB ) - 192 ) << 8 ) | readCV( CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB ) ;
  932. else
  933. DccProcState.myDccAddress = readCV( 1 ) ;
  934. }
  935. return DccProcState.myDccAddress ;
  936. }
  937. void processDirectCVOperation( uint8_t Cmd, uint16_t CVAddr, uint8_t Value, void (*ackFunction)() )
  938. {
  939. // is it a Byte Operation
  940. if( Cmd & 0x04 )
  941. {
  942. // Perform the Write Operation
  943. if( Cmd & 0x08 )
  944. {
  945. if( validCV( CVAddr, 1 ) )
  946. {
  947. DB_PRINT("CV: %d Byte Write: %02X", CVAddr, Value)
  948. if( writeCV( CVAddr, Value ) == Value )
  949. ackFunction();
  950. }
  951. }
  952. else // Perform the Verify Operation
  953. {
  954. if( validCV( CVAddr, 0 ) )
  955. {
  956. DB_PRINT("CV: %d Byte Read: %02X", CVAddr, Value)
  957. if( readCV( CVAddr ) == Value )
  958. ackFunction();
  959. }
  960. }
  961. }
  962. // Perform the Bit-Wise Operation
  963. else
  964. {
  965. uint8_t BitMask = (1 << (Value & 0x07) ) ;
  966. uint8_t BitValue = Value & 0x08 ;
  967. uint8_t BitWrite = Value & 0x10 ;
  968. #ifdef NODEMCUDCC
  969. uint16_t tempValue = readCV( CVAddr ) ; // Read the Current CV Value
  970. #else
  971. uint8_t tempValue = readCV( CVAddr ) ; // Read the Current CV Value
  972. #endif
  973. #ifdef NODEMCUDCC
  974. if (tempValue <= 255) {
  975. DB_PRINT("CV: %d Current Value: %02X Bit-Wise Mode: %s Mask: %02X Value: %02X", CVAddr, tempValue, BitWrite ? "Write":"Read", BitMask, BitValue);
  976. #else
  977. DB_PRINT("CV: %d Current Value: %02X Bit-Wise Mode: %s Mask: %02X Value: %02X", CVAddr, tempValue, BitWrite ? "Write":"Read", BitMask, BitValue);
  978. #endif
  979. // Perform the Bit Write Operation
  980. if( BitWrite )
  981. {
  982. if( validCV( CVAddr, 1 ) )
  983. {
  984. if( BitValue )
  985. tempValue |= BitMask ; // Turn the Bit On
  986. else
  987. tempValue &= ~BitMask ; // Turn the Bit Off
  988. if( writeCV( CVAddr, tempValue ) == tempValue )
  989. ackFunction() ;
  990. }
  991. }
  992. // Perform the Bit Verify Operation
  993. else
  994. {
  995. if( validCV( CVAddr, 0 ) )
  996. {
  997. if( BitValue )
  998. {
  999. if( tempValue & BitMask )
  1000. ackFunction() ;
  1001. }
  1002. else
  1003. {
  1004. if( !( tempValue & BitMask) )
  1005. ackFunction() ;
  1006. }
  1007. }
  1008. }
  1009. #ifdef NODEMCUDCC
  1010. }
  1011. #endif
  1012. }
  1013. }
  1014. /////////////////////////////////////////////////////////////////////////
  1015. #ifdef NMRA_DCC_PROCESS_MULTIFUNCTION
  1016. void processMultiFunctionMessage( uint16_t Addr, DCC_ADDR_TYPE AddrType, uint8_t Cmd, uint8_t Data1, uint8_t Data2 )
  1017. {
  1018. uint8_t speed ;
  1019. uint16_t CVAddr ;
  1020. DCC_DIRECTION dir ;
  1021. DCC_SPEED_STEPS speedSteps ;
  1022. uint8_t CmdMasked = Cmd & 0b11100000 ;
  1023. // NODE_DBG("[dcc_processMultiFunctionMessage] Addr: %d, Type: %d, Cmd: %d ("BYTE_TO_BINARY_PATTERN"), Data: %d, %d, CmdMasked="BYTE_TO_BINARY_PATTERN"\n", Addr, AddrType, Cmd, BYTE_TO_BINARY(Cmd), Data1, Data2, BYTE_TO_BINARY(CmdMasked));
  1024. // If we are an Accessory Decoder
  1025. if( DccProcState.Flags & FLAGS_DCC_ACCESSORY_DECODER )
  1026. {
  1027. // NODE_DBG("[dcc_processMultiFunctionMessage] DccProcState.Flags & FLAGS_DCC_ACCESSORY_DECODER\n");
  1028. // and this isn't an Ops Mode Write or we are NOT faking the Multifunction Ops mode address in CV 33+34 or
  1029. // it's not our fake address, then return
  1030. if( ( CmdMasked != 0b11100000 ) || ( DccProcState.OpsModeAddressBaseCV == 0 ) )
  1031. return ;
  1032. uint16_t FakeOpsAddr = readCV( DccProcState.OpsModeAddressBaseCV ) | ( readCV( DccProcState.OpsModeAddressBaseCV + 1 ) << 8 ) ;
  1033. uint16_t OpsAddr = Addr & 0x3FFF ;
  1034. if( OpsAddr != FakeOpsAddr )
  1035. return ;
  1036. }
  1037. // We are looking for FLAGS_MY_ADDRESS_ONLY but it does not match and it is not a Broadcast Address then return
  1038. else if( ( DccProcState.Flags & FLAGS_MY_ADDRESS_ONLY ) && ( Addr != getMyAddr() ) && ( Addr != 0 ) )
  1039. return ;
  1040. NODE_DBG("[dcc_processMultiFunctionMessage] CmdMasked: %x\n", CmdMasked);
  1041. switch( CmdMasked )
  1042. {
  1043. case 0b00000000: // Decoder Control
  1044. switch( Cmd & 0b00001110 )
  1045. {
  1046. case 0b00000000:
  1047. if( notifyDccReset)
  1048. notifyDccReset( Cmd & 0b00000001 ) ;
  1049. break ;
  1050. case 0b00000010: // Factory Test
  1051. break ;
  1052. case 0b00000110: // Set Decoder Flags
  1053. break ;
  1054. case 0b00001010: // Set Advanced Addressing
  1055. break ;
  1056. case 0b00001110: // Decoder Acknowledgment
  1057. break ;
  1058. default: // Reserved
  1059. ;
  1060. }
  1061. break ;
  1062. case 0b00100000: // Advanced Operations
  1063. switch( Cmd & 0b00011111 )
  1064. {
  1065. case 0b00011111:
  1066. if( notifyDccSpeed )
  1067. {
  1068. switch( Data1 & 0b01111111 )
  1069. {
  1070. case 0b00000000: // 0=STOP
  1071. speed = 1 ; // => 1
  1072. break ;
  1073. case 0b00000001: // 1=EMERGENCY_STOP
  1074. speed = 0 ; // => 0
  1075. break ;
  1076. default: // 2..127
  1077. speed = (Data1 & 0b01111111) ;
  1078. }
  1079. dir = (DCC_DIRECTION) ((Data1 & 0b10000000) >> 7) ;
  1080. notifyDccSpeed( Addr, AddrType, speed, dir, SPEED_STEP_128 ) ;
  1081. }
  1082. }
  1083. break;
  1084. case 0b01000000:
  1085. case 0b01100000:
  1086. //TODO should we cache this info in DCC_PROCESSOR_STATE.Flags ?
  1087. #ifdef NMRA_DCC_ENABLE_14_SPEED_STEP_MODE
  1088. speedSteps = (DccProcState.cv29Value & CV29_F0_LOCATION) ? SPEED_STEP_28 : SPEED_STEP_14 ;
  1089. #else
  1090. speedSteps = SPEED_STEP_28 ;
  1091. #endif
  1092. if( notifyDccSpeed )
  1093. {
  1094. switch( Cmd & 0b00011111 )
  1095. {
  1096. case 0b00000000: // 0 0000 = STOP
  1097. case 0b00010000: // 1 0000 = STOP
  1098. speed = 1 ; // => 1
  1099. break ;
  1100. case 0b00000001: // 0 0001 = EMERGENCY STOP
  1101. case 0b00010001: // 1 0001 = EMERGENCY STOP
  1102. speed = 0 ; // => 0
  1103. break ;
  1104. default:
  1105. #ifdef NMRA_DCC_ENABLE_14_SPEED_STEP_MODE
  1106. if( speedSteps == SPEED_STEP_14 )
  1107. {
  1108. speed = (Cmd & 0b00001111) ; // => 2..15
  1109. }
  1110. else
  1111. {
  1112. #endif
  1113. speed = (((Cmd & 0b00001111) << 1 ) | ((Cmd & 0b00010000) >> 4)) - 2 ; // => 2..29
  1114. #ifdef NMRA_DCC_ENABLE_14_SPEED_STEP_MODE
  1115. }
  1116. #endif
  1117. }
  1118. dir = (DCC_DIRECTION) ((Cmd & 0b00100000) >> 5) ;
  1119. notifyDccSpeed( Addr, AddrType, speed, dir, speedSteps ) ;
  1120. }
  1121. if( notifyDccSpeedRaw )
  1122. notifyDccSpeedRaw(Addr, AddrType, Cmd );
  1123. #ifdef NMRA_DCC_ENABLE_14_SPEED_STEP_MODE
  1124. if( notifyDccFunc && (speedSteps == SPEED_STEP_14) )
  1125. {
  1126. // function light is controlled by this package
  1127. uint8_t fn0 = (Cmd & 0b00010000) ;
  1128. notifyDccFunc( Addr, AddrType, FN_0, fn0 ) ;
  1129. }
  1130. #endif
  1131. break;
  1132. case 0b10000000: // Function Group 0..4
  1133. if( notifyDccFunc )
  1134. {
  1135. // function light is controlled by this package (28 or 128 speed steps)
  1136. notifyDccFunc( Addr, AddrType, FN_0_4, Cmd & 0b00011111 ) ;
  1137. }
  1138. break;
  1139. case 0b10100000: // Function Group 5..8
  1140. if( notifyDccFunc)
  1141. {
  1142. if (Cmd & 0b00010000 )
  1143. notifyDccFunc( Addr, AddrType, FN_5_8, Cmd & 0b00001111 ) ;
  1144. else
  1145. notifyDccFunc( Addr, AddrType, FN_9_12, Cmd & 0b00001111 ) ;
  1146. }
  1147. break;
  1148. case 0b11000000: // Feature Expansion Instruction
  1149. switch(Cmd & 0b00011111)
  1150. {
  1151. case 0b00011110:
  1152. if( notifyDccFunc )
  1153. notifyDccFunc( Addr, AddrType, FN_13_20, Data1 ) ;
  1154. break;
  1155. case 0b00011111:
  1156. if( notifyDccFunc )
  1157. notifyDccFunc( Addr, AddrType, FN_21_28, Data1 ) ;
  1158. break;
  1159. }
  1160. break;
  1161. case 0b11100000: // CV Access
  1162. CVAddr = ( ( ( Cmd & 0x03 ) << 8 ) | Data1 ) + 1 ;
  1163. processDirectCVOperation( Cmd, CVAddr, Data2, ackAdvancedCV) ;
  1164. break;
  1165. }
  1166. }
  1167. #endif
  1168. /////////////////////////////////////////////////////////////////////////
  1169. #ifdef NMRA_DCC_PROCESS_SERVICEMODE
  1170. void processServiceModeOperation( DCC_MSG * pDccMsg )
  1171. {
  1172. uint16_t CVAddr ;
  1173. uint8_t Value ;
  1174. if( pDccMsg->Size == 3) // 3 Byte Packets are for Address Only, Register and Paged Mode
  1175. {
  1176. uint8_t RegisterAddr ;
  1177. DB_PRINT("CV Address, Register & Paged Mode Operation");
  1178. RegisterAddr = pDccMsg->Data[0] & 0x07 ;
  1179. Value = pDccMsg->Data[1] ;
  1180. if( RegisterAddr == 5 )
  1181. {
  1182. DccProcState.PageRegister = Value ;
  1183. ackCV();
  1184. }
  1185. else
  1186. {
  1187. if( RegisterAddr == 4 )
  1188. CVAddr = CV_29_CONFIG ;
  1189. else if( ( RegisterAddr <= 3 ) && ( DccProcState.PageRegister > 0 ) )
  1190. CVAddr = ( ( DccProcState.PageRegister - 1 ) * 4 ) + RegisterAddr + 1 ;
  1191. else
  1192. CVAddr = RegisterAddr + 1 ;
  1193. if( pDccMsg->Data[0] & 0x08 ) // Perform the Write Operation
  1194. {
  1195. if( validCV( CVAddr, 1 ) )
  1196. {
  1197. if( writeCV( CVAddr, Value ) == Value )
  1198. ackCV();
  1199. }
  1200. }
  1201. else // Perform the Verify Operation
  1202. {
  1203. if( validCV( CVAddr, 0 ) )
  1204. {
  1205. if( readCV( CVAddr ) == Value )
  1206. ackCV();
  1207. }
  1208. }
  1209. }
  1210. }
  1211. else if( pDccMsg->Size == 4) // 4 Byte Packets are for Direct Byte & Bit Mode
  1212. {
  1213. DB_PRINT("CV Direct Byte and Bit Mode Mode Operation");
  1214. CVAddr = ( ( ( pDccMsg->Data[0] & 0x03 ) << 8 ) | pDccMsg->Data[1] ) + 1 ;
  1215. Value = pDccMsg->Data[2] ;
  1216. processDirectCVOperation( pDccMsg->Data[0] & 0b00001100, CVAddr, Value, ackCV) ;
  1217. }
  1218. }
  1219. #endif
  1220. /////////////////////////////////////////////////////////////////////////
  1221. void resetServiceModeTimer(uint8_t inServiceMode)
  1222. {
  1223. if (notifyServiceMode && inServiceMode != DccProcState.inServiceMode)
  1224. {
  1225. notifyServiceMode(inServiceMode);
  1226. }
  1227. // Set the Service Mode
  1228. DccProcState.inServiceMode = inServiceMode ;
  1229. DccProcState.LastServiceModeMillis = inServiceMode ? millis() : 0 ;
  1230. if (notifyServiceMode && inServiceMode != DccProcState.inServiceMode)
  1231. {
  1232. notifyServiceMode(inServiceMode);
  1233. }
  1234. }
  1235. /////////////////////////////////////////////////////////////////////////
  1236. void clearDccProcState(uint8_t inServiceMode)
  1237. {
  1238. resetServiceModeTimer( inServiceMode ) ;
  1239. // Set the Page Register to it's default of 1 only on the first Reset
  1240. DccProcState.PageRegister = 1 ;
  1241. // Clear the LastMsg buffer and DuplicateCount in preparation for possible CV programming
  1242. DccProcState.DuplicateCount = 0 ;
  1243. memset( &DccProcState.LastMsg, 0, sizeof( DCC_MSG ) ) ;
  1244. }
  1245. /////////////////////////////////////////////////////////////////////////
  1246. #ifdef DEBUG_PRINT
  1247. void SerialPrintPacketHex(const __FlashStringHelper *strLabel, DCC_MSG * pDccMsg)
  1248. {
  1249. Serial.print( strLabel );
  1250. for( uint8_t i = 0; i < pDccMsg->Size; i++ )
  1251. {
  1252. if( pDccMsg->Data[i] <= 9)
  1253. Serial.print('0');
  1254. Serial.print( pDccMsg->Data[i], HEX );
  1255. Serial.write( ' ' );
  1256. }
  1257. Serial.println();
  1258. }
  1259. #endif
  1260. ///////////////////////////////////////////////////////////////////////////////
  1261. void execDccProcessor( DCC_MSG * pDccMsg )
  1262. {
  1263. NODE_DBG("[dcc_execDccProcessor]\n");
  1264. if( ( pDccMsg->Data[0] == 0 ) && ( pDccMsg->Data[1] == 0 ) )
  1265. {
  1266. if( notifyDccReset )
  1267. notifyDccReset( 0 ) ;
  1268. #ifdef NMRA_DCC_PROCESS_SERVICEMODE
  1269. // If this is the first Reset then perform some one-shot actions as we maybe about to enter service mode
  1270. if( DccProcState.inServiceMode )
  1271. resetServiceModeTimer( 1 ) ;
  1272. else
  1273. clearDccProcState( 1 );
  1274. #endif
  1275. }
  1276. else
  1277. {
  1278. #ifdef NMRA_DCC_PROCESS_SERVICEMODE
  1279. if( DccProcState.inServiceMode && ( pDccMsg->Data[0] >= 112 ) && ( pDccMsg->Data[0] < 128 ) )
  1280. {
  1281. resetServiceModeTimer( 1 ) ;
  1282. //Only check the DCC Packet "Size" and "Data" fields and ignore the "PreambleBits" as they can be different to the previous packet
  1283. if(pDccMsg->Size != DccProcState.LastMsg.Size || memcmp( pDccMsg->Data, &DccProcState.LastMsg.Data, pDccMsg->Size ) != 0 )
  1284. {
  1285. DccProcState.DuplicateCount = 0 ;
  1286. memcpy( &DccProcState.LastMsg, pDccMsg, sizeof( DCC_MSG ) ) ;
  1287. }
  1288. // Wait until you see 2 identical packets before acting on a Service Mode Packet
  1289. else
  1290. {
  1291. DccProcState.DuplicateCount++ ;
  1292. processServiceModeOperation( pDccMsg ) ;
  1293. }
  1294. }
  1295. else
  1296. {
  1297. if( DccProcState.inServiceMode )
  1298. clearDccProcState( 0 );
  1299. #endif
  1300. // Idle Packet
  1301. if( ( pDccMsg->Data[0] == 0b11111111 ) && ( pDccMsg->Data[1] == 0 ) )
  1302. {
  1303. if( notifyDccIdle )
  1304. notifyDccIdle() ;
  1305. }
  1306. #ifdef NMRA_DCC_PROCESS_MULTIFUNCTION
  1307. // Multi Function Decoders (7-bit address)
  1308. else if( pDccMsg->Data[0] < 128 )
  1309. processMultiFunctionMessage( pDccMsg->Data[0], DCC_ADDR_SHORT, pDccMsg->Data[1], pDccMsg->Data[2], pDccMsg->Data[3] ) ;
  1310. // Basic Accessory Decoders (9-bit) & Extended Accessory Decoders (11-bit)
  1311. else if( pDccMsg->Data[0] < 192 )
  1312. #else
  1313. else if( ( pDccMsg->Data[0] >= 128 ) && ( pDccMsg->Data[0] < 192 ) )
  1314. #endif
  1315. {
  1316. if( DccProcState.Flags & FLAGS_DCC_ACCESSORY_DECODER )
  1317. {
  1318. int16_t BoardAddress ;
  1319. int16_t OutputAddress ;
  1320. uint8_t TurnoutPairIndex ;
  1321. #ifdef DEBUG_PRINT
  1322. SerialPrintPacketHex(F( "eDP: AccCmd: "), pDccMsg);
  1323. #endif
  1324. BoardAddress = ( ( (~pDccMsg->Data[1]) & 0b01110000 ) << 2 ) | ( pDccMsg->Data[0] & 0b00111111 ) ;
  1325. TurnoutPairIndex = (pDccMsg->Data[1] & 0b00000110) >> 1;
  1326. DB_PRINT("[dcc_execDccProcessor] eDP: BAddr:%d, Index:%d", BoardAddress, TurnoutPairIndex);
  1327. // First check for Legacy Accessory Decoder Configuration Variable Access Instruction
  1328. // as it's got a different format to the others
  1329. if((pDccMsg->Size == 5) && ((pDccMsg->Data[1] & 0b10001100) == 0b00001100))
  1330. {
  1331. DB_PRINT( "eDP: Legacy Accessory Decoder CV Access Command");
  1332. // Check if this command is for our address or the broadcast address
  1333. if((BoardAddress != getMyAddr()) && ( BoardAddress < 511 ))
  1334. {
  1335. DB_PRINT("[dcc_execDccProcessor] eDP: Board Address Not Matched");
  1336. return;
  1337. }
  1338. uint16_t cvAddress = ((pDccMsg->Data[1] & 0b00000011) << 8) + pDccMsg->Data[2] + 1;
  1339. uint8_t cvValue = pDccMsg->Data[3];
  1340. DB_PRINT("[dcc_execDccProcessor] eDP: CV:%d Value:%d", cvAddress, cvValue );
  1341. if(validCV( cvAddress, 1 ))
  1342. writeCV(cvAddress, cvValue);
  1343. return;
  1344. }
  1345. OutputAddress = (((BoardAddress - 1) << 2 ) | TurnoutPairIndex) + 1 ; //decoder output addresses start with 1, packet address range starts with 0
  1346. // ( according to NMRA 9.2.2 )
  1347. DB_PRINT("[dcc_execDccProcessor] eDP: OAddr:%d", OutputAddress);
  1348. if( DccProcState.inAccDecDCCAddrNextReceivedMode)
  1349. {
  1350. if( DccProcState.Flags & FLAGS_OUTPUT_ADDRESS_MODE )
  1351. {
  1352. DB_PRINT("eDP: Set OAddr:%d", OutputAddress);
  1353. //uint16_t storedOutputAddress = OutputAddress + 1; // The value stored in CV1 & 9 for Output Addressing Mode is + 1
  1354. writeCV(CV_ACCESSORY_DECODER_ADDRESS_LSB, (uint8_t)(OutputAddress % 256));
  1355. writeCV(CV_ACCESSORY_DECODER_ADDRESS_MSB, (uint8_t)(OutputAddress / 256));
  1356. if( notifyDccAccOutputAddrSet )
  1357. notifyDccAccOutputAddrSet(OutputAddress);
  1358. }
  1359. else
  1360. {
  1361. DB_PRINT("eDP: Set BAddr:%d", BoardAddress);
  1362. writeCV(CV_ACCESSORY_DECODER_ADDRESS_LSB, (uint8_t)(BoardAddress % 64));
  1363. writeCV(CV_ACCESSORY_DECODER_ADDRESS_MSB, (uint8_t)(BoardAddress / 64));
  1364. if( notifyDccAccBoardAddrSet )
  1365. notifyDccAccBoardAddrSet(BoardAddress);
  1366. }
  1367. DccProcState.inAccDecDCCAddrNextReceivedMode = 0; // Reset the mode now that we have set the address
  1368. }
  1369. // If we're filtering addresses, does the address match our address or is it a broadcast address? If NOT then return
  1370. if( DccProcState.Flags & FLAGS_MY_ADDRESS_ONLY )
  1371. {
  1372. if( DccProcState.Flags & FLAGS_OUTPUT_ADDRESS_MODE ) {
  1373. DB_PRINT("[dcc_execDccProcessor] AddrChk: OAddr:%d, BAddr:%d, myAddr:%d Chk=%d", OutputAddress, BoardAddress, getMyAddr(), OutputAddress != getMyAddr() );
  1374. if ( OutputAddress != getMyAddr() && OutputAddress < 2045 ) {
  1375. DB_PRINT("[dcc_execDccProcessor] eDP: OAddr:%d, myAddr:%d - no match", OutputAddress, getMyAddr() );
  1376. return;
  1377. }
  1378. } else {
  1379. if( ( BoardAddress != getMyAddr() ) && ( BoardAddress < 511 ) ) {
  1380. DB_PRINT("[dcc_execDccProcessor] eDP: BAddr:%d, myAddr:%d - no match", BoardAddress, getMyAddr() );
  1381. return;
  1382. }
  1383. }
  1384. DB_PRINT("[dcc_execDccProcessor] eDP: Address Matched");
  1385. }
  1386. if((pDccMsg->Size == 4) && ((pDccMsg->Data[1] & 0b10001001) == 1)) // Extended Accessory Decoder Control Packet Format
  1387. {
  1388. // According to the NMRA Dcc Spec the Signal State should only use the lower 5 Bits,
  1389. // however some manufacturers seem to allow/use all 8 bits, so we'll relax that constraint for now
  1390. uint8_t state = pDccMsg->Data[2] ;
  1391. DB_PRINT("eDP: OAddr:%d Extended State:%0X", OutputAddress, state);
  1392. if( notifyDccSigOutputState )
  1393. notifyDccSigOutputState(OutputAddress, state);
  1394. // old callback ( for compatibility with 1.4.2, not to be used in new designs )
  1395. if( notifyDccSigState )
  1396. notifyDccSigState( OutputAddress, TurnoutPairIndex, pDccMsg->Data[2] ) ;
  1397. }
  1398. else if(pDccMsg->Size == 3) // Basic Accessory Decoder Packet Format
  1399. {
  1400. uint8_t direction = pDccMsg->Data[1] & 0b00000001;
  1401. uint8_t outputPower = (pDccMsg->Data[1] & 0b00001000) >> 3;
  1402. // old callback ( for compatibility with 1.4.2, not to be used in new designs )
  1403. if ( notifyDccAccState )
  1404. notifyDccAccState( OutputAddress, BoardAddress, pDccMsg->Data[1] & 0b00000111, outputPower );
  1405. if( DccProcState.Flags & FLAGS_OUTPUT_ADDRESS_MODE )
  1406. {
  1407. DB_PRINT("eDP: OAddr:%d Turnout Dir:%d Output Power:%d", OutputAddress, direction, outputPower);
  1408. if( notifyDccAccTurnoutOutput )
  1409. notifyDccAccTurnoutOutput( OutputAddress, direction, outputPower );
  1410. }
  1411. else
  1412. {
  1413. DB_PRINT("eDP: Turnout Pair Index:%d Dir:%d Output Power: ", TurnoutPairIndex, direction, outputPower);
  1414. if( notifyDccAccTurnoutBoard )
  1415. notifyDccAccTurnoutBoard( BoardAddress, TurnoutPairIndex, direction, outputPower );
  1416. }
  1417. }
  1418. else if(pDccMsg->Size == 6) // Accessory Decoder OPS Mode Programming
  1419. {
  1420. DB_PRINT("eDP: OPS Mode CV Programming Command");
  1421. // Check for unsupported OPS Mode Addressing mode
  1422. if(((pDccMsg->Data[1] & 0b10001001) != 1) && ((pDccMsg->Data[1] & 0b10001111) != 0x80))
  1423. {
  1424. DB_PRINT("eDP: Unsupported OPS Mode CV Addressing Mode");
  1425. return;
  1426. }
  1427. // Check if this command is for our address or the broadcast address
  1428. if(DccProcState.Flags & FLAGS_OUTPUT_ADDRESS_MODE)
  1429. {
  1430. DB_PRINT("eDP: Check Output Address:%d", OutputAddress);
  1431. if((OutputAddress != getMyAddr()) && ( OutputAddress < 2045 ))
  1432. {
  1433. DB_PRINT("eDP: Output Address Not Matched");
  1434. return;
  1435. }
  1436. }
  1437. else
  1438. {
  1439. DB_PRINT("eDP: Check Board Address:%d", BoardAddress);
  1440. if((BoardAddress != getMyAddr()) && ( BoardAddress < 511 ))
  1441. {
  1442. DB_PRINT("eDP: Board Address Not Matched");
  1443. return;
  1444. }
  1445. }
  1446. uint16_t cvAddress = ((pDccMsg->Data[2] & 0b00000011) << 8) + pDccMsg->Data[3] + 1;
  1447. uint8_t cvValue = pDccMsg->Data[4];
  1448. OpsInstructionType insType = (OpsInstructionType)((pDccMsg->Data[2] & 0b00001100) >> 2) ;
  1449. DB_PRINT("eDP: OPS Mode Instruction:%d", insType);
  1450. switch(insType)
  1451. {
  1452. case OPS_INS_RESERVED:
  1453. case OPS_INS_VERIFY_BYTE:
  1454. DB_PRINT("eDP: Unsupported OPS Mode Instruction:%d", insType);
  1455. break; // We only support Write Byte or Bit Manipulation
  1456. case OPS_INS_WRITE_BYTE:
  1457. DB_PRINT("eDP: CV:%d Value:%d", cvAddress, cvValue);
  1458. if(validCV( cvAddress, 1 ))
  1459. writeCV(cvAddress, cvValue);
  1460. break;
  1461. // 111CDBBB
  1462. // Where BBB represents the bit position within the CV,
  1463. // D contains the value of the bit to be verified or written,
  1464. // and C describes whether the operation is a verify bit or a write bit operation.
  1465. // C = "1" WRITE BIT
  1466. // C = "0" VERIFY BIT
  1467. case OPS_INS_BIT_MANIPULATION:
  1468. // Make sure its a Write Bit Manipulation
  1469. if((cvValue & 0b00010000) && validCV(cvAddress, 1 ))
  1470. {
  1471. uint8_t currentValue = readCV(cvAddress);
  1472. uint8_t newValueMask = 1 << (cvValue & 0b00000111);
  1473. if(cvValue & 0b00001000)
  1474. writeCV(cvAddress, currentValue | newValueMask);
  1475. else
  1476. writeCV(cvAddress, currentValue & ~newValueMask);
  1477. }
  1478. break;
  1479. }
  1480. }
  1481. }
  1482. }
  1483. #ifdef NMRA_DCC_PROCESS_MULTIFUNCTION
  1484. // Multi Function Decoders (14-bit address)
  1485. else if( pDccMsg->Data[0] < 232 )
  1486. {
  1487. uint16_t Address ;
  1488. Address = ( ( pDccMsg->Data[0] - 192 ) << 8 ) | pDccMsg->Data[1];
  1489. //TODO should we convert Address to 1 .. 10239 ?
  1490. processMultiFunctionMessage( Address, DCC_ADDR_LONG, pDccMsg->Data[2], pDccMsg->Data[3], pDccMsg->Data[4] ) ;
  1491. }
  1492. #endif
  1493. #ifdef NMRA_DCC_PROCESS_SERVICEMODE
  1494. }
  1495. #endif
  1496. }
  1497. }
  1498. ////////////////////////////////////////////////////////////////////////
  1499. #ifndef NODEMCUDCC
  1500. NmraDcc::NmraDcc()
  1501. {
  1502. }
  1503. #ifdef digitalPinToInterrupt
  1504. void NmraDcc::pin( uint8_t ExtIntPinNum, uint8_t EnablePullup)
  1505. {
  1506. pin(digitalPinToInterrupt(ExtIntPinNum), ExtIntPinNum, EnablePullup);
  1507. }
  1508. #endif
  1509. void NmraDcc::pin( uint8_t ExtIntNum, uint8_t ExtIntPinNum, uint8_t EnablePullup)
  1510. {
  1511. #if defined ( __STM32F1__ )
  1512. // with STM32F1 the interuptnumber is equal the pin number
  1513. DccProcState.ExtIntNum = ExtIntPinNum;
  1514. // because STM32F1 has a NVIC we must set interuptpriorities
  1515. const nvic_irq_num irqNum2nvic[] = { NVIC_EXTI0, NVIC_EXTI1, NVIC_EXTI2, NVIC_EXTI3, NVIC_EXTI4,
  1516. NVIC_EXTI_9_5, NVIC_EXTI_9_5, NVIC_EXTI_9_5, NVIC_EXTI_9_5, NVIC_EXTI_9_5,
  1517. NVIC_EXTI_15_10, NVIC_EXTI_15_10, NVIC_EXTI_15_10, NVIC_EXTI_15_10, NVIC_EXTI_15_10, NVIC_EXTI_15_10 };
  1518. exti_num irqNum = (exti_num)(PIN_MAP[ExtIntPinNum].gpio_bit);
  1519. // DCC-Input IRQ must be able to interrupt other long low priority ( level15 ) IRQ's
  1520. nvic_irq_set_priority ( irqNum2nvic[irqNum], PRIO_DCC_IRQ);
  1521. // Systic must be able to interrupt DCC-IRQ to always get correct micros() values
  1522. nvic_irq_set_priority(NVIC_SYSTICK, PRIO_SYSTIC);
  1523. #else
  1524. DccProcState.ExtIntNum = ExtIntNum;
  1525. #endif
  1526. DccProcState.ExtIntPinNum = ExtIntPinNum;
  1527. #ifdef __AVR_MEGA__
  1528. // because digitalRead at AVR is slow, we will read the dcc input in the ISR
  1529. // by direct port access.
  1530. DccProcState.ExtIntPort = portInputRegister( digitalPinToPort(ExtIntPinNum) );
  1531. DccProcState.ExtIntMask = digitalPinToBitMask( ExtIntPinNum );
  1532. #else
  1533. DccProcState.ExtIntMask = 1;
  1534. #endif
  1535. pinMode( ExtIntPinNum, EnablePullup ? INPUT_PULLUP : INPUT );
  1536. }
  1537. ////////////////////////////////////////////////////////////////////////
  1538. void NmraDcc::initAccessoryDecoder( uint8_t ManufacturerId, uint8_t VersionId, uint8_t Flags, uint8_t OpsModeAddressBaseCV )
  1539. {
  1540. init(ManufacturerId, VersionId, Flags | FLAGS_DCC_ACCESSORY_DECODER, OpsModeAddressBaseCV);
  1541. }
  1542. #endif //#ifndef NODEMCUDCC
  1543. ////////////////////////////////////////////////////////////////////////
  1544. #ifdef NODEMCUDCC
  1545. void dcc_setup(uint8_t pin, uint8_t ManufacturerId, uint8_t VersionId, uint8_t Flags, uint8_t OpsModeAddressBaseCV)
  1546. #else
  1547. void NmraDcc::init( uint8_t ManufacturerId, uint8_t VersionId, uint8_t Flags, uint8_t OpsModeAddressBaseCV )
  1548. #endif
  1549. {
  1550. #if defined(ESP8266)
  1551. EEPROM.begin(MAXCV);
  1552. #endif
  1553. #if defined(ESP32)
  1554. EEPROM.begin(MAXCV);
  1555. #endif
  1556. // Clear all the static member variables
  1557. memset( &DccRx, 0, sizeof( DccRx) );
  1558. MODE_TP1; // only for debugging and timing measurement
  1559. MODE_TP2;
  1560. MODE_TP3;
  1561. MODE_TP4;
  1562. bitMax = MAX_ONEBITFULL;
  1563. bitMin = MIN_ONEBITFULL;
  1564. DccProcState.Flags = Flags ;
  1565. DccProcState.OpsModeAddressBaseCV = OpsModeAddressBaseCV ;
  1566. DccProcState.myDccAddress = -1;
  1567. DccProcState.inAccDecDCCAddrNextReceivedMode = 0;
  1568. ISREdge = RISING;
  1569. #ifdef NODEMCUDCC
  1570. DccProcState.IntPin = pin;
  1571. DccProcState.IntBitmask = 1 << pin_num[pin];
  1572. #else
  1573. // level checking to detect false IRQ's fired by glitches
  1574. ISRLevel = DccProcState.ExtIntMask;
  1575. ISRChkMask = DccProcState.ExtIntMask;
  1576. #endif
  1577. #ifdef ESP32
  1578. ISRWatch = ISREdge;
  1579. attachInterrupt( DccProcState.ExtIntNum, ExternalInterruptHandler, CHANGE);
  1580. #elif defined(NODEMCUDCC)
  1581. platform_gpio_mode(pin, PLATFORM_GPIO_INT, PLATFORM_GPIO_PULLUP);
  1582. NODE_DBG("[dcc_setup] platform_gpio_register_intr_hook - pin: %d, mask: %d\n", DccProcState.IntPin, DccProcState.IntBitmask);
  1583. platform_gpio_register_intr_hook(DccProcState.IntBitmask, InterruptHandler);
  1584. gpio_pin_intr_state_set(GPIO_ID_PIN(pin_num[pin]), RISING);
  1585. #else
  1586. attachInterrupt( DccProcState.ExtIntNum, ExternalInterruptHandler, RISING);
  1587. #endif
  1588. // Set the Bits that control Multifunction or Accessory behaviour
  1589. // and if the Accessory decoder optionally handles Output Addressing
  1590. // we need to peal off the top two bits
  1591. DccProcState.cv29Value = writeCV( CV_29_CONFIG, ( readCV( CV_29_CONFIG ) & ~FLAGS_CV29_BITS ) | (Flags & FLAGS_CV29_BITS) ) ;
  1592. uint8_t doAutoFactoryDefault = 0;
  1593. if((Flags & FLAGS_AUTO_FACTORY_DEFAULT) && (readCV(CV_VERSION_ID) == 255) && (readCV(CV_MANUFACTURER_ID) == 255))
  1594. doAutoFactoryDefault = 1;
  1595. writeCV( CV_VERSION_ID, VersionId ) ;
  1596. writeCV( CV_MANUFACTURER_ID, ManufacturerId ) ;
  1597. clearDccProcState( 0 );
  1598. if(notifyCVResetFactoryDefault && doAutoFactoryDefault)
  1599. notifyCVResetFactoryDefault();
  1600. }
  1601. #ifndef NODEMCUDCC
  1602. ////////////////////////////////////////////////////////////////////////
  1603. uint8_t NmraDcc::getCV( uint16_t CV )
  1604. {
  1605. return readCV(CV);
  1606. }
  1607. ////////////////////////////////////////////////////////////////////////
  1608. uint8_t NmraDcc::setCV( uint16_t CV, uint8_t Value)
  1609. {
  1610. DccProcState.Flags |= FLAGS_SETCV_CALLED;
  1611. uint8_t returnValue = writeCV(CV,Value);
  1612. DccProcState.Flags &= ~FLAGS_SETCV_CALLED;
  1613. return returnValue;
  1614. }
  1615. ////////////////////////////////////////////////////////////////////////
  1616. uint16_t NmraDcc::getAddr(void)
  1617. {
  1618. return getMyAddr();
  1619. }
  1620. ////////////////////////////////////////////////////////////////////////
  1621. uint8_t NmraDcc::isSetCVReady(void)
  1622. {
  1623. if(notifyIsSetCVReady)
  1624. return notifyIsSetCVReady();
  1625. return readyEEPROM();
  1626. }
  1627. ////////////////////////////////////////////////////////////////////////
  1628. #ifdef DCC_DEBUG
  1629. uint8_t NmraDcc::getIntCount(void)
  1630. {
  1631. return DccProcState.IntCount;
  1632. }
  1633. ////////////////////////////////////////////////////////////////////////
  1634. uint8_t NmraDcc::getTickCount(void)
  1635. {
  1636. return DccProcState.TickCount;
  1637. }
  1638. ////////////////////////////////////////////////////////////////////////
  1639. uint8_t NmraDcc::getNestedIrqCount(void)
  1640. {
  1641. return DccProcState.NestedIrqCount;
  1642. }
  1643. ////////////////////////////////////////////////////////////////////////
  1644. uint8_t NmraDcc::getState(void)
  1645. {
  1646. return DccRx.State;
  1647. }
  1648. ////////////////////////////////////////////////////////////////////////
  1649. uint8_t NmraDcc::getBitCount(void)
  1650. {
  1651. return DccRx.BitCount;
  1652. }
  1653. #endif
  1654. ////////////////////////////////////////////////////////////////////////
  1655. void NmraDcc::setAccDecDCCAddrNextReceived(uint8_t enable)
  1656. {
  1657. DccProcState.inAccDecDCCAddrNextReceivedMode = enable;
  1658. }
  1659. #endif //#ifndef NODEMCUDCC
  1660. ////////////////////////////////////////////////////////////////////////
  1661. #ifdef NODEMCUDCC
  1662. static uint8_t process (os_param_t param, uint8_t prio)
  1663. #else
  1664. uint8_t NmraDcc::process()
  1665. #endif
  1666. {
  1667. if( DccProcState.inServiceMode )
  1668. {
  1669. if( (millis() - DccProcState.LastServiceModeMillis ) > 20L )
  1670. {
  1671. clearDccProcState( 0 ) ;
  1672. }
  1673. }
  1674. if( DccRx.DataReady )
  1675. {
  1676. // We need to do this check with interrupts disabled
  1677. #ifdef ESP32
  1678. portENTER_CRITICAL(&mux);
  1679. #elif defined(NODEMCUDCC)
  1680. ETS_GPIO_INTR_DISABLE();
  1681. #else
  1682. noInterrupts();
  1683. #endif
  1684. Msg = DccRx.PacketCopy ;
  1685. DccRx.DataReady = 0 ;
  1686. #ifdef ESP32
  1687. portEXIT_CRITICAL(&mux);
  1688. #elif defined(NODEMCUDCC)
  1689. ETS_GPIO_INTR_ENABLE();
  1690. #else
  1691. interrupts();
  1692. #endif
  1693. // Checking of the XOR-byte is now done in the ISR already
  1694. #ifdef DCC_DBGVAR
  1695. countOf.Tel++;
  1696. #endif
  1697. // Clear trailing bytes
  1698. for ( byte i=Msg.Size; i< MAX_DCC_MESSAGE_LEN; i++ ) Msg.Data[i] = 0;
  1699. if( notifyDccMsg ) notifyDccMsg( &Msg );
  1700. NODE_DBG("[dcc_process] Size: %d\tPreambleBits: %d\t%d, %d, %d, %d, %d, %d\n",
  1701. Msg.Size, Msg.PreambleBits, Msg.Data[0], Msg.Data[1], Msg.Data[2], Msg.Data[3], Msg.Data[4], Msg.Data[5]);
  1702. execDccProcessor( &Msg );
  1703. return 1 ;
  1704. }
  1705. return 0 ;
  1706. };
  1707. #ifdef NODEMCUDCC
  1708. void dcc_close()
  1709. {
  1710. NODE_DBG("[dcc_close]\n");
  1711. platform_gpio_mode(DccProcState.IntPin, PLATFORM_GPIO_INPUT, PLATFORM_GPIO_PULLUP);
  1712. }
  1713. void dcc_init()
  1714. {
  1715. NODE_DBG("[dcc_init]\n");
  1716. DataReady_taskid = task_get_id((task_callback_t) process);
  1717. }
  1718. #endif