2023-09-23 13:37:35 +00:00
# include "Task.h"
# include "TimeLib/TimeLib.h"
2022-05-20 20:46:27 +00:00
# include <logger.h>
2022-04-02 01:20:16 +00:00
2022-04-02 01:36:06 +00:00
# include "TaskRadiolib.h"
2022-04-02 01:20:16 +00:00
2023-08-05 22:56:07 +00:00
volatile bool RadiolibTask : : _modemInterruptOccurred = false ;
2022-04-02 01:20:16 +00:00
2023-08-06 20:49:48 +00:00
RadiolibTask : : RadiolibTask ( TaskQueue < std : : shared_ptr < APRSMessage > > & fromModem , TaskQueue < std : : shared_ptr < APRSMessage > > & toModem ) : Task ( TASK_RADIOLIB , TaskRadiolib ) , _modem ( 0 ) , _rxEnable ( false ) , _txEnable ( false ) , _fromModem ( fromModem ) , _toModem ( toModem ) , _transmitFlag ( false ) , _frequencyTx ( 0.0 ) , _frequencyRx ( 0.0 ) , _frequenciesAreSame ( false ) {
2022-04-02 01:20:16 +00:00
}
2023-06-08 10:50:09 +00:00
RadiolibTask : : ~ RadiolibTask ( ) {
2022-04-02 01:20:16 +00:00
}
bool RadiolibTask : : setup ( System & system ) {
2023-06-08 10:50:09 +00:00
_rxEnable = true ;
_txEnable = system . getUserConfig ( ) - > lora . tx_enable ;
2022-04-02 01:20:16 +00:00
2023-06-08 10:50:09 +00:00
_frequencyTx = ( float ) system . getUserConfig ( ) - > lora . frequencyTx / 1000000 ;
_frequencyRx = ( float ) system . getUserConfig ( ) - > lora . frequencyRx / 1000000 ;
2022-04-02 01:20:16 +00:00
2023-06-08 10:50:09 +00:00
if ( system . getUserConfig ( ) - > lora . frequencyTx = = system . getUserConfig ( ) - > lora . frequencyRx ) {
_frequenciesAreSame = true ;
}
2022-04-02 01:20:16 +00:00
2022-04-02 09:50:54 +00:00
const uint16_t preambleLength = 8 ;
2023-08-05 22:56:07 +00:00
if ( system . getBoardConfig ( ) - > Lora . Modem = = eSX1278 ) {
system . getLogger ( ) . log ( logging : : LoggerLevel : : LOGGER_LEVEL_DEBUG , getName ( ) , " [%s] using SX1278 " , timeString ( ) . c_str ( ) ) ;
_modem = new Modem_SX1278 ( ) ;
2023-08-06 20:49:48 +00:00
} else if ( system . getBoardConfig ( ) - > Lora . Modem = = eSX1268 ) {
system . getLogger ( ) . log ( logging : : LoggerLevel : : LOGGER_LEVEL_DEBUG , getName ( ) , " [%s] using SX1268 " , timeString ( ) . c_str ( ) ) ;
_modem = new Modem_SX1268 ( ) ;
2023-08-05 22:56:07 +00:00
} else {
system . getLogger ( ) . log ( logging : : LoggerLevel : : LOGGER_LEVEL_ERROR , getName ( ) , " [%s] Modem not correctly defined! " , timeString ( ) . c_str ( ) ) ;
2022-04-02 01:20:16 +00:00
}
2023-08-05 22:56:07 +00:00
int16_t state = _modem - > begin ( system . getBoardConfig ( ) - > Lora , system . getUserConfig ( ) - > lora , preambleLength , setFlag ) ;
2022-04-02 01:20:16 +00:00
if ( state ! = RADIOLIB_ERR_NONE ) {
2023-06-08 10:50:09 +00:00
decodeError ( system , state ) ;
2022-04-02 01:20:16 +00:00
}
2023-08-05 22:56:07 +00:00
startRX ( system ) ;
2023-01-10 20:14:48 +00:00
2023-06-08 10:50:09 +00:00
uint32_t preambleDurationMilliSec = ( ( uint64_t ) ( preambleLength + 4 ) < < ( system . getUserConfig ( ) - > lora . spreadingFactor + 10 /* to milli-sec */ ) ) / system . getUserConfig ( ) - > lora . signalBandwidth ;
_txWaitTimer . setTimeout ( preambleDurationMilliSec * 2 ) ;
2022-04-02 09:50:54 +00:00
2022-05-20 20:46:27 +00:00
_stateInfo = " " ;
2022-04-02 01:20:16 +00:00
return true ;
}
bool RadiolibTask : : loop ( System & system ) {
2023-08-05 22:56:07 +00:00
if ( _modemInterruptOccurred ) {
2023-06-08 10:50:09 +00:00
handleModemInterrupt ( system ) ;
} else if ( _txWaitTimer . check ( ) & & ! _toModem . empty ( ) ) {
handleTXing ( system ) ;
}
return true ;
}
void RadiolibTask : : setFlag ( void ) {
2023-08-05 22:56:07 +00:00
_modemInterruptOccurred = true ;
2023-06-08 10:50:09 +00:00
}
void RadiolibTask : : handleModemInterrupt ( System & system ) {
2023-08-05 22:56:07 +00:00
_modemInterruptOccurred = false ;
2023-06-08 10:50:09 +00:00
if ( _transmitFlag ) { // transmitted
_transmitFlag = false ;
system . getLogger ( ) . log ( logging : : LoggerLevel : : LOGGER_LEVEL_DEBUG , getName ( ) , " [%s] TX done " , timeString ( ) . c_str ( ) ) ;
_txWaitTimer . start ( ) ;
startRX ( system ) ;
return ;
}
// received
String str ;
2023-08-05 22:56:07 +00:00
int state = _modem - > readData ( str ) ;
2023-06-08 10:50:09 +00:00
if ( state ! = RADIOLIB_ERR_NONE ) {
system . getLogger ( ) . log ( logging : : LoggerLevel : : LOGGER_LEVEL_ERROR , getName ( ) , " [%s] readData failed, code %d " , timeString ( ) . c_str ( ) , state ) ;
return ;
}
if ( str . substring ( 0 , 3 ) ! = " < \xff \x01 " ) {
2023-08-05 22:56:07 +00:00
system . getLogger ( ) . log ( logging : : LoggerLevel : : LOGGER_LEVEL_DEBUG , getName ( ) , " [%s] Unknown packet '%s' with RSSI %.0fdBm, SNR %.2fdB and FreqErr %fHz " , timeString ( ) . c_str ( ) , str . c_str ( ) , _modem - > getRSSI ( ) , _modem - > getSNR ( ) , - _modem - > getFrequencyError ( ) ) ;
2023-06-08 10:50:09 +00:00
return ;
}
std : : shared_ptr < APRSMessage > msg = std : : shared_ptr < APRSMessage > ( new APRSMessage ( ) ) ;
msg - > decode ( str . substring ( 3 ) ) ;
_fromModem . addElement ( msg ) ;
2023-08-05 22:56:07 +00:00
system . getLogger ( ) . log ( logging : : LoggerLevel : : LOGGER_LEVEL_DEBUG , getName ( ) , " [%s] Received packet '%s' with RSSI %.0fdBm, SNR %.2fdB and FreqErr %fHz " , timeString ( ) . c_str ( ) , msg - > toString ( ) . c_str ( ) , _modem - > getRSSI ( ) , _modem - > getSNR ( ) , - _modem - > getFrequencyError ( ) ) ;
2023-06-08 10:50:09 +00:00
system . getDisplay ( ) . addFrame ( std : : shared_ptr < DisplayFrame > ( new TextFrame ( " LoRa " , msg - > toString ( ) . c_str ( ) ) ) ) ;
}
void RadiolibTask : : handleTXing ( System & system ) {
if ( ! _txEnable ) {
system . getLogger ( ) . log ( logging : : LoggerLevel : : LOGGER_LEVEL_DEBUG , getName ( ) , " [%s] TX is not enabled " , timeString ( ) . c_str ( ) ) ;
_toModem . getElement ( ) ; // empty list, otherwise memory will get full.
return ;
}
2022-04-02 01:20:16 +00:00
2023-06-08 10:50:09 +00:00
static bool txsignaldetected_print = false ;
if ( _transmitFlag ) { // we are currently TXing, need to wait
if ( ! txsignaldetected_print ) {
txsignaldetected_print = true ;
system . getLogger ( ) . log ( logging : : LoggerLevel : : LOGGER_LEVEL_DEBUG , getName ( ) , " [%s] TX signal detected. Waiting TX " , timeString ( ) . c_str ( ) ) ;
2022-04-02 01:20:16 +00:00
}
2023-06-08 10:50:09 +00:00
return ;
}
2022-04-02 01:20:16 +00:00
2023-06-08 10:50:09 +00:00
// we are currently RXing
static bool rxsignaldetected_print = false ;
2023-08-05 22:56:07 +00:00
if ( _frequenciesAreSame & & ( _modem - > getModemStatus ( ) & 0x01 ) = = 0x01 ) {
2023-06-08 10:50:09 +00:00
if ( ! rxsignaldetected_print ) {
rxsignaldetected_print = true ;
system . getLogger ( ) . log ( logging : : LoggerLevel : : LOGGER_LEVEL_DEBUG , getName ( ) , " [%s] RX signal detected. Waiting TX " , timeString ( ) . c_str ( ) ) ;
2022-04-02 01:20:16 +00:00
}
2023-06-08 10:50:09 +00:00
return ;
2022-04-02 01:20:16 +00:00
}
2023-06-08 10:50:09 +00:00
std : : shared_ptr < APRSMessage > msg = _toModem . getElement ( ) ;
system . getLogger ( ) . log ( logging : : LoggerLevel : : LOGGER_LEVEL_DEBUG , getName ( ) , " [%s] Transmitting packet '%s' " , timeString ( ) . c_str ( ) , msg - > toString ( ) . c_str ( ) ) ;
startTX ( system , " < \xff \x01 " + msg - > encode ( ) ) ;
rxsignaldetected_print = false ;
txsignaldetected_print = false ;
2022-04-02 01:20:16 +00:00
}
2023-06-08 10:50:09 +00:00
void RadiolibTask : : startRX ( System & system ) {
if ( ! _frequenciesAreSame ) {
2023-08-05 22:56:07 +00:00
int16_t state = _modem - > setFrequency ( _frequencyRx ) ;
2022-04-02 01:20:16 +00:00
if ( state ! = RADIOLIB_ERR_NONE ) {
2023-06-08 10:50:09 +00:00
system . getLogger ( ) . log ( logging : : LoggerLevel : : LOGGER_LEVEL_ERROR , getName ( ) , " [%s] startRX failed, Freq update, code %d " , timeString ( ) . c_str ( ) , state ) ;
decodeError ( system , state ) ;
return ;
2022-04-02 01:20:16 +00:00
}
}
2023-08-05 22:56:07 +00:00
int16_t state = _modem - > startReceive ( ) ;
2023-06-08 10:50:09 +00:00
if ( state ! = RADIOLIB_ERR_NONE ) {
system . getLogger ( ) . log ( logging : : LoggerLevel : : LOGGER_LEVEL_ERROR , getName ( ) , " [%s] startRX failed, code %d " , timeString ( ) . c_str ( ) , state ) ;
decodeError ( system , state ) ;
}
2022-04-02 01:20:16 +00:00
}
2023-06-08 10:50:09 +00:00
void RadiolibTask : : startTX ( System & system , String & str ) {
if ( ! _frequenciesAreSame ) {
2023-08-05 22:56:07 +00:00
int16_t state = _modem - > setFrequency ( _frequencyTx ) ;
2022-04-02 01:20:16 +00:00
if ( state ! = RADIOLIB_ERR_NONE ) {
2023-06-08 10:50:09 +00:00
system . getLogger ( ) . log ( logging : : LoggerLevel : : LOGGER_LEVEL_ERROR , getName ( ) , " [%s] startTX failed, Freq update, code %d " , timeString ( ) . c_str ( ) , state ) ;
decodeError ( system , state ) ;
startRX ( system ) ;
return ;
2022-04-02 01:20:16 +00:00
}
}
2023-08-05 22:56:07 +00:00
int16_t state = _modem - > startTransmit ( str ) ;
2023-06-08 10:50:09 +00:00
if ( state ! = RADIOLIB_ERR_NONE ) {
system . getLogger ( ) . log ( logging : : LoggerLevel : : LOGGER_LEVEL_ERROR , getName ( ) , " [%s] startTX failed, code %d " , timeString ( ) . c_str ( ) , state ) ;
decodeError ( system , state ) ;
startRX ( system ) ;
return ;
}
_transmitFlag = true ;
}
void RadiolibTask : : decodeError ( System & system , int16_t state ) {
switch ( state ) {
case RADIOLIB_ERR_UNKNOWN :
2023-08-06 20:49:48 +00:00
system . getLogger ( ) . log ( logging : : LoggerLevel : : LOGGER_LEVEL_ERROR , getName ( ) , " [%s] SX12xx unknown error. " , timeString ( ) . c_str ( ) ) ;
2023-06-08 10:50:09 +00:00
_rxEnable = false ;
_txEnable = false ;
break ;
case RADIOLIB_ERR_CHIP_NOT_FOUND :
2023-08-06 20:49:48 +00:00
system . getLogger ( ) . log ( logging : : LoggerLevel : : LOGGER_LEVEL_ERROR , getName ( ) , " [%s] SX12xx init failed, chip not found. " , timeString ( ) . c_str ( ) ) ;
2023-06-08 10:50:09 +00:00
_rxEnable = false ;
_txEnable = false ;
break ;
case RADIOLIB_ERR_PACKET_TOO_LONG :
2023-08-06 20:49:48 +00:00
system . getLogger ( ) . log ( logging : : LoggerLevel : : LOGGER_LEVEL_ERROR , getName ( ) , " [%s] SX12xx packet too long. " , timeString ( ) . c_str ( ) ) ;
2023-06-08 10:50:09 +00:00
break ;
case RADIOLIB_ERR_TX_TIMEOUT :
2023-08-06 20:49:48 +00:00
system . getLogger ( ) . log ( logging : : LoggerLevel : : LOGGER_LEVEL_ERROR , getName ( ) , " [%s] SX12xx tx timeout. " , timeString ( ) . c_str ( ) ) ;
2023-06-08 10:50:09 +00:00
break ;
case RADIOLIB_ERR_RX_TIMEOUT :
2023-08-06 20:49:48 +00:00
system . getLogger ( ) . log ( logging : : LoggerLevel : : LOGGER_LEVEL_ERROR , getName ( ) , " [%s] SX12xx rx timeout. " , timeString ( ) . c_str ( ) ) ;
2023-06-08 10:50:09 +00:00
break ;
case RADIOLIB_ERR_CRC_MISMATCH :
2023-08-06 20:49:48 +00:00
system . getLogger ( ) . log ( logging : : LoggerLevel : : LOGGER_LEVEL_ERROR , getName ( ) , " [%s] SX12xx crc mismatch. " , timeString ( ) . c_str ( ) ) ;
2023-06-08 10:50:09 +00:00
break ;
case RADIOLIB_ERR_INVALID_BANDWIDTH :
2023-08-06 20:49:48 +00:00
system . getLogger ( ) . log ( logging : : LoggerLevel : : LOGGER_LEVEL_ERROR , getName ( ) , " [%s] SX12xx init failed, The supplied bandwidth value (%fkHz) is invalid for this module. Should be 7800, 10400, 15600, 20800, 31250, 41700 ,62500, 125000, 250000, 500000. " , timeString ( ) . c_str ( ) , system . getUserConfig ( ) - > lora . signalBandwidth / 1000 ) ;
2023-06-08 10:50:09 +00:00
_rxEnable = false ;
_txEnable = false ;
break ;
case RADIOLIB_ERR_INVALID_SPREADING_FACTOR :
2023-08-06 20:49:48 +00:00
system . getLogger ( ) . log ( logging : : LoggerLevel : : LOGGER_LEVEL_ERROR , getName ( ) , " [%s] SX12xx init failed, The supplied spreading factor value (%d) is invalid for this module. " , timeString ( ) . c_str ( ) , system . getUserConfig ( ) - > lora . spreadingFactor ) ;
2023-06-08 10:50:09 +00:00
_rxEnable = false ;
_txEnable = false ;
break ;
case RADIOLIB_ERR_INVALID_CODING_RATE :
2023-08-06 20:49:48 +00:00
system . getLogger ( ) . log ( logging : : LoggerLevel : : LOGGER_LEVEL_ERROR , getName ( ) , " [%s] SX12xx init failed, The supplied coding rate value (%d) is invalid for this module. " , timeString ( ) . c_str ( ) , system . getUserConfig ( ) - > lora . codingRate4 ) ;
2023-06-08 10:50:09 +00:00
_rxEnable = false ;
_txEnable = false ;
break ;
case RADIOLIB_ERR_INVALID_FREQUENCY :
2023-08-06 20:49:48 +00:00
system . getLogger ( ) . log ( logging : : LoggerLevel : : LOGGER_LEVEL_ERROR , getName ( ) , " [%s] SX12xx init failed, The supplied frequency value (%fMHz) is invalid for this module. " , timeString ( ) . c_str ( ) , _frequencyRx ) ;
2023-06-08 10:50:09 +00:00
_rxEnable = false ;
_txEnable = false ;
break ;
case RADIOLIB_ERR_INVALID_OUTPUT_POWER :
2023-08-06 20:49:48 +00:00
system . getLogger ( ) . log ( logging : : LoggerLevel : : LOGGER_LEVEL_ERROR , getName ( ) , " [%s] SX12xx init failed, The supplied output power value (%d) is invalid for this module. " , timeString ( ) . c_str ( ) , system . getUserConfig ( ) - > lora . power ) ;
2023-06-08 10:50:09 +00:00
_txEnable = false ;
break ;
case RADIOLIB_ERR_INVALID_CURRENT_LIMIT :
2023-08-06 20:49:48 +00:00
system . getLogger ( ) . log ( logging : : LoggerLevel : : LOGGER_LEVEL_ERROR , getName ( ) , " [%s] SX12xx init failed, The supplied current limit is invalid. " , timeString ( ) . c_str ( ) ) ;
2023-06-08 10:50:09 +00:00
_txEnable = false ;
break ;
case RADIOLIB_ERR_INVALID_PREAMBLE_LENGTH :
2023-08-06 20:49:48 +00:00
system . getLogger ( ) . log ( logging : : LoggerLevel : : LOGGER_LEVEL_ERROR , getName ( ) , " [%s] SX12xx init failed, The supplied preamble length is invalid. " , timeString ( ) . c_str ( ) ) ;
2023-06-08 10:50:09 +00:00
_txEnable = false ;
break ;
case RADIOLIB_ERR_INVALID_GAIN :
2023-08-06 20:49:48 +00:00
system . getLogger ( ) . log ( logging : : LoggerLevel : : LOGGER_LEVEL_ERROR , getName ( ) , " [%s] SX12xx init failed, The supplied gain value (%d) is invalid. " , timeString ( ) . c_str ( ) , system . getUserConfig ( ) - > lora . gainRx ) ;
2023-06-08 10:50:09 +00:00
_rxEnable = false ;
break ;
case RADIOLIB_ERR_WRONG_MODEM :
2023-08-06 20:49:48 +00:00
system . getLogger ( ) . log ( logging : : LoggerLevel : : LOGGER_LEVEL_ERROR , getName ( ) , " [%s] SX12xx init failed, wrong modem selected. " , timeString ( ) . c_str ( ) ) ;
2023-06-08 10:50:09 +00:00
_rxEnable = false ;
_txEnable = false ;
break ;
case RADIOLIB_ERR_INVALID_NUM_SAMPLES :
2023-08-06 20:49:48 +00:00
system . getLogger ( ) . log ( logging : : LoggerLevel : : LOGGER_LEVEL_ERROR , getName ( ) , " [%s] SX12xx invalid number of samples. " , timeString ( ) . c_str ( ) ) ;
2023-06-08 10:50:09 +00:00
break ;
case RADIOLIB_ERR_INVALID_RSSI_OFFSET :
2023-08-06 20:49:48 +00:00
system . getLogger ( ) . log ( logging : : LoggerLevel : : LOGGER_LEVEL_ERROR , getName ( ) , " [%s] SX12xx invalid RSSI offset. " , timeString ( ) . c_str ( ) ) ;
2023-06-08 10:50:09 +00:00
break ;
case RADIOLIB_ERR_INVALID_ENCODING :
2023-08-06 20:49:48 +00:00
system . getLogger ( ) . log ( logging : : LoggerLevel : : LOGGER_LEVEL_ERROR , getName ( ) , " [%s] SX12xx invalid encoding. " , timeString ( ) . c_str ( ) ) ;
2023-06-08 10:50:09 +00:00
break ;
case RADIOLIB_ERR_LORA_HEADER_DAMAGED :
2023-08-06 20:49:48 +00:00
system . getLogger ( ) . log ( logging : : LoggerLevel : : LOGGER_LEVEL_ERROR , getName ( ) , " [%s] SX12xx LoRa header damaged. " , timeString ( ) . c_str ( ) ) ;
2023-06-08 10:50:09 +00:00
break ;
case RADIOLIB_ERR_INVALID_DIO_PIN :
2023-08-06 20:49:48 +00:00
system . getLogger ( ) . log ( logging : : LoggerLevel : : LOGGER_LEVEL_ERROR , getName ( ) , " [%s] SX12xx invalid DIO pin. " , timeString ( ) . c_str ( ) ) ;
2023-06-08 10:50:09 +00:00
break ;
case RADIOLIB_ERR_INVALID_RSSI_THRESHOLD :
2023-08-06 20:49:48 +00:00
system . getLogger ( ) . log ( logging : : LoggerLevel : : LOGGER_LEVEL_ERROR , getName ( ) , " [%s] SX12xx invalid RSSI threshold. " , timeString ( ) . c_str ( ) ) ;
2023-06-08 10:50:09 +00:00
break ;
case RADIOLIB_ERR_INVALID_BIT_RATE :
2023-08-06 20:49:48 +00:00
system . getLogger ( ) . log ( logging : : LoggerLevel : : LOGGER_LEVEL_ERROR , getName ( ) , " [%s] SX12xx invalid bit rate. " , timeString ( ) . c_str ( ) ) ;
2023-06-08 10:50:09 +00:00
break ;
case RADIOLIB_ERR_INVALID_FREQUENCY_DEVIATION :
2023-08-06 20:49:48 +00:00
system . getLogger ( ) . log ( logging : : LoggerLevel : : LOGGER_LEVEL_ERROR , getName ( ) , " [%s] SX12xx invalid frequency deviation. " , timeString ( ) . c_str ( ) ) ;
2023-06-08 10:50:09 +00:00
break ;
case RADIOLIB_ERR_INVALID_RX_BANDWIDTH :
2023-08-06 20:49:48 +00:00
system . getLogger ( ) . log ( logging : : LoggerLevel : : LOGGER_LEVEL_ERROR , getName ( ) , " [%s] SX12xx invalid rx bandwidth. " , timeString ( ) . c_str ( ) ) ;
2023-06-08 10:50:09 +00:00
break ;
case RADIOLIB_ERR_INVALID_SYNC_WORD :
2023-08-06 20:49:48 +00:00
system . getLogger ( ) . log ( logging : : LoggerLevel : : LOGGER_LEVEL_ERROR , getName ( ) , " [%s] SX12xx invalid sync word. " , timeString ( ) . c_str ( ) ) ;
2023-06-08 10:50:09 +00:00
break ;
case RADIOLIB_ERR_INVALID_DATA_SHAPING :
2023-08-06 20:49:48 +00:00
system . getLogger ( ) . log ( logging : : LoggerLevel : : LOGGER_LEVEL_ERROR , getName ( ) , " [%s] SX12xx invalid data shaping. " , timeString ( ) . c_str ( ) ) ;
2023-06-08 10:50:09 +00:00
break ;
case RADIOLIB_ERR_INVALID_MODULATION :
2023-08-06 20:49:48 +00:00
system . getLogger ( ) . log ( logging : : LoggerLevel : : LOGGER_LEVEL_ERROR , getName ( ) , " [%s] SX12xx invalid modulation. " , timeString ( ) . c_str ( ) ) ;
2023-06-08 10:50:09 +00:00
break ;
default :
2023-08-06 20:49:48 +00:00
system . getLogger ( ) . log ( logging : : LoggerLevel : : LOGGER_LEVEL_ERROR , getName ( ) , " [%s] SX12xx init failed, code %d " , timeString ( ) . c_str ( ) , state ) ;
2023-06-08 10:50:09 +00:00
_rxEnable = false ;
_txEnable = false ;
}
_stateInfo = " LoRa-Modem failed " ;
_state = Error ;
2022-04-02 01:20:16 +00:00
}