diff --git a/drivers/RFM95/RFM95.cpp b/drivers/RFM95/RFM95.cpp index 316040e..c49edd3 100644 --- a/drivers/RFM95/RFM95.cpp +++ b/drivers/RFM95/RFM95.cpp @@ -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; } diff --git a/drivers/RFM95/RFM95.h b/drivers/RFM95/RFM95.h index c9f253f..b7fd629 100644 --- a/drivers/RFM95/RFM95.h +++ b/drivers/RFM95/RFM95.h @@ -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 */