_loraModem.ino 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153
  1. // 1-channel LoRa Gateway for ESP8266
  2. // Copyright (c) 2016, 2017, 2018, 2019 Maarten Westenberg version for ESP8266
  3. // Version 6.1.3
  4. // Date: 2019-11-20
  5. //
  6. // based on work done by Thomas Telkamp for Raspberry PI 1ch gateway
  7. // and many others.
  8. //
  9. // All rights reserved. This program and the accompanying materials
  10. // are made available under the terms of the MIT License
  11. // which accompanies this distribution, and is available at
  12. // https://opensource.org/licenses/mit-license.php
  13. //
  14. // NO WARRANTY OF ANY KIND IS PROVIDED
  15. //
  16. // Author: Maarten Westenberg (mw12554@hotmail.com)
  17. //
  18. // This file contains the LoRa modem specific code enabling to receive
  19. // and transmit packages/messages.
  20. // ========================================================================================
  21. //
  22. //
  23. // ----------------------------------------------------------------------------------------
  24. // Variable definitions
  25. //
  26. //
  27. // ----------------------------------------------------------------------------------------
  28. //
  29. // ========================================================================================
  30. // SPI AND INTERRUPTS
  31. // The RFM96/SX1276 communicates with the ESP8266 by means of interrupts
  32. // and SPI interface. The SPI interface is bidirectional and allows both
  33. // parties to simultaneous write and read to registers.
  34. // Major drawback is that access is not protected for interrupt and non-
  35. // interrupt access. This means that when a program in loop() and a program
  36. // in interrupt do access the readRegister and writeRegister() function
  37. // at the same time that probably an error will occur.
  38. // Therefore it is best to either not use interrupts AT all (like LMIC)
  39. // or only use these functions in interrupts and to further processing
  40. // in the main loop() program.
  41. //
  42. // ========================================================================================
  43. // ----------------------------------------------------------------------------------------
  44. // Mutex definitions
  45. //
  46. // ----------------------------------------------------------------------------------------
  47. #if MUTEX==1
  48. void CreateMutux(int *mutex) {
  49. *mutex=1;
  50. }
  51. #define LIB_MUTEX 1
  52. #if LIB_MUTEX==1
  53. bool GetMutex(int *mutex) {
  54. //noInterrupts();
  55. if (*mutex==1) {
  56. *mutex=0;
  57. //interrupts();
  58. return(true);
  59. }
  60. //interrupts();
  61. return(false);
  62. }
  63. #else
  64. bool GetMutex(int *mutex) {
  65. int iOld = 1, iNew = 0;
  66. asm volatile (
  67. "rsil a15, 1\n" // read and set interrupt level to 1
  68. "l32i %0, %1, 0\n" // load value of mutex
  69. "bne %0, %2, 1f\n" // compare with iOld, branch if not equal
  70. "s32i %3, %1, 0\n" // store iNew in mutex
  71. "1:\n" // branch target
  72. "wsr.ps a15\n" // restore program state
  73. "rsync\n"
  74. : "=&r" (iOld)
  75. : "r" (mutex), "r" (iOld), "r" (iNew)
  76. : "a15", "memory"
  77. );
  78. return (bool)iOld;
  79. }
  80. #endif
  81. void ReleaseMutex(int *mutex) {
  82. *mutex=1;
  83. }
  84. #endif //MUTEX==1
  85. // ----------------------------------------------------------------------------------------
  86. // Read one byte value, par addr is address
  87. // Returns the value of register(addr)
  88. //
  89. // The SS (Chip select) pin is used to make sure the RFM95 is selected
  90. // The variable is for obvious reasons valid for read and write traffic at the
  91. // same time. Since both read and write mean that we write to the SPI interface.
  92. // Parameters:
  93. // Address: SPI address to read from. Type uint8_t
  94. // Return:
  95. // Value read from address
  96. // ----------------------------------------------------------------------------------------
  97. // define the SPI settings for reading messages
  98. SPISettings readSettings(SPISPEED, MSBFIRST, SPI_MODE0);
  99. uint8_t readRegister(uint8_t addr)
  100. {
  101. SPI.beginTransaction(readSettings);
  102. digitalWrite(pins.ss, LOW); // Select Receiver
  103. SPI.transfer(addr & 0x7F);
  104. uint8_t res = (uint8_t) SPI.transfer(0x00);
  105. digitalWrite(pins.ss, HIGH); // Unselect Receiver
  106. SPI.endTransaction();
  107. return((uint8_t) res);
  108. }
  109. // ----------------------------------------------------------------------------
  110. // Write value to a register with address addr.
  111. // Function writes one byte at a time.
  112. // Parameters:
  113. // addr: SPI address to write to
  114. // value: The value to write to address
  115. // Returns:
  116. // <void>
  117. // ----------------------------------------------------------------------------
  118. // define the settings for SPI writing
  119. SPISettings writeSettings(SPISPEED, MSBFIRST, SPI_MODE0);
  120. void writeRegister(uint8_t addr, uint8_t value)
  121. {
  122. SPI.beginTransaction(writeSettings);
  123. digitalWrite(pins.ss, LOW); // Select Receiver
  124. SPI.transfer((addr | 0x80) & 0xFF);
  125. SPI.transfer(value & 0xFF);
  126. digitalWrite(pins.ss, HIGH); // Unselect Receiver
  127. SPI.endTransaction();
  128. }
  129. // ----------------------------------------------------------------------------
  130. // Write a buffer to a register with address addr.
  131. // Function writes one byte at a time.
  132. // Parameters:
  133. // addr: SPI address to write to
  134. // value: The value to write to address
  135. // Returns:
  136. // <void>
  137. // ----------------------------------------------------------------------------
  138. void writeBuffer(uint8_t addr, uint8_t *buf, uint8_t len)
  139. {
  140. //noInterrupts(); // XXX
  141. SPI.beginTransaction(writeSettings);
  142. digitalWrite(pins.ss, LOW); // Select Receiver
  143. SPI.transfer((addr | 0x80) & 0xFF); // write buffer address
  144. for (uint8_t i=0; i<len; i++) {
  145. SPI.transfer(buf[i] & 0xFF);
  146. }
  147. digitalWrite(pins.ss, HIGH); // Unselect Receiver
  148. SPI.endTransaction();
  149. }
  150. // ----------------------------------------------------------------------------
  151. // setRate is setting rate and spreading factor and CRC etc. for transmission
  152. // for example
  153. // Modem Config 1 (MC1) == 0x72 for sx1276
  154. // Modem Config 2 (MC2) == (CRC_ON) | (sf<<4)
  155. // Modem Config 3 (MC3) == 0x04 | (optional SF11/12 LOW DATA OPTIMIZE 0x08)
  156. // sf == SF7 default 0x07, (SF7<<4) == SX72_MC2_SF7
  157. // bw == 125 == 0x70
  158. // cr == CR4/5 == 0x02
  159. // CRC_ON == 0x04
  160. //
  161. // sf is SF7 to SF12
  162. // crc is 0x00 (off) or
  163. // ----------------------------------------------------------------------------
  164. void setRate(uint8_t sf, uint8_t crc)
  165. {
  166. uint8_t mc1=0, mc2=0, mc3=0;
  167. #if _DUSB>=2
  168. if ((sf<SF7) || (sf>SF12)) {
  169. if (( debug>=1 ) && ( pdebug & P_RADIO )) {
  170. Serial.print(F("setRate:: SF="));
  171. Serial.println(sf);
  172. }
  173. return;
  174. }
  175. #endif
  176. // Set rate based on Spreading Factor etc
  177. if (sx1272) {
  178. mc1= 0x0A; // SX1276_MC1_BW_250 0x80 | SX1276_MC1_CR_4_5 0x02
  179. mc2= ((sf<<4) | crc) % 0xFF;
  180. // SX1276_MC1_BW_250 0x80 | SX1276_MC1_CR_4_5 0x02 | SX1276_MC1_IMPLICIT_HEADER_MODE_ON 0x01
  181. if (sf == SF11 || sf == SF12) {
  182. mc1= 0x0B;
  183. }
  184. }
  185. // For sx1276 chips is the CRC ON is
  186. else {
  187. uint8_t bw = 0; // bw setting is in freqs[ifreq].dwnBw
  188. uint8_t cr = 0; // cr settings dependent on SF setting
  189. //switch (
  190. if (sf==SF8) {
  191. mc1= 0x78; // SX1276_MC1_BW_125==0x70 | SX1276_MC1_CR_4_8==0x08
  192. }
  193. else {
  194. mc1= 0x72; // SX1276_MC1_BW_125==0x70 | SX1276_MC1_CR_4_5==0x02
  195. }
  196. mc2= ((sf<<4) | crc) & 0xFF; // crc is 0x00 or 0x04==SX1276_MC2_RX_PAYLOAD_CRCON
  197. mc3= 0x04; // 0x04; SX1276_MC3_AGCAUTO
  198. if (sf == SF11 || sf == SF12) { mc3|= 0x08; } // 0x08 | 0x04
  199. }
  200. // Implicit Header (IH), for class b beacons (&& SF6)
  201. //if (getIh(LMIC.rps)) {
  202. // mc1 |= SX1276_MC1_IMPLICIT_HEADER_MODE_ON;
  203. // writeRegister(REG_PAYLOAD_LENGTH, getIh(LMIC.rps)); // required length
  204. //}
  205. writeRegister(REG_MODEM_CONFIG1, (uint8_t) mc1);
  206. writeRegister(REG_MODEM_CONFIG2, (uint8_t) mc2);
  207. writeRegister(REG_MODEM_CONFIG3, (uint8_t) mc3);
  208. // Symbol timeout settings
  209. if (sf == SF10 || sf == SF11 || sf == SF12) {
  210. writeRegister(REG_SYMB_TIMEOUT_LSB, (uint8_t) 0x05);
  211. } else {
  212. writeRegister(REG_SYMB_TIMEOUT_LSB, (uint8_t) 0x08);
  213. }
  214. return;
  215. }
  216. // ----------------------------------------------------------------------------
  217. // Set the frequency for our gateway
  218. // The function has no parameter other than the freq setting used in init.
  219. // Since we are using a 1ch gateway this value is set fixed.
  220. // ----------------------------------------------------------------------------
  221. void setFreq(uint32_t freq)
  222. {
  223. // set frequency
  224. uint64_t frf = ((uint64_t)freq << 19) / 32000000;
  225. writeRegister(REG_FRF_MSB, (uint8_t)(frf>>16) );
  226. writeRegister(REG_FRF_MID, (uint8_t)(frf>> 8) );
  227. writeRegister(REG_FRF_LSB, (uint8_t)(frf>> 0) );
  228. return;
  229. }
  230. // ----------------------------------------------------------------------------
  231. // Set Power for our gateway
  232. // ----------------------------------------------------------------------------
  233. void setPow(uint8_t powe)
  234. {
  235. if (powe >= 16) powe = 15;
  236. //if (powe >= 15) powe = 14;
  237. else if (powe < 2) powe =2;
  238. ASSERT((powe>=2)&&(powe<=15));
  239. uint8_t pac = (0x80 | (powe & 0xF)) & 0xFF;
  240. writeRegister(REG_PAC, (uint8_t)pac); // set 0x09 to pac
  241. // XXX Power settings for CFG_sx1272 are different
  242. return;
  243. }
  244. // ----------------------------------------------------------------------------
  245. // Used to set the radio to LoRa mode (transmitter)
  246. // Please note that this mode can only be set in SLEEP mode and not in Standby.
  247. // Also there should be not need to re-init this mode is set in the setup()
  248. // function.
  249. // For high freqs (>860 MHz) we need to & with 0x08 otherwise with 0x00
  250. // ----------------------------------------------------------------------------
  251. //void ICACHE_RAM_ATTR opmodeLora()
  252. //{
  253. //#ifdef CFG_sx1276_radio
  254. // uint8_t u = OPMODE_LORA | 0x80; // TBD: sx1276 high freq
  255. //#else // SX-1272
  256. // uint8_t u = OPMODE_LORA | 0x08;
  257. //#endif
  258. // writeRegister(REG_OPMODE, (uint8_t) u);
  259. //}
  260. // ----------------------------------------------------------------------------
  261. // Set the opmode to a value as defined on top
  262. // Values are 0x00 to 0x07
  263. // The value is set for the lowest 3 bits, the other bits are as before.
  264. // ----------------------------------------------------------------------------
  265. void opmode(uint8_t mode)
  266. {
  267. if (mode == OPMODE_LORA)
  268. writeRegister(REG_OPMODE, (uint8_t) mode);
  269. else
  270. writeRegister(REG_OPMODE, (uint8_t)((readRegister(REG_OPMODE) & ~OPMODE_MASK) | mode));
  271. }
  272. // ----------------------------------------------------------------------------
  273. // Hop to next frequency as defined by NUM_HOPS
  274. // This function should only be used for receiver operation. The current
  275. // receiver frequency is determined by ifreq index like so: freqs[ifreq]
  276. // ----------------------------------------------------------------------------
  277. void hop() {
  278. // 1. Set radio to standby
  279. opmode(OPMODE_STANDBY);
  280. // 3. Set frequency based on value in freq
  281. ifreq = (ifreq + 1) % NUM_HOPS ; // Increment the freq round robin
  282. setFreq(freqs[ifreq].upFreq);
  283. // 4. Set spreading Factor
  284. sf = SF7; // Starting the new frequency
  285. setRate(sf, 0x40); // set the sf to SF7
  286. // Low Noise Amplifier used in receiver
  287. writeRegister(REG_LNA, (uint8_t) LNA_MAX_GAIN); // 0x0C, 0x23
  288. // 7. set sync word
  289. writeRegister(REG_SYNC_WORD, (uint8_t) 0x34); // set 0x39 to 0x34 LORA_MAC_PREAMBLE
  290. // prevent node to node communication
  291. writeRegister(REG_INVERTIQ,0x27); // 0x33, 0x27; to reset from TX
  292. // Max Payload length is dependent on 256 byte buffer. At startup TX starts at
  293. // 0x80 and RX at 0x00. RX therefore maximized at 128 Bytes
  294. writeRegister(REG_MAX_PAYLOAD_LENGTH,MAX_PAYLOAD_LENGTH); // set 0x23 to 0x80==128 bytes
  295. writeRegister(REG_PAYLOAD_LENGTH,PAYLOAD_LENGTH); // 0x22, 0x40==64Byte long
  296. writeRegister(REG_FIFO_ADDR_PTR, (uint8_t) readRegister(REG_FIFO_RX_BASE_AD)); // set reg 0x0D to 0x0F
  297. writeRegister(REG_HOP_PERIOD,0x00); // reg 0x24, set to 0x00
  298. // 5. Config PA Ramp up time // set reg 0x0A
  299. writeRegister(REG_PARAMP, (readRegister(REG_PARAMP) & 0xF0) | 0x08); // set PA ramp-up time 50 uSec
  300. // Set 0x4D PADAC for SX1276 ; XXX register is 0x5a for sx1272
  301. writeRegister(REG_PADAC_SX1276, 0x84); // set 0x4D (PADAC) to 0x84
  302. //writeRegister(REG_PADAC, readRegister(REG_PADAC) | 0x4);
  303. // 8. Reset interrupt Mask, enable all interrupts
  304. writeRegister(REG_IRQ_FLAGS_MASK, 0x00);
  305. // 9. clear all radio IRQ flags
  306. writeRegister(REG_IRQ_FLAGS, 0xFF);
  307. // Be aware that micros() has increased significantly from calling
  308. // the hop function until printed below
  309. //
  310. #if _DUSB>=1
  311. if (( debug>=2 ) && ( pdebug & P_RADIO )){
  312. Serial.print(F("hop:: hopTime:: "));
  313. Serial.print(micros() - hopTime);
  314. Serial.print(F(", "));
  315. SerialStat(0);
  316. }
  317. #endif
  318. // Remember the last time we hop
  319. hopTime = micros(); // At what time did we hop
  320. }
  321. // ----------------------------------------------------------------------------
  322. // This LoRa function reads a message from the LoRa transceiver
  323. // on Success: returns message length read when message correctly received
  324. // on Failure: it returns a negative value on error (CRC error for example).
  325. // UP function
  326. // This is the "lowlevel" receive function called by stateMachine()
  327. // dealing with the radio specific LoRa functions
  328. //
  329. // Parameters:
  330. // Payload: uint8_t[] message. when message is read it is returned in payload.
  331. // Returns:
  332. // Length of payload received
  333. //
  334. // 9 bytes header
  335. // followed by data N bytes
  336. // 4 bytes MIC end
  337. // ----------------------------------------------------------------------------
  338. uint8_t receivePkt(uint8_t *payload)
  339. {
  340. uint8_t irqflags = readRegister(REG_IRQ_FLAGS); // 0x12; read back flags
  341. statc.msg_ttl++; // Receive statistics counter
  342. uint8_t crcUsed = readRegister(REG_HOP_CHANNEL);
  343. if (crcUsed & 0x40) {
  344. #if _DUSB>=1
  345. if (( debug>=2) && (pdebug & P_RX )) {
  346. Serial.println(F("R rxPkt:: CRC used"));
  347. }
  348. #endif
  349. }
  350. // Check for payload IRQ_LORA_CRCERR_MASK=0x20 set
  351. if (irqflags & IRQ_LORA_CRCERR_MASK)
  352. {
  353. #if _DUSB>=1
  354. if (( debug>=0) && ( pdebug & P_RADIO )) {
  355. Serial.print(F("rxPkt:: Err CRC, ="));
  356. SerialTime();
  357. Serial.println();
  358. }
  359. #endif
  360. return 0;
  361. }
  362. // Is header OK?
  363. // Please note that if we reset the HEADER interrupt in RX,
  364. // that we would here conclude that there is no HEADER
  365. else if ((irqflags & IRQ_LORA_HEADER_MASK) == false)
  366. {
  367. #if _DUSB>=1
  368. if (( debug>=0) && ( pdebug & P_RADIO )) {
  369. Serial.println(F("rxPkt:: Err HEADER"));
  370. }
  371. #endif
  372. // Reset VALID-HEADER flag 0x10
  373. writeRegister(REG_IRQ_FLAGS, (uint8_t)(IRQ_LORA_HEADER_MASK | IRQ_LORA_RXDONE_MASK)); // 0x12; clear HEADER (== 0x10) flag
  374. return 0;
  375. }
  376. // If there are no error messages, read the buffer from the FIFO
  377. // This means "Set FifoAddrPtr to FifoRxBaseAddr"
  378. else {
  379. statc.msg_ok++; // Receive OK statistics counter
  380. switch(statr[0].ch) {
  381. case 0: statc.msg_ok_0++; break;
  382. case 1: statc.msg_ok_1++; break;
  383. case 2: statc.msg_ok_2++; break;
  384. }
  385. if (readRegister(REG_FIFO_RX_CURRENT_ADDR) != readRegister(REG_FIFO_RX_BASE_AD)) {
  386. if (( debug>=0 ) && ( pdebug & P_RADIO )) {
  387. Serial.print(F("RX BASE <"));
  388. Serial.print(readRegister(REG_FIFO_RX_BASE_AD));
  389. Serial.print(F("> != RX CURRENT <"));
  390. Serial.print(readRegister(REG_FIFO_RX_CURRENT_ADDR));
  391. Serial.print(F(">"));
  392. Serial.println();
  393. }
  394. }
  395. //uint8_t currentAddr = readRegister(REG_FIFO_RX_CURRENT_ADDR); // 0x10
  396. uint8_t currentAddr = readRegister(REG_FIFO_RX_BASE_AD); // 0x0F
  397. uint8_t receivedCount = readRegister(REG_RX_NB_BYTES); // 0x13; How many bytes were read
  398. #if _DUSB>=1
  399. if ((debug>=0) && (currentAddr > 64)) {
  400. Serial.print(F("rxPkt:: Rx addr>64"));
  401. Serial.println(currentAddr);
  402. }
  403. #endif
  404. writeRegister(REG_FIFO_ADDR_PTR, (uint8_t) currentAddr); // 0x0D
  405. if (receivedCount > PAYLOAD_LENGTH) {
  406. #if _DUSB>=1
  407. if (( debug>=0 ) & ( pdebug & P_RADIO )) {
  408. Serial.print(F("rxPkt:: receivedCount="));
  409. Serial.println(receivedCount);
  410. }
  411. #endif
  412. receivedCount=PAYLOAD_LENGTH;
  413. }
  414. for(int i=0; i < receivedCount; i++)
  415. {
  416. payload[i] = readRegister(REG_FIFO); // 0x00, FIFO will auto shift register
  417. }
  418. writeRegister(REG_IRQ_FLAGS, (uint8_t) 0xFF); // Reset ALL interrupts
  419. // A long as _DUSB is enabled, and RX debug messages are selected,
  420. //the received packet is displayed on the output.
  421. #if _DUSB>=1
  422. if (( debug>=0 ) && ( pdebug & P_RX )){
  423. Serial.print(F("rxPkt:: t="));
  424. SerialTime();
  425. Serial.print(F(", f="));
  426. Serial.print(ifreq);
  427. Serial.print(F(", sf="));
  428. Serial.print(sf);
  429. Serial.print(F(", a="));
  430. if (payload[4]<0x10) Serial.print('0'); Serial.print(payload[4], HEX);
  431. if (payload[3]<0x10) Serial.print('0'); Serial.print(payload[3], HEX);
  432. if (payload[2]<0x10) Serial.print('0'); Serial.print(payload[2], HEX);
  433. if (payload[1]<0x10) Serial.print('0'); Serial.print(payload[1], HEX);
  434. Serial.print(F(", flags="));
  435. Serial.print(irqflags,HEX);
  436. Serial.print(F(", addr="));
  437. Serial.print(currentAddr);
  438. Serial.print(F(", len="));
  439. Serial.print(receivedCount);
  440. // If debug level 1 is specified, we display the content of the message as well
  441. // We need to decode the message as well will it make any sense
  442. if (debug>=1) { // Must be 1 for operational use
  443. #if _TRUSTED_DECODE==2
  444. int index; // The index of the codex struct to decode
  445. String response="";
  446. uint8_t data[receivedCount];
  447. uint8_t DevAddr [4];
  448. DevAddr[0] = payload[4];
  449. DevAddr[1] = payload[3];
  450. DevAddr[2] = payload[2];
  451. DevAddr[3] = payload[1];
  452. if ((index = inDecodes((char *)(payload+1))) >=0 ) {
  453. Serial.print(F(", Ind="));
  454. Serial.print(index);
  455. //Serial.println();
  456. }
  457. else if (debug>=1) {
  458. Serial.print(F(", No Index"));
  459. Serial.println();
  460. return(receivedCount);
  461. }
  462. // ------------------------------
  463. Serial.print(F(", data="));
  464. for (int i=0; i<receivedCount; i++) { data[i] = payload[i]; } // Copy array
  465. //for (int i=0; i<receivedCount; i++) {
  466. // if (payload[i]<=0xF) Serial.print('0');
  467. // Serial.print(payload[i], HEX);
  468. // Serial.print(' ');
  469. //}
  470. uint16_t frameCount=payload[7]*256 + payload[6];
  471. // The message received has a length, but data starts at byte 9, and stops 4 bytes
  472. // before the end since those are MIC bytes
  473. uint8_t CodeLength = encodePacket((uint8_t *)(data + 9), receivedCount-9-4, (uint16_t)frameCount, DevAddr, decodes[index].appKey, 0);
  474. Serial.print(F("- NEW fc="));
  475. Serial.print(frameCount);
  476. Serial.print(F(", addr="));
  477. for (int i=0; i<4; i++) {
  478. if (DevAddr[i]<=0xF) Serial.print('0');
  479. Serial.print(DevAddr[i], HEX);
  480. Serial.print(' ');
  481. }
  482. Serial.print(F(", len="));
  483. Serial.print(CodeLength);
  484. Serial.print(F(", data="));
  485. for (int i=0; i<receivedCount; i++) {
  486. if (data[i]<=0xF) Serial.print('0');
  487. Serial.print(data[i], HEX);
  488. Serial.print(' ');
  489. }
  490. #endif // _TRUSTED_DECODE
  491. }
  492. Serial.println();
  493. if (debug>=2) Serial.flush();
  494. }
  495. #endif //DUSB
  496. return(receivedCount);
  497. }
  498. writeRegister(REG_IRQ_FLAGS, (uint8_t) (
  499. IRQ_LORA_RXDONE_MASK |
  500. IRQ_LORA_RXTOUT_MASK |
  501. IRQ_LORA_HEADER_MASK |
  502. IRQ_LORA_CRCERR_MASK)); // 0x12; Clear RxDone IRQ_LORA_RXDONE_MASK
  503. return 0;
  504. } //receivePkt
  505. // ----------------------------------------------------------------------------
  506. // This DOWN function sends a payload to the LoRa node over the air
  507. // Radio must go back in standby mode as soon as the transmission is finished
  508. //
  509. // NOTE:: writeRegister functions should not be used outside interrupts
  510. // ----------------------------------------------------------------------------
  511. bool sendPkt(uint8_t *payLoad, uint8_t payLength)
  512. {
  513. #if _DUSB>=2
  514. if (payLength>=128) {
  515. if (debug>=1) {
  516. Serial.print("sendPkt:: len=");
  517. Serial.println(payLength);
  518. }
  519. return false;
  520. }
  521. #endif
  522. writeRegister(REG_FIFO_ADDR_PTR, (uint8_t) readRegister(REG_FIFO_TX_BASE_AD)); // 0x0D, 0x0E
  523. writeRegister(REG_PAYLOAD_LENGTH, (uint8_t) payLength); // 0x22
  524. payLoad[payLength] = 0x00;
  525. writeBuffer(REG_FIFO, (uint8_t *) payLoad, payLength);
  526. return true;
  527. }
  528. // ----------------------------------------------------------------------------
  529. // loraWait()
  530. // This function implements the wait protocol needed for downstream transmissions.
  531. // Note: Timing of downstream and JoinAccept messages is VERY critical.
  532. //
  533. // As the ESP8266 watchdog will not like us to wait more than a few hundred
  534. // milliseconds (or it will kick in) we have to implement a simple way to wait
  535. // time in case we have to wait seconds before sending messages (e.g. for OTAA 5 or 6 seconds)
  536. // Without it, the system is known to crash in half of the cases it has to wait for
  537. // JOIN-ACCEPT messages to send.
  538. //
  539. // This function uses a combination of delay() statements and delayMicroseconds().
  540. // As we use delay() only when there is still enough time to wait and we use micros()
  541. // to make sure that delay() did not take too much time this works.
  542. //
  543. // Parameter: uint32-t tmst gives the micros() value when transmission should start. (!!!)
  544. // Note: We assume LoraDown.sfTx contains the SF we will use for downstream message.
  545. // ----------------------------------------------------------------------------
  546. void loraWait(const uint32_t timestamp)
  547. {
  548. uint32_t startMics = micros(); // Start of the loraWait function
  549. uint32_t tmst = timestamp;
  550. // XXX
  551. int32_t adjust=0;
  552. switch (LoraDown.sfTx) {
  553. case 7: adjust= 60000; break; // Make time for SF7 longer
  554. case 8: break; // Around 60ms
  555. case 9: break;
  556. case 10: break;
  557. case 11: break;
  558. case 12: break;
  559. default:
  560. #if _DUSB>=1
  561. if (( debug>=1 ) && ( pdebug & P_TX )) {
  562. Serial.print(F("T loraWait:: unknown SF="));
  563. Serial.print(LoraDown.sfTx);
  564. }
  565. #endif
  566. break;
  567. }
  568. tmst = tmst + gwayConfig.txDelay + adjust; // tmst based on txDelay and spreading factor
  569. uint32_t waitTime = tmst - micros(); // Or make waitTime an unsigned and change next statement
  570. if (micros()>tmst) { // to (waitTime<0)
  571. Serial.println(F("loraWait:: Error wait time < 0"));
  572. return;
  573. }
  574. // For larger delay times we use delay() since that is for > 15ms
  575. // This is the most efficient way
  576. while (waitTime > 16000) {
  577. delay(15); // ms delay including yield, slightly shorter
  578. waitTime= tmst - micros();
  579. }
  580. // The remaining wait time is less tan 15000 uSecs
  581. // And we use delayMicroseconds() to wait
  582. if (waitTime>0) delayMicroseconds(waitTime);
  583. #if _DUSB>=1
  584. else if ((waitTime+20) < 0) {
  585. Serial.println(F("loraWait:: TOO LATE")); // Never happens
  586. }
  587. if (( debug>=2 ) && ( pdebug & P_TX )) {
  588. Serial.print(F("T start: "));
  589. Serial.print(startMics);
  590. Serial.print(F(", tmst: ")); // tmst
  591. Serial.print(tmst);
  592. Serial.print(F(", end: ")); // This must be micros(), and equal to tmst
  593. Serial.print(micros());
  594. Serial.print(F(", waited: "));
  595. Serial.print(tmst - startMics);
  596. Serial.print(F(", delay="));
  597. Serial.print(gwayConfig.txDelay);
  598. Serial.println();
  599. if (debug>=2) Serial.flush();
  600. }
  601. #endif
  602. }
  603. // ----------------------------------------------------------------------------
  604. // txLoraModem
  605. // Init the transmitter and transmit the buffer
  606. // After successful transmission (dio0==1) TxDone re-init the receiver
  607. //
  608. // crc is set to 0x00 for TX
  609. // iiq is set to 0x27 (or 0x40 based on ipol value in txpkt)
  610. //
  611. // 1. opmode Lora (only in Sleep mode)
  612. // 2. opmode StandBY
  613. // 3. Configure Modem
  614. // 4. Configure Channel
  615. // 5. write PA Ramp
  616. // 6. config Power
  617. // 7. RegLoRaSyncWord LORA_MAC_PREAMBLE
  618. // 8. write REG dio mapping (dio0)
  619. // 9. write REG IRQ flags
  620. // 10. write REG IRQ mask
  621. // 11. write REG LoRa Fifo Base Address
  622. // 12. write REG LoRa Fifo Addr Ptr
  623. // 13. write REG LoRa Payload Length
  624. // 14. Write buffer (byte by byte)
  625. // 15. Wait until the right time to transmit has arrived
  626. // 16. opmode TX
  627. // ----------------------------------------------------------------------------
  628. void txLoraModem(
  629. uint8_t *payLoad, // Payload contents
  630. uint8_t payLength, // Length of payload
  631. uint32_t tmst, // Timestamp
  632. uint8_t sfTx, // Sending spreading factor
  633. uint8_t powe, // power
  634. uint32_t freq, // frequency
  635. uint8_t crc, // Do we use CRC error checking
  636. uint8_t iiq // Interrupt
  637. )
  638. {
  639. #if _DUSB>=2
  640. if (debug>=1) {
  641. // Make sure that all serial stuff is done before continuing
  642. Serial.print(F("txLoraModem::"));
  643. Serial.print(F(" powe: ")); Serial.print(powe);
  644. Serial.print(F(", freq: ")); Serial.print(freq);
  645. Serial.print(F(", crc: ")); Serial.print(crc);
  646. Serial.print(F(", iiq: 0X")); Serial.print(iiq,HEX);
  647. Serial.println();
  648. if (debug>=2) Serial.flush();
  649. }
  650. #endif
  651. _state = S_TX;
  652. // 1. Select LoRa modem from sleep mode
  653. //opmode(OPMODE_LORA); // set register 0x01 to 0x80
  654. // Assert the value of the current mode
  655. ASSERT((readRegister(REG_OPMODE) & OPMODE_LORA) != 0);
  656. // 2. enter standby mode (required for FIFO loading))
  657. opmode(OPMODE_STANDBY); // set 0x01 to 0x01
  658. // 3. Init spreading factor and other Modem setting
  659. setRate(sfTx, crc);
  660. // Frequency hopping
  661. //writeRegister(REG_HOP_PERIOD, (uint8_t) 0x00); // set 0x24 to 0x00 only for receivers
  662. // 4. Init Frequency, config channel
  663. setFreq(freq);
  664. // 6. Set power level, REG_PAC
  665. setPow(powe);
  666. // 7. prevent node to node communication
  667. writeRegister(REG_INVERTIQ, (uint8_t) iiq); // 0x33, (0x27 or 0x40)
  668. // 8. set the IRQ mapping DIO0=TxDone DIO1=NOP DIO2=NOP (or less for 1ch gateway)
  669. writeRegister(REG_DIO_MAPPING_1, (uint8_t)(
  670. MAP_DIO0_LORA_TXDONE |
  671. MAP_DIO1_LORA_NOP |
  672. MAP_DIO2_LORA_NOP |
  673. MAP_DIO3_LORA_CRC));
  674. // 9. clear all radio IRQ flags
  675. writeRegister(REG_IRQ_FLAGS, (uint8_t) 0xFF);
  676. // 10. mask all IRQs but TxDone
  677. writeRegister(REG_IRQ_FLAGS_MASK, (uint8_t) ~IRQ_LORA_TXDONE_MASK);
  678. // txLora
  679. opmode(OPMODE_FSTX); // set 0x01 to 0x02 (actual value becomes 0x82)
  680. // 11, 12, 13, 14. write the buffer to the FiFo
  681. sendPkt(payLoad, payLength);
  682. // 15. wait extra delay out. The delayMicroseconds timer is accurate until 16383 uSec.
  683. loraWait(tmst);
  684. //Set the base addres of the transmit buffer in FIFO
  685. writeRegister(REG_FIFO_ADDR_PTR, (uint8_t) readRegister(REG_FIFO_TX_BASE_AD)); // set 0x0D to 0x0F (contains 0x80);
  686. //For TX we have to set the PAYLOAD_LENGTH
  687. writeRegister(REG_PAYLOAD_LENGTH, (uint8_t) payLength); // set 0x22, max 0x40==64Byte long
  688. //For TX we have to set the MAX_PAYLOAD_LENGTH
  689. writeRegister(REG_MAX_PAYLOAD_LENGTH, (uint8_t) MAX_PAYLOAD_LENGTH); // set 0x22, max 0x40==64Byte long
  690. // Reset the IRQ register
  691. writeRegister(REG_IRQ_FLAGS_MASK, (uint8_t) 0x00); // Clear the mask
  692. writeRegister(REG_IRQ_FLAGS, (uint8_t) IRQ_LORA_TXDONE_MASK);// set 0x12 to 0x08, clear TXDONE
  693. // 16. Initiate actual transmission of FiFo
  694. opmode(OPMODE_TX); // set 0x01 to 0x03 (actual value becomes 0x83)
  695. }// txLoraModem
  696. // ----------------------------------------------------------------------------
  697. // Setup the LoRa receiver on the connected transceiver.
  698. // - Determine the correct transceiver type (sx1272/RFM92 or sx1276/RFM95)
  699. // - Set the frequency to listen to (1-channel remember)
  700. // - Set Spreading Factor (standard SF7)
  701. // The reset RST pin might not be necessary for at least the RFM95 transceiver
  702. //
  703. // 1. Put the radio in LoRa mode
  704. // 2. Put modem in sleep or in standby
  705. // 3. Set Frequency
  706. // 4. Spreading Factor
  707. // 5. Set interrupt mask
  708. // 6. Clear all interrupt flags
  709. // 7. Set opmode to OPMODE_RX
  710. // 8. Set _state to S_RX
  711. // 9. Reset all interrupts
  712. // ----------------------------------------------------------------------------
  713. void rxLoraModem()
  714. {
  715. // 1. Put system in LoRa mode
  716. //opmode(OPMODE_LORA); // Is already so
  717. // 2. Put the radio in sleep mode
  718. opmode(OPMODE_STANDBY); // CAD set 0x01 to 0x00
  719. // 3. Set frequency based on value in freq
  720. setFreq(freqs[ifreq].upFreq); // set to the right frequency
  721. // 4. Set spreading Factor and CRC
  722. setRate(sf, 0x04);
  723. // prevent node to node communication
  724. writeRegister(REG_INVERTIQ, (uint8_t) 0x27); // 0x33, 0x27; to reset from TX
  725. // Max Payload length is dependent on 256 byte buffer.
  726. // At startup TX starts at 0x80 and RX at 0x00. RX therefore maximized at 128 Bytes
  727. //For TX we have to set the PAYLOAD_LENGTH
  728. //writeRegister(REG_PAYLOAD_LENGTH, (uint8_t) PAYLOAD_LENGTH); // set 0x22, 0x40==64Byte long
  729. // Set CRC Protection or MAX payload protection
  730. //writeRegister(REG_MAX_PAYLOAD_LENGTH, (uint8_t) MAX_PAYLOAD_LENGTH); // set 0x23 to 0x80==128
  731. //Set the start address for the FiFO (Which should be 0)
  732. writeRegister(REG_FIFO_ADDR_PTR, (uint8_t) readRegister(REG_FIFO_RX_BASE_AD)); // set 0x0D to 0x0F (contains 0x00);
  733. // Low Noise Amplifier used in receiver
  734. writeRegister(REG_LNA, (uint8_t) LNA_MAX_GAIN); // 0x0C, 0x23
  735. // Accept no interrupts except RXDONE, RXTOUT en RXCRC
  736. writeRegister(REG_IRQ_FLAGS_MASK, (uint8_t) ~(
  737. IRQ_LORA_RXDONE_MASK |
  738. IRQ_LORA_RXTOUT_MASK |
  739. IRQ_LORA_HEADER_MASK |
  740. IRQ_LORA_CRCERR_MASK));
  741. // set frequency hopping
  742. if (_hop) {
  743. //writeRegister(REG_HOP_PERIOD, 0x01); // 0x24, 0x01 was 0xFF
  744. writeRegister(REG_HOP_PERIOD,0x00); // 0x24, 0x00 was 0xFF
  745. }
  746. else {
  747. writeRegister(REG_HOP_PERIOD,0x00); // 0x24, 0x00 was 0xFF
  748. }
  749. // Set RXDONE interrupt to dio0
  750. writeRegister(REG_DIO_MAPPING_1, (uint8_t)(
  751. MAP_DIO0_LORA_RXDONE |
  752. MAP_DIO1_LORA_RXTOUT |
  753. MAP_DIO2_LORA_NOP |
  754. MAP_DIO3_LORA_CRC));
  755. // Set the opmode to either single or continuous receive. The first is used when
  756. // every message can come on a different SF, the second when we have fixed SF
  757. if (_cad) {
  758. // cad Scanner setup, set _state to S_RX
  759. // Set Single Receive Mode, goes in STANDBY mode after receipt
  760. _state= S_RX;
  761. opmode(OPMODE_RX_SINGLE); // 0x80 | 0x06 (listen one message)
  762. }
  763. else {
  764. // Set Continous Receive Mode, useful if we stay on one SF
  765. _state= S_RX;
  766. if (_hop) Serial.println(F("rxLoraModem:: ERROR continuous receive in hop mode"));
  767. opmode(OPMODE_RX); // 0x80 | 0x05 (listen)
  768. }
  769. // 9. clear all radio IRQ flags
  770. writeRegister(REG_IRQ_FLAGS, 0xFF);
  771. return;
  772. }// rxLoraModem
  773. // ----------------------------------------------------------------------------
  774. // function cadScanner()
  775. //
  776. // CAD Scanner will scan on the given channel for a valid Symbol/Preamble signal.
  777. // So instead of receiving continuous on a given channel/sf combination
  778. // we will wait on the given channel and scan for a preamble. Once received
  779. // we will set the radio to the SF with best rssi (indicating reception on that sf).
  780. // The function sets the _state to S_SCAN
  781. // NOTE: DO not set the frequency here but use the frequency hopper
  782. // ----------------------------------------------------------------------------
  783. void cadScanner()
  784. {
  785. // 1. Put system in LoRa mode (which destroys all other modes)
  786. //opmode(OPMODE_LORA);
  787. // 2. Put the radio in sleep mode
  788. opmode(OPMODE_STANDBY); // Was old value
  789. // 3. Set frequency based on value in ifreq // XXX New, might be needed when receiving down
  790. setFreq(freqs[ifreq].upFreq); // set to the right frequency
  791. // For every time we start the scanner, we set the SF to the begin value
  792. //sf = SF7; // XXX 180501 Not by default
  793. // 4. Set spreading Factor and CRC
  794. setRate(sf, 0x04);
  795. // listen to LORA_MAC_PREAMBLE
  796. writeRegister(REG_SYNC_WORD, (uint8_t) 0x34); // set reg 0x39 to 0x34
  797. // Set the interrupts we want to listen to
  798. writeRegister(REG_DIO_MAPPING_1, (uint8_t)(
  799. MAP_DIO0_LORA_CADDONE |
  800. MAP_DIO1_LORA_CADDETECT |
  801. MAP_DIO2_LORA_NOP |
  802. MAP_DIO3_LORA_CRC ));
  803. // Set the mask for interrupts (we do not want to listen to) except for
  804. writeRegister(REG_IRQ_FLAGS_MASK, (uint8_t) ~(
  805. IRQ_LORA_CDDONE_MASK |
  806. IRQ_LORA_CDDETD_MASK |
  807. IRQ_LORA_CRCERR_MASK |
  808. IRQ_LORA_HEADER_MASK));
  809. // Set the opMode to CAD
  810. opmode(OPMODE_CAD);
  811. // Clear all relevant interrupts
  812. //writeRegister(REG_IRQ_FLAGS, (uint8_t) 0xFF ); // May work better, clear ALL interrupts
  813. // If we are here. we either might have set the SF or we have a timeout in which
  814. // case the receive is started just as normal.
  815. return;
  816. }// cadScanner
  817. // ----------------------------------------------------------------------------
  818. // First time initialisation of the LoRa modem
  819. // Subsequent changes to the modem state etc. done by txLoraModem or rxLoraModem
  820. // After initialisation the modem is put in rx mode (listen)
  821. // ----------------------------------------------------------------------------
  822. void initLoraModem(
  823. )
  824. {
  825. _state = S_INIT;
  826. #if ESP32_ARCH==1
  827. digitalWrite(pins.rst, LOW);
  828. delayMicroseconds(10000);
  829. digitalWrite(pins.rst, HIGH);
  830. delayMicroseconds(10000);
  831. digitalWrite(pins.ss, HIGH);
  832. #if _DUSB>=1
  833. #endif
  834. #else
  835. // Reset the transceiver chip with a pulse of 10 mSec
  836. digitalWrite(pins.rst, HIGH);
  837. delayMicroseconds(10000);
  838. digitalWrite(pins.rst, LOW);
  839. delayMicroseconds(10000);
  840. #endif
  841. // 2. Set radio to sleep
  842. opmode(OPMODE_SLEEP); // set register 0x01 to 0x00
  843. // 1 Set LoRa Mode
  844. opmode(OPMODE_LORA); // set register 0x01 to 0x80
  845. // 3. Set frequency based on value in freq
  846. setFreq(freqs[ifreq].upFreq); // set to 868.1MHz or the last saved frequency
  847. // 4. Set spreading Factor
  848. setRate(sf, 0x04);
  849. // Low Noise Amplifier used in receiver
  850. writeRegister(REG_LNA, (uint8_t) LNA_MAX_GAIN); // 0x0C, 0x23
  851. #if _PIN_OUT==4
  852. delay(1);
  853. #endif
  854. uint8_t version = readRegister(REG_VERSION); // Read the LoRa chip version id
  855. if (version == 0x22) {
  856. // sx1272
  857. #if _DUSB>=2
  858. Serial.println(F("WARNING:: SX1272 detected"));
  859. #endif
  860. sx1272 = true;
  861. }
  862. else if (version == 0x12) {
  863. // sx1276?
  864. #if _DUSB>=2
  865. if (debug >=1)
  866. Serial.println(F("SX1276 starting"));
  867. #endif
  868. sx1272 = false;
  869. }
  870. else {
  871. // Normally this means that we connected the wrong type of board and
  872. // therefore specified the wrong type of wiring/pins to the software
  873. // Maybe this issue can be resolved of we try one of the other defined
  874. // boards. (Comresult or Hallard or ...)
  875. #if _DUSB>=1
  876. Serial.print(F("Unknown transceiver="));
  877. Serial.print(version,HEX);
  878. Serial.print(F(", pins.rst =")); Serial.print(pins.rst);
  879. Serial.print(F(", pins.ss =")); Serial.print(pins.ss);
  880. Serial.print(F(", pins.dio0 =")); Serial.print(pins.dio0);
  881. Serial.print(F(", pins.dio1 =")); Serial.print(pins.dio1);
  882. Serial.print(F(", pins.dio2 =")); Serial.print(pins.dio2);
  883. Serial.println();
  884. Serial.flush();
  885. #endif
  886. die(""); // Maybe first try another kind of receiver
  887. }
  888. // If we are here, the chip is recognized successfully
  889. // 7. set sync word
  890. writeRegister(REG_SYNC_WORD, (uint8_t) 0x34); // set 0x39 to 0x34 LORA_MAC_PREAMBLE
  891. // prevent node to node communication
  892. writeRegister(REG_INVERTIQ,0x27); // 0x33, 0x27; to reset from TX
  893. // Max Payload length is dependent on 256 byte buffer. At startup TX starts at
  894. // 0x80 and RX at 0x00. RX therefore maximized at 128 Bytes
  895. writeRegister(REG_MAX_PAYLOAD_LENGTH,MAX_PAYLOAD_LENGTH); // set 0x23 to 0x80==128 bytes
  896. writeRegister(REG_PAYLOAD_LENGTH,PAYLOAD_LENGTH); // 0x22, 0x40==64Byte long
  897. writeRegister(REG_FIFO_ADDR_PTR, (uint8_t) readRegister(REG_FIFO_RX_BASE_AD)); // set reg 0x0D to 0x0F
  898. writeRegister(REG_HOP_PERIOD,0x00); // reg 0x24, set to 0x00
  899. // 5. Config PA Ramp up time // set reg 0x0A
  900. writeRegister(REG_PARAMP, (readRegister(REG_PARAMP) & 0xF0) | 0x08); // set PA ramp-up time 50 uSec
  901. // Set 0x4D PADAC for SX1276 ; XXX register is 0x5a for sx1272
  902. writeRegister(REG_PADAC_SX1276, 0x84); // set 0x4D (PADAC) to 0x84
  903. //writeRegister(REG_PADAC, readRegister(REG_PADAC) | 0x4);
  904. // Reset interrupt Mask, enable all interrupts
  905. writeRegister(REG_IRQ_FLAGS_MASK, 0x00);
  906. // 9. clear all radio IRQ flags
  907. writeRegister(REG_IRQ_FLAGS, 0xFF);
  908. }// initLoraModem
  909. // ----------------------------------------------------------------------------
  910. // Void function startReceiver.
  911. // This function starts the receiver loop of the LoRa service.
  912. // It starts the LoRa modem with initLoraModem(), and then starts
  913. // the receiver either in single message (CAD) of in continuous
  914. // reception (STD).
  915. // ----------------------------------------------------------------------------
  916. void startReceiver() {
  917. initLoraModem(); // XXX 180326, after adapting this function
  918. if (_cad) {
  919. #if _DUSB>=1
  920. if (( debug>=1 ) && ( pdebug & P_SCAN )) {
  921. Serial.println(F("S PULL:: _state set to S_SCAN"));
  922. if (debug>=2) Serial.flush();
  923. }
  924. #endif
  925. _state = S_SCAN;
  926. sf = SF7;
  927. cadScanner();
  928. }
  929. else {
  930. _state = S_RX;
  931. rxLoraModem();
  932. }
  933. writeRegister(REG_IRQ_FLAGS_MASK, (uint8_t) 0x00);
  934. writeRegister(REG_IRQ_FLAGS, 0xFF); // Reset all interrupt flags
  935. }
  936. // ----------------------------------------------------------------------------
  937. // Interrupt_0 Handler.
  938. // Both interrupts DIO0 and DIO1 are mapped on GPIO15. Se we have to look at
  939. // the interrupt flags to see which interrupt(s) are called.
  940. //
  941. // NOTE:: This method may work not as good as just using more GPIO pins on
  942. // the ESP8266 mcu. But in practice it works good enough
  943. // ----------------------------------------------------------------------------
  944. void ICACHE_RAM_ATTR Interrupt_0()
  945. {
  946. _event=1;
  947. }
  948. // ----------------------------------------------------------------------------
  949. // Interrupt handler for DIO1 having High Value
  950. // As DIO0 and DIO1 may be multiplexed on one GPIO interrupt handler
  951. // (as we do) we have to be careful only to call the right Interrupt_x
  952. // handler and clear the corresponding interrupts for that dio.
  953. // NOTE: Make sure all Serial communication is only for debug level 3 and up.
  954. // Handler for:
  955. // - CDDETD
  956. // - RXTIMEOUT
  957. // - (RXDONE error only)
  958. // ----------------------------------------------------------------------------
  959. void ICACHE_RAM_ATTR Interrupt_1()
  960. {
  961. _event=1;
  962. }
  963. // ----------------------------------------------------------------------------
  964. // Frequency Hopping Channel (FHSS) dio2
  965. // ----------------------------------------------------------------------------
  966. void ICACHE_RAM_ATTR Interrupt_2()
  967. {
  968. _event=1;
  969. }