SX1261 and sx1262 common library

Dependents:   SX126xDevKit SX1262PingPong SX126X_TXonly SX126X_PingPong_Demo ... more

Fork of SX126xLib by Gregory Cristian

Committer:
GregCr
Date:
Mon Sep 04 15:16:44 2017 +0000
Revision:
4:c6ef863d0b07
Parent:
3:7e3595a9ebe0
Child:
5:e488e6f185f3
Candidate release

Who changed what in which revision?

UserRevisionLine numberNew contents of line
GregCr 0:deaafdfde3bb 1 /*
GregCr 4:c6ef863d0b07 2 ______ _
GregCr 0:deaafdfde3bb 3 / _____) _ | |
GregCr 0:deaafdfde3bb 4 ( (____ _____ ____ _| |_ _____ ____| |__
GregCr 0:deaafdfde3bb 5 \____ \| ___ | (_ _) ___ |/ ___) _ \
GregCr 0:deaafdfde3bb 6 _____) ) ____| | | || |_| ____( (___| | | |
GregCr 0:deaafdfde3bb 7 (______/|_____)_|_|_| \__)_____)\____)_| |_|
GregCr 4:c6ef863d0b07 8 (C)2017 Semtech
GregCr 0:deaafdfde3bb 9
GregCr 4:c6ef863d0b07 10 Description: Generic SX126x driver implementation
GregCr 0:deaafdfde3bb 11
GregCr 0:deaafdfde3bb 12 License: Revised BSD License, see LICENSE.TXT file include in the project
GregCr 0:deaafdfde3bb 13
GregCr 4:c6ef863d0b07 14 Authors: Miguel Luis, Gregory Cristian
GregCr 0:deaafdfde3bb 15 */
GregCr 0:deaafdfde3bb 16 #include "mbed.h"
GregCr 1:35d34672a089 17 #include "sx126x.h"
GregCr 1:35d34672a089 18 #include "sx126x-hal.h"
GregCr 0:deaafdfde3bb 19
GregCr 0:deaafdfde3bb 20 /*!
GregCr 4:c6ef863d0b07 21 * \brief Radio registers definition
GregCr 0:deaafdfde3bb 22 */
GregCr 0:deaafdfde3bb 23 typedef struct
GregCr 0:deaafdfde3bb 24 {
GregCr 0:deaafdfde3bb 25 uint16_t Addr; //!< The address of the register
GregCr 0:deaafdfde3bb 26 uint8_t Value; //!< The value of the register
GregCr 0:deaafdfde3bb 27 }RadioRegisters_t;
GregCr 0:deaafdfde3bb 28
GregCr 0:deaafdfde3bb 29 /*!
GregCr 4:c6ef863d0b07 30 * \brief Stores the last frequency error measured on LoRa received packet
GregCr 0:deaafdfde3bb 31 */
GregCr 4:c6ef863d0b07 32 volatile uint32_t FrequencyError = 0;
GregCr 0:deaafdfde3bb 33
GregCr 2:4ff11ea92fbe 34 void SX126x::Init( void )
GregCr 0:deaafdfde3bb 35 {
GregCr 4:c6ef863d0b07 36 /*!
GregCr 4:c6ef863d0b07 37 * \brief pin OPT is used to detect if the board has a TCXO or a XTAL
GregCr 4:c6ef863d0b07 38 *
GregCr 4:c6ef863d0b07 39 * OPT = 0 >> TCXO; OPT = 1 >> XTAL
GregCr 4:c6ef863d0b07 40 */
GregCr 4:c6ef863d0b07 41 DigitalIn OPT( A3 );
GregCr 4:c6ef863d0b07 42
GregCr 0:deaafdfde3bb 43 Reset( );
GregCr 4:c6ef863d0b07 44
GregCr 0:deaafdfde3bb 45 IoIrqInit( dioIrq );
GregCr 4:c6ef863d0b07 46
GregCr 0:deaafdfde3bb 47 Wakeup( );
GregCr 3:7e3595a9ebe0 48 SetStandby( STDBY_RC );
GregCr 4:c6ef863d0b07 49
GregCr 4:c6ef863d0b07 50 if( OPT == 0 )
GregCr 3:7e3595a9ebe0 51 {
GregCr 4:c6ef863d0b07 52 SetDio3AsTcxoCtrl( TCXO_CTRL_1_7V, 6400 ); //100 ms
GregCr 4:c6ef863d0b07 53 WriteReg( REG_XTA_TRIM, 0x2F );
GregCr 3:7e3595a9ebe0 54 }
GregCr 4:c6ef863d0b07 55
GregCr 4:c6ef863d0b07 56 SetPollingMode( );
GregCr 4:c6ef863d0b07 57
GregCr 4:c6ef863d0b07 58 AntSwOn( );
GregCr 4:c6ef863d0b07 59 SetDio2AsRfSwitchCtrl( true );
GregCr 4:c6ef863d0b07 60
GregCr 4:c6ef863d0b07 61 SetPacketType( PACKET_TYPE_LORA );
GregCr 0:deaafdfde3bb 62
GregCr 4:c6ef863d0b07 63 #ifdef USE_CONFIG_PUBLIC_NETOWRK
GregCr 4:c6ef863d0b07 64 // Change LoRa modem Sync Word for Public Networks
GregCr 4:c6ef863d0b07 65 WriteReg( REG_LR_SYNCWORD, ( LORA_MAC_PUBLIC_SYNCWORD >> 8 ) & 0xFF );
GregCr 4:c6ef863d0b07 66 WriteReg( REG_LR_SYNCWORD + 1, LORA_MAC_PUBLIC_SYNCWORD & 0xFF );
GregCr 4:c6ef863d0b07 67 #else
GregCr 4:c6ef863d0b07 68 // Change LoRa modem SyncWord for Private Networks
GregCr 4:c6ef863d0b07 69 WriteReg( REG_LR_SYNCWORD, ( LORA_MAC_PRIVATE_SYNCWORD >> 8 ) & 0xFF );
GregCr 4:c6ef863d0b07 70 WriteReg( REG_LR_SYNCWORD + 1, LORA_MAC_PRIVATE_SYNCWORD & 0xFF );
GregCr 4:c6ef863d0b07 71 #endif
GregCr 0:deaafdfde3bb 72 }
GregCr 0:deaafdfde3bb 73
GregCr 4:c6ef863d0b07 74 RadioOperatingModes_t SX126x::GetOperatingMode( void )
GregCr 0:deaafdfde3bb 75 {
GregCr 4:c6ef863d0b07 76 return OperatingMode;
GregCr 0:deaafdfde3bb 77 }
GregCr 0:deaafdfde3bb 78
GregCr 4:c6ef863d0b07 79 void SX126x::CheckDeviceReady( void )
GregCr 0:deaafdfde3bb 80 {
GregCr 4:c6ef863d0b07 81 if( ( GetOperatingMode( ) == MODE_SLEEP ) || ( GetOperatingMode( ) == MODE_RX_DC ) )
GregCr 0:deaafdfde3bb 82 {
GregCr 4:c6ef863d0b07 83 Wakeup( );
GregCr 4:c6ef863d0b07 84 // Switch is turned off when device is in sleep mode and turned on is all other modes
GregCr 4:c6ef863d0b07 85 AntSwOn( );
GregCr 0:deaafdfde3bb 86 }
GregCr 0:deaafdfde3bb 87 }
GregCr 0:deaafdfde3bb 88
GregCr 4:c6ef863d0b07 89 void SX126x::SetPayload( uint8_t *payload, uint8_t size )
GregCr 0:deaafdfde3bb 90 {
GregCr 4:c6ef863d0b07 91 WriteBuffer( 0x00, payload, size );
GregCr 0:deaafdfde3bb 92 }
GregCr 0:deaafdfde3bb 93
GregCr 2:4ff11ea92fbe 94 uint8_t SX126x::GetPayload( uint8_t *buffer, uint8_t *size, uint8_t maxSize )
GregCr 0:deaafdfde3bb 95 {
GregCr 4:c6ef863d0b07 96 uint8_t offset = 0;
GregCr 0:deaafdfde3bb 97
GregCr 0:deaafdfde3bb 98 GetRxBufferStatus( size, &offset );
GregCr 4:c6ef863d0b07 99 if( *size > maxSize )
GregCr 0:deaafdfde3bb 100 {
GregCr 0:deaafdfde3bb 101 return 1;
GregCr 0:deaafdfde3bb 102 }
GregCr 0:deaafdfde3bb 103 ReadBuffer( offset, buffer, *size );
GregCr 0:deaafdfde3bb 104 return 0;
GregCr 0:deaafdfde3bb 105 }
GregCr 0:deaafdfde3bb 106
GregCr 2:4ff11ea92fbe 107 void SX126x::SendPayload( uint8_t *payload, uint8_t size, uint32_t timeout )
GregCr 0:deaafdfde3bb 108 {
GregCr 0:deaafdfde3bb 109 SetPayload( payload, size );
GregCr 0:deaafdfde3bb 110 SetTx( timeout );
GregCr 0:deaafdfde3bb 111 }
GregCr 0:deaafdfde3bb 112
GregCr 2:4ff11ea92fbe 113 uint8_t SX126x::SetSyncWord( uint8_t *syncWord )
GregCr 0:deaafdfde3bb 114 {
GregCr 3:7e3595a9ebe0 115 WriteRegister( REG_LR_SYNCWORDBASEADDRESS, syncWord, 8 );
GregCr 0:deaafdfde3bb 116 return 0;
GregCr 0:deaafdfde3bb 117 }
GregCr 0:deaafdfde3bb 118
GregCr 3:7e3595a9ebe0 119 void SX126x::SetCrcSeed( uint16_t seed )
GregCr 0:deaafdfde3bb 120 {
GregCr 3:7e3595a9ebe0 121 uint8_t buf[2];
GregCr 4:c6ef863d0b07 122
GregCr 3:7e3595a9ebe0 123 buf[0] = ( uint8_t )( ( seed >> 8 ) & 0xFF );
GregCr 3:7e3595a9ebe0 124 buf[1] = ( uint8_t )( seed & 0xFF );
GregCr 4:c6ef863d0b07 125
GregCr 0:deaafdfde3bb 126 switch( GetPacketType( ) )
GregCr 0:deaafdfde3bb 127 {
GregCr 0:deaafdfde3bb 128 case PACKET_TYPE_GFSK:
GregCr 3:7e3595a9ebe0 129 WriteRegister( REG_LR_CRCSEEDBASEADDR, buf, 2 );
GregCr 0:deaafdfde3bb 130 break;
GregCr 4:c6ef863d0b07 131
GregCr 0:deaafdfde3bb 132 default:
GregCr 0:deaafdfde3bb 133 break;
GregCr 0:deaafdfde3bb 134 }
GregCr 0:deaafdfde3bb 135 }
GregCr 0:deaafdfde3bb 136
GregCr 3:7e3595a9ebe0 137 void SX126x::SetCrcPolynomial( uint16_t polynomial )
GregCr 0:deaafdfde3bb 138 {
GregCr 3:7e3595a9ebe0 139 uint8_t buf[2];
GregCr 4:c6ef863d0b07 140
GregCr 3:7e3595a9ebe0 141 buf[0] = ( uint8_t )( ( polynomial >> 8 ) & 0xFF );
GregCr 3:7e3595a9ebe0 142 buf[1] = ( uint8_t )( polynomial & 0xFF );
GregCr 4:c6ef863d0b07 143
GregCr 0:deaafdfde3bb 144 switch( GetPacketType( ) )
GregCr 0:deaafdfde3bb 145 {
GregCr 0:deaafdfde3bb 146 case PACKET_TYPE_GFSK:
GregCr 3:7e3595a9ebe0 147 WriteRegister( REG_LR_CRCPOLYBASEADDR, buf, 2 );
GregCr 0:deaafdfde3bb 148 break;
GregCr 4:c6ef863d0b07 149
GregCr 0:deaafdfde3bb 150 default:
GregCr 0:deaafdfde3bb 151 break;
GregCr 0:deaafdfde3bb 152 }
GregCr 0:deaafdfde3bb 153 }
GregCr 0:deaafdfde3bb 154
GregCr 4:c6ef863d0b07 155 void SX126x::SetWhiteningSeed( uint16_t seed )
GregCr 0:deaafdfde3bb 156 {
GregCr 4:c6ef863d0b07 157 uint8_t regValue = 0;
GregCr 4:c6ef863d0b07 158
GregCr 0:deaafdfde3bb 159 switch( GetPacketType( ) )
GregCr 0:deaafdfde3bb 160 {
GregCr 0:deaafdfde3bb 161 case PACKET_TYPE_GFSK:
GregCr 4:c6ef863d0b07 162 regValue = ReadReg( REG_LR_WHITSEEDBASEADDR_MSB ) & 0xFE;
GregCr 4:c6ef863d0b07 163 regValue = ( ( seed >> 8 ) & 0x01 ) | regValue;
GregCr 4:c6ef863d0b07 164 WriteReg( REG_LR_WHITSEEDBASEADDR_MSB, regValue ); // only 1 bit.
GregCr 4:c6ef863d0b07 165 WriteReg( REG_LR_WHITSEEDBASEADDR_LSB, ( uint8_t )seed );
GregCr 0:deaafdfde3bb 166 break;
GregCr 4:c6ef863d0b07 167
GregCr 0:deaafdfde3bb 168 default:
GregCr 0:deaafdfde3bb 169 break;
GregCr 0:deaafdfde3bb 170 }
GregCr 0:deaafdfde3bb 171 }
GregCr 0:deaafdfde3bb 172
GregCr 4:c6ef863d0b07 173 uint32_t SX126x::GetRandom( void )
GregCr 4:c6ef863d0b07 174 {
GregCr 4:c6ef863d0b07 175 uint8_t buf[] = { 0, 0, 0, 0 };
GregCr 4:c6ef863d0b07 176
GregCr 4:c6ef863d0b07 177 // Set radio in continuous reception
GregCr 4:c6ef863d0b07 178 SetRx( 0 );
GregCr 4:c6ef863d0b07 179
GregCr 4:c6ef863d0b07 180 wait_ms( 1 );
GregCr 4:c6ef863d0b07 181
GregCr 4:c6ef863d0b07 182 ReadRegister( RANDOM_NUMBER_GENERATORBASEADDR, buf, 4 );
GregCr 4:c6ef863d0b07 183
GregCr 4:c6ef863d0b07 184 SetStandby( STDBY_RC );
GregCr 4:c6ef863d0b07 185
GregCr 4:c6ef863d0b07 186 return ( buf[0] << 24 ) | ( buf[1] << 16 ) | ( buf[2] << 8 ) | buf[3];
GregCr 4:c6ef863d0b07 187 }
GregCr 4:c6ef863d0b07 188
GregCr 4:c6ef863d0b07 189 void SX126x::SetSleep( SleepParams_t sleepConfig )
GregCr 0:deaafdfde3bb 190 {
GregCr 4:c6ef863d0b07 191 #ifdef ADV_DEBUG
GregCr 4:c6ef863d0b07 192 printf("SetSleep ");
GregCr 4:c6ef863d0b07 193 #endif
GregCr 4:c6ef863d0b07 194
GregCr 4:c6ef863d0b07 195 AntSwOff( );
GregCr 4:c6ef863d0b07 196
GregCr 4:c6ef863d0b07 197 WriteCommand( RADIO_SET_SLEEP, &sleepConfig.Value, 1 );
GregCr 4:c6ef863d0b07 198 OperatingMode = MODE_SLEEP;
GregCr 4:c6ef863d0b07 199 }
GregCr 0:deaafdfde3bb 200
GregCr 4:c6ef863d0b07 201 void SX126x::SetStandby( RadioStandbyModes_t standbyConfig )
GregCr 4:c6ef863d0b07 202 {
GregCr 4:c6ef863d0b07 203 #ifdef ADV_DEBUG
GregCr 4:c6ef863d0b07 204 printf("SetStandby ");
GregCr 4:c6ef863d0b07 205 #endif
GregCr 4:c6ef863d0b07 206 WriteCommand( RADIO_SET_STANDBY, ( uint8_t* )&standbyConfig, 1 );
GregCr 4:c6ef863d0b07 207 if( standbyConfig == STDBY_RC )
GregCr 4:c6ef863d0b07 208 {
GregCr 4:c6ef863d0b07 209 OperatingMode = MODE_STDBY_RC;
GregCr 4:c6ef863d0b07 210 }
GregCr 4:c6ef863d0b07 211 else
GregCr 0:deaafdfde3bb 212 {
GregCr 4:c6ef863d0b07 213 OperatingMode = MODE_STDBY_XOSC;
GregCr 4:c6ef863d0b07 214 }
GregCr 4:c6ef863d0b07 215 }
GregCr 4:c6ef863d0b07 216
GregCr 4:c6ef863d0b07 217 void SX126x::SetFs( void )
GregCr 4:c6ef863d0b07 218 {
GregCr 4:c6ef863d0b07 219 #ifdef ADV_DEBUG
GregCr 4:c6ef863d0b07 220 printf("SetFs ");
GregCr 4:c6ef863d0b07 221 #endif
GregCr 4:c6ef863d0b07 222 WriteCommand( RADIO_SET_FS, 0, 0 );
GregCr 4:c6ef863d0b07 223 OperatingMode = MODE_FS;
GregCr 4:c6ef863d0b07 224 }
GregCr 4:c6ef863d0b07 225
GregCr 4:c6ef863d0b07 226 void SX126x::SetTx( uint32_t timeout )
GregCr 4:c6ef863d0b07 227 {
GregCr 4:c6ef863d0b07 228 uint8_t buf[3];
GregCr 4:c6ef863d0b07 229
GregCr 4:c6ef863d0b07 230 OperatingMode = MODE_TX;
GregCr 4:c6ef863d0b07 231
GregCr 4:c6ef863d0b07 232 #ifdef ADV_DEBUG
GregCr 4:c6ef863d0b07 233 printf("SetTx ");
GregCr 4:c6ef863d0b07 234 #endif
GregCr 4:c6ef863d0b07 235
GregCr 4:c6ef863d0b07 236 buf[0] = ( uint8_t )( ( timeout >> 16 ) & 0xFF );
GregCr 4:c6ef863d0b07 237 buf[1] = ( uint8_t )( ( timeout >> 8 ) & 0xFF );
GregCr 4:c6ef863d0b07 238 buf[2] = ( uint8_t )( timeout & 0xFF );
GregCr 4:c6ef863d0b07 239 WriteCommand( RADIO_SET_TX, buf, 3 );
GregCr 4:c6ef863d0b07 240 }
GregCr 4:c6ef863d0b07 241
GregCr 4:c6ef863d0b07 242 void SX126x::SetRxBoosted( uint32_t timeout )
GregCr 4:c6ef863d0b07 243 {
GregCr 4:c6ef863d0b07 244 uint8_t buf[3];
GregCr 4:c6ef863d0b07 245
GregCr 4:c6ef863d0b07 246 OperatingMode = MODE_RX;
GregCr 4:c6ef863d0b07 247
GregCr 4:c6ef863d0b07 248 #ifdef ADV_DEBUG
GregCr 4:c6ef863d0b07 249 printf("SetRxBoosted ");
GregCr 4:c6ef863d0b07 250 #endif
GregCr 4:c6ef863d0b07 251
GregCr 4:c6ef863d0b07 252 WriteReg( REG_RX_GAIN, 0x96 ); // max LNA gain, increase current by ~2mA for around ~3dB in sensivity
GregCr 4:c6ef863d0b07 253
GregCr 4:c6ef863d0b07 254 buf[0] = ( uint8_t )( ( timeout >> 16 ) & 0xFF );
GregCr 4:c6ef863d0b07 255 buf[1] = ( uint8_t )( ( timeout >> 8 ) & 0xFF );
GregCr 4:c6ef863d0b07 256 buf[2] = ( uint8_t )( timeout & 0xFF );
GregCr 4:c6ef863d0b07 257 WriteCommand( RADIO_SET_RX, buf, 3 );
GregCr 4:c6ef863d0b07 258 }
GregCr 4:c6ef863d0b07 259
GregCr 4:c6ef863d0b07 260 void SX126x::SetRx( uint32_t timeout )
GregCr 4:c6ef863d0b07 261 {
GregCr 4:c6ef863d0b07 262 uint8_t buf[3];
GregCr 4:c6ef863d0b07 263
GregCr 4:c6ef863d0b07 264 OperatingMode = MODE_RX;
GregCr 4:c6ef863d0b07 265
GregCr 4:c6ef863d0b07 266 #ifdef ADV_DEBUG
GregCr 4:c6ef863d0b07 267 printf("SetRx ");
GregCr 4:c6ef863d0b07 268 #endif
GregCr 4:c6ef863d0b07 269
GregCr 4:c6ef863d0b07 270 buf[0] = ( uint8_t )( ( timeout >> 16 ) & 0xFF );
GregCr 4:c6ef863d0b07 271 buf[1] = ( uint8_t )( ( timeout >> 8 ) & 0xFF );
GregCr 4:c6ef863d0b07 272 buf[2] = ( uint8_t )( timeout & 0xFF );
GregCr 4:c6ef863d0b07 273 WriteCommand( RADIO_SET_RX, buf, 3 );
GregCr 4:c6ef863d0b07 274 }
GregCr 4:c6ef863d0b07 275
GregCr 4:c6ef863d0b07 276 void SX126x::SetRxDutyCycle( uint32_t rxTime, uint32_t sleepTime )
GregCr 4:c6ef863d0b07 277 {
GregCr 4:c6ef863d0b07 278 uint8_t buf[6];
GregCr 4:c6ef863d0b07 279
GregCr 4:c6ef863d0b07 280 SetLongPreamble( true );
GregCr 4:c6ef863d0b07 281
GregCr 4:c6ef863d0b07 282 buf[0] = ( uint8_t )( ( rxTime >> 16 ) & 0xFF );
GregCr 4:c6ef863d0b07 283 buf[1] = ( uint8_t )( ( rxTime >> 8 ) & 0xFF );
GregCr 4:c6ef863d0b07 284 buf[2] = ( uint8_t )( rxTime & 0xFF );
GregCr 4:c6ef863d0b07 285 buf[3] = ( uint8_t )( ( sleepTime >> 16 ) & 0xFF );
GregCr 4:c6ef863d0b07 286 buf[4] = ( uint8_t )( ( sleepTime >> 8 ) & 0xFF );
GregCr 4:c6ef863d0b07 287 buf[5] = ( uint8_t )( sleepTime & 0xFF );
GregCr 4:c6ef863d0b07 288 WriteCommand( RADIO_SET_RXDUTYCYCLE, buf, 6 );
GregCr 4:c6ef863d0b07 289 OperatingMode = MODE_RX_DC;
GregCr 4:c6ef863d0b07 290 }
GregCr 4:c6ef863d0b07 291
GregCr 4:c6ef863d0b07 292 void SX126x::SetCad( void )
GregCr 4:c6ef863d0b07 293 {
GregCr 4:c6ef863d0b07 294 WriteCommand( RADIO_SET_CAD, 0, 0 );
GregCr 4:c6ef863d0b07 295 OperatingMode = MODE_CAD;
GregCr 4:c6ef863d0b07 296 }
GregCr 4:c6ef863d0b07 297
GregCr 4:c6ef863d0b07 298 void SX126x::SetTxContinuousWave( void )
GregCr 4:c6ef863d0b07 299 {
GregCr 4:c6ef863d0b07 300 #ifdef ADV_DEBUG
GregCr 4:c6ef863d0b07 301 printf("SetTxContinuousWave ");
GregCr 4:c6ef863d0b07 302 #endif
GregCr 4:c6ef863d0b07 303 WriteCommand( RADIO_SET_TXCONTINUOUSWAVE, 0, 0 );
GregCr 4:c6ef863d0b07 304 }
GregCr 4:c6ef863d0b07 305
GregCr 4:c6ef863d0b07 306 void SX126x::SetTxInfinitePreamble( void )
GregCr 4:c6ef863d0b07 307 {
GregCr 4:c6ef863d0b07 308 #ifdef ADV_DEBUG
GregCr 4:c6ef863d0b07 309 printf("SetTxContinuousPreamble ");
GregCr 4:c6ef863d0b07 310 #endif
GregCr 4:c6ef863d0b07 311 WriteCommand( RADIO_SET_TXCONTINUOUSPREAMBLE, 0, 0 );
GregCr 4:c6ef863d0b07 312 }
GregCr 4:c6ef863d0b07 313
GregCr 4:c6ef863d0b07 314 void SX126x::SetStopRxTimerOnPreambleDetect( bool enable )
GregCr 4:c6ef863d0b07 315 {
GregCr 4:c6ef863d0b07 316 WriteCommand( RADIO_SET_STOPRXTIMERONPREAMBLE, ( uint8_t* )&enable, 1 );
GregCr 4:c6ef863d0b07 317 }
GregCr 4:c6ef863d0b07 318
GregCr 4:c6ef863d0b07 319 void SX126x::SetLoRaSymbNumTimeout( uint8_t SymbNum )
GregCr 4:c6ef863d0b07 320 {
GregCr 4:c6ef863d0b07 321 WriteCommand( RADIO_SET_LORASYMBTIMEOUT, &SymbNum, 1 );
GregCr 4:c6ef863d0b07 322 }
GregCr 4:c6ef863d0b07 323
GregCr 4:c6ef863d0b07 324 void SX126x::SetRegulatorMode( RadioRegulatorMode_t mode )
GregCr 4:c6ef863d0b07 325 {
GregCr 4:c6ef863d0b07 326 #ifdef ADV_DEBUG
GregCr 4:c6ef863d0b07 327 printf("SetRegulatorMode ");
GregCr 4:c6ef863d0b07 328 #endif
GregCr 4:c6ef863d0b07 329 WriteCommand( RADIO_SET_REGULATORMODE, ( uint8_t* )&mode, 1 );
GregCr 4:c6ef863d0b07 330 }
GregCr 4:c6ef863d0b07 331
GregCr 4:c6ef863d0b07 332 void SX126x::Calibrate( CalibrationParams_t calibParam )
GregCr 4:c6ef863d0b07 333 {
GregCr 4:c6ef863d0b07 334 WriteCommand( RADIO_CALIBRATE, &calibParam.Value, 1 );
GregCr 4:c6ef863d0b07 335 }
GregCr 4:c6ef863d0b07 336
GregCr 4:c6ef863d0b07 337 void SX126x::SetLongPreamble( uint8_t enable )
GregCr 4:c6ef863d0b07 338 {
GregCr 4:c6ef863d0b07 339 WriteCommand( RADIO_SET_LONGPREAMBLE, &enable, 1 );
GregCr 4:c6ef863d0b07 340 }
GregCr 4:c6ef863d0b07 341
GregCr 4:c6ef863d0b07 342 void SX126x::SetPaConfig( uint8_t paDutyCycle, uint8_t HpMax, uint8_t deviceSel, uint8_t paLUT )
GregCr 4:c6ef863d0b07 343 {
GregCr 4:c6ef863d0b07 344 uint8_t buf[4];
GregCr 4:c6ef863d0b07 345
GregCr 4:c6ef863d0b07 346 #ifdef ADV_DEBUG
GregCr 4:c6ef863d0b07 347 printf("SetPaConfig ");
GregCr 4:c6ef863d0b07 348 #endif
GregCr 4:c6ef863d0b07 349
GregCr 4:c6ef863d0b07 350 buf[0] = paDutyCycle;
GregCr 4:c6ef863d0b07 351 buf[1] = HpMax;
GregCr 4:c6ef863d0b07 352 buf[2] = deviceSel;
GregCr 4:c6ef863d0b07 353 buf[3] = paLUT;
GregCr 4:c6ef863d0b07 354 WriteCommand( RADIO_SET_PACONFIG, buf, 4 );
GregCr 4:c6ef863d0b07 355 }
GregCr 4:c6ef863d0b07 356
GregCr 4:c6ef863d0b07 357 void SX126x::SetRxTxFallbackMode( uint8_t fallbackMode )
GregCr 4:c6ef863d0b07 358 {
GregCr 4:c6ef863d0b07 359 WriteCommand( RADIO_SET_TXFALLBACKMODE, &fallbackMode, 1 );
GregCr 4:c6ef863d0b07 360 }
GregCr 4:c6ef863d0b07 361
GregCr 4:c6ef863d0b07 362 void SX126x::SetDioIrqParams( uint16_t irqMask, uint16_t dio1Mask, uint16_t dio2Mask, uint16_t dio3Mask )
GregCr 4:c6ef863d0b07 363 {
GregCr 4:c6ef863d0b07 364 uint8_t buf[8];
GregCr 4:c6ef863d0b07 365
GregCr 4:c6ef863d0b07 366 #ifdef ADV_DEBUG
GregCr 4:c6ef863d0b07 367 printf("SetDioIrqParams ");
GregCr 4:c6ef863d0b07 368 #endif
GregCr 4:c6ef863d0b07 369
GregCr 4:c6ef863d0b07 370 buf[0] = ( uint8_t )( ( irqMask >> 8 ) & 0x00FF );
GregCr 4:c6ef863d0b07 371 buf[1] = ( uint8_t )( irqMask & 0x00FF );
GregCr 4:c6ef863d0b07 372 buf[2] = ( uint8_t )( ( dio1Mask >> 8 ) & 0x00FF );
GregCr 4:c6ef863d0b07 373 buf[3] = ( uint8_t )( dio1Mask & 0x00FF );
GregCr 4:c6ef863d0b07 374 buf[4] = ( uint8_t )( ( dio2Mask >> 8 ) & 0x00FF );
GregCr 4:c6ef863d0b07 375 buf[5] = ( uint8_t )( dio2Mask & 0x00FF );
GregCr 4:c6ef863d0b07 376 buf[6] = ( uint8_t )( ( dio3Mask >> 8 ) & 0x00FF );
GregCr 4:c6ef863d0b07 377 buf[7] = ( uint8_t )( dio3Mask & 0x00FF );
GregCr 4:c6ef863d0b07 378 WriteCommand( RADIO_CFG_DIOIRQ, buf, 8 );
GregCr 4:c6ef863d0b07 379 }
GregCr 4:c6ef863d0b07 380
GregCr 4:c6ef863d0b07 381 uint16_t SX126x::GetIrqStatus( void )
GregCr 4:c6ef863d0b07 382 {
GregCr 4:c6ef863d0b07 383 uint8_t irqStatus[2];
GregCr 4:c6ef863d0b07 384
GregCr 4:c6ef863d0b07 385 ReadCommand( RADIO_GET_IRQSTATUS, irqStatus, 2 );
GregCr 4:c6ef863d0b07 386 return ( irqStatus[0] << 8 ) | irqStatus[1];
GregCr 4:c6ef863d0b07 387 }
GregCr 4:c6ef863d0b07 388
GregCr 4:c6ef863d0b07 389 void SX126x::SetDio2AsRfSwitchCtrl( uint8_t enable )
GregCr 4:c6ef863d0b07 390 {
GregCr 4:c6ef863d0b07 391 #ifdef ADV_DEBUG
GregCr 4:c6ef863d0b07 392 printf("SetDio2AsRfSwitchCtrl ");
GregCr 4:c6ef863d0b07 393 #endif
GregCr 4:c6ef863d0b07 394 WriteCommand( RADIO_SET_RFSWITCHMODE, &enable, 1 );
GregCr 4:c6ef863d0b07 395 }
GregCr 4:c6ef863d0b07 396
GregCr 4:c6ef863d0b07 397 void SX126x::SetDio3AsTcxoCtrl( RadioTcxoCtrlVoltage_t tcxoVoltage, uint32_t timeout )
GregCr 4:c6ef863d0b07 398 {
GregCr 4:c6ef863d0b07 399 uint8_t buf[4];
GregCr 4:c6ef863d0b07 400
GregCr 4:c6ef863d0b07 401 buf[0] = tcxoVoltage & 0x08;
GregCr 4:c6ef863d0b07 402 buf[1] = ( uint8_t )( ( timeout >> 16 ) & 0xFF );
GregCr 4:c6ef863d0b07 403 buf[2] = ( uint8_t )( ( timeout >> 8 ) & 0xFF );
GregCr 4:c6ef863d0b07 404 buf[3] = ( uint8_t )( timeout & 0xFF );
GregCr 4:c6ef863d0b07 405
GregCr 4:c6ef863d0b07 406 WriteCommand( RADIO_SET_TCXOMODE, buf, 4 );
GregCr 4:c6ef863d0b07 407 }
GregCr 4:c6ef863d0b07 408
GregCr 4:c6ef863d0b07 409 void SX126x::SetRfFrequency( uint32_t frequency )
GregCr 4:c6ef863d0b07 410 {
GregCr 4:c6ef863d0b07 411 uint8_t buf[4];
GregCr 4:c6ef863d0b07 412 uint32_t freq = 0;
GregCr 4:c6ef863d0b07 413
GregCr 4:c6ef863d0b07 414 #ifdef ADV_DEBUG
GregCr 4:c6ef863d0b07 415 printf("SetRfFrequency ");
GregCr 4:c6ef863d0b07 416 #endif
GregCr 4:c6ef863d0b07 417
GregCr 4:c6ef863d0b07 418 freq = ( uint32_t )( ( double )frequency / ( double )FREQ_STEP );
GregCr 4:c6ef863d0b07 419 buf[0] = ( uint8_t )( ( freq >> 24 ) & 0xFF );
GregCr 4:c6ef863d0b07 420 buf[1] = ( uint8_t )( ( freq >> 16 ) & 0xFF );
GregCr 4:c6ef863d0b07 421 buf[2] = ( uint8_t )( ( freq >> 8 ) & 0xFF );
GregCr 4:c6ef863d0b07 422 buf[3] = ( uint8_t )( freq & 0xFF );
GregCr 4:c6ef863d0b07 423 WriteCommand( RADIO_SET_RFFREQUENCY, buf, 4 );
GregCr 4:c6ef863d0b07 424 }
GregCr 4:c6ef863d0b07 425
GregCr 4:c6ef863d0b07 426 void SX126x::SetPacketType( RadioPacketTypes_t packetType )
GregCr 4:c6ef863d0b07 427 {
GregCr 4:c6ef863d0b07 428 #ifdef ADV_DEBUG
GregCr 4:c6ef863d0b07 429 printf("SetPacketType ");
GregCr 4:c6ef863d0b07 430 #endif
GregCr 4:c6ef863d0b07 431
GregCr 4:c6ef863d0b07 432 // Save packet type internally to avoid questioning the radio
GregCr 4:c6ef863d0b07 433 this->PacketType = packetType;
GregCr 4:c6ef863d0b07 434
GregCr 4:c6ef863d0b07 435 if( packetType == PACKET_TYPE_GFSK )
GregCr 4:c6ef863d0b07 436 {
GregCr 4:c6ef863d0b07 437 WriteReg( REG_BIT_SYNC, 0x00 );
GregCr 4:c6ef863d0b07 438 }
GregCr 4:c6ef863d0b07 439
GregCr 4:c6ef863d0b07 440 WriteCommand( RADIO_SET_PACKETTYPE, ( uint8_t* )&packetType, 1 );
GregCr 4:c6ef863d0b07 441 }
GregCr 4:c6ef863d0b07 442
GregCr 4:c6ef863d0b07 443 RadioPacketTypes_t SX126x::GetPacketType( void )
GregCr 4:c6ef863d0b07 444 {
GregCr 4:c6ef863d0b07 445 return this->PacketType;
GregCr 4:c6ef863d0b07 446 }
GregCr 4:c6ef863d0b07 447
GregCr 4:c6ef863d0b07 448 void SX126x::SetTxParams( int8_t power, RadioRampTimes_t rampTime )
GregCr 4:c6ef863d0b07 449 {
GregCr 4:c6ef863d0b07 450 uint8_t buf[2];
GregCr 4:c6ef863d0b07 451 DigitalIn OPT( A3 );
GregCr 4:c6ef863d0b07 452
GregCr 4:c6ef863d0b07 453 #ifdef ADV_DEBUG
GregCr 4:c6ef863d0b07 454 printf("SetTxParams ");
GregCr 4:c6ef863d0b07 455 #endif
GregCr 4:c6ef863d0b07 456
GregCr 4:c6ef863d0b07 457 if( GetDeviceType( ) == 1 ) // sx1261
GregCr 4:c6ef863d0b07 458 {
GregCr 4:c6ef863d0b07 459 if( power == 15 )
GregCr 0:deaafdfde3bb 460 {
GregCr 4:c6ef863d0b07 461 SetPaConfig( 0x06, 0x00, 0x01, 0x00 );
GregCr 0:deaafdfde3bb 462 }
GregCr 4:c6ef863d0b07 463 else
GregCr 4:c6ef863d0b07 464 {
GregCr 4:c6ef863d0b07 465 SetPaConfig( 0x04, 0x00, 0x01, 0x00 );
GregCr 4:c6ef863d0b07 466 }
GregCr 4:c6ef863d0b07 467 if( power >= 14 )
GregCr 4:c6ef863d0b07 468 {
GregCr 4:c6ef863d0b07 469 power = 14;
GregCr 4:c6ef863d0b07 470 }
GregCr 4:c6ef863d0b07 471 else if( power < -3 )
GregCr 4:c6ef863d0b07 472 {
GregCr 4:c6ef863d0b07 473 power = -3;
GregCr 0:deaafdfde3bb 474 }
GregCr 4:c6ef863d0b07 475 }
GregCr 4:c6ef863d0b07 476 else // sx1262
GregCr 4:c6ef863d0b07 477 {
GregCr 4:c6ef863d0b07 478 SetPaConfig( 0x04, 0x07, 0x00, 0x01 );
GregCr 4:c6ef863d0b07 479 if( power > 22 )
GregCr 4:c6ef863d0b07 480 {
GregCr 4:c6ef863d0b07 481 power = 22;
GregCr 4:c6ef863d0b07 482 }
GregCr 4:c6ef863d0b07 483 else if( power < -3 )
GregCr 4:c6ef863d0b07 484 {
GregCr 4:c6ef863d0b07 485 power = -3;
GregCr 4:c6ef863d0b07 486 }
GregCr 4:c6ef863d0b07 487 }
GregCr 4:c6ef863d0b07 488 buf[0] = power;
GregCr 4:c6ef863d0b07 489 if( OPT == 0 )
GregCr 4:c6ef863d0b07 490 {
GregCr 4:c6ef863d0b07 491 if( ( uint8_t )rampTime < RADIO_RAMP_200_US )
GregCr 4:c6ef863d0b07 492 {
GregCr 4:c6ef863d0b07 493 buf[1] = RADIO_RAMP_200_US;
GregCr 4:c6ef863d0b07 494 }
GregCr 4:c6ef863d0b07 495 else
GregCr 4:c6ef863d0b07 496 {
GregCr 4:c6ef863d0b07 497 buf[1] = ( uint8_t )rampTime;
GregCr 0:deaafdfde3bb 498 }
GregCr 0:deaafdfde3bb 499 }
GregCr 0:deaafdfde3bb 500 else
GregCr 0:deaafdfde3bb 501 {
GregCr 4:c6ef863d0b07 502 buf[1] = ( uint8_t )rampTime;
GregCr 4:c6ef863d0b07 503 }
GregCr 4:c6ef863d0b07 504 WriteCommand( RADIO_SET_TXPARAMS, buf, 2 );
GregCr 4:c6ef863d0b07 505 }
GregCr 4:c6ef863d0b07 506
GregCr 4:c6ef863d0b07 507 void SX126x::SetModulationParams( ModulationParams_t *modulationParams )
GregCr 4:c6ef863d0b07 508 {
GregCr 4:c6ef863d0b07 509 uint8_t n;
GregCr 4:c6ef863d0b07 510 uint32_t tempVal = 0;
GregCr 4:c6ef863d0b07 511 uint8_t buf[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
GregCr 4:c6ef863d0b07 512
GregCr 4:c6ef863d0b07 513 #ifdef ADV_DEBUG
GregCr 4:c6ef863d0b07 514 printf("SetModulationParams ");
GregCr 4:c6ef863d0b07 515 #endif
GregCr 4:c6ef863d0b07 516
GregCr 4:c6ef863d0b07 517 // Check if required configuration corresponds to the stored packet type
GregCr 4:c6ef863d0b07 518 // If not, silently update radio packet type
GregCr 4:c6ef863d0b07 519 if( this->PacketType != modulationParams->PacketType )
GregCr 4:c6ef863d0b07 520 {
GregCr 4:c6ef863d0b07 521 this->SetPacketType( modulationParams->PacketType );
GregCr 0:deaafdfde3bb 522 }
GregCr 4:c6ef863d0b07 523
GregCr 4:c6ef863d0b07 524 switch( modulationParams->PacketType )
GregCr 4:c6ef863d0b07 525 {
GregCr 4:c6ef863d0b07 526 case PACKET_TYPE_GFSK:
GregCr 4:c6ef863d0b07 527 n = 8;
GregCr 4:c6ef863d0b07 528 tempVal = ( uint32_t )( 32 * ( ( double )XTAL_FREQ / ( double )modulationParams->Params.Gfsk.BitRate ) );
GregCr 4:c6ef863d0b07 529 buf[0] = ( tempVal >> 16 ) & 0xFF;
GregCr 4:c6ef863d0b07 530 buf[1] = ( tempVal >> 8 ) & 0xFF;
GregCr 4:c6ef863d0b07 531 buf[2] = tempVal & 0xFF;
GregCr 4:c6ef863d0b07 532 buf[3] = modulationParams->Params.Gfsk.ModulationShaping;
GregCr 4:c6ef863d0b07 533 buf[4] = modulationParams->Params.Gfsk.Bandwidth;
GregCr 4:c6ef863d0b07 534 tempVal = ( uint32_t )( ( double )modulationParams->Params.Gfsk.Fdev / ( double )FREQ_STEP );
GregCr 4:c6ef863d0b07 535 buf[5] = ( tempVal >> 16 ) & 0xFF;
GregCr 4:c6ef863d0b07 536 buf[6] = ( tempVal >> 8 ) & 0xFF;
GregCr 4:c6ef863d0b07 537 buf[7] = ( tempVal& 0xFF );
GregCr 4:c6ef863d0b07 538 break;
GregCr 4:c6ef863d0b07 539 case PACKET_TYPE_LORA:
GregCr 4:c6ef863d0b07 540 n = 4;
GregCr 4:c6ef863d0b07 541 switch( modulationParams->Params.LoRa.Bandwidth )
GregCr 4:c6ef863d0b07 542 {
GregCr 4:c6ef863d0b07 543 case LORA_BW_500:
GregCr 4:c6ef863d0b07 544 modulationParams->Params.LoRa.LowDatarateOptimize = 0x00;
GregCr 4:c6ef863d0b07 545 break;
GregCr 4:c6ef863d0b07 546 case LORA_BW_250:
GregCr 4:c6ef863d0b07 547 if( modulationParams->Params.LoRa.SpreadingFactor == 12 )
GregCr 4:c6ef863d0b07 548 {
GregCr 4:c6ef863d0b07 549 modulationParams->Params.LoRa.LowDatarateOptimize = 0x01;
GregCr 4:c6ef863d0b07 550 }
GregCr 4:c6ef863d0b07 551 else
GregCr 4:c6ef863d0b07 552 {
GregCr 4:c6ef863d0b07 553 modulationParams->Params.LoRa.LowDatarateOptimize = 0x00;
GregCr 4:c6ef863d0b07 554 }
GregCr 4:c6ef863d0b07 555 break;
GregCr 4:c6ef863d0b07 556 case LORA_BW_125:
GregCr 4:c6ef863d0b07 557 if( modulationParams->Params.LoRa.SpreadingFactor >= 11 )
GregCr 4:c6ef863d0b07 558 {
GregCr 4:c6ef863d0b07 559 modulationParams->Params.LoRa.LowDatarateOptimize = 0x01;
GregCr 4:c6ef863d0b07 560 }
GregCr 4:c6ef863d0b07 561 else
GregCr 4:c6ef863d0b07 562 {
GregCr 4:c6ef863d0b07 563 modulationParams->Params.LoRa.LowDatarateOptimize = 0x00;
GregCr 4:c6ef863d0b07 564 }
GregCr 4:c6ef863d0b07 565 break;
GregCr 4:c6ef863d0b07 566 case LORA_BW_062:
GregCr 4:c6ef863d0b07 567 if( modulationParams->Params.LoRa.SpreadingFactor >= 10 )
GregCr 4:c6ef863d0b07 568 {
GregCr 4:c6ef863d0b07 569 modulationParams->Params.LoRa.LowDatarateOptimize = 0x01;
GregCr 4:c6ef863d0b07 570 }
GregCr 4:c6ef863d0b07 571 else
GregCr 4:c6ef863d0b07 572 {
GregCr 4:c6ef863d0b07 573 modulationParams->Params.LoRa.LowDatarateOptimize = 0x00;
GregCr 4:c6ef863d0b07 574 }
GregCr 4:c6ef863d0b07 575 break;
GregCr 4:c6ef863d0b07 576 case LORA_BW_041:
GregCr 4:c6ef863d0b07 577 if( modulationParams->Params.LoRa.SpreadingFactor >= 9 )
GregCr 4:c6ef863d0b07 578 {
GregCr 4:c6ef863d0b07 579 modulationParams->Params.LoRa.LowDatarateOptimize = 0x01;
GregCr 4:c6ef863d0b07 580 }
GregCr 4:c6ef863d0b07 581 else
GregCr 4:c6ef863d0b07 582 {
GregCr 4:c6ef863d0b07 583 modulationParams->Params.LoRa.LowDatarateOptimize = 0x00;
GregCr 4:c6ef863d0b07 584 }
GregCr 4:c6ef863d0b07 585 break;
GregCr 4:c6ef863d0b07 586 case LORA_BW_031:
GregCr 4:c6ef863d0b07 587 case LORA_BW_020:
GregCr 4:c6ef863d0b07 588 case LORA_BW_015:
GregCr 4:c6ef863d0b07 589 case LORA_BW_010:
GregCr 4:c6ef863d0b07 590 case LORA_BW_007:
GregCr 4:c6ef863d0b07 591 modulationParams->Params.LoRa.LowDatarateOptimize = 0x01;
GregCr 4:c6ef863d0b07 592 break;
GregCr 4:c6ef863d0b07 593 default:
GregCr 4:c6ef863d0b07 594 break;
GregCr 4:c6ef863d0b07 595 }
GregCr 4:c6ef863d0b07 596 buf[0] = modulationParams->Params.LoRa.SpreadingFactor;
GregCr 4:c6ef863d0b07 597 buf[1] = modulationParams->Params.LoRa.Bandwidth;
GregCr 4:c6ef863d0b07 598 buf[2] = modulationParams->Params.LoRa.CodingRate;
GregCr 4:c6ef863d0b07 599 buf[3] = modulationParams->Params.LoRa.LowDatarateOptimize;
GregCr 4:c6ef863d0b07 600 break;
GregCr 4:c6ef863d0b07 601 default:
GregCr 4:c6ef863d0b07 602 case PACKET_TYPE_NONE:
GregCr 4:c6ef863d0b07 603 return;
GregCr 4:c6ef863d0b07 604 }
GregCr 4:c6ef863d0b07 605 WriteCommand( RADIO_SET_MODULATIONPARAMS, buf, n );
GregCr 0:deaafdfde3bb 606 }
GregCr 0:deaafdfde3bb 607
GregCr 4:c6ef863d0b07 608 void SX126x::SetPacketParams( PacketParams_t *packetParams )
GregCr 0:deaafdfde3bb 609 {
GregCr 4:c6ef863d0b07 610 uint8_t n;
GregCr 4:c6ef863d0b07 611 uint8_t crcVal = 0;
GregCr 4:c6ef863d0b07 612 uint8_t buf[9] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
GregCr 0:deaafdfde3bb 613
GregCr 4:c6ef863d0b07 614 #ifdef ADV_DEBUG
GregCr 4:c6ef863d0b07 615 printf("SetPacketParams ");
GregCr 4:c6ef863d0b07 616 #endif
GregCr 4:c6ef863d0b07 617
GregCr 4:c6ef863d0b07 618 // Check if required configuration corresponds to the stored packet type
GregCr 4:c6ef863d0b07 619 // If not, silently update radio packet type
GregCr 4:c6ef863d0b07 620 if( this->PacketType != packetParams->PacketType )
GregCr 0:deaafdfde3bb 621 {
GregCr 4:c6ef863d0b07 622 this->SetPacketType( packetParams->PacketType );
GregCr 0:deaafdfde3bb 623 }
GregCr 0:deaafdfde3bb 624
GregCr 4:c6ef863d0b07 625 switch( packetParams->PacketType )
GregCr 4:c6ef863d0b07 626 {
GregCr 4:c6ef863d0b07 627 case PACKET_TYPE_GFSK:
GregCr 4:c6ef863d0b07 628 if( packetParams->Params.Gfsk.CrcLength == RADIO_CRC_2_BYTES_IBM )
GregCr 4:c6ef863d0b07 629 {
GregCr 4:c6ef863d0b07 630 SetCrcSeed( CRC_IBM_SEED );
GregCr 4:c6ef863d0b07 631 SetCrcPolynomial( CRC_POLYNOMIAL_IBM );
GregCr 4:c6ef863d0b07 632 crcVal = RADIO_CRC_2_BYTES;
GregCr 4:c6ef863d0b07 633 }
GregCr 4:c6ef863d0b07 634 else if( packetParams->Params.Gfsk.CrcLength == RADIO_CRC_2_BYTES_CCIT )
GregCr 4:c6ef863d0b07 635 {
GregCr 4:c6ef863d0b07 636 SetCrcSeed( CRC_CCITT_SEED );
GregCr 4:c6ef863d0b07 637 SetCrcPolynomial( CRC_POLYNOMIAL_CCITT );
GregCr 4:c6ef863d0b07 638 crcVal = RADIO_CRC_2_BYTES_INV;
GregCr 4:c6ef863d0b07 639 }
GregCr 4:c6ef863d0b07 640 else
GregCr 4:c6ef863d0b07 641 {
GregCr 4:c6ef863d0b07 642 crcVal = packetParams->Params.Gfsk.CrcLength;
GregCr 4:c6ef863d0b07 643 }
GregCr 4:c6ef863d0b07 644 n = 9;
GregCr 4:c6ef863d0b07 645 // convert preamble length from byte to bit
GregCr 4:c6ef863d0b07 646 packetParams->Params.Gfsk.PreambleLength = packetParams->Params.Gfsk.PreambleLength << 3;
GregCr 4:c6ef863d0b07 647
GregCr 4:c6ef863d0b07 648 buf[0] = ( packetParams->Params.Gfsk.PreambleLength >> 8 ) & 0xFF;
GregCr 4:c6ef863d0b07 649 buf[1] = packetParams->Params.Gfsk.PreambleLength;
GregCr 4:c6ef863d0b07 650 buf[2] = packetParams->Params.Gfsk.PreambleMinDetect;
GregCr 4:c6ef863d0b07 651 buf[3] = ( packetParams->Params.Gfsk.SyncWordLength << 3 ); // convert from byte to bit
GregCr 4:c6ef863d0b07 652 buf[4] = packetParams->Params.Gfsk.AddrComp;
GregCr 4:c6ef863d0b07 653 buf[5] = packetParams->Params.Gfsk.HeaderType;
GregCr 4:c6ef863d0b07 654 buf[6] = packetParams->Params.Gfsk.PayloadLength;
GregCr 4:c6ef863d0b07 655 buf[7] = crcVal;
GregCr 4:c6ef863d0b07 656 buf[8] = packetParams->Params.Gfsk.DcFree;
GregCr 4:c6ef863d0b07 657 break;
GregCr 4:c6ef863d0b07 658 case PACKET_TYPE_LORA:
GregCr 4:c6ef863d0b07 659 n = 6;
GregCr 4:c6ef863d0b07 660 buf[0] = ( packetParams->Params.LoRa.PreambleLength >> 8 ) & 0xFF;
GregCr 4:c6ef863d0b07 661 buf[1] = packetParams->Params.LoRa.PreambleLength;
GregCr 4:c6ef863d0b07 662 buf[2] = packetParams->Params.LoRa.HeaderType;
GregCr 4:c6ef863d0b07 663 buf[3] = packetParams->Params.LoRa.PayloadLength;
GregCr 4:c6ef863d0b07 664 buf[4] = packetParams->Params.LoRa.CrcMode;
GregCr 4:c6ef863d0b07 665 buf[5] = packetParams->Params.LoRa.InvertIQ;
GregCr 4:c6ef863d0b07 666 break;
GregCr 4:c6ef863d0b07 667 default:
GregCr 4:c6ef863d0b07 668 case PACKET_TYPE_NONE:
GregCr 4:c6ef863d0b07 669 return;
GregCr 4:c6ef863d0b07 670 }
GregCr 4:c6ef863d0b07 671 WriteCommand( RADIO_SET_PACKETPARAMS, buf, n );
GregCr 4:c6ef863d0b07 672 }
GregCr 4:c6ef863d0b07 673
GregCr 4:c6ef863d0b07 674 void SX126x::SetCadParams( RadioLoRaCadSymbols_t cadSymbolNum, uint8_t cadDetPeak, uint8_t cadDetMin, RadioCadExitModes_t cadExitMode, uint32_t cadTimeout )
GregCr 4:c6ef863d0b07 675 {
GregCr 4:c6ef863d0b07 676 uint8_t buf[7];
GregCr 4:c6ef863d0b07 677
GregCr 4:c6ef863d0b07 678 buf[0] = ( uint8_t )cadSymbolNum;
GregCr 4:c6ef863d0b07 679 buf[1] = cadDetPeak;
GregCr 4:c6ef863d0b07 680 buf[2] = cadDetMin;
GregCr 4:c6ef863d0b07 681 buf[3] = ( uint8_t )cadExitMode;
GregCr 4:c6ef863d0b07 682 buf[4] = ( uint8_t )( ( cadTimeout >> 16 ) & 0xFF );
GregCr 4:c6ef863d0b07 683 buf[5] = ( uint8_t )( ( cadTimeout >> 8 ) & 0xFF );
GregCr 4:c6ef863d0b07 684 buf[6] = ( uint8_t )( cadTimeout & 0xFF );
GregCr 4:c6ef863d0b07 685 WriteCommand( RADIO_SET_CADPARAMS, buf, 5 );
GregCr 4:c6ef863d0b07 686 OperatingMode = MODE_CAD;
GregCr 4:c6ef863d0b07 687 }
GregCr 4:c6ef863d0b07 688
GregCr 4:c6ef863d0b07 689 void SX126x::SetBufferBaseAddresses( uint8_t txBaseAddress, uint8_t rxBaseAddress )
GregCr 4:c6ef863d0b07 690 {
GregCr 4:c6ef863d0b07 691 uint8_t buf[2];
GregCr 4:c6ef863d0b07 692
GregCr 4:c6ef863d0b07 693 #ifdef ADV_DEBUG
GregCr 4:c6ef863d0b07 694 printf("SetBufferBaseAddresses ");
GregCr 4:c6ef863d0b07 695 #endif
GregCr 4:c6ef863d0b07 696
GregCr 4:c6ef863d0b07 697 buf[0] = txBaseAddress;
GregCr 4:c6ef863d0b07 698 buf[1] = rxBaseAddress;
GregCr 4:c6ef863d0b07 699 WriteCommand( RADIO_SET_BUFFERBASEADDRESS, buf, 2 );
GregCr 4:c6ef863d0b07 700 }
GregCr 4:c6ef863d0b07 701
GregCr 4:c6ef863d0b07 702 RadioStatus_t SX126x::GetStatus( void )
GregCr 4:c6ef863d0b07 703 {
GregCr 4:c6ef863d0b07 704 uint8_t stat = 0;
GregCr 4:c6ef863d0b07 705 RadioStatus_t status;
GregCr 4:c6ef863d0b07 706
GregCr 4:c6ef863d0b07 707 ReadCommand( RADIO_GET_STATUS, ( uint8_t * )&stat, 1 );
GregCr 4:c6ef863d0b07 708 status.Value = stat;
GregCr 4:c6ef863d0b07 709 return status;
GregCr 4:c6ef863d0b07 710 }
GregCr 4:c6ef863d0b07 711
GregCr 4:c6ef863d0b07 712 int8_t SX126x::GetRssiInst( void )
GregCr 4:c6ef863d0b07 713 {
GregCr 4:c6ef863d0b07 714 int8_t rssi;
GregCr 4:c6ef863d0b07 715
GregCr 4:c6ef863d0b07 716 ReadCommand( RADIO_GET_RSSIINST, ( uint8_t* )&rssi, 1 );
GregCr 4:c6ef863d0b07 717 return( -( rssi / 2 ) );
GregCr 4:c6ef863d0b07 718 }
GregCr 4:c6ef863d0b07 719
GregCr 4:c6ef863d0b07 720 void SX126x::GetRxBufferStatus( uint8_t *payloadLength, uint8_t *rxStartBufferPointer )
GregCr 4:c6ef863d0b07 721 {
GregCr 4:c6ef863d0b07 722 uint8_t status[2];
GregCr 4:c6ef863d0b07 723
GregCr 4:c6ef863d0b07 724 ReadCommand( RADIO_GET_RXBUFFERSTATUS, status, 2 );
GregCr 4:c6ef863d0b07 725
GregCr 4:c6ef863d0b07 726 // In case of LORA fixed header, the payloadLength is obtained by reading
GregCr 4:c6ef863d0b07 727 // the register REG_LR_PAYLOADLENGTH
GregCr 4:c6ef863d0b07 728 if( ( this->GetPacketType( ) == PACKET_TYPE_LORA ) && ( ReadReg( REG_LR_PACKETPARAMS ) >> 7 == 1 ) )
GregCr 4:c6ef863d0b07 729 {
GregCr 4:c6ef863d0b07 730 *payloadLength = ReadReg( REG_LR_PAYLOADLENGTH );
GregCr 4:c6ef863d0b07 731 }
GregCr 4:c6ef863d0b07 732 else
GregCr 4:c6ef863d0b07 733 {
GregCr 4:c6ef863d0b07 734 *payloadLength = status[0];
GregCr 4:c6ef863d0b07 735 }
GregCr 4:c6ef863d0b07 736 *rxStartBufferPointer = status[1];
GregCr 4:c6ef863d0b07 737 }
GregCr 4:c6ef863d0b07 738
GregCr 4:c6ef863d0b07 739 void SX126x::GetPacketStatus( PacketStatus_t *pktStatus )
GregCr 4:c6ef863d0b07 740 {
GregCr 4:c6ef863d0b07 741 uint8_t status[3];
GregCr 4:c6ef863d0b07 742
GregCr 4:c6ef863d0b07 743 ReadCommand( RADIO_GET_PACKETSTATUS, status, 3 );
GregCr 4:c6ef863d0b07 744
GregCr 4:c6ef863d0b07 745 pktStatus->packetType = this -> GetPacketType( );
GregCr 4:c6ef863d0b07 746 switch( pktStatus->packetType )
GregCr 4:c6ef863d0b07 747 {
GregCr 4:c6ef863d0b07 748 case PACKET_TYPE_GFSK:
GregCr 4:c6ef863d0b07 749 pktStatus->Params.Gfsk.RxStatus = status[0];
GregCr 4:c6ef863d0b07 750 pktStatus->Params.Gfsk.RssiSync = -status[1] / 2;
GregCr 4:c6ef863d0b07 751 pktStatus->Params.Gfsk.RssiAvg = -status[2] / 2;
GregCr 4:c6ef863d0b07 752 pktStatus->Params.Gfsk.FreqError = 0;
GregCr 4:c6ef863d0b07 753 break;
GregCr 4:c6ef863d0b07 754
GregCr 4:c6ef863d0b07 755 case PACKET_TYPE_LORA:
GregCr 4:c6ef863d0b07 756 pktStatus->Params.LoRa.RssiPkt = -status[0] / 2;
GregCr 4:c6ef863d0b07 757 ( status[1] < 128 ) ? ( pktStatus->Params.LoRa.SnrPkt = status[1] / 4 ) : ( pktStatus->Params.LoRa.SnrPkt = ( ( status[1] - 256 ) /4 ) );
GregCr 4:c6ef863d0b07 758 pktStatus->Params.LoRa.SignalRssiPkt = -status[2] / 2;
GregCr 4:c6ef863d0b07 759 pktStatus->Params.LoRa.FreqError = FrequencyError;
GregCr 4:c6ef863d0b07 760 break;
GregCr 4:c6ef863d0b07 761
GregCr 4:c6ef863d0b07 762 default:
GregCr 4:c6ef863d0b07 763 case PACKET_TYPE_NONE:
GregCr 4:c6ef863d0b07 764 // In that specific case, we set everything in the pktStatus to zeros
GregCr 4:c6ef863d0b07 765 // and reset the packet type accordingly
GregCr 4:c6ef863d0b07 766 memset( pktStatus, 0, sizeof( PacketStatus_t ) );
GregCr 4:c6ef863d0b07 767 pktStatus->packetType = PACKET_TYPE_NONE;
GregCr 4:c6ef863d0b07 768 break;
GregCr 4:c6ef863d0b07 769 }
GregCr 4:c6ef863d0b07 770 }
GregCr 4:c6ef863d0b07 771
GregCr 4:c6ef863d0b07 772 RadioError_t SX126x::GetDeviceErrors( void )
GregCr 4:c6ef863d0b07 773 {
GregCr 4:c6ef863d0b07 774 RadioError_t error;
GregCr 4:c6ef863d0b07 775
GregCr 4:c6ef863d0b07 776 ReadCommand( RADIO_GET_ERROR, ( uint8_t * )&error, 2 );
GregCr 4:c6ef863d0b07 777 return error;
GregCr 4:c6ef863d0b07 778 }
GregCr 4:c6ef863d0b07 779
GregCr 4:c6ef863d0b07 780 void SX126x::ClearIrqStatus( uint16_t irq )
GregCr 4:c6ef863d0b07 781 {
GregCr 4:c6ef863d0b07 782 uint8_t buf[2];
GregCr 4:c6ef863d0b07 783 #ifdef ADV_DEBUG
GregCr 4:c6ef863d0b07 784 printf("ClearIrqStatus ");
GregCr 4:c6ef863d0b07 785 #endif
GregCr 4:c6ef863d0b07 786 buf[0] = ( uint8_t )( ( ( uint16_t )irq >> 8 ) & 0x00FF );
GregCr 4:c6ef863d0b07 787 buf[1] = ( uint8_t )( ( uint16_t )irq & 0x00FF );
GregCr 4:c6ef863d0b07 788 WriteCommand( RADIO_CLR_IRQSTATUS, buf, 2 );
GregCr 4:c6ef863d0b07 789 }
GregCr 4:c6ef863d0b07 790
GregCr 4:c6ef863d0b07 791 void SX126x::SetPollingMode( void )
GregCr 4:c6ef863d0b07 792 {
GregCr 4:c6ef863d0b07 793 this->PollingMode = true;
GregCr 4:c6ef863d0b07 794 }
GregCr 4:c6ef863d0b07 795
GregCr 4:c6ef863d0b07 796 void SX126x::SetInterruptMode( void )
GregCr 4:c6ef863d0b07 797 {
GregCr 4:c6ef863d0b07 798 this->PollingMode = false;
GregCr 0:deaafdfde3bb 799 }
GregCr 0:deaafdfde3bb 800
GregCr 2:4ff11ea92fbe 801 void SX126x::OnDioIrq( void )
GregCr 0:deaafdfde3bb 802 {
GregCr 4:c6ef863d0b07 803 /*
GregCr 4:c6ef863d0b07 804 * When polling mode is activated, it is up to the application to call
GregCr 4:c6ef863d0b07 805 * ProcessIrqs( ). Otherwise, the driver automatically calls ProcessIrqs( )
GregCr 4:c6ef863d0b07 806 * on radio interrupt.
GregCr 4:c6ef863d0b07 807 */
GregCr 4:c6ef863d0b07 808 if( this->PollingMode == true )
GregCr 4:c6ef863d0b07 809 {
GregCr 4:c6ef863d0b07 810 this->IrqState = true;
GregCr 4:c6ef863d0b07 811 }
GregCr 4:c6ef863d0b07 812 else
GregCr 0:deaafdfde3bb 813 {
GregCr 4:c6ef863d0b07 814 this->ProcessIrqs( );
GregCr 4:c6ef863d0b07 815 }
GregCr 4:c6ef863d0b07 816 }
GregCr 4:c6ef863d0b07 817
GregCr 4:c6ef863d0b07 818 void SX126x::ProcessIrqs( void )
GregCr 4:c6ef863d0b07 819 {
GregCr 4:c6ef863d0b07 820 if( this->PollingMode == true )
GregCr 4:c6ef863d0b07 821 {
GregCr 4:c6ef863d0b07 822 if( this->IrqState == true )
GregCr 4:c6ef863d0b07 823 {
GregCr 4:c6ef863d0b07 824 __disable_irq( );
GregCr 4:c6ef863d0b07 825 this->IrqState = false;
GregCr 4:c6ef863d0b07 826 __enable_irq( );
GregCr 4:c6ef863d0b07 827 }
GregCr 4:c6ef863d0b07 828 else
GregCr 4:c6ef863d0b07 829 {
GregCr 4:c6ef863d0b07 830 return;
GregCr 4:c6ef863d0b07 831 }
GregCr 0:deaafdfde3bb 832 }
GregCr 3:7e3595a9ebe0 833
GregCr 0:deaafdfde3bb 834 uint16_t irqRegs = GetIrqStatus( );
GregCr 0:deaafdfde3bb 835 ClearIrqStatus( IRQ_RADIO_ALL );
GregCr 0:deaafdfde3bb 836
GregCr 4:c6ef863d0b07 837 #ifdef ADV_DEBUG
GregCr 4:c6ef863d0b07 838 printf("0x%04x\n\r", irqRegs );
GregCr 4:c6ef863d0b07 839 #endif
GregCr 0:deaafdfde3bb 840
GregCr 4:c6ef863d0b07 841 if( ( irqRegs & IRQ_HEADER_VALID ) == IRQ_HEADER_VALID )
GregCr 0:deaafdfde3bb 842 {
GregCr 4:c6ef863d0b07 843 // LoRa Only
GregCr 4:c6ef863d0b07 844 FrequencyError = 0x000000 | ( ( 0x0F & ReadReg( 0x076A ) ) << 16 );
GregCr 4:c6ef863d0b07 845 FrequencyError = FrequencyError | ( ReadReg( 0x076B ) << 8 );
GregCr 4:c6ef863d0b07 846 FrequencyError = FrequencyError | ( ReadReg( 0x076c ) );
GregCr 0:deaafdfde3bb 847 }
GregCr 4:c6ef863d0b07 848
GregCr 4:c6ef863d0b07 849 if( ( irqRegs & IRQ_SYNCWORD_VALID ) == IRQ_SYNCWORD_VALID )
GregCr 4:c6ef863d0b07 850 {
GregCr 4:c6ef863d0b07 851 // GFSK Only
GregCr 4:c6ef863d0b07 852 FrequencyError = 0x000000 | ( ( 0x0F & ReadReg( 0x06B0 ) ) << 8 );
GregCr 4:c6ef863d0b07 853 FrequencyError = FrequencyError | ( ReadReg( 0x06B1 ) );
GregCr 4:c6ef863d0b07 854 }
GregCr 0:deaafdfde3bb 855
GregCr 3:7e3595a9ebe0 856 if( ( irqRegs & IRQ_TX_DONE ) == IRQ_TX_DONE )
GregCr 0:deaafdfde3bb 857 {
GregCr 0:deaafdfde3bb 858 if( txDone != NULL )
GregCr 0:deaafdfde3bb 859 {
GregCr 0:deaafdfde3bb 860 txDone( );
GregCr 0:deaafdfde3bb 861 }
GregCr 0:deaafdfde3bb 862 }
GregCr 0:deaafdfde3bb 863
GregCr 3:7e3595a9ebe0 864 if( ( irqRegs & IRQ_RX_DONE ) == IRQ_RX_DONE )
GregCr 0:deaafdfde3bb 865 {
GregCr 3:7e3595a9ebe0 866 if( ( irqRegs & IRQ_CRC_ERROR ) == IRQ_CRC_ERROR )
GregCr 0:deaafdfde3bb 867 {
GregCr 3:7e3595a9ebe0 868 if( rxError != NULL )
GregCr 3:7e3595a9ebe0 869 {
GregCr 3:7e3595a9ebe0 870 rxError( IRQ_CRC_ERROR_CODE );
GregCr 3:7e3595a9ebe0 871 }
GregCr 3:7e3595a9ebe0 872 }
GregCr 3:7e3595a9ebe0 873 else
GregCr 3:7e3595a9ebe0 874 {
GregCr 3:7e3595a9ebe0 875 if( rxDone != NULL )
GregCr 3:7e3595a9ebe0 876 {
GregCr 3:7e3595a9ebe0 877 rxDone( );
GregCr 3:7e3595a9ebe0 878 }
GregCr 0:deaafdfde3bb 879 }
GregCr 0:deaafdfde3bb 880 }
GregCr 0:deaafdfde3bb 881
GregCr 4:c6ef863d0b07 882 if( ( irqRegs & IRQ_CAD_DONE ) == IRQ_CAD_DONE )
GregCr 4:c6ef863d0b07 883 {
GregCr 4:c6ef863d0b07 884 if( cadDone != NULL )
GregCr 4:c6ef863d0b07 885 {
GregCr 4:c6ef863d0b07 886 cadDone( ( irqRegs & IRQ_CAD_ACTIVITY_DETECTED ) == IRQ_CAD_ACTIVITY_DETECTED );
GregCr 4:c6ef863d0b07 887 }
GregCr 4:c6ef863d0b07 888 }
GregCr 4:c6ef863d0b07 889
GregCr 3:7e3595a9ebe0 890 if( ( irqRegs & IRQ_RX_TX_TIMEOUT ) == IRQ_RX_TX_TIMEOUT )
GregCr 3:7e3595a9ebe0 891 {
GregCr 4:c6ef863d0b07 892 if( ( txTimeout != NULL ) && ( OperatingMode == MODE_TX ) )
GregCr 3:7e3595a9ebe0 893 {
GregCr 4:c6ef863d0b07 894 txTimeout( );
GregCr 3:7e3595a9ebe0 895 }
GregCr 4:c6ef863d0b07 896 else if( ( rxTimeout != NULL ) && ( OperatingMode == MODE_RX ) )
GregCr 3:7e3595a9ebe0 897 {
GregCr 4:c6ef863d0b07 898 rxTimeout( );
GregCr 3:7e3595a9ebe0 899 }
GregCr 3:7e3595a9ebe0 900 else
GregCr 3:7e3595a9ebe0 901 {
GregCr 4:c6ef863d0b07 902 assert_param( FAIL );
GregCr 3:7e3595a9ebe0 903 }
GregCr 3:7e3595a9ebe0 904 }
GregCr 3:7e3595a9ebe0 905
GregCr 3:7e3595a9ebe0 906 /*
GregCr 0:deaafdfde3bb 907 //IRQ_PREAMBLE_DETECTED = 0x0004,
GregCr 0:deaafdfde3bb 908 if( irqRegs & IRQ_PREAMBLE_DETECTED )
GregCr 0:deaafdfde3bb 909 {
GregCr 0:deaafdfde3bb 910 if( rxPblSyncWordHeader != NULL )
GregCr 0:deaafdfde3bb 911 {
GregCr 0:deaafdfde3bb 912 rxPblSyncWordHeader( IRQ_PBL_DETECT_CODE);
GregCr 3:7e3595a9ebe0 913
GregCr 0:deaafdfde3bb 914 }
GregCr 0:deaafdfde3bb 915 }
GregCr 0:deaafdfde3bb 916
GregCr 0:deaafdfde3bb 917 //IRQ_SYNCWORD_VALID = 0x0008,
GregCr 0:deaafdfde3bb 918 if( irqRegs & IRQ_SYNCWORD_VALID )
GregCr 0:deaafdfde3bb 919 {
GregCr 0:deaafdfde3bb 920 if( rxPblSyncWordHeader != NULL )
GregCr 0:deaafdfde3bb 921 {
GregCr 0:deaafdfde3bb 922 rxPblSyncWordHeader( IRQ_SYNCWORD_VALID_CODE );
GregCr 0:deaafdfde3bb 923 }
GregCr 0:deaafdfde3bb 924 }
GregCr 0:deaafdfde3bb 925
GregCr 0:deaafdfde3bb 926 //IRQ_HEADER_VALID = 0x0010,
GregCr 0:deaafdfde3bb 927 if ( irqRegs & IRQ_HEADER_VALID )
GregCr 0:deaafdfde3bb 928 {
GregCr 0:deaafdfde3bb 929 if( rxPblSyncWordHeader != NULL )
GregCr 0:deaafdfde3bb 930 {
GregCr 3:7e3595a9ebe0 931 rxPblSyncWordHeader( IRQ_HEADER_VALID_CODE );
GregCr 0:deaafdfde3bb 932 }
GregCr 0:deaafdfde3bb 933 }
GregCr 0:deaafdfde3bb 934
GregCr 4:c6ef863d0b07 935 //IRQ_HEADER_ERROR = 0x0020,
GregCr 0:deaafdfde3bb 936 if( irqRegs & IRQ_HEADER_ERROR )
GregCr 0:deaafdfde3bb 937 {
GregCr 0:deaafdfde3bb 938 if( rxError != NULL )
GregCr 0:deaafdfde3bb 939 {
GregCr 0:deaafdfde3bb 940 rxError( IRQ_HEADER_ERROR_CODE );
GregCr 0:deaafdfde3bb 941 }
GregCr 0:deaafdfde3bb 942 }
GregCr 4:c6ef863d0b07 943 */
GregCr 0:deaafdfde3bb 944 }
GregCr 0:deaafdfde3bb 945
GregCr 0:deaafdfde3bb 946
GregCr 0:deaafdfde3bb 947