_loraModem.ino 38 KB

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