1 /*!
2 * \file sx1272mb2das-board.c
3 *
4 * \brief Target board SX1272MB2DAS 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 "delay.h"
27 #include "radio.h"
28 #include "sx1272-board.h"
29
30 /*!
31 * \brief Gets the board PA selection configuration
32 *
33 * \param [IN] channel Channel frequency in Hz
34 * \retval PaSelect RegPaConfig PaSelect value
35 */
36 static uint8_t SX1272GetPaSelect( uint32_t channel );
37
38 /*!
39 * Flag used to set the RF switch control pins in low power mode when the radio is not active.
40 */
41 static bool RadioIsActive = false;
42
43 /*!
44 * Radio driver structure initialization
45 */
46 const struct Radio_s Radio =
47 {
48 SX1272Init,
49 SX1272GetStatus,
50 SX1272SetModem,
51 SX1272SetChannel,
52 SX1272IsChannelFree,
53 SX1272Random,
54 SX1272SetRxConfig,
55 SX1272SetTxConfig,
56 SX1272CheckRfFrequency,
57 SX1272GetTimeOnAir,
58 SX1272Send,
59 SX1272SetSleep,
60 SX1272SetStby,
61 SX1272SetRx,
62 SX1272StartCad,
63 SX1272SetTxContinuousWave,
64 SX1272ReadRssi,
65 SX1272Write,
66 SX1272Read,
67 SX1272WriteBuffer,
68 SX1272ReadBuffer,
69 SX1272SetMaxPayloadLength,
70 SX1272SetPublicNetwork,
71 SX1272GetWakeupTime,
72 NULL, // void ( *IrqProcess )( void )
73 NULL, // void ( *RxBoosted )( uint32_t timeout ) - SX126x Only
74 NULL, // void ( *SetRxDutyCycle )( uint32_t rxTime, uint32_t sleepTime ) - SX126x Only
75 };
76
77 /*!
78 * Antenna switch GPIO pins objects
79 */
80 Gpio_t AntSwitch;
81
82 /*!
83 * Debug GPIO pins objects
84 */
85 #if defined( USE_RADIO_DEBUG )
86 Gpio_t DbgPinTx;
87 Gpio_t DbgPinRx;
88 #endif
89
SX1272IoInit(void)90 void SX1272IoInit( void )
91 {
92 GpioInit( &SX1272.Spi.Nss, RADIO_NSS, PIN_OUTPUT, PIN_PUSH_PULL, PIN_NO_PULL, 1 );
93
94 GpioInit( &SX1272.DIO0, RADIO_DIO_0, PIN_INPUT, PIN_PUSH_PULL, PIN_PULL_UP, 0 );
95 GpioInit( &SX1272.DIO1, RADIO_DIO_1, PIN_INPUT, PIN_PUSH_PULL, PIN_PULL_UP, 0 );
96 GpioInit( &SX1272.DIO2, RADIO_DIO_2, PIN_INPUT, PIN_PUSH_PULL, PIN_PULL_UP, 0 );
97 GpioInit( &SX1272.DIO3, RADIO_DIO_3, PIN_INPUT, PIN_PUSH_PULL, PIN_PULL_UP, 0 );
98 // DIO4 and DIO5 aren't connected.
99 // Initialize Gpio_t port to NULL.
100 SX1272.DIO4.port = NULL;
101 SX1272.DIO5.port = NULL;
102 }
103
SX1272IoIrqInit(DioIrqHandler ** irqHandlers)104 void SX1272IoIrqInit( DioIrqHandler **irqHandlers )
105 {
106 GpioSetInterrupt( &SX1272.DIO0, IRQ_RISING_EDGE, IRQ_HIGH_PRIORITY, irqHandlers[0] );
107 GpioSetInterrupt( &SX1272.DIO1, IRQ_RISING_FALLING_EDGE, IRQ_HIGH_PRIORITY, irqHandlers[1] );
108 GpioSetInterrupt( &SX1272.DIO2, IRQ_RISING_EDGE, IRQ_HIGH_PRIORITY, irqHandlers[2] );
109 GpioSetInterrupt( &SX1272.DIO3, IRQ_RISING_EDGE, IRQ_HIGH_PRIORITY, irqHandlers[3] );
110 }
111
SX1272IoDeInit(void)112 void SX1272IoDeInit( void )
113 {
114 GpioInit( &SX1272.Spi.Nss, RADIO_NSS, PIN_OUTPUT, PIN_PUSH_PULL, PIN_NO_PULL, 1 );
115
116 GpioInit( &SX1272.DIO0, RADIO_DIO_0, PIN_INPUT, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
117 GpioInit( &SX1272.DIO1, RADIO_DIO_1, PIN_INPUT, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
118 GpioInit( &SX1272.DIO2, RADIO_DIO_2, PIN_INPUT, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
119 GpioInit( &SX1272.DIO3, RADIO_DIO_3, PIN_INPUT, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
120 }
121
SX1272IoDbgInit(void)122 void SX1272IoDbgInit( void )
123 {
124 #if defined( USE_RADIO_DEBUG )
125 GpioInit( &DbgPinTx, RADIO_DBG_PIN_TX, PIN_OUTPUT, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
126 GpioInit( &DbgPinRx, RADIO_DBG_PIN_RX, PIN_OUTPUT, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
127 #endif
128 }
129
SX1272IoTcxoInit(void)130 void SX1272IoTcxoInit( void )
131 {
132 // No TCXO component available on this board design.
133 }
134
SX1272SetBoardTcxo(uint8_t state)135 void SX1272SetBoardTcxo( uint8_t state )
136 {
137 // No TCXO component available on this board design.
138 #if 0
139 if( state == true )
140 {
141 TCXO_ON( );
142 DelayMs( BOARD_TCXO_WAKEUP_TIME );
143 }
144 else
145 {
146 TCXO_OFF( );
147 }
148 #endif
149 }
150
SX1272GetBoardTcxoWakeupTime(void)151 uint32_t SX1272GetBoardTcxoWakeupTime( void )
152 {
153 return BOARD_TCXO_WAKEUP_TIME;
154 }
155
SX1272Reset(void)156 void SX1272Reset( void )
157 {
158 // Enables the TCXO if available on the board design
159 SX1272SetBoardTcxo( true );
160
161 // Set RESET pin to 1
162 GpioInit( &SX1272.Reset, RADIO_RESET, PIN_OUTPUT, PIN_PUSH_PULL, PIN_NO_PULL, 1 );
163
164 // Wait 1 ms
165 DelayMs( 1 );
166
167 // Configure RESET as input
168 GpioInit( &SX1272.Reset, RADIO_RESET, PIN_INPUT, PIN_PUSH_PULL, PIN_NO_PULL, 1 );
169
170 // Wait 6 ms
171 DelayMs( 6 );
172 }
173
SX1272SetRfTxPower(int8_t power)174 void SX1272SetRfTxPower( int8_t power )
175 {
176 uint8_t paConfig = 0;
177 uint8_t paDac = 0;
178
179 paConfig = SX1272Read( REG_PACONFIG );
180 paDac = SX1272Read( REG_PADAC );
181
182 paConfig = ( paConfig & RF_PACONFIG_PASELECT_MASK ) | SX1272GetPaSelect( SX1272.Settings.Channel );
183
184 if( ( paConfig & RF_PACONFIG_PASELECT_PABOOST ) == RF_PACONFIG_PASELECT_PABOOST )
185 {
186 if( power > 17 )
187 {
188 paDac = ( paDac & RF_PADAC_20DBM_MASK ) | RF_PADAC_20DBM_ON;
189 }
190 else
191 {
192 paDac = ( paDac & RF_PADAC_20DBM_MASK ) | RF_PADAC_20DBM_OFF;
193 }
194 if( ( paDac & RF_PADAC_20DBM_ON ) == RF_PADAC_20DBM_ON )
195 {
196 if( power < 5 )
197 {
198 power = 5;
199 }
200 if( power > 20 )
201 {
202 power = 20;
203 }
204 paConfig = ( paConfig & RFLR_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power - 5 ) & 0x0F );
205 }
206 else
207 {
208 if( power < 2 )
209 {
210 power = 2;
211 }
212 if( power > 17 )
213 {
214 power = 17;
215 }
216 paConfig = ( paConfig & RFLR_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power - 2 ) & 0x0F );
217 }
218 }
219 else
220 {
221 if( power < -1 )
222 {
223 power = -1;
224 }
225 if( power > 14 )
226 {
227 power = 14;
228 }
229 paConfig = ( paConfig & RFLR_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power + 1 ) & 0x0F );
230 }
231 SX1272Write( REG_PACONFIG, paConfig );
232 SX1272Write( REG_PADAC, paDac );
233 }
234
SX1272GetPaSelect(uint32_t channel)235 static uint8_t SX1272GetPaSelect( uint32_t channel )
236 {
237 return RF_PACONFIG_PASELECT_RFO;
238 }
239
SX1272SetAntSwLowPower(bool status)240 void SX1272SetAntSwLowPower( bool status )
241 {
242 if( RadioIsActive != status )
243 {
244 RadioIsActive = status;
245
246 if( status == false )
247 {
248 SX1272AntSwInit( );
249 }
250 else
251 {
252 SX1272AntSwDeInit( );
253 }
254 }
255 }
256
SX1272AntSwInit(void)257 void SX1272AntSwInit( void )
258 {
259 GpioInit( &AntSwitch, RADIO_ANT_SWITCH, PIN_OUTPUT, PIN_PUSH_PULL, PIN_PULL_UP, 0 );
260 }
261
SX1272AntSwDeInit(void)262 void SX1272AntSwDeInit( void )
263 {
264 GpioInit( &AntSwitch, RADIO_ANT_SWITCH, PIN_ANALOGIC, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
265 }
266
SX1272SetAntSw(uint8_t opMode)267 void SX1272SetAntSw( uint8_t opMode )
268 {
269 switch( opMode )
270 {
271 case RFLR_OPMODE_TRANSMITTER:
272 GpioWrite( &AntSwitch, 1 );
273 break;
274 case RFLR_OPMODE_RECEIVER:
275 case RFLR_OPMODE_RECEIVER_SINGLE:
276 case RFLR_OPMODE_CAD:
277 default:
278 GpioWrite( &AntSwitch, 0 );
279 break;
280 }
281 }
282
SX1272CheckRfFrequency(uint32_t frequency)283 bool SX1272CheckRfFrequency( uint32_t frequency )
284 {
285 // Implement check. Currently all frequencies are supported
286 return true;
287 }
288
SX1272GetDio1PinState(void)289 uint32_t SX1272GetDio1PinState( void )
290 {
291 return GpioRead( &SX1272.DIO1 );
292 }
293
294 #if defined( USE_RADIO_DEBUG )
SX1272DbgPinTxWrite(uint8_t state)295 void SX1272DbgPinTxWrite( uint8_t state )
296 {
297 GpioWrite( &DbgPinTx, state );
298 }
299
SX1272DbgPinRxWrite(uint8_t state)300 void SX1272DbgPinRxWrite( uint8_t state )
301 {
302 GpioWrite( &DbgPinRx, state );
303 }
304 #endif
305