_loraModem.ino 38 KB

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