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.
 
 
 
 
 
 

349 lines
7.8 KiB

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