SX1276.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376
  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/SX1276_LoRa
  7. */
  8. #include "SX1276.h"
  9. #include <string.h>
  10. //////////////////////////////////
  11. // logic
  12. //////////////////////////////////
  13. __weak void SX1276_hw_init(SX1276_hw_t * hw) {
  14. SX1276_hw_SetNSS(hw, 1);
  15. HAL_GPIO_WritePin(hw->reset.port, hw->reset.pin, GPIO_PIN_SET);
  16. }
  17. __weak void SX1276_hw_SetNSS(SX1276_hw_t * hw, int value) {
  18. HAL_GPIO_WritePin(hw->nss.port, hw->nss.pin,
  19. (value == 1) ? GPIO_PIN_SET : GPIO_PIN_RESET);
  20. }
  21. __weak void SX1276_hw_Reset(SX1276_hw_t * hw) {
  22. SX1276_hw_SetNSS(hw, 1);
  23. HAL_GPIO_WritePin(hw->reset.port, hw->reset.pin, GPIO_PIN_RESET);
  24. SX1276_hw_DelayMs(1);
  25. HAL_GPIO_WritePin(hw->reset.port, hw->reset.pin, GPIO_PIN_SET);
  26. SX1276_hw_DelayMs(100);
  27. }
  28. #if 0 // PYJ.2019.04.01_BEGIN --
  29. __weak void SX1276_hw_SPICommand(SX1276_hw_t * hw, uint8_t cmd) {
  30. SX1276_hw_SetNSS(hw, 0);
  31. HAL_SPI_Transmit(hw->spi, &cmd, 1, 1000);
  32. while (HAL_SPI_GetState(hw->spi) != HAL_SPI_STATE_READY)
  33. ;
  34. }
  35. #endif // PYJ.2019.04.01_END --
  36. void SX1276_hw_SPICommand(SX1276_hw_t * hw, uint8_t cmd) {
  37. SX1276_hw_SetNSS(hw, 0);
  38. BLUECELL_SPI_Transmit(cmd);
  39. }
  40. #if 0 // PYJ.2019.04.01_BEGIN --
  41. __weak uint8_t SX1276_hw_SPIReadByte(SX1276_hw_t * hw) {
  42. uint8_t txByte = 0x00;
  43. uint8_t rxByte = 0x00;
  44. SX1276_hw_SetNSS(hw, 0);
  45. HAL_SPI_TransmitReceive(hw->spi, &txByte, &rxByte, 1, 1000);
  46. return rxByte;
  47. }
  48. #endif // PYJ.2019.04.01_END --
  49. uint8_t SX1276_hw_SPIReadByte(SX1276_hw_t * hw) {
  50. //uint8_t txByte = 0x00;
  51. uint8_t rxByte = 0x00;
  52. SX1276_hw_SetNSS(hw, 0);
  53. // HAL_SPI_TransmitReceive(hw->spi, &txByte, &rxByte, 1, 1000);
  54. rxByte = SpiRead();
  55. return rxByte;
  56. }
  57. __weak void SX1276_hw_DelayMs(uint32_t msec) {
  58. HAL_Delay(msec);
  59. }
  60. __weak int SX1276_hw_GetDIO0(SX1276_hw_t * hw) {
  61. return (HAL_GPIO_ReadPin(hw->dio0.port, hw->dio0.pin) == GPIO_PIN_SET);
  62. }
  63. //////////////////////////////////
  64. // logic
  65. //////////////////////////////////
  66. uint8_t SX1276_SPIRead(SX1276_t * module, uint8_t addr) {
  67. uint8_t tmp;
  68. SX1276_hw_SPICommand(module->hw, addr);
  69. tmp = SX1276_hw_SPIReadByte(module->hw);
  70. SX1276_hw_SetNSS(module->hw, 1);
  71. return tmp;
  72. }
  73. uint8_t SX1276_SPIIDRead(SX1276_t * module, uint8_t addr) {
  74. uint8_t tmp;
  75. SX1276_hw_SPICommand(module->hw, addr);
  76. tmp = SX1276_hw_SPIReadByte(module->hw);
  77. SX1276_hw_SetNSS(module->hw, 1);
  78. return tmp;
  79. }
  80. void SX1276_SPIWrite(SX1276_t * module, uint8_t addr, uint8_t cmd) {
  81. SX1276_hw_SetNSS(module->hw, 0);
  82. SX1276_hw_SPICommand(module->hw, addr | 0x80);
  83. SX1276_hw_SPICommand(module->hw, cmd);
  84. // SPIGPIOTxRx(addr | 0x80,cmd);
  85. SX1276_hw_SetNSS(module->hw, 1);
  86. }
  87. void SX1276_SPIBurstRead(SX1276_t * module, uint8_t addr, uint8_t* rxBuf,
  88. uint8_t length) {
  89. uint8_t i;
  90. if (length <= 1) {
  91. return;
  92. } else {
  93. SX1276_hw_SetNSS(module->hw, 0);
  94. SX1276_hw_SPICommand(module->hw, addr);
  95. //printf("Test Data:");
  96. for (i = 0; i < length; i++) {
  97. rxBuf[i] = SX1276_hw_SPIReadByte(module->hw);
  98. //printf("%02x ",rxBuf[i]);
  99. }
  100. //printf("\n");
  101. SX1276_hw_SetNSS(module->hw, 1);
  102. }
  103. }
  104. void SX1276_SPIBurstWrite(SX1276_t * module, uint8_t addr, uint8_t* txBuf,
  105. uint8_t length) {
  106. uint8_t i;
  107. if (length <= 1) {
  108. return;
  109. } else {
  110. SX1276_hw_SetNSS(module->hw, 0);
  111. SX1276_hw_SPICommand(module->hw, addr | 0x80);
  112. // printf("Test Data:");
  113. for (i = 0; i < length; i++) {
  114. SX1276_hw_SPICommand(module->hw, txBuf[i]);
  115. // printf("%02x ",txBuf[i]);
  116. }
  117. // printf("\n");
  118. SX1276_hw_SetNSS(module->hw, 1);
  119. }
  120. }
  121. void SX1276_defaultConfig(SX1276_t * module) {
  122. SX1276_config(module, module->frequency, module->power, module->LoRa_Rate,
  123. module->LoRa_BW,module->LoRa_Lna);
  124. }
  125. void SX1276_config(SX1276_t * module, uint8_t frequency, uint8_t power,
  126. uint8_t LoRa_Rate, uint8_t LoRa_BW,uint8_t LoRa_Lna) {
  127. SX1276_sleep(module); //Change modem mode Must in Sleep mode
  128. SX1276_hw_DelayMs(15);
  129. SX1276_entryLoRa(module);
  130. //SX1276_SPIWrite(module, 0x5904); //?? Change digital regulator form 1.6V to 1.47V: see errata note
  131. SX1276_SPIBurstWrite(module, LR_RegFrMsb,
  132. (uint8_t*) SX1276_Frequency[frequency], 3); //setting frequency parameter
  133. //setting base parameter
  134. SX1276_SPIWrite(module, LR_RegPaConfig, SX1276_Power[power]); //Setting output power parameter
  135. SX1276_SPIWrite(module, LR_RegOcp, 0x0B); //RegOcp,Close Ocp
  136. // SX1276_SPIWrite(module, LR_RegLna, 0x20); //RegLNA,High & LNA Enable
  137. SX1276_SPIWrite(module, LR_RegLna, LoRa_Lna); //RegLNA,High & LNA Enable
  138. if (SX1276_SpreadFactor[LoRa_Rate] == 6) { //SFactor=6
  139. uint8_t tmp;
  140. SX1276_SPIWrite(module,
  141. LR_RegModemConfig1,
  142. ((SX1276_LoRaBandwidth[LoRa_BW] << 4) + (SX1276_CR << 1) + 0x01)); //Implicit Enable CRC Enable(0x02) & Error Coding rate 4/5(0x01), 4/6(0x02), 4/7(0x03), 4/8(0x04)
  143. SX1276_SPIWrite(module,
  144. LR_RegModemConfig2,
  145. ((SX1276_SpreadFactor[LoRa_Rate] << 4) + (SX1276_CRC << 2)
  146. + 0x03));
  147. tmp = SX1276_SPIRead(module, 0x31);
  148. tmp &= 0xF8;
  149. tmp |= 0x05;
  150. SX1276_SPIWrite(module, 0x31, tmp);
  151. SX1276_SPIWrite(module, 0x37, 0x0C);
  152. } else {
  153. SX1276_SPIWrite(module,
  154. LR_RegModemConfig1,
  155. ((SX1276_LoRaBandwidth[LoRa_BW] << 4) + (SX1276_CR << 1) + 0x00)); //Explicit Enable CRC Enable(0x02) & Error Coding rate 4/5(0x01), 4/6(0x02), 4/7(0x03), 4/8(0x04)
  156. SX1276_SPIWrite(module,
  157. LR_RegModemConfig2,
  158. ((SX1276_SpreadFactor[LoRa_Rate] << 4) + (SX1276_CRC << 2)
  159. + 0x03)); //SFactor & LNA gain set by the internal AGC loop
  160. }
  161. SX1276_SPIWrite(module, LR_RegSymbTimeoutLsb, 0xFF); //RegSymbTimeoutLsb Timeout = 0x3FF(Max)
  162. SX1276_SPIWrite(module, LR_RegPreambleMsb, 0x00); //RegPreambleMsb
  163. SX1276_SPIWrite(module, LR_RegPreambleLsb, 12); //RegPreambleLsb 8+4=12byte Preamble
  164. SX1276_SPIWrite(module, REG_LR_DIOMAPPING2, 0x01); //RegDioMapping2 DIO5=00, DIO4=01
  165. module->readBytes = 0;
  166. SX1276_standby(module); //Entry standby mode
  167. }
  168. void SX1276_standby(SX1276_t * module) {
  169. SX1276_SPIWrite(module, LR_RegOpMode, 0x09);
  170. module->status = STANDBY;
  171. }
  172. void SX1276_sleep(SX1276_t * module) {
  173. SX1276_SPIWrite(module, LR_RegOpMode, 0x08);
  174. module->status = SLEEP;
  175. }
  176. void SX1276_entryLoRa(SX1276_t * module) {
  177. SX1276_SPIWrite(module, LR_RegOpMode, 0x88);
  178. }
  179. void SX1276_clearLoRaIrq(SX1276_t * module) {
  180. SX1276_SPIWrite(module, LR_RegIrqFlags, 0xFF);
  181. }
  182. int SX1276_LoRaEntryRx(SX1276_t * module, uint8_t length, uint32_t timeout) {
  183. uint8_t addr;
  184. module->packetLength = length;
  185. SX1276_defaultConfig(module); //Setting base parameter
  186. SX1276_SPIWrite(module, REG_LR_PADAC, 0x84); //Normal and RX
  187. SX1276_SPIWrite(module, LR_RegHopPeriod, 0xFF); //No FHSS
  188. SX1276_SPIWrite(module, REG_LR_DIOMAPPING1, 0x01);//DIO=00,DIO1=00,DIO2=00, DIO3=01
  189. SX1276_SPIWrite(module, LR_RegIrqFlagsMask, 0x3F);//Open RxDone interrupt & Timeout
  190. SX1276_clearLoRaIrq(module);
  191. SX1276_SPIWrite(module, LR_RegPayloadLength, length);//Payload Length 21byte(this register must difine when the data long of one byte in SF is 6)
  192. addr = SX1276_SPIRead(module, LR_RegFifoRxBaseAddr); //Read RxBaseAddr
  193. SX1276_SPIWrite(module, LR_RegFifoAddrPtr, addr); //RxBaseAddr->FiFoAddrPtr
  194. SX1276_SPIWrite(module, LR_RegOpMode, 0x85); //Mode//Low Frequency Mode
  195. //SX1276_SPIWrite(module, LR_RegOpMode,0x05); //Continuous Rx Mode //High Frequency Mode
  196. module->readBytes = 0;
  197. while (1) {
  198. if ((SX1276_SPIRead(module, LR_RegModemStat) & 0x04) == 0x04) { //Rx-on going RegModemStat
  199. module->status = RX;
  200. return 1;
  201. }
  202. if (--timeout == 0) {
  203. SX1276_hw_Reset(module->hw);
  204. SX1276_defaultConfig(module);
  205. return 0;
  206. }
  207. SX1276_hw_DelayMs(1);
  208. }
  209. }
  210. uint8_t SX1276_LoRaRxPacket(SX1276_t * module) {
  211. unsigned char addr;
  212. unsigned char packet_size;
  213. if (SX1276_hw_GetDIO0(module->hw)) {
  214. memset(module->rxBuffer, 0x00, SX1276_MAX_PACKET);
  215. addr = SX1276_SPIRead(module, LR_RegFifoRxCurrentaddr); //last packet addr
  216. SX1276_SPIWrite(module, LR_RegFifoAddrPtr, addr); //RxBaseAddr -> FiFoAddrPtr
  217. if (module->LoRa_Rate == SX1276_LORA_SF_6) { //When SpreadFactor is six,will used Implicit Header mode(Excluding internal packet length)
  218. packet_size = module->packetLength;
  219. } else {
  220. packet_size = SX1276_SPIRead(module, LR_RegRxNbBytes); //Number for received bytes
  221. }
  222. SX1276_SPIBurstRead(module, 0x00, module->rxBuffer, packet_size);
  223. module->readBytes = packet_size;
  224. SX1276_clearLoRaIrq(module);
  225. }
  226. return module->readBytes;
  227. }
  228. int SX1276_LoRaEntryTx(SX1276_t * module, uint8_t length, uint32_t timeout) {
  229. uint8_t addr;
  230. uint8_t temp;
  231. module->packetLength = length;
  232. SX1276_defaultConfig(module); //setting base parameter
  233. SX1276_SPIWrite(module, REG_LR_PADAC, 0x87); //Tx for 20dBm
  234. SX1276_SPIWrite(module, LR_RegHopPeriod, 0x00); //RegHopPeriod NO FHSS
  235. SX1276_SPIWrite(module, REG_LR_DIOMAPPING1, 0x41); //DIO0=01, DIO1=00,DIO2=00, DIO3=01
  236. SX1276_clearLoRaIrq(module);
  237. SX1276_SPIWrite(module, LR_RegIrqFlagsMask, 0xF7); //Open TxDone interrupt
  238. SX1276_SPIWrite(module, LR_RegPayloadLength, length); //RegPayloadLength 21byte
  239. addr = SX1276_SPIRead(module, LR_RegFifoTxBaseAddr); //RegFiFoTxBaseAddr
  240. SX1276_SPIWrite(module, LR_RegFifoAddrPtr, addr); //RegFifoAddrPtr
  241. while (1) {
  242. temp = SX1276_SPIRead(module, LR_RegPayloadLength);
  243. if (temp == length) {
  244. module->status = TX;
  245. return 1;
  246. }
  247. if (--timeout == 0) {
  248. SX1276_hw_Reset(module->hw);
  249. SX1276_defaultConfig(module);
  250. return 0;
  251. }
  252. }
  253. }
  254. int SX1276_LoRaTxPacket(SX1276_t * module, uint8_t* txBuffer, uint8_t length,
  255. uint32_t timeout) {
  256. SX1276_SPIBurstWrite(module, 0x00, txBuffer, length);
  257. SX1276_SPIWrite(module, LR_RegOpMode, 0x8b); //Tx Mode
  258. while (1) {
  259. if (SX1276_hw_GetDIO0(module->hw)) { //if(Get_NIRQ()) //Packet send over
  260. SX1276_SPIRead(module, LR_RegIrqFlags);
  261. SX1276_clearLoRaIrq(module); //Clear irq
  262. SX1276_standby(module); //Entry Standby mode
  263. return 1;
  264. }
  265. if (--timeout == 0) {
  266. SX1276_hw_Reset(module->hw);
  267. SX1276_defaultConfig(module);
  268. return 0;
  269. }
  270. SX1276_hw_DelayMs(1);
  271. }
  272. }
  273. void SX1276_begin(SX1276_t * module, uint8_t frequency, uint8_t power,
  274. uint8_t LoRa_Rate, uint8_t LoRa_BW, uint8_t packetLength,uint8_t LoRa_Lna) {
  275. SX1276_hw_init(module->hw);
  276. module->frequency = frequency;
  277. module->power = power;
  278. module->LoRa_Rate = LoRa_Rate;
  279. module->LoRa_BW = LoRa_BW;
  280. module->packetLength = packetLength;
  281. module->LoRa_Lna = LoRa_Lna;
  282. SX1276_defaultConfig(module);
  283. }
  284. int SX1276_transmit(SX1276_t * module, uint8_t* txBuf, uint8_t length,
  285. uint32_t timeout) {
  286. if (SX1276_LoRaEntryTx(module, length, timeout)) {
  287. return SX1276_LoRaTxPacket(module, txBuf, length, timeout);
  288. }
  289. return 0;
  290. }
  291. int SX1276_receive(SX1276_t * module, uint8_t length, uint32_t timeout) {
  292. return SX1276_LoRaEntryRx(module, length, timeout);
  293. }
  294. uint8_t SX1276_available(SX1276_t * module) {
  295. return SX1276_LoRaRxPacket(module);
  296. }
  297. uint8_t SX1276_read(SX1276_t * module, uint8_t* rxBuf, uint8_t length) {
  298. if (length != module->readBytes)
  299. length = module->readBytes;
  300. memcpy(rxBuf, module->rxBuffer, length);
  301. rxBuf[length] = '\0';
  302. module->readBytes = 0;
  303. return length;
  304. }
  305. uint8_t SX1276_RSSI_LoRa(SX1276_t * module) {
  306. uint32_t temp = 10;
  307. temp = SX1276_SPIRead(module, LR_RegRssiValue); //Read RegRssiValue, Rssi value
  308. temp = temp + 127 - 137; //127:Max RSSI, 137:RSSI offset
  309. return (uint8_t) temp;
  310. }
  311. uint8_t SX1276_RSSI(SX1276_t * module) {
  312. uint8_t temp = 0xff;
  313. temp = SX1276_SPIRead(module, 0x11);
  314. temp = 127 - (temp >> 1); //127:Max RSSI
  315. return temp;
  316. }