Implement a secure ICS protocol targeting LoRa Node151 microcontroller for controlling irrigation.
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.
 
 
 
 
 
 

301 lines
8.3 KiB

  1. /*!
  2. * \file sx1272-board.c
  3. *
  4. * \brief Target board SX1272 driver implementation
  5. *
  6. * \copyright Revised BSD License, see section \ref LICENSE.
  7. *
  8. * \code
  9. * ______ _
  10. * / _____) _ | |
  11. * ( (____ _____ ____ _| |_ _____ ____| |__
  12. * \____ \| ___ | (_ _) ___ |/ ___) _ \
  13. * _____) ) ____| | | || |_| ____( (___| | | |
  14. * (______/|_____)_|_|_| \__)_____)\____)_| |_|
  15. * (C)2013-2017 Semtech
  16. *
  17. * \endcode
  18. *
  19. * \author Miguel Luis ( Semtech )
  20. *
  21. * \author Gregory Cristian ( Semtech )
  22. */
  23. #include <stdlib.h>
  24. #include "utilities.h"
  25. #include "board-config.h"
  26. #include "delay.h"
  27. #include "radio.h"
  28. #include "sx1272-board.h"
  29. /*!
  30. * Flag used to set the RF switch control pins in low power mode when the radio is not active.
  31. */
  32. static bool RadioIsActive = false;
  33. /*!
  34. * Radio driver structure initialization
  35. */
  36. const struct Radio_s Radio =
  37. {
  38. SX1272Init,
  39. SX1272GetStatus,
  40. SX1272SetModem,
  41. SX1272SetChannel,
  42. SX1272IsChannelFree,
  43. SX1272Random,
  44. SX1272SetRxConfig,
  45. SX1272SetTxConfig,
  46. SX1272CheckRfFrequency,
  47. SX1272GetTimeOnAir,
  48. SX1272Send,
  49. SX1272SetSleep,
  50. SX1272SetStby,
  51. SX1272SetRx,
  52. SX1272StartCad,
  53. SX1272SetTxContinuousWave,
  54. SX1272ReadRssi,
  55. SX1272Write,
  56. SX1272Read,
  57. SX1272WriteBuffer,
  58. SX1272ReadBuffer,
  59. SX1272SetMaxPayloadLength,
  60. SX1272SetPublicNetwork,
  61. SX1272GetWakeupTime,
  62. NULL, // void ( *IrqProcess )( void )
  63. NULL, // void ( *RxBoosted )( uint32_t timeout ) - SX126x Only
  64. NULL, // void ( *SetRxDutyCycle )( uint32_t rxTime, uint32_t sleepTime ) - SX126x Only
  65. };
  66. /*!
  67. * Antenna switch GPIO pins objects
  68. */
  69. Gpio_t RadioSwitchCtrl1;
  70. Gpio_t RadioSwitchCtrl2;
  71. Gpio_t RadioPwrAmpCtrl;
  72. /*!
  73. * Debug GPIO pins objects
  74. */
  75. #if defined( USE_RADIO_DEBUG )
  76. Gpio_t DbgPinTx;
  77. Gpio_t DbgPinRx;
  78. #endif
  79. /*
  80. PD_2=0 PD_2=1
  81. op PaB rfo rfo
  82. 0 4.6 18.5 27.0
  83. 1 5.6 21.1 28.1
  84. 2 6.7 23.3 29.1
  85. 3 7.7 25.3 30.1
  86. 4 8.8 26.2 30.7
  87. 5 9.8 27.3 31.2
  88. 6 10.7 28.1 31.6
  89. 7 11.7 28.6 32.2
  90. 8 12.8 29.2 32.4
  91. 9 13.7 29.9 32.9
  92. 10 14.7 30.5 33.1
  93. 11 15.6 30.8 33.4
  94. 12 16.4 30.9 33.6
  95. 13 17.1 31.0 33.7
  96. 14 17.8 31.1 33.7
  97. 15 18.4 31.1 33.7
  98. */
  99. // txpow: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
  100. static const uint8_t PaBTable[20] = { 0, 0, 0, 0, 0, 1, 2, 3, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, 15 };
  101. // txpow: 20 21 22 23 24 25 26 27 28 29 30
  102. static const uint8_t RfoTable[11] = { 1, 1, 1, 2, 2, 3, 4, 5, 6, 8, 9 };
  103. void SX1272IoInit( void )
  104. {
  105. GpioInit( &SX1272.Spi.Nss, RADIO_NSS, PIN_OUTPUT, PIN_PUSH_PULL, PIN_NO_PULL, 1 );
  106. GpioInit( &SX1272.DIO0, RADIO_DIO_0, PIN_INPUT, PIN_PUSH_PULL, PIN_PULL_UP, 0 );
  107. GpioInit( &SX1272.DIO1, RADIO_DIO_1, PIN_INPUT, PIN_PUSH_PULL, PIN_PULL_UP, 0 );
  108. GpioInit( &SX1272.DIO2, RADIO_DIO_2, PIN_INPUT, PIN_PUSH_PULL, PIN_PULL_UP, 0 );
  109. GpioInit( &SX1272.DIO3, RADIO_DIO_3, PIN_INPUT, PIN_PUSH_PULL, PIN_PULL_UP, 0 );
  110. GpioInit( &SX1272.DIO4, RADIO_DIO_4, PIN_INPUT, PIN_PUSH_PULL, PIN_PULL_UP, 0 );
  111. GpioInit( &SX1272.DIO5, RADIO_DIO_5, PIN_INPUT, PIN_PUSH_PULL, PIN_PULL_UP, 0 );
  112. }
  113. void SX1272IoIrqInit( DioIrqHandler **irqHandlers )
  114. {
  115. GpioSetInterrupt( &SX1272.DIO0, IRQ_RISING_EDGE, IRQ_HIGH_PRIORITY, irqHandlers[0] );
  116. GpioSetInterrupt( &SX1272.DIO1, IRQ_RISING_FALLING_EDGE, IRQ_HIGH_PRIORITY, irqHandlers[1] );
  117. GpioSetInterrupt( &SX1272.DIO2, IRQ_RISING_EDGE, IRQ_HIGH_PRIORITY, irqHandlers[2] );
  118. GpioSetInterrupt( &SX1272.DIO3, IRQ_RISING_EDGE, IRQ_HIGH_PRIORITY, irqHandlers[3] );
  119. GpioSetInterrupt( &SX1272.DIO4, IRQ_RISING_EDGE, IRQ_HIGH_PRIORITY, irqHandlers[4] );
  120. GpioSetInterrupt( &SX1272.DIO5, IRQ_RISING_EDGE, IRQ_HIGH_PRIORITY, irqHandlers[5] );
  121. }
  122. void SX1272IoDeInit( void )
  123. {
  124. GpioInit( &SX1272.Spi.Nss, RADIO_NSS, PIN_OUTPUT, PIN_PUSH_PULL, PIN_NO_PULL, 1 );
  125. GpioInit( &SX1272.DIO0, RADIO_DIO_0, PIN_INPUT, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
  126. GpioInit( &SX1272.DIO1, RADIO_DIO_1, PIN_INPUT, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
  127. GpioInit( &SX1272.DIO2, RADIO_DIO_2, PIN_INPUT, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
  128. GpioInit( &SX1272.DIO3, RADIO_DIO_3, PIN_INPUT, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
  129. GpioInit( &SX1272.DIO4, RADIO_DIO_4, PIN_INPUT, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
  130. GpioInit( &SX1272.DIO5, RADIO_DIO_5, PIN_INPUT, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
  131. }
  132. void SX1272IoDbgInit( void )
  133. {
  134. #if defined( USE_RADIO_DEBUG )
  135. GpioInit( &DbgPinTx, RADIO_DBG_PIN_TX, PIN_OUTPUT, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
  136. GpioInit( &DbgPinRx, RADIO_DBG_PIN_RX, PIN_OUTPUT, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
  137. #endif
  138. }
  139. void SX1272IoTcxoInit( void )
  140. {
  141. // No TCXO component available on this board design.
  142. }
  143. void SX1272SetBoardTcxo( uint8_t state )
  144. {
  145. // No TCXO component available on this board design.
  146. #if 0
  147. if( state == true )
  148. {
  149. TCXO_ON( );
  150. DelayMs( BOARD_TCXO_WAKEUP_TIME );
  151. }
  152. else
  153. {
  154. TCXO_OFF( );
  155. }
  156. #endif
  157. }
  158. uint32_t SX1272GetBoardTcxoWakeupTime( void )
  159. {
  160. return BOARD_TCXO_WAKEUP_TIME;
  161. }
  162. void SX1272Reset( void )
  163. {
  164. // Enables the TCXO if available on the board design
  165. SX1272SetBoardTcxo( true );
  166. // Set RESET pin to 1
  167. GpioInit( &SX1272.Reset, RADIO_RESET, PIN_OUTPUT, PIN_PUSH_PULL, PIN_NO_PULL, 1 );
  168. // Wait 1 ms
  169. DelayMs( 1 );
  170. // Configure RESET as input
  171. GpioInit( &SX1272.Reset, RADIO_RESET, PIN_INPUT, PIN_PUSH_PULL, PIN_NO_PULL, 1 );
  172. // Wait 6 ms
  173. DelayMs( 6 );
  174. }
  175. void SX1272SetRfTxPower( int8_t power )
  176. {
  177. uint8_t paConfig = 0;
  178. uint8_t paDac = 0;
  179. paConfig = Radio.Read( REG_PACONFIG );
  180. paDac = Radio.Read( REG_PADAC );
  181. if( power > 19 )
  182. {
  183. paConfig = ( paConfig & RF_PACONFIG_PASELECT_MASK ) | RF_PACONFIG_PASELECT_RFO;
  184. paConfig = ( paConfig & RFLR_PACONFIG_OUTPUTPOWER_MASK ) | RfoTable[power - 20];
  185. }
  186. else
  187. {
  188. paConfig = ( paConfig & RF_PACONFIG_PASELECT_MASK ) | RF_PACONFIG_PASELECT_PABOOST;
  189. paConfig = ( paConfig & RFLR_PACONFIG_OUTPUTPOWER_MASK ) | PaBTable[MAX( power, 0 )];
  190. }
  191. Radio.Write( REG_PACONFIG, paConfig );
  192. Radio.Write( REG_PADAC, paDac );
  193. }
  194. void SX1272SetAntSwLowPower( bool status )
  195. {
  196. if( RadioIsActive != status )
  197. {
  198. RadioIsActive = status;
  199. if( status == false )
  200. {
  201. SX1272AntSwInit( );
  202. }
  203. else
  204. {
  205. SX1272AntSwDeInit( );
  206. }
  207. }
  208. }
  209. void SX1272AntSwInit( void )
  210. {
  211. GpioInit( &RadioSwitchCtrl1, RADIO_SWITCH_CTRL1, PIN_OUTPUT, PIN_PUSH_PULL, PIN_PULL_UP, 0 );
  212. GpioInit( &RadioSwitchCtrl2, RADIO_SWITCH_CTRL2, PIN_OUTPUT, PIN_PUSH_PULL, PIN_PULL_UP, 0 );
  213. GpioInit( &RadioPwrAmpCtrl , RADIO_PWRAMP_CTRL , PIN_OUTPUT, PIN_PUSH_PULL, PIN_PULL_UP, 0 );
  214. }
  215. void SX1272AntSwDeInit( void )
  216. {
  217. GpioInit( &RadioSwitchCtrl1, RADIO_SWITCH_CTRL1, PIN_OUTPUT, PIN_PUSH_PULL, PIN_PULL_UP, 0 );
  218. GpioInit( &RadioSwitchCtrl2, RADIO_SWITCH_CTRL2, PIN_OUTPUT, PIN_PUSH_PULL, PIN_PULL_UP, 0 );
  219. GpioInit( &RadioPwrAmpCtrl , RADIO_PWRAMP_CTRL , PIN_OUTPUT, PIN_PUSH_PULL, PIN_PULL_UP, 0 );
  220. }
  221. void SX1272SetAntSw( uint8_t opMode )
  222. {
  223. switch( opMode )
  224. {
  225. case RFLR_OPMODE_TRANSMITTER:
  226. if( ( Radio.Read( REG_PACONFIG ) & RF_PACONFIG_PASELECT_PABOOST ) == RF_PACONFIG_PASELECT_PABOOST )
  227. {
  228. GpioWrite( &RadioSwitchCtrl1, 1 );
  229. GpioWrite( &RadioSwitchCtrl2, 0 );
  230. }
  231. else
  232. {
  233. GpioWrite( &RadioSwitchCtrl1, 0 );
  234. GpioWrite( &RadioSwitchCtrl2, 1 );
  235. }
  236. break;
  237. case RFLR_OPMODE_RECEIVER:
  238. case RFLR_OPMODE_RECEIVER_SINGLE:
  239. case RFLR_OPMODE_CAD:
  240. GpioWrite( &RadioSwitchCtrl1, 1 );
  241. GpioWrite( &RadioSwitchCtrl2, 1 );
  242. break;
  243. default:
  244. GpioWrite( &RadioSwitchCtrl1, 0 );
  245. GpioWrite( &RadioSwitchCtrl2, 0 );
  246. GpioWrite( &RadioPwrAmpCtrl, 0 );
  247. break;
  248. }
  249. }
  250. bool SX1272CheckRfFrequency( uint32_t frequency )
  251. {
  252. // Implement check. Currently all frequencies are supported
  253. return true;
  254. }
  255. uint32_t SX1272GetDio1PinState( void )
  256. {
  257. return GpioRead( &SX1272.DIO1 );
  258. }
  259. #if defined( USE_RADIO_DEBUG )
  260. void SX1272DbgPinTxWrite( uint8_t state )
  261. {
  262. GpioWrite( &DbgPinTx, state );
  263. }
  264. void SX1272DbgPinRxWrite( uint8_t state )
  265. {
  266. GpioWrite( &DbgPinRx, state );
  267. }
  268. #endif