RadioLib/src/Module.cpp

372 wiersze
9.3 KiB
C++
Czysty Zwykły widok Historia

2018-03-05 16:08:42 +00:00
#include "Module.h"
2020-07-04 14:05:56 +00:00
Module::Module(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst):
_cs(cs),
_irq(irq),
_rst(rst),
_rx(RADIOLIB_NC),
_tx(RADIOLIB_NC),
_spiSettings(SPISettings(2000000, MSBFIRST, SPI_MODE0))
{
_spi = &RADIOLIB_DEFAULT_SPI;
_initInterface = true;
2020-07-04 11:43:39 +00:00
ModuleSerial = NULL;
}
2020-07-04 14:05:56 +00:00
Module::Module(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE gpio):
_cs(cs),
_irq(irq),
_rst(rst),
_rx(gpio),
_tx(RADIOLIB_NC),
_spiSettings(SPISettings(2000000, MSBFIRST, SPI_MODE0))
{
_spi = &RADIOLIB_DEFAULT_SPI;
_initInterface = true;
2020-07-04 11:43:39 +00:00
ModuleSerial = NULL;
}
2020-07-04 14:05:56 +00:00
Module::Module(RADIOLIB_PIN_TYPE rx, RADIOLIB_PIN_TYPE tx, HardwareSerial* serial, RADIOLIB_PIN_TYPE rst):
_cs(RADIOLIB_NC),
_irq(RADIOLIB_NC),
_rst(rst),
_rx(rx),
_tx(tx),
_spiSettings(SPISettings(2000000, MSBFIRST, SPI_MODE0))
{
_initInterface = true;
2019-05-13 13:03:09 +00:00
2019-11-20 15:22:50 +00:00
#ifdef RADIOLIB_SOFTWARE_SERIAL_UNSUPPORTED
2020-07-04 11:43:39 +00:00
ModuleSerial = serial;
#else
2019-02-23 08:36:08 +00:00
ModuleSerial = new SoftwareSerial(_rx, _tx);
2020-07-04 11:43:39 +00:00
(void)serial;
#endif
2019-02-23 08:36:08 +00:00
}
2020-07-04 14:05:56 +00:00
Module::Module(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, SPIClass& spi, SPISettings spiSettings):
_cs(cs),
_irq(irq),
_rst(rst),
_rx(RADIOLIB_NC),
_tx(RADIOLIB_NC),
_spiSettings(spiSettings)
{
2019-03-22 18:01:56 +00:00
_spi = &spi;
_initInterface = false;
2020-07-04 11:43:39 +00:00
ModuleSerial = NULL;
2018-07-11 16:15:54 +00:00
}
2020-07-04 14:05:56 +00:00
Module::Module(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE gpio, SPIClass& spi, SPISettings spiSettings):
_cs(cs),
_irq(irq),
_rst(rst),
_rx(gpio),
_tx(RADIOLIB_NC),
_spiSettings(spiSettings)
{
_spi = &spi;
_initInterface = false;
2020-07-04 11:43:39 +00:00
ModuleSerial = NULL;
}
2020-07-04 14:05:56 +00:00
Module::Module(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE rx, RADIOLIB_PIN_TYPE tx, SPIClass& spi, SPISettings spiSettings, HardwareSerial* serial):
_cs(cs),
_irq(irq),
_rst(rst),
_rx(rx),
_tx(tx),
_spiSettings(spiSettings)
{
2019-03-22 18:01:56 +00:00
_spi = &spi;
_initInterface = false;
2019-05-13 13:03:09 +00:00
2019-11-20 15:22:50 +00:00
#ifdef RADIOLIB_SOFTWARE_SERIAL_UNSUPPORTED
2020-07-04 11:43:39 +00:00
ModuleSerial = serial;
#else
ModuleSerial = new SoftwareSerial(_rx, _tx);
2020-07-04 11:43:39 +00:00
(void)serial;
#endif
2018-03-05 16:08:42 +00:00
}
Module::Module(const Module& mod) {
*this = mod;
}
Module& Module::operator=(const Module& mod) {
this->ModuleSerial = mod.ModuleSerial;
this->baudrate = mod.baudrate;
memcpy(this->AtLineFeed, mod.AtLineFeed, strlen(mod.AtLineFeed));
this->SPIreadCommand = mod.SPIreadCommand;
this->SPIwriteCommand = mod.SPIwriteCommand;
this->_cs = mod.getCs();
this->_irq = mod.getIrq();
this->_rst = mod.getRst();
this->_rx = mod.getRx();
this->_tx = mod.getTx();
this->_spiSettings = mod.getSpiSettings();
this->_spi = mod.getSpi();
return(*this);
}
void Module::init(uint8_t interface) {
2019-03-22 18:06:03 +00:00
// select interface
2018-03-05 16:08:42 +00:00
switch(interface) {
2019-11-20 15:22:50 +00:00
case RADIOLIB_USE_SPI:
Module::pinMode(_cs, OUTPUT);
Module::digitalWrite(_cs, HIGH);
if(_initInterface) {
_spi->begin();
}
2018-03-05 16:08:42 +00:00
break;
2019-11-20 15:22:50 +00:00
case RADIOLIB_USE_UART:
if(_initInterface) {
#if defined(ESP32)
ModuleSerial->begin(baudrate, SERIAL_8N1, _rx, _tx);
#else
ModuleSerial->begin(baudrate);
#endif
}
2018-03-05 16:08:42 +00:00
break;
2019-11-20 15:22:50 +00:00
case RADIOLIB_USE_I2C:
2018-03-05 16:08:42 +00:00
break;
}
}
void Module::term(uint8_t interface) {
// stop hardware interfaces (if they were initialized by the library)
if(!_initInterface) {
return;
}
if((interface == RADIOLIB_USE_SPI) && (_spi != nullptr)) {
2020-02-20 11:38:51 +00:00
_spi->end();
}
if(((interface == RADIOLIB_USE_UART) && ModuleSerial != nullptr)) {
2020-02-20 11:38:51 +00:00
ModuleSerial->end();
2020-02-20 11:35:44 +00:00
}
2019-03-22 18:01:56 +00:00
}
2018-03-05 16:08:42 +00:00
void Module::ATemptyBuffer() {
while(ModuleSerial->available() > 0) {
ModuleSerial->read();
}
}
bool Module::ATsendCommand(const char* cmd) {
ATemptyBuffer();
ModuleSerial->print(cmd);
2018-03-31 08:06:45 +00:00
ModuleSerial->print(AtLineFeed);
return(ATgetResponse());
}
bool Module::ATsendData(uint8_t* data, uint32_t len) {
ATemptyBuffer();
for(uint32_t i = 0; i < len; i++) {
ModuleSerial->write(data[i]);
}
2019-05-13 13:03:09 +00:00
ModuleSerial->print(AtLineFeed);
2018-03-05 16:08:42 +00:00
return(ATgetResponse());
}
bool Module::ATgetResponse() {
char data[128];
char* dataPtr = data;
2019-05-13 13:03:09 +00:00
uint32_t start = millis();
while(millis() - start < _ATtimeout) {
2018-03-05 16:08:42 +00:00
while(ModuleSerial->available() > 0) {
char c = ModuleSerial->read();
2019-09-28 08:30:50 +00:00
RADIOLIB_VERBOSE_PRINT(c);
*dataPtr++ = c;
2018-03-05 16:08:42 +00:00
}
2019-05-13 13:03:09 +00:00
if(strstr(data, "OK") == 0) {
2019-09-28 08:30:50 +00:00
RADIOLIB_VERBOSE_PRINTLN();
2018-03-05 16:08:42 +00:00
return(true);
} else if(strstr(data, "ERROR") == 0) {
2019-09-28 08:30:50 +00:00
RADIOLIB_VERBOSE_PRINTLN();
2018-03-05 16:08:42 +00:00
return(false);
}
2019-05-13 13:03:09 +00:00
2018-03-05 16:08:42 +00:00
}
2019-09-28 08:30:50 +00:00
RADIOLIB_VERBOSE_PRINTLN();
2018-03-05 16:08:42 +00:00
return(false);
}
2018-07-23 09:19:34 +00:00
int16_t Module::SPIgetRegValue(uint8_t reg, uint8_t msb, uint8_t lsb) {
2018-03-05 16:08:42 +00:00
if((msb > 7) || (lsb > 7) || (lsb > msb)) {
return(ERR_INVALID_BIT_RANGE);
}
2019-05-13 13:03:09 +00:00
2018-03-05 16:08:42 +00:00
uint8_t rawValue = SPIreadRegister(reg);
uint8_t maskedValue = rawValue & ((0b11111111 << lsb) & (0b11111111 >> (7 - msb)));
return(maskedValue);
}
2018-10-31 16:44:47 +00:00
int16_t Module::SPIsetRegValue(uint8_t reg, uint8_t value, uint8_t msb, uint8_t lsb, uint8_t checkInterval) {
2018-07-23 09:19:34 +00:00
if((msb > 7) || (lsb > 7) || (lsb > msb)) {
return(ERR_INVALID_BIT_RANGE);
}
2019-05-13 13:03:09 +00:00
2018-07-23 09:19:34 +00:00
uint8_t currentValue = SPIreadRegister(reg);
uint8_t mask = ~((0b11111111 << (msb + 1)) | (0b11111111 >> (8 - lsb)));
uint8_t newValue = (currentValue & ~mask) | (value & mask);
SPIwriteRegister(reg, newValue);
2019-05-13 13:03:09 +00:00
2018-10-31 16:44:47 +00:00
// check register value each millisecond until check interval is reached
// some registers need a bit of time to process the change (e.g. SX127X_REG_OP_MODE)
uint32_t start = micros();
uint8_t readValue;
2018-10-31 16:44:47 +00:00
while(micros() - start < (checkInterval * 1000)) {
readValue = SPIreadRegister(reg);
if(readValue == newValue) {
// check passed, we can stop the loop
return(ERR_NONE);
}
2018-07-23 09:19:34 +00:00
}
2019-05-13 13:03:09 +00:00
2018-10-31 16:44:47 +00:00
// check failed, print debug info
2019-09-28 08:30:50 +00:00
RADIOLIB_DEBUG_PRINTLN();
RADIOLIB_DEBUG_PRINT(F("address:\t0x"));
RADIOLIB_DEBUG_PRINTLN(reg, HEX);
RADIOLIB_DEBUG_PRINT(F("bits:\t\t"));
RADIOLIB_DEBUG_PRINT(msb);
RADIOLIB_DEBUG_PRINT(' ');
RADIOLIB_DEBUG_PRINTLN(lsb);
RADIOLIB_DEBUG_PRINT(F("value:\t\t0b"));
RADIOLIB_DEBUG_PRINTLN(value, BIN);
RADIOLIB_DEBUG_PRINT(F("current:\t0b"));
RADIOLIB_DEBUG_PRINTLN(currentValue, BIN);
RADIOLIB_DEBUG_PRINT(F("mask:\t\t0b"));
RADIOLIB_DEBUG_PRINTLN(mask, BIN);
RADIOLIB_DEBUG_PRINT(F("new:\t\t0b"));
RADIOLIB_DEBUG_PRINTLN(newValue, BIN);
RADIOLIB_DEBUG_PRINT(F("read:\t\t0b"));
RADIOLIB_DEBUG_PRINTLN(readValue, BIN);
RADIOLIB_DEBUG_PRINTLN();
2019-05-13 13:03:09 +00:00
2018-10-31 16:44:47 +00:00
return(ERR_SPI_WRITE_FAILED);
2018-07-23 09:19:34 +00:00
}
void Module::SPIreadRegisterBurst(uint8_t reg, uint8_t numBytes, uint8_t* inBytes) {
2019-03-22 18:01:56 +00:00
SPItransfer(SPIreadCommand, reg, NULL, inBytes, numBytes);
2018-03-05 16:08:42 +00:00
}
uint8_t Module::SPIreadRegister(uint8_t reg) {
2019-11-23 09:10:53 +00:00
uint8_t resp = 0;
2019-03-22 18:01:56 +00:00
SPItransfer(SPIreadCommand, reg, NULL, &resp, 1);
return(resp);
2018-03-05 16:08:42 +00:00
}
void Module::SPIwriteRegisterBurst(uint8_t reg, uint8_t* data, uint8_t numBytes) {
2019-03-22 18:01:56 +00:00
SPItransfer(SPIwriteCommand, reg, data, NULL, numBytes);
2018-03-05 16:08:42 +00:00
}
void Module::SPIwriteRegister(uint8_t reg, uint8_t data) {
2019-03-22 18:01:56 +00:00
SPItransfer(SPIwriteCommand, reg, &data, NULL, 1);
}
void Module::SPItransfer(uint8_t cmd, uint8_t reg, uint8_t* dataOut, uint8_t* dataIn, uint8_t numBytes) {
// start SPI transaction
_spi->beginTransaction(_spiSettings);
2019-05-13 13:03:09 +00:00
2019-03-22 18:01:56 +00:00
// pull CS low
Module::digitalWrite(_cs, LOW);
2019-05-13 13:03:09 +00:00
2019-03-22 18:01:56 +00:00
// send SPI register address with access command
_spi->transfer(reg | cmd);
2020-01-06 16:20:18 +00:00
#ifdef RADIOLIB_VERBOSE
if(cmd == SPIwriteCommand) {
RADIOLIB_VERBOSE_PRINT('W');
} else if(cmd == SPIreadCommand) {
RADIOLIB_VERBOSE_PRINT('R');
}
RADIOLIB_VERBOSE_PRINT('\t')
RADIOLIB_VERBOSE_PRINT(reg, HEX);
RADIOLIB_VERBOSE_PRINT('\t');
#endif
2019-05-13 13:03:09 +00:00
2019-03-22 18:01:56 +00:00
// send data or get response
if(cmd == SPIwriteCommand) {
2020-07-04 11:43:39 +00:00
if(dataOut != NULL) {
for(size_t n = 0; n < numBytes; n++) {
_spi->transfer(dataOut[n]);
RADIOLIB_VERBOSE_PRINT(dataOut[n], HEX);
RADIOLIB_VERBOSE_PRINT('\t');
}
2019-03-22 18:01:56 +00:00
}
} else if (cmd == SPIreadCommand) {
2020-07-04 11:43:39 +00:00
if(dataIn != NULL) {
for(size_t n = 0; n < numBytes; n++) {
dataIn[n] = _spi->transfer(0x00);
RADIOLIB_VERBOSE_PRINT(dataIn[n], HEX);
RADIOLIB_VERBOSE_PRINT('\t');
}
2019-03-22 18:01:56 +00:00
}
}
2019-09-28 08:30:50 +00:00
RADIOLIB_VERBOSE_PRINTLN();
2019-05-13 13:03:09 +00:00
2019-03-22 18:01:56 +00:00
// release CS
Module::digitalWrite(_cs, HIGH);
2019-05-13 13:03:09 +00:00
2019-03-22 18:01:56 +00:00
// end SPI transaction
_spi->endTransaction();
2018-03-05 16:08:42 +00:00
}
2019-12-01 07:12:04 +00:00
2020-03-27 13:10:45 +00:00
void Module::pinMode(RADIOLIB_PIN_TYPE pin, RADIOLIB_PIN_MODE mode) {
if(pin != RADIOLIB_NC) {
::pinMode(pin, mode);
}
}
2020-03-27 13:10:45 +00:00
void Module::digitalWrite(RADIOLIB_PIN_TYPE pin, RADIOLIB_PIN_STATUS value) {
if(pin != RADIOLIB_NC) {
::digitalWrite(pin, value);
2019-12-01 07:12:04 +00:00
}
}
2020-03-27 13:10:45 +00:00
RADIOLIB_PIN_STATUS Module::digitalRead(RADIOLIB_PIN_TYPE pin) {
if(pin != RADIOLIB_NC) {
return(::digitalRead(pin));
}
return(LOW);
}
2020-04-30 15:07:28 +00:00
void Module::tone(RADIOLIB_PIN_TYPE pin, uint16_t value) {
#ifndef RADIOLIB_TONE_UNSUPPORTED
if(pin != RADIOLIB_NC) {
::tone(pin, value);
}
#endif
}
void Module::noTone(RADIOLIB_PIN_TYPE pin) {
#ifndef RADIOLIB_TONE_UNSUPPORTED
if(pin != RADIOLIB_NC) {
::noTone(pin);
}
#endif
}
2020-06-18 14:31:38 +00:00
void Module::setRfSwitchPins(RADIOLIB_PIN_TYPE rxEn, RADIOLIB_PIN_TYPE txEn) {
_useRfSwitch = true;
_rxEn = rxEn;
_txEn = txEn;
Module::pinMode(rxEn, OUTPUT);
Module::pinMode(txEn, OUTPUT);
}
void Module::setRfSwitchState(RADIOLIB_PIN_STATUS rxPinState, RADIOLIB_PIN_STATUS txPinState) {
2020-06-18 14:31:38 +00:00
// check RF switch control is enabled
if(!_useRfSwitch) {
return;
}
// set pins
Module::digitalWrite(_rxEn, rxPinState);
Module::digitalWrite(_txEn, txPinState);
2020-06-18 14:31:38 +00:00
}