2018-03-05 16:08:42 +00:00
|
|
|
#include "Module.h"
|
|
|
|
|
2019-09-07 13:30:57 +00:00
|
|
|
Module::Module(int rx, int tx, HardwareSerial* useSer) {
|
2019-02-23 08:36:08 +00:00
|
|
|
_cs = -1;
|
|
|
|
_rx = rx;
|
|
|
|
_tx = tx;
|
|
|
|
_int0 = -1;
|
|
|
|
_int1 = -1;
|
2019-05-13 13:03:09 +00:00
|
|
|
|
2019-11-20 15:22:50 +00:00
|
|
|
#ifdef RADIOLIB_SOFTWARE_SERIAL_UNSUPPORTED
|
2019-09-28 08:39:20 +00:00
|
|
|
ModuleSerial = useSer;
|
2019-09-07 13:30:57 +00:00
|
|
|
#else
|
2019-02-23 08:36:08 +00:00
|
|
|
ModuleSerial = new SoftwareSerial(_rx, _tx);
|
2019-09-28 10:22:52 +00:00
|
|
|
(void)useSer;
|
2019-09-07 13:30:57 +00:00
|
|
|
#endif
|
2019-02-23 08:36:08 +00:00
|
|
|
}
|
|
|
|
|
2019-05-19 14:16:24 +00:00
|
|
|
Module::Module(int cs, int int0, int int1, SPIClass& spi, SPISettings spiSettings) {
|
2018-07-11 16:15:54 +00:00
|
|
|
_cs = cs;
|
|
|
|
_rx = -1;
|
2019-01-16 17:02:32 +00:00
|
|
|
_tx = -1;
|
2018-07-11 16:15:54 +00:00
|
|
|
_int0 = int0;
|
|
|
|
_int1 = int1;
|
2019-03-22 18:01:56 +00:00
|
|
|
_spi = &spi;
|
2019-05-19 14:16:24 +00:00
|
|
|
_spiSettings = spiSettings;
|
2018-07-11 16:15:54 +00:00
|
|
|
}
|
|
|
|
|
2019-09-07 13:30:57 +00:00
|
|
|
Module::Module(int cs, int int0, int int1, int rx, int tx, SPIClass& spi, SPISettings spiSettings, HardwareSerial* useSer) {
|
2018-03-05 16:08:42 +00:00
|
|
|
_cs = cs;
|
|
|
|
_rx = rx;
|
2019-01-16 17:02:32 +00:00
|
|
|
_tx = tx;
|
2018-03-05 16:08:42 +00:00
|
|
|
_int0 = int0;
|
|
|
|
_int1 = int1;
|
2019-03-22 18:01:56 +00:00
|
|
|
_spi = &spi;
|
2019-05-19 14:37:12 +00:00
|
|
|
_spiSettings = spiSettings;
|
2019-05-13 13:03:09 +00:00
|
|
|
|
2019-11-20 15:22:50 +00:00
|
|
|
#ifdef RADIOLIB_SOFTWARE_SERIAL_UNSUPPORTED
|
2019-09-07 13:30:57 +00:00
|
|
|
ModuleSerial = useSer;
|
|
|
|
#else
|
2019-01-16 17:02:32 +00:00
|
|
|
ModuleSerial = new SoftwareSerial(_rx, _tx);
|
2019-09-28 10:22:52 +00:00
|
|
|
(void)useSer;
|
2019-09-07 13:30:57 +00:00
|
|
|
#endif
|
2018-03-05 16:08:42 +00:00
|
|
|
}
|
|
|
|
|
2019-05-20 06:51:34 +00:00
|
|
|
Module::Module(int cs, int int0, int int1, int int2, SPIClass& spi, SPISettings spiSettings) {
|
|
|
|
_cs = cs;
|
|
|
|
_rx = int2;
|
|
|
|
_tx = -1;
|
|
|
|
_int0 = int0;
|
|
|
|
_int1 = int1;
|
|
|
|
_spi = &spi;
|
|
|
|
_spiSettings = spiSettings;
|
|
|
|
}
|
|
|
|
|
2018-07-23 09:19:34 +00:00
|
|
|
void Module::init(uint8_t interface, uint8_t gpio) {
|
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:
|
2018-03-05 16:08:42 +00:00
|
|
|
pinMode(_cs, OUTPUT);
|
|
|
|
digitalWrite(_cs, HIGH);
|
2019-03-22 18:01:56 +00:00
|
|
|
_spi->begin();
|
2018-03-05 16:08:42 +00:00
|
|
|
break;
|
2019-11-20 15:22:50 +00:00
|
|
|
case RADIOLIB_USE_UART:
|
2019-09-07 13:30:57 +00:00
|
|
|
#if defined(ESP32)
|
|
|
|
ModuleSerial->begin(baudrate, SERIAL_8N1, _rx, _tx);
|
|
|
|
#else
|
2018-03-05 16:08:42 +00:00
|
|
|
ModuleSerial->begin(baudrate);
|
2019-09-07 13:30:57 +00:00
|
|
|
#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;
|
|
|
|
}
|
2019-05-13 13:03:09 +00:00
|
|
|
|
2019-03-22 18:06:03 +00:00
|
|
|
// select GPIO
|
2018-03-05 16:08:42 +00:00
|
|
|
switch(gpio) {
|
2019-11-20 15:22:50 +00:00
|
|
|
case RADIOLIB_INT_NONE:
|
2018-03-05 16:08:42 +00:00
|
|
|
break;
|
2019-11-20 15:22:50 +00:00
|
|
|
case RADIOLIB_INT_0:
|
2018-03-05 16:08:42 +00:00
|
|
|
pinMode(_int0, INPUT);
|
|
|
|
break;
|
2019-11-20 15:22:50 +00:00
|
|
|
case RADIOLIB_INT_1:
|
2018-03-05 16:08:42 +00:00
|
|
|
pinMode(_int1, INPUT);
|
|
|
|
break;
|
2019-11-20 15:22:50 +00:00
|
|
|
case RADIOLIB_INT_BOTH:
|
2018-03-05 16:08:42 +00:00
|
|
|
pinMode(_int0, INPUT);
|
|
|
|
pinMode(_int1, INPUT);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-22 18:01:56 +00:00
|
|
|
void Module::term() {
|
|
|
|
// stop SPI
|
|
|
|
_spi->end();
|
|
|
|
}
|
|
|
|
|
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);
|
2018-04-10 18:47:57 +00:00
|
|
|
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
|
|
|
|
2018-04-10 18:47:57 +00:00
|
|
|
ModuleSerial->print(AtLineFeed);
|
2018-03-05 16:08:42 +00:00
|
|
|
return(ATgetResponse());
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Module::ATgetResponse() {
|
2018-04-13 18:51:12 +00:00
|
|
|
String data = "";
|
2019-05-13 13:03:09 +00:00
|
|
|
uint32_t start = millis();
|
2018-03-05 16:08:42 +00:00
|
|
|
while (millis() - start < _ATtimeout) {
|
|
|
|
while(ModuleSerial->available() > 0) {
|
|
|
|
char c = ModuleSerial->read();
|
2019-09-28 08:30:50 +00:00
|
|
|
RADIOLIB_VERBOSE_PRINT(c);
|
2018-03-05 16:08:42 +00:00
|
|
|
data += c;
|
|
|
|
}
|
2019-05-13 13:03:09 +00:00
|
|
|
|
2018-03-05 16:08:42 +00:00
|
|
|
if(data.indexOf("OK") != -1) {
|
2019-09-28 08:30:50 +00:00
|
|
|
RADIOLIB_VERBOSE_PRINTLN();
|
2018-03-05 16:08:42 +00:00
|
|
|
return(true);
|
|
|
|
} else if (data.indexOf("ERROR") != -1) {
|
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 = 0;
|
|
|
|
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-03-22 18:01:56 +00:00
|
|
|
uint8_t resp;
|
|
|
|
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
|
2019-05-19 14:16:24 +00:00
|
|
|
_spi->beginTransaction(_spiSettings);
|
2019-05-13 13:03:09 +00:00
|
|
|
|
2019-03-22 18:01:56 +00:00
|
|
|
// pull CS low
|
2018-03-05 16:08:42 +00:00
|
|
|
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);
|
2019-09-28 08:30:50 +00:00
|
|
|
RADIOLIB_VERBOSE_PRINT(reg | cmd, HEX);
|
|
|
|
RADIOLIB_VERBOSE_PRINT('\t');
|
|
|
|
RADIOLIB_VERBOSE_PRINT(reg | cmd, BIN);
|
|
|
|
RADIOLIB_VERBOSE_PRINT('\t');
|
2019-05-13 13:03:09 +00:00
|
|
|
|
2019-03-22 18:01:56 +00:00
|
|
|
// send data or get response
|
|
|
|
if(cmd == SPIwriteCommand) {
|
|
|
|
for(size_t n = 0; n < numBytes; n++) {
|
|
|
|
_spi->transfer(dataOut[n]);
|
2019-09-28 08:30:50 +00:00
|
|
|
RADIOLIB_VERBOSE_PRINT(dataOut[n], HEX);
|
|
|
|
RADIOLIB_VERBOSE_PRINT('\t');
|
|
|
|
RADIOLIB_VERBOSE_PRINT(dataOut[n], BIN);
|
|
|
|
RADIOLIB_VERBOSE_PRINT('\t');
|
2019-03-22 18:01:56 +00:00
|
|
|
}
|
|
|
|
} else if (cmd == SPIreadCommand) {
|
|
|
|
for(size_t n = 0; n < numBytes; n++) {
|
|
|
|
dataIn[n] = _spi->transfer(0x00);
|
2019-09-28 08:30:50 +00:00
|
|
|
RADIOLIB_VERBOSE_PRINT(dataIn[n], HEX);
|
|
|
|
RADIOLIB_VERBOSE_PRINT('\t');
|
|
|
|
RADIOLIB_VERBOSE_PRINT(dataIn[n], BIN);
|
|
|
|
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
|
2018-03-05 16:08:42 +00:00
|
|
|
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
|
|
|
}
|