SX1276.c 11 KB

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