sx1276-Fsk.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611
  1. /*
  2. * THE FOLLOWING FIRMWARE IS PROVIDED: (1) "AS IS" WITH NO WARRANTY; AND
  3. * (2)TO ENABLE ACCESS TO CODING INFORMATION TO GUIDE AND FACILITATE CUSTOMER.
  4. * CONSEQUENTLY, SEMTECH SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR
  5. * CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
  6. * OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION
  7. * CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
  8. *
  9. * Copyright (C) SEMTECH S.A.
  10. */
  11. /*!
  12. * \file sx1276.c
  13. * \brief SX1276 RF chip driver
  14. *
  15. * \version 2.0.0
  16. * \date May 6 2013
  17. * \author Gregory Cristian
  18. *
  19. * Last modified by Miguel Luis on Jun 19 2013
  20. */
  21. #include <string.h>
  22. #include <stdint.h>
  23. #include <math.h>
  24. #include "platform.h"
  25. #if defined( USE_SX1276_RADIO )
  26. #include "radio.h"
  27. #include "sx1276-Hal.h"
  28. #include "sx1276.h"
  29. #include "sx1276-FskMisc.h"
  30. #include "sx1276-Fsk.h"
  31. // Default settings
  32. tFskSettings FskSettings =
  33. {
  34. 434000000, // RFFrequency
  35. 1200, // Bitrate
  36. 50000, // Fdev 50000
  37. 20, // Power
  38. 100000, // RxBw
  39. 150000, // RxBwAfc
  40. true, // CrcOn
  41. true, // AfcOn
  42. 255 // PayloadLength (set payload size to the maximum for variable mode, else set the exact payload length)
  43. };
  44. /*!
  45. * SX1276 FSK registers variable
  46. */
  47. tSX1276* SX1276;
  48. /*!
  49. * Local RF buffer for communication support
  50. */
  51. static uint8_t RFBuffer[RF_BUFFER_SIZE];
  52. /*!
  53. * Chunk size of data write in buffer
  54. */
  55. static uint8_t DataChunkSize = 32;
  56. /*!
  57. * RF state machine variable
  58. */
  59. static uint8_t RFState = RF_STATE_IDLE;
  60. /*!
  61. * Rx management support variables
  62. */
  63. /*!
  64. * PacketTimeout holds the RF packet timeout
  65. * SyncSize = [0..8]
  66. * VariableSize = [0;1]
  67. * AddressSize = [0;1]
  68. * PayloadSize = [0..RF_BUFFER_SIZE]
  69. * CrcSize = [0;2]
  70. * PacketTimeout = ( ( 8 * ( VariableSize + AddressSize + PayloadSize + CrcSize ) / BR ) * 1000.0 ) + 1
  71. * Computed timeout is in miliseconds
  72. */
  73. static uint32_t PacketTimeout;
  74. /*!
  75. * Preamble2SyncTimeout
  76. * Preamble2SyncTimeout = ( ( 8 * ( PremableSize + SyncSize ) / RFBitrate ) * 1000.0 ) + 1
  77. * Computed timeout is in miliseconds
  78. */
  79. static uint32_t Preamble2SyncTimeout;
  80. static bool PreambleDetected = false;
  81. static bool SyncWordDetected = false;
  82. static bool PacketDetected = false;
  83. static uint16_t RxPacketSize = 0;
  84. static uint8_t RxBytesRead = 0;
  85. static uint8_t TxBytesSent = 0;
  86. static double RxPacketRssiValue;
  87. static uint32_t RxPacketAfcValue;
  88. static uint8_t RxGain = 1;
  89. static uint32_t RxTimeoutTimer = 0;
  90. static uint32_t Preamble2SyncTimer = 0;
  91. /*!
  92. * Tx management support variables
  93. */
  94. static uint16_t TxPacketSize = 0;
  95. static uint32_t TxTimeoutTimer = 0;
  96. void SX1276FskInit( void )
  97. {
  98. RFState = RF_STATE_IDLE;
  99. SX1276FskSetDefaults( );
  100. SX1276ReadBuffer( REG_OPMODE, SX1276Regs + 1, 0x70 - 1 );
  101. // Set the device in FSK mode and Sleep Mode
  102. SX1276->RegOpMode = RF_OPMODE_MODULATIONTYPE_FSK | RF_OPMODE_SLEEP;
  103. SX1276Write( REG_OPMODE, SX1276->RegOpMode );
  104. SX1276->RegPaRamp = RF_PARAMP_MODULATIONSHAPING_01;
  105. SX1276Write( REG_PARAMP, SX1276->RegPaRamp );
  106. SX1276->RegLna = RF_LNA_GAIN_G1;
  107. SX1276Write( REG_LNA, SX1276->RegLna );
  108. // SX1276->RegTcxo = RF_TCXO_TCXOINPUT_ON;
  109. if( FskSettings.AfcOn == true )
  110. {
  111. SX1276->RegRxConfig = RF_RXCONFIG_RESTARTRXONCOLLISION_OFF | RF_RXCONFIG_AFCAUTO_ON |
  112. RF_RXCONFIG_AGCAUTO_ON | RF_RXCONFIG_RXTRIGER_PREAMBLEDETECT;
  113. }
  114. else
  115. {
  116. SX1276->RegRxConfig = RF_RXCONFIG_RESTARTRXONCOLLISION_OFF | RF_RXCONFIG_AFCAUTO_OFF |
  117. RF_RXCONFIG_AGCAUTO_ON | RF_RXCONFIG_RXTRIGER_PREAMBLEDETECT;
  118. }
  119. SX1276->RegPreambleLsb = 8;
  120. SX1276->RegPreambleDetect = RF_PREAMBLEDETECT_DETECTOR_ON | RF_PREAMBLEDETECT_DETECTORSIZE_2 |
  121. RF_PREAMBLEDETECT_DETECTORTOL_10;
  122. SX1276->RegRssiThresh = 0xFF;
  123. SX1276->RegSyncConfig = RF_SYNCCONFIG_AUTORESTARTRXMODE_WAITPLL_ON | RF_SYNCCONFIG_PREAMBLEPOLARITY_AA |
  124. RF_SYNCCONFIG_SYNC_ON |
  125. RF_SYNCCONFIG_SYNCSIZE_4;
  126. SX1276->RegSyncValue1 = 0x69;
  127. SX1276->RegSyncValue2 = 0x81;
  128. SX1276->RegSyncValue3 = 0x7E;
  129. SX1276->RegSyncValue4 = 0x96;
  130. SX1276->RegPacketConfig1 = RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE | RF_PACKETCONFIG1_DCFREE_OFF |
  131. ( FskSettings.CrcOn << 4 ) | RF_PACKETCONFIG1_CRCAUTOCLEAR_ON |
  132. RF_PACKETCONFIG1_ADDRSFILTERING_OFF | RF_PACKETCONFIG1_CRCWHITENINGTYPE_CCITT;
  133. SX1276FskGetPacketCrcOn( ); // Update CrcOn on FskSettings
  134. SX1276->RegPayloadLength = FskSettings.PayloadLength;
  135. // we can now update the registers with our configuration
  136. SX1276WriteBuffer( REG_OPMODE, SX1276Regs + 1, 0x70 - 1 );
  137. // then we need to set the RF settings
  138. SX1276FskSetRFFrequency( FskSettings.RFFrequency );
  139. SX1276FskSetBitrate( FskSettings.Bitrate );
  140. SX1276FskSetFdev( FskSettings.Fdev );
  141. SX1276FskSetDccBw( &SX1276->RegRxBw, 0, FskSettings.RxBw );
  142. SX1276FskSetDccBw( &SX1276->RegAfcBw, 0, FskSettings.RxBwAfc );
  143. SX1276FskSetRssiOffset( 0 );
  144. #if( ( MODULE_SX1276RF1IAS == 1 ) || ( MODULE_SX1276RF1KAS == 1 ) )
  145. if( FskSettings.RFFrequency > 860000000 )
  146. {
  147. SX1276FskSetPAOutput( RF_PACONFIG_PASELECT_RFO );
  148. SX1276FskSetPa20dBm( true );
  149. // FskSettings.Power = 14;
  150. SX1276FskSetRFPower( FskSettings.Power );
  151. }
  152. else
  153. {
  154. SX1276FskSetPAOutput( RF_PACONFIG_PASELECT_PABOOST );
  155. SX1276FskSetPa20dBm( true );
  156. // FskSettings.Power = 20;
  157. SX1276FskSetRFPower( FskSettings.Power );
  158. }
  159. #elif( MODULE_SX1276RF1JAS == 1 )
  160. if( FskSettings.RFFrequency > 860000000 )
  161. {
  162. SX1276FskSetPAOutput( RF_PACONFIG_PASELECT_PABOOST );
  163. SX1276FskSetPa20dBm( true );
  164. // FskSettings.Power = 20;
  165. SX1276FskSetRFPower( FskSettings.Power );
  166. }
  167. else
  168. {
  169. // SX1276FskSetPAOutput( RF_PACONFIG_PASELECT_RFO );
  170. // SX1276FskSetPa20dBm( true );
  171. //// FskSettings.Power = 14;
  172. // SX1276FskSetRFPower( FskSettings.Power );
  173. SX1276FskSetPAOutput( RF_PACONFIG_PASELECT_PABOOST );
  174. SX1276FskSetPa20dBm( true );
  175. // FskSettings.Power = 20;
  176. SX1276FskSetRFPower( FskSettings.Power );
  177. }
  178. #endif
  179. SX1276FskSetOpMode( RF_OPMODE_STANDBY );
  180. // Calibrate the HF
  181. SX1276FskRxCalibrate( );
  182. }
  183. void SX1276FskSetDefaults( void )
  184. {
  185. // REMARK: See SX1276 datasheet for modified default values.
  186. SX1276Read( REG_VERSION, &SX1276->RegVersion );
  187. }
  188. void SX1276FskSetOpMode( uint8_t opMode )
  189. {
  190. static uint8_t opModePrev = RF_OPMODE_STANDBY;
  191. static bool antennaSwitchTxOnPrev = true;
  192. bool antennaSwitchTxOn = false;
  193. opModePrev = SX1276->RegOpMode & ~RF_OPMODE_MASK;
  194. if( opMode != opModePrev )
  195. {
  196. if( opMode == RF_OPMODE_TRANSMITTER )
  197. {
  198. antennaSwitchTxOn = true;
  199. }
  200. else
  201. {
  202. antennaSwitchTxOn = false;
  203. }
  204. if( antennaSwitchTxOn != antennaSwitchTxOnPrev )
  205. {
  206. antennaSwitchTxOnPrev = antennaSwitchTxOn;
  207. RXTX( antennaSwitchTxOn ); // Antenna switch control
  208. }
  209. SX1276->RegOpMode = ( SX1276->RegOpMode & RF_OPMODE_MASK ) | opMode;
  210. SX1276Write( REG_OPMODE, SX1276->RegOpMode );
  211. }
  212. }
  213. uint8_t SX1276FskGetOpMode( void )
  214. {
  215. SX1276Read( REG_OPMODE, &SX1276->RegOpMode );
  216. return SX1276->RegOpMode & ~RF_OPMODE_MASK;
  217. }
  218. int32_t SX1276FskReadFei( void )
  219. {
  220. SX1276ReadBuffer( REG_FEIMSB, &SX1276->RegFeiMsb, 2 ); // Reads the FEI value
  221. return ( int32_t )(( double )( ( ( uint16_t )SX1276->RegFeiMsb << 8 ) | ( uint16_t )SX1276->RegFeiLsb ) * ( double )FREQ_STEP);
  222. }
  223. int32_t SX1276FskReadAfc( void )
  224. {
  225. SX1276ReadBuffer( REG_AFCMSB, &SX1276->RegAfcMsb, 2 ); // Reads the AFC value
  226. return ( int32_t )(( double )( ( ( uint16_t )SX1276->RegAfcMsb << 8 ) | ( uint16_t )SX1276->RegAfcLsb ) * ( double )FREQ_STEP);
  227. }
  228. uint8_t SX1276FskReadRxGain( void )
  229. {
  230. SX1276Read( REG_LNA, &SX1276->RegLna );
  231. return( SX1276->RegLna >> 5 ) & 0x07;
  232. }
  233. double SX1276FskReadRssi( void )
  234. {
  235. SX1276Read( REG_RSSIVALUE, &SX1276->RegRssiValue ); // Reads the RSSI value
  236. return -( double )( ( double )SX1276->RegRssiValue / 2.0 );
  237. }
  238. uint8_t SX1276FskGetPacketRxGain( void )
  239. {
  240. return RxGain;
  241. }
  242. double SX1276FskGetPacketRssi( void )
  243. {
  244. return RxPacketRssiValue;
  245. }
  246. uint32_t SX1276FskGetPacketAfc( void )
  247. {
  248. return RxPacketAfcValue;
  249. }
  250. void SX1276FskStartRx( void )
  251. {
  252. SX1276FskSetRFState( RF_STATE_RX_INIT );
  253. }
  254. void SX1276FskGetRxPacket( void *buffer, uint16_t *size )
  255. {
  256. *size = RxPacketSize;
  257. RxPacketSize = 0;
  258. memcpy( ( void * )buffer, ( void * )RFBuffer, ( size_t )*size );
  259. }
  260. void SX1276FskSetTxPacket( const void *buffer, uint16_t size )
  261. {
  262. TxPacketSize = size;
  263. memcpy( ( void * )RFBuffer, buffer, ( size_t )TxPacketSize );
  264. RFState = RF_STATE_TX_INIT;
  265. }
  266. // Remark: SX1276 must be fully initialized before calling this function
  267. uint16_t SX1276FskGetPacketPayloadSize( void )
  268. {
  269. uint16_t syncSize;
  270. uint16_t variableSize;
  271. uint16_t addressSize;
  272. uint16_t payloadSize;
  273. uint16_t crcSize;
  274. syncSize = ( SX1276->RegSyncConfig & 0x07 ) + 1;
  275. variableSize = ( ( SX1276->RegPacketConfig1 & 0x80 ) == 0x80 ) ? 1 : 0;
  276. addressSize = ( ( SX1276->RegPacketConfig1 & 0x06 ) != 0x00 ) ? 1 : 0;
  277. payloadSize = SX1276->RegPayloadLength;
  278. crcSize = ( ( SX1276->RegPacketConfig1 & 0x10 ) == 0x10 ) ? 2 : 0;
  279. return syncSize + variableSize + addressSize + payloadSize + crcSize;
  280. }
  281. // Remark: SX1276 must be fully initialized before calling this function
  282. uint16_t SX1276FskGetPacketHeaderSize( void )
  283. {
  284. uint16_t preambleSize;
  285. uint16_t syncSize;
  286. preambleSize = ( ( uint16_t )SX1276->RegPreambleMsb << 8 ) | ( uint16_t )SX1276->RegPreambleLsb;
  287. syncSize = ( SX1276->RegSyncConfig & 0x07 ) + 1;
  288. return preambleSize + syncSize;
  289. }
  290. uint8_t SX1276FskGetRFState( void )
  291. {
  292. return RFState;
  293. }
  294. void SX1276FskSetRFState( uint8_t state )
  295. {
  296. RFState = state;
  297. }
  298. uint32_t SX1276FskProcess( void )
  299. {
  300. uint32_t result = RF_BUSY;
  301. switch( RFState )
  302. {
  303. case RF_STATE_IDLE:
  304. break;
  305. // Rx management
  306. case RF_STATE_RX_INIT:
  307. // DIO mapping setup
  308. if( ( SX1276->RegPacketConfig1 & RF_PACKETCONFIG1_CRC_ON ) == RF_PACKETCONFIG1_CRC_ON )
  309. {
  310. // CrcOk, FifoLevel, SyncAddr, FifoEmpty
  311. SX1276->RegDioMapping1 = RF_DIOMAPPING1_DIO0_01 | RF_DIOMAPPING1_DIO1_00 | RF_DIOMAPPING1_DIO2_11 | RF_DIOMAPPING1_DIO3_00;
  312. }
  313. else
  314. {
  315. // PayloadReady, FifoLevel, SyncAddr, FifoEmpty
  316. SX1276->RegDioMapping1 = RF_DIOMAPPING1_DIO0_00 | RF_DIOMAPPING1_DIO1_00 | RF_DIOMAPPING1_DIO2_11 | RF_DIOMAPPING1_DIO3_00;
  317. }
  318. // Preamble, Data
  319. SX1276->RegDioMapping2 = RF_DIOMAPPING2_DIO4_11 | RF_DIOMAPPING2_DIO5_10 | RF_DIOMAPPING2_MAP_PREAMBLEDETECT;
  320. SX1276WriteBuffer( REG_DIOMAPPING1, &SX1276->RegDioMapping1, 2 );
  321. SX1276FskSetOpMode( RF_OPMODE_RECEIVER );
  322. memset( RFBuffer, 0, ( size_t )RF_BUFFER_SIZE );
  323. PacketTimeout = ( uint16_t )( round( ( 8.0 * ( ( double )SX1276FskGetPacketPayloadSize( ) ) / ( double )FskSettings.Bitrate ) * 1000.0 ) + 1.0 );
  324. PacketTimeout = PacketTimeout + ( PacketTimeout >> 1 ); // Set the Packet timeout as 1.5 times the full payload transmission time
  325. Preamble2SyncTimeout = PacketTimeout;
  326. Preamble2SyncTimer = RxTimeoutTimer = GET_TICK_COUNT( );
  327. SX1276->RegFifoThresh = RF_FIFOTHRESH_TXSTARTCONDITION_FIFONOTEMPTY | 0x20; // 32 bytes of data
  328. SX1276Write( REG_FIFOTHRESH, SX1276->RegFifoThresh );
  329. PreambleDetected = false;
  330. SyncWordDetected = false;
  331. PacketDetected = false;
  332. RxBytesRead = 0;
  333. RxPacketSize = 0;
  334. RFState = RF_STATE_RX_SYNC;
  335. break;
  336. case RF_STATE_RX_SYNC:
  337. if( ( DIO4 == 1 ) && ( PreambleDetected == false ) )// Preamble
  338. {
  339. PreambleDetected = true;
  340. Preamble2SyncTimer = GET_TICK_COUNT( );
  341. }
  342. if( ( DIO2 == 1 ) && ( PreambleDetected == true ) && ( SyncWordDetected == false ) ) // SyncAddr
  343. {
  344. SyncWordDetected = true;
  345. RxPacketRssiValue = SX1276FskReadRssi( );
  346. RxPacketAfcValue = SX1276FskReadAfc( );
  347. RxGain = SX1276FskReadRxGain( );
  348. Preamble2SyncTimer = RxTimeoutTimer = GET_TICK_COUNT( );
  349. RFState = RF_STATE_RX_RUNNING;
  350. }
  351. // Preamble 2 SyncAddr timeout
  352. if( ( SyncWordDetected == false ) && ( PreambleDetected == true ) && ( ( GET_TICK_COUNT( ) - Preamble2SyncTimer ) > Preamble2SyncTimeout ) )
  353. {
  354. RFState = RF_STATE_RX_INIT;
  355. SX1276Write( REG_RXCONFIG, SX1276->RegRxConfig | RF_RXCONFIG_RESTARTRXWITHPLLLOCK );
  356. }
  357. if( ( SyncWordDetected == false ) &&
  358. ( PreambleDetected == false ) &&
  359. ( PacketDetected == false ) &&
  360. ( ( GET_TICK_COUNT( ) - RxTimeoutTimer ) > PacketTimeout ) )
  361. {
  362. RFState = RF_STATE_RX_TIMEOUT;
  363. }
  364. break;
  365. case RF_STATE_RX_RUNNING:
  366. if( RxPacketSize > RF_BUFFER_SIZE_MAX )
  367. {
  368. RFState = RF_STATE_RX_LEN_ERROR;
  369. break;
  370. }
  371. #if 1
  372. if( DIO1 == 1 ) // FifoLevel
  373. {
  374. if( ( RxPacketSize == 0 ) && ( RxBytesRead == 0 ) ) // Read received packet size
  375. {
  376. if( ( SX1276->RegPacketConfig1 & RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE ) == RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE )
  377. {
  378. SX1276ReadFifo( ( uint8_t* )&RxPacketSize, 1 );
  379. }
  380. else
  381. {
  382. RxPacketSize = SX1276->RegPayloadLength;
  383. }
  384. }
  385. if( ( RxPacketSize - RxBytesRead ) > ( SX1276->RegFifoThresh & 0x3F ) )
  386. {
  387. SX1276ReadFifo( ( RFBuffer + RxBytesRead ), ( SX1276->RegFifoThresh & 0x3F ) );
  388. RxBytesRead += ( SX1276->RegFifoThresh & 0x3F );
  389. }
  390. else
  391. {
  392. SX1276ReadFifo( ( RFBuffer + RxBytesRead ), RxPacketSize - RxBytesRead );
  393. RxBytesRead += ( RxPacketSize - RxBytesRead );
  394. }
  395. }
  396. #endif
  397. if( DIO0 == 1 ) // PayloadReady/CrcOk
  398. {
  399. RxTimeoutTimer = GET_TICK_COUNT( );
  400. if( ( RxPacketSize == 0 ) && ( RxBytesRead == 0 ) ) // Read received packet size
  401. {
  402. if( ( SX1276->RegPacketConfig1 & RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE ) == RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE )
  403. {
  404. SX1276ReadFifo( ( uint8_t* )&RxPacketSize, 1 );
  405. }
  406. else
  407. {
  408. RxPacketSize = SX1276->RegPayloadLength;
  409. }
  410. SX1276ReadFifo( RFBuffer + RxBytesRead, RxPacketSize - RxBytesRead );
  411. RxBytesRead += ( RxPacketSize - RxBytesRead );
  412. PacketDetected = true;
  413. RFState = RF_STATE_RX_DONE;
  414. }
  415. else
  416. {
  417. SX1276ReadFifo( RFBuffer + RxBytesRead, RxPacketSize - RxBytesRead );
  418. RxBytesRead += ( RxPacketSize - RxBytesRead );
  419. PacketDetected = true;
  420. RFState = RF_STATE_RX_DONE;
  421. }
  422. }
  423. // Packet timeout
  424. if( ( PacketDetected == false ) && ( ( GET_TICK_COUNT( ) - RxTimeoutTimer ) > PacketTimeout ) )
  425. {
  426. RFState = RF_STATE_RX_TIMEOUT;
  427. }
  428. break;
  429. case RF_STATE_RX_DONE:
  430. RxBytesRead = 0;
  431. RFState = RF_STATE_RX_INIT;
  432. result = RF_RX_DONE;
  433. break;
  434. case RF_STATE_RX_TIMEOUT:
  435. RxBytesRead = 0;
  436. RxPacketSize = 0;
  437. SX1276Write( REG_RXCONFIG, SX1276->RegRxConfig | RF_RXCONFIG_RESTARTRXWITHPLLLOCK );
  438. RFState = RF_STATE_RX_INIT;
  439. result = RF_RX_TIMEOUT;
  440. break;
  441. case RF_STATE_RX_LEN_ERROR:
  442. RxBytesRead = 0;
  443. RxPacketSize = 0;
  444. SX1276Write( REG_RXCONFIG, SX1276->RegRxConfig | RF_RXCONFIG_RESTARTRXWITHPLLLOCK );
  445. RFState = RF_STATE_RX_INIT;
  446. result = RF_LEN_ERROR;
  447. break;
  448. // Tx management
  449. case RF_STATE_TX_INIT:
  450. // Packet DIO mapping setup
  451. // PacketSent, FifoLevel, FifoFull, TxReady
  452. SX1276->RegDioMapping1 = RF_DIOMAPPING1_DIO0_00 | RF_DIOMAPPING1_DIO1_00 | RF_DIOMAPPING1_DIO2_00 | RF_DIOMAPPING1_DIO3_01;
  453. // LowBat, Data
  454. SX1276->RegDioMapping2 = RF_DIOMAPPING2_DIO4_00 | RF_DIOMAPPING2_DIO5_10;
  455. SX1276WriteBuffer( REG_DIOMAPPING1, &SX1276->RegDioMapping1, 2 );
  456. SX1276->RegFifoThresh = RF_FIFOTHRESH_TXSTARTCONDITION_FIFONOTEMPTY | 0x18; // 24 bytes of data
  457. SX1276Write( REG_FIFOTHRESH, SX1276->RegFifoThresh );
  458. SX1276FskSetOpMode( RF_OPMODE_TRANSMITTER );
  459. RFState = RF_STATE_TX_READY_WAIT;
  460. TxBytesSent = 0;
  461. break;
  462. case RF_STATE_TX_READY_WAIT:
  463. if( DIO3 == 1 ) // TxReady
  464. {
  465. if( ( SX1276->RegPacketConfig1 & RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE ) == RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE )
  466. {
  467. SX1276WriteFifo( ( uint8_t* )&TxPacketSize, 1 );
  468. }
  469. if( ( TxPacketSize > 0 ) && ( TxPacketSize <= 64 ) )
  470. {
  471. DataChunkSize = TxPacketSize;
  472. }
  473. else
  474. {
  475. DataChunkSize = 32;
  476. }
  477. SX1276WriteFifo( RFBuffer, DataChunkSize );
  478. TxBytesSent += DataChunkSize;
  479. TxTimeoutTimer = GET_TICK_COUNT( );
  480. RFState = RF_STATE_TX_RUNNING;
  481. }
  482. break;
  483. case RF_STATE_TX_RUNNING:
  484. if( DIO1 == 0 ) // FifoLevel below thresold
  485. {
  486. if( ( TxPacketSize - TxBytesSent ) > DataChunkSize )
  487. {
  488. SX1276WriteFifo( ( RFBuffer + TxBytesSent ), DataChunkSize );
  489. TxBytesSent += DataChunkSize;
  490. }
  491. else
  492. {
  493. // we write the last chunk of data
  494. SX1276WriteFifo( RFBuffer + TxBytesSent, TxPacketSize - TxBytesSent );
  495. TxBytesSent += TxPacketSize - TxBytesSent;
  496. }
  497. }
  498. if( DIO0 == 1 ) // PacketSent
  499. {
  500. TxTimeoutTimer = GET_TICK_COUNT( );
  501. RFState = RF_STATE_TX_DONE;
  502. SX1276FskSetOpMode( RF_OPMODE_STANDBY );
  503. }
  504. // Packet timeout
  505. if( ( GET_TICK_COUNT( ) - TxTimeoutTimer ) > TICK_RATE_MS( 1000 ) )
  506. {
  507. RFState = RF_STATE_TX_TIMEOUT;
  508. }
  509. break;
  510. case RF_STATE_TX_DONE:
  511. RFState = RF_STATE_IDLE;
  512. result = RF_TX_DONE;
  513. break;
  514. case RF_STATE_TX_TIMEOUT:
  515. RFState = RF_STATE_IDLE;
  516. result = RF_TX_TIMEOUT;
  517. break;
  518. default:
  519. break;
  520. }
  521. return result;
  522. }
  523. #endif // USE_SX1276_RADIO