25
25
#include " RFM95.h"
26
26
27
27
#if defined(LINUX_ARCH_RASPBERRYPI)
28
- uint8_t spi_rxbuff[ 32 + 1 ]; // SPI receive buffer (payload max 32 bytes, MYS protocol limitation )
29
- uint8_t spi_txbuff[ 32 +
30
- 1 ]; // SPI transmit buffer (payload max 32 bytes + 1 byte for the command, MYS protocol limitation)
28
+ // SPI RX and TX buffers ( max packet len + 1 byte for the command )
29
+ uint8_t spi_rxbuff[RFM95_MAX_PACKET_LEN + 1 ];
30
+ uint8_t spi_txbuff[RFM95_MAX_PACKET_LEN + 1 ];
31
31
#endif
32
32
33
+ volatile rfm95_internal_t RFM95; // !< internal variables
34
+
33
35
LOCAL void RFM95_csn (const bool level)
34
36
{
35
37
hwDigitalWrite (MY_RFM95_SPI_CS, level);
@@ -110,10 +112,6 @@ LOCAL uint8_t RFM95_RAW_writeByteRegister(const uint8_t address, uint8_t value)
110
112
#define RFM95_burstReadReg (__reg, __buf, __len ) RFM95_spiMultiByteTransfer( __reg & RFM95_READ_REGISTER, (uint8_t *)__buf, __len, true )
111
113
#define RFM95_burstWriteReg (__reg, __buf, __len ) RFM95_spiMultiByteTransfer( __reg | RFM95_WRITE_REGISTER, (uint8_t *)__buf, __len, false )
112
114
113
-
114
- // check RegPktRssiValue (0x1A) vs. RegRssiValue (0x1B)
115
-
116
-
117
115
LOCAL bool RFM95_initialise (const float frequency)
118
116
{
119
117
RFM95_DEBUG (PSTR (" RFM95:INIT\n " ));
@@ -134,7 +132,7 @@ LOCAL bool RFM95_initialise(const float frequency)
134
132
RFM95.txSequenceNumber = 0 ; // initialise TX sequence counter
135
133
RFM95.powerLevel = 0 ;
136
134
RFM95.ATCenabled = false ;
137
- RFM95.ATCtargetRSSI = RFM95_TARGET_RSSI + RFM95_RSSI_OFFSET ;
135
+ RFM95.ATCtargetRSSI = RFM95_RSSItoInternal ( RFM95_TARGET_RSSI) ;
138
136
139
137
// SPI init
140
138
hwDigitalWrite (MY_RFM95_SPI_CS, HIGH);
@@ -143,8 +141,7 @@ LOCAL bool RFM95_initialise(const float frequency)
143
141
144
142
// Set LoRa mode (during sleep mode)
145
143
RFM95_writeReg (RFM95_REG_01_OP_MODE, RFM95_MODE_SLEEP | RFM95_LONG_RANGE_MODE);
146
- delay (10 ); // Wait for sleep mode to take over from say, CAD
147
- // Check we are in sleep mode, with LORA set
144
+ delay (10 ); // Wait for sleep mode to take over
148
145
if (RFM95_readReg (RFM95_REG_01_OP_MODE) != (RFM95_MODE_SLEEP | RFM95_LONG_RANGE_MODE)) {
149
146
return false ; // No device present?
150
147
}
@@ -167,8 +164,14 @@ LOCAL bool RFM95_initialise(const float frequency)
167
164
#if defined (SPI_HAS_TRANSACTION) && !defined (ESP8266)
168
165
_SPI.usingInterrupt (digitalPinToInterrupt (MY_RFM95_IRQ_PIN));
169
166
#endif
170
- attachInterrupt (digitalPinToInterrupt (MY_RFM95_IRQ_PIN), RFM95_interruptHandler, RISING);
171
167
168
+ if (!RFM95_sanityCheck ()) {
169
+ RFM95_DEBUG (
170
+ PSTR (" !RFM95:INIT:SANCHK FAIL\n " )); // sanity check failed, check wiring or replace module
171
+ return false ;
172
+ }
173
+
174
+ attachInterrupt (digitalPinToInterrupt (MY_RFM95_IRQ_PIN), RFM95_interruptHandler, RISING);
172
175
return true ;
173
176
}
174
177
@@ -191,7 +194,8 @@ LOCAL void RFM95_interruptHandler(void)
191
194
// Reset the fifo read ptr to the beginning of the packet
192
195
RFM95_writeReg (RFM95_REG_0D_FIFO_ADDR_PTR, RFM95_readReg (RFM95_REG_10_FIFO_RX_CURRENT_ADDR));
193
196
RFM95_burstReadReg (RFM95_REG_00_FIFO, RFM95.currentPacket .data , bufLen);
194
- RFM95.currentPacket .RSSI = RFM95_readReg (RFM95_REG_1A_PKT_RSSI_VALUE);
197
+ RFM95.currentPacket .RSSI = RFM95_readReg (
198
+ RFM95_REG_1A_PKT_RSSI_VALUE); // RSSI of latest packet received
195
199
RFM95.currentPacket .SNR = static_cast <rfm95_SNR_t>(RFM95_readReg (RFM95_REG_19_PKT_SNR_VALUE));
196
200
RFM95.currentPacket .payloadLen = bufLen - RFM95_HEADER_LEN;
197
201
// Message for us
@@ -244,14 +248,13 @@ LOCAL uint8_t RFM95_recv(uint8_t* buf)
244
248
const rfm95_RSSI_t RSSI = RFM95.currentPacket .RSSI ; // of incoming packet
245
249
const rfm95_SNR_t SNR = RFM95.currentPacket .SNR ;
246
250
if (buf != NULL ) {
247
- memcpy ((void *)buf, (void *)RFM95.currentPacket .payload , payloadLen);
251
+ ( void ) memcpy ((void *)buf, (void *)RFM95.currentPacket .payload , payloadLen);
248
252
RFM95.rxBufferValid = false ;
249
253
}
250
254
interrupts ();
251
255
252
256
// ACK handling
253
257
if (RFM95_getACKRequested (controlFlags)) {
254
- RFM95_DEBUG (PSTR (" RFM95:RCV:SEND ACK\n " ));
255
258
RFM95_sendACK (sender, sequenceNumber, RSSI, SNR);
256
259
}
257
260
@@ -262,9 +265,8 @@ LOCAL bool RFM95_send(rfm95_packet_t &packet)
262
265
{
263
266
const uint8_t finalLen = packet.payloadLen + RFM95_HEADER_LEN;
264
267
// Make sure we dont interrupt an outgoing message
265
- RFM95_waitPacketSent ();
268
+ ( void ) RFM95_waitPacketSent ();
266
269
(void )RFM95_setRadioMode (RFM95_RADIO_MODE_STDBY);
267
-
268
270
// Check channel activity
269
271
if (!RFM95_waitCAD ()) {
270
272
return false ;
@@ -289,9 +291,9 @@ LOCAL bool RFM95_sendFrame(const uint8_t recipient, uint8_t* data, const uint8_t
289
291
packet.header .sender = RFM95.address ;
290
292
packet.header .recipient = recipient;
291
293
packet.header .controlFlags = 0x00 ;
292
- packet.payloadLen = min (len, (const uint8_t )RFM95_MAX_PAYLOAD_LEN);
294
+ packet.payloadLen = min (len, (uint8_t )RFM95_MAX_PAYLOAD_LEN);
293
295
packet.header .controlFlags = flags;
294
- memcpy (&packet.payload , data, packet.payloadLen );
296
+ ( void ) memcpy (&packet.payload , data, packet.payloadLen );
295
297
return RFM95_send (packet);
296
298
}
297
299
@@ -314,8 +316,7 @@ LOCAL bool RFM95_setTxPower(uint8_t powerLevel)
314
316
if (powerLevel > 20 ) {
315
317
// enable DAC, adds 3dBm
316
318
// The documentation is pretty confusing on this topic: PaSelect says the max power is 20dBm,
317
- // but OutputPower claims it would be 17dBm.
318
- // My measurements show 20dBm is correct
319
+ // but OutputPower claims it would be 17dBm. Measurements show 20dBm is correct
319
320
RFM95_writeReg (RFM95_REG_4D_PA_DAC, RFM95_PA_DAC_ENABLE);
320
321
val = powerLevel - 8 ;
321
322
} else {
@@ -354,17 +355,6 @@ LOCAL uint8_t RFM95_getAddress(void)
354
355
return RFM95.address ;
355
356
}
356
357
357
-
358
- LOCAL bool RFM95_isChannelActive (void )
359
- {
360
- (void )RFM95_setRadioMode (RFM95_RADIO_MODE_CAD);
361
- while (RFM95.radioMode == RFM95_RADIO_MODE_CAD) {
362
- doYield ();
363
- }
364
-
365
- return RFM95.cad ;
366
- }
367
-
368
358
LOCAL bool RFM95_setRadioMode (const rfm95_radioMode_t newRadioMode)
369
359
{
370
360
if (RFM95.radioMode == newRadioMode) {
@@ -403,7 +393,7 @@ LOCAL bool RFM95_sleep(void)
403
393
LOCAL void RFM95_sendACK (const uint8_t recipient, const rfm95_sequenceNumber_t sequenceNumber,
404
394
const rfm95_RSSI_t RSSI, const rfm95_RSSI_t SNR)
405
395
{
406
- RFM95_DEBUG (PSTR (" RFM95:SAC:SEND ACK to=%d,RSSI=%d\n " ),recipient,RSSI);
396
+ RFM95_DEBUG (PSTR (" RFM95:SAC:SEND ACK to=%d,RSSI=%d\n " ),recipient,RFM95_internalToRSSI ( RSSI) );
407
397
rfm95_ack_t ACK;
408
398
ACK.sequenceNumber = sequenceNumber;
409
399
ACK.RSSI = RSSI;
@@ -416,19 +406,21 @@ LOCAL void RFM95_sendACK(const uint8_t recipient, const rfm95_sequenceNumber_t s
416
406
417
407
LOCAL bool RFM95_executeATC (const rfm95_RSSI_t currentRSSI, const rfm95_RSSI_t targetRSSI)
418
408
{
419
- // allow +-5%
420
- if (currentRSSI < (targetRSSI*1.05 ) && RFM95.powerLevel < RFM95_MAX_POWER_LEVEL_DBM) {
409
+ // RFM95 internal format RSSI has an offset
410
+ if (currentRSSI < (targetRSSI * (1 + RFM95_ATC_TARGET_RANGE_PERCENT / 100 )) &&
411
+ RFM95.powerLevel < RFM95_MAX_POWER_LEVEL_DBM) {
421
412
// increase transmitter power
422
413
RFM95.powerLevel ++;
423
- } else if (currentRSSI > (targetRSSI*0.95 ) && RFM95.powerLevel > RFM95_MIN_POWER_LEVEL_DBM) {
414
+ } else if (currentRSSI > (targetRSSI * (1 - RFM95_ATC_TARGET_RANGE_PERCENT / 100 )) &&
415
+ RFM95.powerLevel > RFM95_MIN_POWER_LEVEL_DBM) {
424
416
// decrease transmitter power
425
417
RFM95.powerLevel --;
426
418
} else {
427
419
// nothing to adjust
428
420
return false ;
429
421
}
430
- RFM95_DEBUG (PSTR (" RFM95:ATC:ADJ TXL,cR=%d,tR=%d,TXL=%d\n " ), currentRSSI - RFM95_RSSI_OFFSET ,
431
- targetRSSI - RFM95_RSSI_OFFSET , RFM95.powerLevel );
422
+ RFM95_DEBUG (PSTR (" RFM95:ATC:ADJ TXL,cR=%d,tR=%d,TXL=%d\n " ), RFM95_internalToRSSI ( currentRSSI) ,
423
+ RFM95_internalToRSSI ( targetRSSI) , RFM95.powerLevel );
432
424
return RFM95_setTxPower (RFM95.powerLevel );;
433
425
}
434
426
@@ -454,7 +446,8 @@ LOCAL bool RFM95_sendWithRetry(const uint8_t recipient, const void* buffer,
454
446
if (sender == recipient && RFM95_getACKReceived (flag) &&
455
447
(ACKsequenceNumber == RFM95.txSequenceNumber - 1 )) {
456
448
RFM95_DEBUG (PSTR (" RFM95:SWR:ACK FROM=%d,SEQ=%d,RSSI=%d,SNR=%d\n " ),sender,ACKsequenceNumber,
457
- RFM95.currentPacket .ACK .RSSI -RFM95_RSSI_OFFSET, (int8_t )RFM95.currentPacket .ACK .SNR / 4 );
449
+ RFM95_internalToRSSI (RFM95.currentPacket .ACK .RSSI ),
450
+ RFM95_internalToSNR (RFM95.currentPacket .ACK .SNR ));
458
451
RFM95_clearRxBuffer ();
459
452
460
453
// ATC
@@ -469,24 +462,24 @@ LOCAL bool RFM95_sendWithRetry(const uint8_t recipient, const void* buffer,
469
462
RFM95_DEBUG (PSTR (" !RFM95:SWR:NACK\n " ));
470
463
if (RFM95.ATCenabled ) {
471
464
// No ACK received, maybe out of reach: increase power level
472
- RFM95_setTxPower (RFM95.powerLevel ++);
465
+ ( void ) RFM95_setTxPower (RFM95.powerLevel ++);
473
466
}
474
467
}
475
468
return false ;
476
469
}
477
470
478
-
479
471
// Wait until no channel activity detected or timeout
480
472
LOCAL bool RFM95_waitCAD (void )
481
473
{
474
+ (void )RFM95_setRadioMode (RFM95_RADIO_MODE_CAD);
482
475
const uint32_t enterMS = hwMillis ();
483
- while (RFM95_isChannelActive () ) {
476
+ while (RFM95. radioMode == RFM95_RADIO_MODE_CAD ) {
484
477
if (hwMillis () - enterMS > RFM95_CAD_TIMEOUT_MS) {
485
478
return false ;
486
479
}
487
480
doYield ();
488
481
}
489
- return true ;
482
+ return !RFM95. cad ;
490
483
}
491
484
492
485
// Wait for any previous transmission to finish
@@ -498,15 +491,10 @@ LOCAL bool RFM95_waitPacketSent(void)
498
491
return true ;
499
492
}
500
493
501
- LOCAL int16_t RFM95_getRSSI (void )
502
- {
503
- return (int16_t )(RFM95.currentPacket .RSSI - RFM95_RSSI_OFFSET);
504
- }
505
-
506
494
LOCAL void RFM95_ATCmode (const bool OnOff, const int16_t targetRSSI)
507
495
{
508
496
RFM95.ATCenabled = OnOff;
509
- RFM95.ATCtargetRSSI = ( uint8_t )( targetRSSI + RFM95_RSSI_OFFSET );
497
+ RFM95.ATCtargetRSSI = RFM95_RSSItoInternal ( targetRSSI);
510
498
}
511
499
512
500
LOCAL bool RFM95_sanityCheck (void )
@@ -516,11 +504,46 @@ LOCAL bool RFM95_sanityCheck(void)
516
504
}
517
505
518
506
507
+ LOCAL int16_t RFM95_getSendingRSSI (void )
508
+ {
509
+ // own RSSI, as measured by the recipient - ACK part
510
+ if (RFM95_getACKRSSIReport (RFM95.currentPacket .header .controlFlags )) {
511
+ return RFM95_internalToRSSI (RFM95.currentPacket .ACK .RSSI );
512
+ } else {
513
+ // not possible
514
+ return RFM95_RSSI_INVALID;
515
+ }
516
+ }
519
517
518
+ LOCAL int8_t RFM95_getSendingSNR (void )
519
+ {
520
+ // own SNR, as measured by the recipient - ACK part
521
+ if (RFM95_getACKRSSIReport (RFM95.currentPacket .header .controlFlags )) {
522
+ return RFM95_internalToSNR (RFM95.currentPacket .ACK .SNR );
523
+ } else {
524
+ // not possible
525
+ return RFM95_SNR_INVALID;
526
+ }
527
+ }
520
528
529
+ LOCAL int16_t RFM95_getReceivingRSSI (void )
530
+ {
531
+ // RSSI from last received packet
532
+ return RFM95_internalToRSSI (RFM95.currentPacket .RSSI );
533
+ }
521
534
535
+ LOCAL int8_t RFM95_getReceivingSNR (void )
536
+ {
537
+ // SNR from last received packet
538
+ return RFM95_internalToSNR (RFM95.currentPacket .SNR );
539
+ }
522
540
523
-
524
-
525
-
541
+ LOCAL uint8_t RFM95_getTxPowerPercent (void )
542
+ {
543
+ // report TX level in %
544
+ const uint8_t result = (uint8_t )(100 .0f * (RFM95.powerLevel - RFM95_MIN_POWER_LEVEL_DBM) /
545
+ (RFM95_MAX_POWER_LEVEL_DBM
546
+ - RFM95_MIN_POWER_LEVEL_DBM));
547
+ return result;
548
+ }
526
549
0 commit comments