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.
 
 
 
 
 
 

356 lines
8.1 KiB

  1. /*!
  2. * \file sx1262mbxdas-board.c
  3. *
  4. * \brief Target board SX1262MBXDAS shield driver implementation
  5. *
  6. * \remark This target board is only available with the SX126xDVK1xAS
  7. * development kit.
  8. *
  9. * \copyright Revised BSD License, see section \ref LICENSE.
  10. *
  11. * \code
  12. * ______ _
  13. * / _____) _ | |
  14. * ( (____ _____ ____ _| |_ _____ ____| |__
  15. * \____ \| ___ | (_ _) ___ |/ ___) _ \
  16. * _____) ) ____| | | || |_| ____( (___| | | |
  17. * (______/|_____)_|_|_| \__)_____)\____)_| |_|
  18. * (C)2013-2017 Semtech
  19. *
  20. * \endcode
  21. *
  22. * \author Miguel Luis ( Semtech )
  23. *
  24. * \author Gregory Cristian ( Semtech )
  25. */
  26. #include <stdlib.h>
  27. #include "utilities.h"
  28. #include "board-config.h"
  29. #include "board.h"
  30. #include "delay.h"
  31. #include "radio.h"
  32. #include "sx126x-board.h"
  33. #if defined( USE_RADIO_DEBUG )
  34. /*!
  35. * \brief Writes new Tx debug pin state
  36. *
  37. * \param [IN] state Debug pin state
  38. */
  39. static void SX126xDbgPinTxWrite( uint8_t state );
  40. /*!
  41. * \brief Writes new Rx debug pin state
  42. *
  43. * \param [IN] state Debug pin state
  44. */
  45. static void SX126xDbgPinRxWrite( uint8_t state );
  46. #endif
  47. /*!
  48. * \brief Holds the internal operating mode of the radio
  49. */
  50. static RadioOperatingModes_t OperatingMode;
  51. /*!
  52. * Antenna switch GPIO pins objects
  53. */
  54. Gpio_t AntPow;
  55. Gpio_t DeviceSel;
  56. /*!
  57. * Debug GPIO pins objects
  58. */
  59. #if defined( USE_RADIO_DEBUG )
  60. Gpio_t DbgPinTx;
  61. Gpio_t DbgPinRx;
  62. #endif
  63. void SX126xIoInit( void )
  64. {
  65. GpioInit( &SX126x.Spi.Nss, RADIO_NSS, PIN_OUTPUT, PIN_PUSH_PULL, PIN_NO_PULL, 1 );
  66. GpioInit( &SX126x.BUSY, RADIO_BUSY, PIN_INPUT, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
  67. GpioInit( &SX126x.DIO1, RADIO_DIO_1, PIN_INPUT, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
  68. GpioInit( &DeviceSel, RADIO_DEVICE_SEL, PIN_INPUT, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
  69. }
  70. void SX126xIoIrqInit( DioIrqHandler dioIrq )
  71. {
  72. GpioSetInterrupt( &SX126x.DIO1, IRQ_RISING_EDGE, IRQ_HIGH_PRIORITY, dioIrq );
  73. }
  74. void SX126xIoDeInit( void )
  75. {
  76. GpioInit( &SX126x.Spi.Nss, RADIO_NSS, PIN_OUTPUT, PIN_PUSH_PULL, PIN_NO_PULL, 1 );
  77. GpioInit( &SX126x.BUSY, RADIO_BUSY, PIN_INPUT, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
  78. GpioInit( &SX126x.DIO1, RADIO_DIO_1, PIN_INPUT, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
  79. }
  80. void SX126xIoDbgInit( void )
  81. {
  82. #if defined( USE_RADIO_DEBUG )
  83. GpioInit( &DbgPinTx, RADIO_DBG_PIN_TX, PIN_OUTPUT, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
  84. GpioInit( &DbgPinRx, RADIO_DBG_PIN_RX, PIN_OUTPUT, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
  85. #endif
  86. }
  87. void SX126xIoTcxoInit( void )
  88. {
  89. CalibrationParams_t calibParam;
  90. SX126xSetDio3AsTcxoCtrl( TCXO_CTRL_1_7V, SX126xGetBoardTcxoWakeupTime( ) << 6 ); // convert from ms to SX126x time base
  91. calibParam.Value = 0x7F;
  92. SX126xCalibrate( calibParam );
  93. }
  94. uint32_t SX126xGetBoardTcxoWakeupTime( void )
  95. {
  96. return BOARD_TCXO_WAKEUP_TIME;
  97. }
  98. void SX126xIoRfSwitchInit( void )
  99. {
  100. SX126xSetDio2AsRfSwitchCtrl( true );
  101. }
  102. RadioOperatingModes_t SX126xGetOperatingMode( void )
  103. {
  104. return OperatingMode;
  105. }
  106. void SX126xSetOperatingMode( RadioOperatingModes_t mode )
  107. {
  108. OperatingMode = mode;
  109. #if defined( USE_RADIO_DEBUG )
  110. switch( mode )
  111. {
  112. case MODE_TX:
  113. SX126xDbgPinTxWrite( 1 );
  114. SX126xDbgPinRxWrite( 0 );
  115. break;
  116. case MODE_RX:
  117. case MODE_RX_DC:
  118. SX126xDbgPinTxWrite( 0 );
  119. SX126xDbgPinRxWrite( 1 );
  120. break;
  121. default:
  122. SX126xDbgPinTxWrite( 0 );
  123. SX126xDbgPinRxWrite( 0 );
  124. break;
  125. }
  126. #endif
  127. }
  128. void SX126xReset( void )
  129. {
  130. DelayMs( 10 );
  131. GpioInit( &SX126x.Reset, RADIO_RESET, PIN_OUTPUT, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
  132. DelayMs( 20 );
  133. GpioInit( &SX126x.Reset, RADIO_RESET, PIN_ANALOGIC, PIN_PUSH_PULL, PIN_NO_PULL, 0 ); // internal pull-up
  134. DelayMs( 10 );
  135. }
  136. void SX126xWaitOnBusy( void )
  137. {
  138. while( GpioRead( &SX126x.BUSY ) == 1 );
  139. }
  140. void SX126xWakeup( void )
  141. {
  142. CRITICAL_SECTION_BEGIN( );
  143. GpioWrite( &SX126x.Spi.Nss, 0 );
  144. SpiInOut( &SX126x.Spi, RADIO_GET_STATUS );
  145. SpiInOut( &SX126x.Spi, 0x00 );
  146. GpioWrite( &SX126x.Spi.Nss, 1 );
  147. // Wait for chip to be ready.
  148. SX126xWaitOnBusy( );
  149. // Update operating mode context variable
  150. SX126xSetOperatingMode( MODE_STDBY_RC );
  151. CRITICAL_SECTION_END( );
  152. }
  153. void SX126xWriteCommand( RadioCommands_t command, uint8_t *buffer, uint16_t size )
  154. {
  155. SX126xCheckDeviceReady( );
  156. GpioWrite( &SX126x.Spi.Nss, 0 );
  157. SpiInOut( &SX126x.Spi, ( uint8_t )command );
  158. for( uint16_t i = 0; i < size; i++ )
  159. {
  160. SpiInOut( &SX126x.Spi, buffer[i] );
  161. }
  162. GpioWrite( &SX126x.Spi.Nss, 1 );
  163. if( command != RADIO_SET_SLEEP )
  164. {
  165. SX126xWaitOnBusy( );
  166. }
  167. }
  168. uint8_t SX126xReadCommand( RadioCommands_t command, uint8_t *buffer, uint16_t size )
  169. {
  170. uint8_t status = 0;
  171. SX126xCheckDeviceReady( );
  172. GpioWrite( &SX126x.Spi.Nss, 0 );
  173. SpiInOut( &SX126x.Spi, ( uint8_t )command );
  174. status = SpiInOut( &SX126x.Spi, 0x00 );
  175. for( uint16_t i = 0; i < size; i++ )
  176. {
  177. buffer[i] = SpiInOut( &SX126x.Spi, 0 );
  178. }
  179. GpioWrite( &SX126x.Spi.Nss, 1 );
  180. SX126xWaitOnBusy( );
  181. return status;
  182. }
  183. void SX126xWriteRegisters( uint16_t address, uint8_t *buffer, uint16_t size )
  184. {
  185. SX126xCheckDeviceReady( );
  186. GpioWrite( &SX126x.Spi.Nss, 0 );
  187. SpiInOut( &SX126x.Spi, RADIO_WRITE_REGISTER );
  188. SpiInOut( &SX126x.Spi, ( address & 0xFF00 ) >> 8 );
  189. SpiInOut( &SX126x.Spi, address & 0x00FF );
  190. for( uint16_t i = 0; i < size; i++ )
  191. {
  192. SpiInOut( &SX126x.Spi, buffer[i] );
  193. }
  194. GpioWrite( &SX126x.Spi.Nss, 1 );
  195. SX126xWaitOnBusy( );
  196. }
  197. void SX126xWriteRegister( uint16_t address, uint8_t value )
  198. {
  199. SX126xWriteRegisters( address, &value, 1 );
  200. }
  201. void SX126xReadRegisters( uint16_t address, uint8_t *buffer, uint16_t size )
  202. {
  203. SX126xCheckDeviceReady( );
  204. GpioWrite( &SX126x.Spi.Nss, 0 );
  205. SpiInOut( &SX126x.Spi, RADIO_READ_REGISTER );
  206. SpiInOut( &SX126x.Spi, ( address & 0xFF00 ) >> 8 );
  207. SpiInOut( &SX126x.Spi, address & 0x00FF );
  208. SpiInOut( &SX126x.Spi, 0 );
  209. for( uint16_t i = 0; i < size; i++ )
  210. {
  211. buffer[i] = SpiInOut( &SX126x.Spi, 0 );
  212. }
  213. GpioWrite( &SX126x.Spi.Nss, 1 );
  214. SX126xWaitOnBusy( );
  215. }
  216. uint8_t SX126xReadRegister( uint16_t address )
  217. {
  218. uint8_t data;
  219. SX126xReadRegisters( address, &data, 1 );
  220. return data;
  221. }
  222. void SX126xWriteBuffer( uint8_t offset, uint8_t *buffer, uint8_t size )
  223. {
  224. SX126xCheckDeviceReady( );
  225. GpioWrite( &SX126x.Spi.Nss, 0 );
  226. SpiInOut( &SX126x.Spi, RADIO_WRITE_BUFFER );
  227. SpiInOut( &SX126x.Spi, offset );
  228. for( uint16_t i = 0; i < size; i++ )
  229. {
  230. SpiInOut( &SX126x.Spi, buffer[i] );
  231. }
  232. GpioWrite( &SX126x.Spi.Nss, 1 );
  233. SX126xWaitOnBusy( );
  234. }
  235. void SX126xReadBuffer( uint8_t offset, uint8_t *buffer, uint8_t size )
  236. {
  237. SX126xCheckDeviceReady( );
  238. GpioWrite( &SX126x.Spi.Nss, 0 );
  239. SpiInOut( &SX126x.Spi, RADIO_READ_BUFFER );
  240. SpiInOut( &SX126x.Spi, offset );
  241. SpiInOut( &SX126x.Spi, 0 );
  242. for( uint16_t i = 0; i < size; i++ )
  243. {
  244. buffer[i] = SpiInOut( &SX126x.Spi, 0 );
  245. }
  246. GpioWrite( &SX126x.Spi.Nss, 1 );
  247. SX126xWaitOnBusy( );
  248. }
  249. void SX126xSetRfTxPower( int8_t power )
  250. {
  251. SX126xSetTxParams( power, RADIO_RAMP_40_US );
  252. }
  253. uint8_t SX126xGetDeviceId( void )
  254. {
  255. if( GpioRead( &DeviceSel ) == 1 )
  256. {
  257. return SX1261;
  258. }
  259. else
  260. {
  261. return SX1262;
  262. }
  263. }
  264. void SX126xAntSwOn( void )
  265. {
  266. GpioInit( &AntPow, RADIO_ANT_SWITCH_POWER, PIN_OUTPUT, PIN_PUSH_PULL, PIN_PULL_UP, 1 );
  267. }
  268. void SX126xAntSwOff( void )
  269. {
  270. GpioInit( &AntPow, RADIO_ANT_SWITCH_POWER, PIN_ANALOGIC, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
  271. }
  272. bool SX126xCheckRfFrequency( uint32_t frequency )
  273. {
  274. // Implement check. Currently all frequencies are supported
  275. return true;
  276. }
  277. uint32_t SX126xGetDio1PinState( void )
  278. {
  279. return GpioRead( &SX126x.DIO1 );
  280. }
  281. #if defined( USE_RADIO_DEBUG )
  282. static void SX126xDbgPinTxWrite( uint8_t state )
  283. {
  284. GpioWrite( &DbgPinTx, state );
  285. }
  286. static void SX126xDbgPinRxWrite( uint8_t state )
  287. {
  288. GpioWrite( &DbgPinRx, state );
  289. }
  290. #endif