Merge pull request #649 from tekka007/transportRFM95Update

RFM95 updates for RPI
This commit is contained in:
Henrik Ekblad
2016-11-20 21:03:48 +01:00
committed by GitHub
2 changed files with 63 additions and 24 deletions
+56 -19
View File
@@ -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;
}
+7 -5
View File
@@ -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
*/