Merge pull request #649 from tekka007/transportRFM95Update
RFM95 updates for RPI
This commit is contained in:
+56
-19
@@ -24,6 +24,11 @@
|
||||
|
||||
#include "RFM95.h"
|
||||
|
||||
#if defined(LINUX_ARCH_RASPBERRYPI)
|
||||
uint8_t spi_rxbuff[32 + 1]; //SPI receive buffer (payload max 32 bytes, MYS protocol limitation)
|
||||
uint8_t spi_txbuff[32 + 1]; //SPI transmit buffer (payload max 32 bytes + 1 byte for the command, MYS protocol limitation)
|
||||
#endif
|
||||
|
||||
LOCAL void RFM95_csn(const bool level) {
|
||||
hwDigitalWrite(MY_RFM95_SPI_CS, level);
|
||||
}
|
||||
@@ -31,11 +36,41 @@ LOCAL void RFM95_csn(const bool level) {
|
||||
LOCAL uint8_t RFM95_spiMultiByteTransfer(const uint8_t cmd, uint8_t* buf, uint8_t len, const bool aReadMode) {
|
||||
uint8_t status;
|
||||
uint8_t* current = buf;
|
||||
noInterrupts();
|
||||
#if !defined(MY_SOFTSPI)
|
||||
_SPI.beginTransaction(SPISettings(MY_RFM95_SPI_MAX_SPEED, MY_RFM95_SPI_DATA_ORDER, MY_RFM95_SPI_DATA_MODE));
|
||||
#endif
|
||||
RFM95_csn(LOW);
|
||||
#if defined(LINUX_ARCH_RASPBERRYPI)
|
||||
uint8_t * prx = spi_rxbuff;
|
||||
uint8_t * ptx = spi_txbuff;
|
||||
uint8_t size = len + 1; // Add register value to transmit buffer
|
||||
|
||||
*ptx++ = cmd;
|
||||
while (len--) {
|
||||
if (aReadMode) {
|
||||
*ptx++ = RF24_NOP;
|
||||
}
|
||||
else {
|
||||
*ptx++ = *current++;
|
||||
}
|
||||
}
|
||||
_SPI.transfernb((char *)spi_txbuff, (char *)spi_rxbuff, size);
|
||||
if (aReadMode) {
|
||||
if (size == 2) {
|
||||
status = *++prx; // result is 2nd byte of receive buffer
|
||||
}
|
||||
else {
|
||||
status = *prx++; // status is 1st byte of receive buffer
|
||||
// decrement before to skip status byte
|
||||
while (--size) {
|
||||
*buf++ = *prx++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
status = *prx; // status is 1st byte of receive buffer
|
||||
}
|
||||
#else
|
||||
status = _SPI.transfer(cmd);
|
||||
while (len--) {
|
||||
if (aReadMode) {
|
||||
@@ -46,11 +81,11 @@ LOCAL uint8_t RFM95_spiMultiByteTransfer(const uint8_t cmd, uint8_t* buf, uint8_
|
||||
}
|
||||
else status = _SPI.transfer(*current++);
|
||||
}
|
||||
#endif
|
||||
RFM95_csn(HIGH);
|
||||
#if !defined(MY_SOFTSPI)
|
||||
_SPI.endTransaction();
|
||||
#endif
|
||||
interrupts();
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -114,9 +149,9 @@ LOCAL bool RFM95_initialise(const float frequency) {
|
||||
RFM95_writeReg(RFM95_REG_23_MAX_PAYLOAD_LENGTH, RFM95_MAX_PACKET_LEN);
|
||||
|
||||
(void)RFM95_setRadioMode(RFM95_RADIO_MODE_STDBY);
|
||||
const modemConfig_t configuration = { MY_RFM95_MODEM_CONFIGRUATION };
|
||||
const rfm95_modemConfig_t configuration = { MY_RFM95_MODEM_CONFIGRUATION };
|
||||
RFM95_setModemRegisters(configuration);
|
||||
RFM95_setPreambleLength(8); // default
|
||||
RFM95_setPreambleLength(RFM95_PREAMBLE_LENGTH);
|
||||
RFM95_setFrequency(frequency);
|
||||
// set power level
|
||||
RFM95_setTxPower(MY_RFM95_TX_POWER);
|
||||
@@ -134,12 +169,12 @@ LOCAL bool RFM95_initialise(const float frequency) {
|
||||
// RxDone, TxDone, CADDone is mapped to DI0
|
||||
LOCAL void RFM95_interruptHandler(void) {
|
||||
// Read the interrupt register
|
||||
const uint8_t irq_flags = RFM95_readReg(RFM95_REG_12_IRQ_FLAGS);
|
||||
if (RFM95.radioMode == RFM95_RADIO_MODE_RX && (irq_flags & (RFM95_RX_TIMEOUT | RFM95_PAYLOAD_CRC_ERROR)) ) {
|
||||
const uint8_t irqFlags = RFM95_readReg(RFM95_REG_12_IRQ_FLAGS);
|
||||
if (RFM95.radioMode == RFM95_RADIO_MODE_RX && (irqFlags & (RFM95_RX_TIMEOUT | RFM95_PAYLOAD_CRC_ERROR)) ) {
|
||||
// CRC error or timeout
|
||||
// RXcontinuous mode: radio stays in RX mode, clearing IRQ needed
|
||||
}
|
||||
else if (RFM95.radioMode == RFM95_RADIO_MODE_RX && (irq_flags & RFM95_RX_DONE)) {
|
||||
else if (RFM95.radioMode == RFM95_RADIO_MODE_RX && (irqFlags & RFM95_RX_DONE)) {
|
||||
// set radio to STDBY (we are in RXcontinuous mode)
|
||||
(void)RFM95_setRadioMode(RFM95_RADIO_MODE_STDBY);
|
||||
// Have received a packet
|
||||
@@ -160,16 +195,16 @@ LOCAL void RFM95_interruptHandler(void) {
|
||||
}
|
||||
|
||||
}
|
||||
else if (RFM95.radioMode == RFM95_RADIO_MODE_TX && (irq_flags & RFM95_TX_DONE) ) {
|
||||
else if (RFM95.radioMode == RFM95_RADIO_MODE_TX && (irqFlags & RFM95_TX_DONE) ) {
|
||||
(void)RFM95_setRadioMode(RFM95_RADIO_MODE_STDBY);
|
||||
}
|
||||
else if (RFM95.radioMode == RFM95_RADIO_MODE_CAD && (irq_flags & RFM95_CAD_DONE) ) {
|
||||
RFM95.cad = irq_flags & RFM95_CAD_DETECTED;
|
||||
else if (RFM95.radioMode == RFM95_RADIO_MODE_CAD && (irqFlags & RFM95_CAD_DONE) ) {
|
||||
RFM95.cad = irqFlags & RFM95_CAD_DETECTED;
|
||||
(void)RFM95_setRadioMode(RFM95_RADIO_MODE_STDBY);
|
||||
}
|
||||
|
||||
// Clear all IRQ flags
|
||||
RFM95_writeReg(RFM95_REG_12_IRQ_FLAGS, 0xff);
|
||||
RFM95_writeReg(RFM95_REG_12_IRQ_FLAGS, 0xFF);
|
||||
}
|
||||
|
||||
LOCAL bool RFM95_available(void) {
|
||||
@@ -283,7 +318,7 @@ LOCAL bool RFM95_setTxPower(uint8_t powerLevel) {
|
||||
}
|
||||
|
||||
// Sets registers from a canned modem configuration structure
|
||||
LOCAL void RFM95_setModemRegisters(const modemConfig_t config) {
|
||||
LOCAL void RFM95_setModemRegisters(const rfm95_modemConfig_t config) {
|
||||
RFM95_writeReg(RFM95_REG_1D_MODEM_CONFIG1, config.reg_1d);
|
||||
RFM95_writeReg(RFM95_REG_1E_MODEM_CONFIG2, config.reg_1e);
|
||||
RFM95_writeReg(RFM95_REG_26_MODEM_CONFIG3, config.reg_26);
|
||||
@@ -306,13 +341,13 @@ LOCAL uint8_t RFM95_getAddress(void) {
|
||||
LOCAL bool RFM95_isChannelActive(void) {
|
||||
(void)RFM95_setRadioMode(RFM95_RADIO_MODE_CAD);
|
||||
while (RFM95.radioMode == RFM95_RADIO_MODE_CAD) {
|
||||
yield();
|
||||
doYield();
|
||||
}
|
||||
|
||||
return RFM95.cad;
|
||||
}
|
||||
|
||||
LOCAL bool RFM95_setRadioMode(const rfm95_radio_mode_t newRadioMode) {
|
||||
LOCAL bool RFM95_setRadioMode(const rfm95_radioMode_t newRadioMode) {
|
||||
if (RFM95.radioMode == newRadioMode) {
|
||||
return false;
|
||||
}
|
||||
@@ -390,7 +425,7 @@ LOCAL bool RFM95_sendWithRetry(const uint8_t recipient, const void* buffer, cons
|
||||
return true;
|
||||
}
|
||||
const uint32_t enterMS = hwMillis();
|
||||
while (hwMillis() - enterMS < 500) {
|
||||
while (hwMillis() - enterMS < RFM95_RETRY_TIMEOUT_MS) {
|
||||
if (RFM95.rxBufferValid) {
|
||||
const uint8_t sender = RFM95.currentPacket.header.sender;
|
||||
const rfm95_sequenceNumber_t ACKsequenceNumber = RFM95.currentPacket.ACK.sequenceNumber;
|
||||
@@ -406,7 +441,7 @@ LOCAL bool RFM95_sendWithRetry(const uint8_t recipient, const void* buffer, cons
|
||||
return true;
|
||||
} // seq check
|
||||
}
|
||||
yield();
|
||||
doYield();
|
||||
}
|
||||
RFM95_DEBUG(PSTR("!RFM95:SWR:NACK\n"));
|
||||
if (RFM95.ATCenabled) {
|
||||
@@ -425,15 +460,16 @@ LOCAL bool RFM95_waitCAD(void) {
|
||||
if (hwMillis() - enterMS > RFM95_CAD_TIMEOUT_MS) {
|
||||
return false;
|
||||
}
|
||||
yield();
|
||||
doYield();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Wait for any previous transmission to finish
|
||||
LOCAL bool RFM95_waitPacketSent(void) {
|
||||
while (RFM95.radioMode == RFM95_RADIO_MODE_TX)
|
||||
yield();
|
||||
while (RFM95.radioMode == RFM95_RADIO_MODE_TX) {
|
||||
doYield();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -454,6 +490,7 @@ LOCAL void RFM95_ATCmode(const bool OnOff, const int16_t targetRSSI) {
|
||||
}
|
||||
|
||||
LOCAL bool RFM95_sanityCheck(void) {
|
||||
// not implemented yet
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -133,6 +133,8 @@
|
||||
#define RFM95_RX_FIFO_ADDR (0x00u) //!< RX FIFO addr pointer
|
||||
#define RFM95_TX_FIFO_ADDR (0x80u) //!< TX FIFO addr pointer
|
||||
#define RFM95_MAX_PACKET_LEN (0x40u) //!< This is the maximum number of bytes that can be carried by the LORA
|
||||
#define RFM95_PREAMBLE_LENGTH (8u) //!< Preamble length, default=8
|
||||
|
||||
|
||||
#define RFM95_CAD_TIMEOUT_MS (2*1000ul) //!< channel activity detection timeout
|
||||
#define RFM95_FXOSC (32000000.0f) //!< The crystal oscillator frequency of the module
|
||||
@@ -177,7 +179,7 @@ typedef enum {
|
||||
RFM95_RADIO_MODE_CAD = 2, //!< CAD mode
|
||||
RFM95_RADIO_MODE_SLEEP = 3, //!< SLEEP mode
|
||||
RFM95_RADIO_MODE_STDBY = 4 //!< STDBY mode
|
||||
} rfm95_radio_mode_t;
|
||||
} rfm95_radioMode_t;
|
||||
|
||||
/**
|
||||
* @brief RFM95 modem config registers
|
||||
@@ -186,7 +188,7 @@ typedef struct {
|
||||
uint8_t reg_1d; //!< Value for register REG_1D_MODEM_CONFIG1
|
||||
uint8_t reg_1e; //!< Value for register REG_1E_MODEM_CONFIG2
|
||||
uint8_t reg_26; //!< Value for register REG_26_MODEM_CONFIG3
|
||||
} modemConfig_t;
|
||||
} rfm95_modemConfig_t;
|
||||
|
||||
/**
|
||||
* @brief Sequence number data type
|
||||
@@ -258,7 +260,7 @@ typedef struct {
|
||||
uint8_t powerLevel; //!< TX power level dBm
|
||||
uint8_t ATCtargetRSSI; //!< ATC: target RSSI
|
||||
// 8 bit
|
||||
rfm95_radio_mode_t radioMode : 3; //!< current transceiver state
|
||||
rfm95_radioMode_t radioMode : 3; //!< current transceiver state
|
||||
bool cad : 1; //!< RFM95_cad
|
||||
bool rxBufferValid : 1; //!< RX buffer valid
|
||||
bool ATCenabled : 1; //!< ATC enabled
|
||||
@@ -288,7 +290,7 @@ LOCAL uint8_t RFM95_getAddress(void);
|
||||
* bandwidth, spreading factor etc.
|
||||
* @param config See modemConfig_t and references therein
|
||||
*/
|
||||
LOCAL void RFM95_setModemRegisters(const modemConfig_t config);
|
||||
LOCAL void RFM95_setModemRegisters(const rfm95_modemConfig_t config);
|
||||
/**
|
||||
* @brief Tests whether a new message is available
|
||||
* @return True if a new, complete, error-free uncollected message is available to be retreived by @ref RFM95_recv()
|
||||
@@ -374,7 +376,7 @@ LOCAL bool RFM95_waitPacketSent(void);
|
||||
* @param newRadioMode
|
||||
* @return True if mode changed
|
||||
*/
|
||||
LOCAL bool RFM95_setRadioMode(const rfm95_radio_mode_t newRadioMode);
|
||||
LOCAL bool RFM95_setRadioMode(const rfm95_radioMode_t newRadioMode);
|
||||
/**
|
||||
* @brief Low level interrupt handler
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user