A low cost DIY sound pressure level sensor for enabling environmental noise awareness. https://lukasschwarz.org/noise-sensor
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

SX1278.c 9.3 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. /**
  2. * Author Wojciech Domski <Wojciech.Domski@gmail.com>
  3. * www: www.Domski.pl
  4. *
  5. * work based on DORJI.COM sample code and
  6. * https://github.com/realspinner/SX1278_LoRa
  7. */
  8. #include <string.h>
  9. #include <SX1278.h>
  10. uint8_t SX1278_SPIRead(SX1278_t *module, uint8_t addr) {
  11. uint8_t tmp;
  12. SX1278_hw_SPICommand(module->hw, addr);
  13. tmp = SX1278_hw_SPIReadByte(module->hw);
  14. SX1278_hw_SetNSS(module->hw, 1);
  15. return tmp;
  16. }
  17. void SX1278_SPIWrite(SX1278_t *module, uint8_t addr, uint8_t cmd) {
  18. SX1278_hw_SetNSS(module->hw, 0);
  19. SX1278_hw_SPICommand(module->hw, addr | 0x80);
  20. SX1278_hw_SPICommand(module->hw, cmd);
  21. SX1278_hw_SetNSS(module->hw, 1);
  22. }
  23. void SX1278_SPIBurstRead(SX1278_t *module, uint8_t addr, uint8_t *rxBuf,
  24. uint8_t length) {
  25. uint8_t i;
  26. if (length <= 1) {
  27. return;
  28. } else {
  29. SX1278_hw_SetNSS(module->hw, 0);
  30. SX1278_hw_SPICommand(module->hw, addr);
  31. for (i = 0; i < length; i++) {
  32. *(rxBuf + i) = SX1278_hw_SPIReadByte(module->hw);
  33. }
  34. SX1278_hw_SetNSS(module->hw, 1);
  35. }
  36. }
  37. void SX1278_SPIBurstWrite(SX1278_t *module, uint8_t addr, uint8_t *txBuf,
  38. uint8_t length) {
  39. unsigned char i;
  40. if (length <= 1) {
  41. return;
  42. } else {
  43. SX1278_hw_SetNSS(module->hw, 0);
  44. SX1278_hw_SPICommand(module->hw, addr | 0x80);
  45. for (i = 0; i < length; i++) {
  46. SX1278_hw_SPICommand(module->hw, *(txBuf + i));
  47. }
  48. SX1278_hw_SetNSS(module->hw, 1);
  49. }
  50. }
  51. void SX1278_config(SX1278_t *module) {
  52. SX1278_sleep(module); //Change modem mode Must in Sleep mode
  53. SX1278_hw_DelayMs(15);
  54. SX1278_entryLoRa(module);
  55. //SX1278_SPIWrite(module, 0x5904); //?? Change digital regulator form 1.6V to 1.47V: see errata note
  56. uint64_t freq = ((uint64_t) module->frequency << 19) / 32000000;
  57. uint8_t freq_reg[3];
  58. freq_reg[0] = (uint8_t) (freq >> 16);
  59. freq_reg[1] = (uint8_t) (freq >> 8);
  60. freq_reg[2] = (uint8_t) (freq >> 0);
  61. SX1278_SPIBurstWrite(module, LR_RegFrMsb, (uint8_t*) freq_reg, 3); //setting frequency parameter
  62. /* According to Semtech syncWord doesn't really work all that well. I'll set it anyway; for completeness' sake */
  63. SX1278_SPIWrite(module, RegSyncWord, 0xff);
  64. //setting base parameter
  65. SX1278_SPIWrite(module, LR_RegPaConfig, SX1278_Power[module->power]); //Setting output power parameter
  66. SX1278_SPIWrite(module, LR_RegOcp, 0x0B); //RegOcp,Close Ocp
  67. SX1278_SPIWrite(module, LR_RegLna, 0x23); //RegLNA,High & LNA Enable
  68. if (SX1278_SpreadFactor[module->LoRa_SF] == 6) { //SFactor=6
  69. uint8_t tmp;
  70. SX1278_SPIWrite(module,
  71. LR_RegModemConfig1,
  72. ((SX1278_LoRaBandwidth[module->LoRa_BW] << 4)
  73. + (SX1278_CodingRate[module->LoRa_CR] << 1) + 0x01)); //Implicit Enable CRC Enable(0x02) & Error Coding rate 4/5(0x01), 4/6(0x02), 4/7(0x03), 4/8(0x04)
  74. SX1278_SPIWrite(module,
  75. LR_RegModemConfig2,
  76. ((SX1278_SpreadFactor[module->LoRa_SF] << 4)
  77. + (SX1278_CRC_Sum[module->LoRa_CRC_sum] << 2) + 0x03));
  78. tmp = SX1278_SPIRead(module, 0x31);
  79. tmp &= 0xF8;
  80. tmp |= 0x05;
  81. SX1278_SPIWrite(module, 0x31, tmp);
  82. SX1278_SPIWrite(module, 0x37, 0x0C);
  83. } else {
  84. SX1278_SPIWrite(module,
  85. LR_RegModemConfig1,
  86. ((SX1278_LoRaBandwidth[module->LoRa_BW] << 4)
  87. + (SX1278_CodingRate[module->LoRa_CR] << 1) + 0x00)); //Explicit Enable CRC Enable(0x02) & Error Coding rate 4/5(0x01), 4/6(0x02), 4/7(0x03), 4/8(0x04)
  88. SX1278_SPIWrite(module,
  89. LR_RegModemConfig2,
  90. ((SX1278_SpreadFactor[module->LoRa_SF] << 4)
  91. + (SX1278_CRC_Sum[module->LoRa_CRC_sum] << 2) + 0x00)); //SFactor & LNA gain set by the internal AGC loop
  92. }
  93. SX1278_SPIWrite(module, LR_RegModemConfig3, 0x04);
  94. SX1278_SPIWrite(module, LR_RegSymbTimeoutLsb, 0x08); //RegSymbTimeoutLsb Timeout = 0x3FF(Max)
  95. SX1278_SPIWrite(module, LR_RegPreambleMsb, 0x00); //RegPreambleMsb
  96. SX1278_SPIWrite(module, LR_RegPreambleLsb, 8); //RegPreambleLsb 8+4=12byte Preamble
  97. SX1278_SPIWrite(module, REG_LR_DIOMAPPING2, 0x01); //RegDioMapping2 DIO5=00, DIO4=01
  98. module->readBytes = 0;
  99. SX1278_standby(module); //Entry standby mode
  100. }
  101. void SX1278_standby(SX1278_t *module) {
  102. SX1278_SPIWrite(module, LR_RegOpMode, 0x09);
  103. module->status = STANDBY;
  104. }
  105. void SX1278_sleep(SX1278_t *module) {
  106. SX1278_SPIWrite(module, LR_RegOpMode, 0x08);
  107. module->status = SLEEP;
  108. }
  109. void SX1278_entryLoRa(SX1278_t *module) {
  110. SX1278_SPIWrite(module, LR_RegOpMode, 0x88);
  111. }
  112. void SX1278_clearLoRaIrq(SX1278_t *module) {
  113. SX1278_SPIWrite(module, LR_RegIrqFlags, 0xFF);
  114. }
  115. int SX1278_LoRaEntryRx(SX1278_t *module, uint8_t length, uint32_t timeout) {
  116. uint8_t addr;
  117. module->packetLength = length;
  118. SX1278_config(module); //Setting base parameter
  119. SX1278_SPIWrite(module, REG_LR_PADAC, 0x84); //Normal and RX
  120. SX1278_SPIWrite(module, LR_RegHopPeriod, 0xFF); //No FHSS
  121. SX1278_SPIWrite(module, REG_LR_DIOMAPPING1, 0x01);//DIO=00,DIO1=00,DIO2=00, DIO3=01
  122. SX1278_SPIWrite(module, LR_RegIrqFlagsMask, 0x3F);//Open RxDone interrupt & Timeout
  123. SX1278_clearLoRaIrq(module);
  124. SX1278_SPIWrite(module, LR_RegPayloadLength, length);//Payload Length 21byte(this register must difine when the data long of one byte in SF is 6)
  125. addr = SX1278_SPIRead(module, LR_RegFifoRxBaseAddr); //Read RxBaseAddr
  126. SX1278_SPIWrite(module, LR_RegFifoAddrPtr, addr); //RxBaseAddr->FiFoAddrPtr
  127. SX1278_SPIWrite(module, LR_RegOpMode, 0x8d); //Mode//Low Frequency Mode
  128. //SX1278_SPIWrite(module, LR_RegOpMode,0x05); //Continuous Rx Mode //High Frequency Mode
  129. module->readBytes = 0;
  130. while (1) {
  131. if ((SX1278_SPIRead(module, LR_RegModemStat) & 0x04) == 0x04) { //Rx-on going RegModemStat
  132. module->status = RX;
  133. return 1;
  134. }
  135. if (--timeout == 0) {
  136. SX1278_hw_Reset(module->hw);
  137. SX1278_config(module);
  138. return 0;
  139. }
  140. SX1278_hw_DelayMs(1);
  141. }
  142. }
  143. uint8_t SX1278_LoRaRxPacket(SX1278_t *module) {
  144. unsigned char addr;
  145. unsigned char packet_size;
  146. if (SX1278_hw_GetDIO0(module->hw)) {
  147. memset(module->rxBuffer, 0x00, SX1278_MAX_PACKET);
  148. addr = SX1278_SPIRead(module, LR_RegFifoRxCurrentaddr); //last packet addr
  149. SX1278_SPIWrite(module, LR_RegFifoAddrPtr, addr); //RxBaseAddr -> FiFoAddrPtr
  150. if (module->LoRa_SF == SX1278_LORA_SF_6) { //When SpreadFactor is six,will used Implicit Header mode(Excluding internal packet length)
  151. packet_size = module->packetLength;
  152. } else {
  153. packet_size = SX1278_SPIRead(module, LR_RegRxNbBytes); //Number for received bytes
  154. }
  155. SX1278_SPIBurstRead(module, 0x00, module->rxBuffer, packet_size);
  156. module->readBytes = packet_size;
  157. SX1278_clearLoRaIrq(module);
  158. }
  159. return module->readBytes;
  160. }
  161. int SX1278_LoRaEntryTx(SX1278_t *module, uint8_t length, uint32_t timeout) {
  162. uint8_t addr;
  163. uint8_t temp;
  164. module->packetLength = length;
  165. SX1278_config(module); //setting base parameter
  166. SX1278_SPIWrite(module, REG_LR_PADAC, 0x87); //Tx for 20dBm
  167. SX1278_SPIWrite(module, LR_RegHopPeriod, 0x00); //RegHopPeriod NO FHSS
  168. SX1278_SPIWrite(module, REG_LR_DIOMAPPING1, 0x41); //DIO0=01, DIO1=00,DIO2=00, DIO3=01
  169. SX1278_clearLoRaIrq(module);
  170. SX1278_SPIWrite(module, LR_RegIrqFlagsMask, 0xF7); //Open TxDone interrupt
  171. SX1278_SPIWrite(module, LR_RegPayloadLength, length); //RegPayloadLength 21byte
  172. addr = SX1278_SPIRead(module, LR_RegFifoTxBaseAddr); //RegFiFoTxBaseAddr
  173. SX1278_SPIWrite(module, LR_RegFifoAddrPtr, addr); //RegFifoAddrPtr
  174. while (1) {
  175. temp = SX1278_SPIRead(module, LR_RegPayloadLength);
  176. if (temp == length) {
  177. module->status = TX;
  178. return 1;
  179. }
  180. if (--timeout == 0) {
  181. SX1278_hw_Reset(module->hw);
  182. SX1278_config(module);
  183. return 0;
  184. }
  185. }
  186. }
  187. int SX1278_LoRaTxPacket(SX1278_t *module, uint8_t *txBuffer, uint8_t length,
  188. uint32_t timeout) {
  189. SX1278_SPIBurstWrite(module, 0x00, txBuffer, length);
  190. SX1278_SPIWrite(module, LR_RegOpMode, 0x8b); //Tx Mode
  191. while (1) {
  192. if (SX1278_hw_GetDIO0(module->hw)) { //if(Get_NIRQ()) //Packet send over
  193. SX1278_SPIRead(module, LR_RegIrqFlags);
  194. SX1278_clearLoRaIrq(module); //Clear irq
  195. SX1278_standby(module); //Entry Standby mode
  196. return 1;
  197. }
  198. if (--timeout == 0) {
  199. SX1278_hw_Reset(module->hw);
  200. SX1278_config(module);
  201. return 0;
  202. }
  203. SX1278_hw_DelayMs(1);
  204. }
  205. }
  206. void SX1278_init(SX1278_t *module, uint64_t frequency, uint8_t power,
  207. uint8_t LoRa_SF, uint8_t LoRa_BW, uint8_t LoRa_CR,
  208. uint8_t LoRa_CRC_sum, uint8_t packetLength) {
  209. SX1278_hw_init(module->hw);
  210. module->frequency = frequency;
  211. module->power = power;
  212. module->LoRa_SF = LoRa_SF;
  213. module->LoRa_BW = LoRa_BW;
  214. module->LoRa_CR = LoRa_CR;
  215. module->LoRa_CRC_sum = LoRa_CRC_sum;
  216. module->packetLength = packetLength;
  217. SX1278_config(module);
  218. }
  219. int SX1278_transmit(SX1278_t *module, uint8_t *txBuf, uint8_t length,
  220. uint32_t timeout) {
  221. if (SX1278_LoRaEntryTx(module, length, timeout)) {
  222. return SX1278_LoRaTxPacket(module, txBuf, length, timeout);
  223. }
  224. return 0;
  225. }
  226. int SX1278_receive(SX1278_t *module, uint8_t length, uint32_t timeout) {
  227. return SX1278_LoRaEntryRx(module, length, timeout);
  228. }
  229. uint8_t SX1278_available(SX1278_t *module) {
  230. return SX1278_LoRaRxPacket(module);
  231. }
  232. uint8_t SX1278_read(SX1278_t *module, uint8_t *rxBuf, uint8_t length) {
  233. if (length != module->readBytes)
  234. length = module->readBytes;
  235. memcpy(rxBuf, module->rxBuffer, length);
  236. rxBuf[length] = '\0';
  237. module->readBytes = 0;
  238. return length;
  239. }
  240. uint8_t SX1278_RSSI_LoRa(SX1278_t *module) {
  241. uint32_t temp = 10;
  242. temp = SX1278_SPIRead(module, LR_RegRssiValue); //Read RegRssiValue, Rssi value
  243. temp = temp + 127 - 137; //127:Max RSSI, 137:RSSI offset
  244. return (uint8_t) temp;
  245. }
  246. uint8_t SX1278_RSSI(SX1278_t *module) {
  247. uint8_t temp = 0xff;
  248. temp = SX1278_SPIRead(module, RegRssiValue);
  249. temp = 127 - (temp >> 1); //127:Max RSSI
  250. return temp;
  251. }