Skip to content

Removing software RX timeouts in RX chain #22

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jun 26, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
148 changes: 69 additions & 79 deletions SX1272/SX1272_LoRaRadio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ bool SX1272_LoRaRadio::check_rf_frequency(uint32_t frequency)
void SX1272_LoRaRadio::set_channel(uint32_t freq)
{
_rf_settings.channel = freq;
freq = (uint32_t) ((double) freq / (double) FREQ_STEP);
freq = (uint32_t) ((float) freq / (float) FREQ_STEP);
write_to_register(REG_FRFMSB, (uint8_t) ((freq >> 16) & 0xFF));
write_to_register(REG_FRFMID, (uint8_t) ((freq >> 8) & 0xFF));
write_to_register(REG_FRFLSB, (uint8_t) (freq & 0xFF));
Expand All @@ -306,7 +306,6 @@ void SX1272_LoRaRadio::sleep()
{
// stop timers
tx_timeout_timer.detach();
rx_timeout_timer.detach();

// put module in sleep mode
set_operation_mode(RF_OPMODE_SLEEP);
Expand Down Expand Up @@ -415,10 +414,9 @@ void SX1272_LoRaRadio::set_rx_config(radio_modems_t modem, uint32_t bandwidth,
_rf_settings.fsk.iq_inverted = iq_inverted;
_rf_settings.fsk.rx_continuous = rx_continuous;
_rf_settings.fsk.preamble_len = preamble_len;
_rf_settings.fsk.rx_single_timeout =
symb_timeout * ((1.0 / (double) datarate) * 8.0) * 1e3;
_rf_settings.fsk.rx_single_timeout = (symb_timeout + 1) / 2; // dividing by 2 as our detector size is 2 symbols (16 bytes)

datarate = (uint16_t) ((double) XTAL_FREQ / (double) datarate);
datarate = (uint16_t) ((float) XTAL_FREQ / (float) datarate);
write_to_register(REG_BITRATEMSB, (uint8_t) (datarate >> 8));
write_to_register(REG_BITRATELSB, (uint8_t) (datarate & 0xFF));

Expand Down Expand Up @@ -547,11 +545,11 @@ void SX1272_LoRaRadio::set_tx_config(radio_modems_t modem, int8_t power,
_rf_settings.fsk.iq_inverted = iq_inverted;
_rf_settings.fsk.tx_timeout = timeout;

fdev = (uint16_t) ((double) fdev / (double) FREQ_STEP);
fdev = (uint16_t) ((float) fdev / (float) FREQ_STEP);
write_to_register( REG_FDEVMSB, (uint8_t) (fdev >> 8));
write_to_register( REG_FDEVLSB, (uint8_t) (fdev & 0xFF));

datarate = (uint16_t) ((double) XTAL_FREQ / (double) datarate);
datarate = (uint16_t) ((float) XTAL_FREQ / (float) datarate);
write_to_register( REG_BITRATEMSB, (uint8_t) (datarate >> 8));
write_to_register( REG_BITRATELSB, (uint8_t) (datarate & 0xFF));

Expand Down Expand Up @@ -658,48 +656,48 @@ uint32_t SX1272_LoRaRadio::time_on_air(radio_modems_t modem, uint8_t pkt_len)
+ ((read_register( REG_SYNCCONFIG)
& ~RF_SYNCCONFIG_SYNCSIZE_MASK) + 1)
+ ((_rf_settings.fsk.fix_len == 0x01) ?
0.0 : 1.0)
0.0f : 1.0f)
+ (((read_register( REG_PACKETCONFIG1)
& ~RF_PACKETCONFIG1_ADDRSFILTERING_MASK)
!= 0x00) ? 1.0 : 0) + pkt_len
!= 0x00) ? 1.0f : 0) + pkt_len
+ ((_rf_settings.fsk.crc_on == 0x01) ?
2.0 : 0))
/ _rf_settings.fsk.datarate) * 1e3);
2.0f : 0))
/ _rf_settings.fsk.datarate) * 1000);
}
break;
case MODEM_LORA: {
double bw = 0.0;
float bw = 0.0f;
switch (_rf_settings.lora.bandwidth) {
case 0: // 125 kHz
bw = 125e3;
bw = 125000;
break;
case 1: // 250 kHz
bw = 250e3;
bw = 250000;
break;
case 2: // 500 kHz
bw = 500e3;
bw = 500000;
break;
}

// Symbol rate : time for one symbol (secs)
double rs = bw / (1 << _rf_settings.lora.datarate);
double ts = 1 / rs;
float rs = bw / (1 << _rf_settings.lora.datarate);
float ts = 1 / rs;
// time of preamble
double preamble_time = (_rf_settings.lora.preamble_len + 4.25) * ts;
float preamble_time = (_rf_settings.lora.preamble_len + 4.25f) * ts;
// Symbol length of payload and time
double tmp = ceil((8 * pkt_len - 4 * _rf_settings.lora.datarate + 28
float tmp = ceil((8 * pkt_len - 4 * _rf_settings.lora.datarate + 28
+ 16 * _rf_settings.lora.crc_on -
(_rf_settings.lora.fix_len ? 20 : 0))
/ (double) (4 * (_rf_settings.lora.datarate -
/ (float) (4 * (_rf_settings.lora.datarate -
((_rf_settings.lora.low_datarate_optimize
> 0) ? 2 : 0)))) *
(_rf_settings.lora.coderate + 4);
double n_payload = 8 + ((tmp > 0) ? tmp : 0);
double t_payload = n_payload * ts;
float n_payload = 8 + ((tmp > 0) ? tmp : 0);
float t_payload = n_payload * ts;
// Time on air
double t_onair = preamble_time + t_payload;
float t_onair = preamble_time + t_payload;
// return ms secs
airtime = floor(t_onair * 1e3 + 0.999);
airtime = floor(t_onair * 1000 + 0.999f);
}
break;
}
Expand Down Expand Up @@ -867,19 +865,13 @@ void SX1272_LoRaRadio::transmit(uint32_t timeout)
* and finally a DIO0 interrupt let's the state machine know that a packet is
* ready to be read from the FIFO
*/
void SX1272_LoRaRadio::receive(uint32_t timeout)
void SX1272_LoRaRadio::receive(void)
{
switch (_rf_settings.modem) {
case MODEM_FSK:
if (timeout == 0 && _rf_settings.fsk.rx_continuous == false) {
// user messed up probably timeout was 0 but mode was not
// continuous, force it to be continuous
_rf_settings.fsk.rx_continuous = true;
}

// DIO0=PayloadReady
// DIO1=FifoLevel
// DIO2=SyncAddr
// DIO2=RxTimeout
// DIO3=FifoEmpty
// DIO4=Preamble
// DIO5=ModeReady
Expand All @@ -889,7 +881,7 @@ void SX1272_LoRaRadio::receive(uint32_t timeout)
RF_DIOMAPPING1_DIO2_MASK) |
RF_DIOMAPPING1_DIO0_00 |
RF_DIOMAPPING1_DIO1_00 |
RF_DIOMAPPING1_DIO2_11);
RF_DIOMAPPING1_DIO2_10);

write_to_register(REG_DIOMAPPING2, (read_register(REG_DIOMAPPING2) &
RF_DIOMAPPING2_DIO4_MASK &
Expand All @@ -904,6 +896,16 @@ void SX1272_LoRaRadio::receive(uint32_t timeout)
RF_RXCONFIG_AGCAUTO_ON |
RF_RXCONFIG_RXTRIGER_PREAMBLEDETECT);

if (!_rf_settings.fsk.rx_continuous) {
// the value for rx timeout in symbols cannot be more than 255
// as the preamble length is fixed. We assert here for quick
// diagnostics
MBED_ASSERT(_rf_settings.fsk.rx_single_timeout <= 255);
write_to_register(REG_RXTIMEOUT2, _rf_settings.fsk.rx_single_timeout);
write_to_register(REG_RXTIMEOUT3, 0x00);
write_to_register(REG_RXTIMEOUT1, 0x00);
}

_rf_settings.fsk_packet_handler.preamble_detected = 0;
_rf_settings.fsk_packet_handler.sync_word_detected = 0;
_rf_settings.fsk_packet_handler.nb_bytes = 0;
Expand All @@ -912,11 +914,6 @@ void SX1272_LoRaRadio::receive(uint32_t timeout)
break;

case MODEM_LORA:
if (timeout == 0 && _rf_settings.lora.rx_continuous == false) {
// user messed up probably timeout was 0 but mode was not
// continuous, force it to be continuous
_rf_settings.lora.rx_continuous = true;
}

if (_rf_settings.lora.iq_inverted == true) {
write_to_register(REG_LR_INVERTIQ, ((read_register(REG_LR_INVERTIQ) &
Expand Down Expand Up @@ -971,21 +968,8 @@ void SX1272_LoRaRadio::receive(uint32_t timeout)

_rf_settings.state = RF_RX_RUNNING;

if (timeout != 0) {
rx_timeout_timer.attach_us(callback(this,
&SX1272_LoRaRadio::timeout_irq_isr),
timeout*1e3);
}

if (_rf_settings.modem == MODEM_FSK) {
set_operation_mode(RF_OPMODE_RECEIVER);

if (_rf_settings.fsk.rx_continuous == false) {
rx_timeout_sync_word.attach_us(callback(this,
&SX1272_LoRaRadio::timeout_irq_isr),
_rf_settings.fsk.rx_single_timeout * 1e3);
}

return;
}

Expand Down Expand Up @@ -1144,8 +1128,6 @@ void SX1272_LoRaRadio::set_tx_continuous_wave(uint32_t freq, int8_t power,
void SX1272_LoRaRadio::standby( void )
{
tx_timeout_timer.detach();
rx_timeout_timer.detach();

set_operation_mode(RF_OPMODE_STANDBY);
_rf_settings.state = RF_IDLE;
}
Expand Down Expand Up @@ -1732,7 +1714,6 @@ void SX1272_LoRaRadio::handle_dio0_irq()


if (_rf_settings.fsk.rx_continuous == false) {
rx_timeout_sync_word.detach();
_rf_settings.state = RF_IDLE;
} else {
// Continuous mode restart Rx chain
Expand All @@ -1741,8 +1722,6 @@ void SX1272_LoRaRadio::handle_dio0_irq()
RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK);
}

rx_timeout_timer.detach();

if ((_radio_events != NULL)
&& (_radio_events->rx_error)) {
_radio_events->rx_error();
Expand All @@ -1757,6 +1736,15 @@ void SX1272_LoRaRadio::handle_dio0_irq()
}
}

// This block was moved from dio2_handler.
// We can have a snapshot of RSSI here as at this point it
// should be more smoothed out.
_rf_settings.fsk_packet_handler.rssi_value = -(read_register(REG_RSSIVALUE) >> 1);
_rf_settings.fsk_packet_handler.afc_value = (int32_t)(float)(((uint16_t)read_register(REG_AFCMSB) << 8) |
(uint16_t)read_register(REG_AFCLSB)) *
(float)FREQ_STEP;
_rf_settings.fsk_packet_handler.rx_gain = (read_register(REG_LNA) >> 5) & 0x07;

// Read received packet size
if ((_rf_settings.fsk_packet_handler.size == 0)
&& (_rf_settings.fsk_packet_handler.nb_bytes == 0)) {
Expand All @@ -1778,15 +1766,12 @@ void SX1272_LoRaRadio::handle_dio0_irq()

if (_rf_settings.fsk.rx_continuous == false) {
_rf_settings.state = RF_IDLE;
rx_timeout_sync_word.detach();
} else {
// Continuous mode restart Rx chain
write_to_register(REG_RXCONFIG, read_register(REG_RXCONFIG)
| RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK);
}

rx_timeout_timer.detach();

if ((_radio_events != NULL) && (_radio_events->rx_done)) {
_radio_events->rx_done(
_data_buffer,
Expand Down Expand Up @@ -1814,7 +1799,6 @@ void SX1272_LoRaRadio::handle_dio0_irq()
if (_rf_settings.lora.rx_continuous == false) {
_rf_settings.state = RF_IDLE;
}
rx_timeout_timer.detach();

if ((_radio_events != NULL)
&& (_radio_events->rx_error)) {
Expand Down Expand Up @@ -1849,7 +1833,6 @@ void SX1272_LoRaRadio::handle_dio0_irq()
if (_rf_settings.lora.rx_continuous == false) {
_rf_settings.state = RF_IDLE;
}
rx_timeout_timer.detach();

if ((_radio_events != NULL)
&& (_radio_events->rx_done)) {
Expand Down Expand Up @@ -1923,7 +1906,6 @@ void SX1272_LoRaRadio::handle_dio1_irq()
break;
case MODEM_LORA:
// Sync time out
rx_timeout_timer.detach( );
_rf_settings.state = RF_IDLE;
if ((_radio_events != NULL) && (_radio_events->rx_timeout)) {
_radio_events->rx_timeout();
Expand Down Expand Up @@ -1969,23 +1951,33 @@ void SX1272_LoRaRadio::handle_dio2_irq(void)
switch( _rf_settings.modem )
{
case MODEM_FSK:
_rf_settings.fsk_packet_handler.preamble_detected = 0;
_rf_settings.fsk_packet_handler.sync_word_detected = 0;
_rf_settings.fsk_packet_handler.nb_bytes = 0;
_rf_settings.fsk_packet_handler.size = 0;

// Clear Irqs
write_to_register(REG_IRQFLAGS1, RF_IRQFLAGS1_RSSI |
RF_IRQFLAGS1_PREAMBLEDETECT |
RF_IRQFLAGS1_SYNCADDRESSMATCH |
RF_IRQFLAGS1_TIMEOUT);

write_to_register( REG_IRQFLAGS2, RF_IRQFLAGS2_FIFOOVERRUN);

if (_rf_settings.fsk.rx_continuous == true) {
// Continuous mode restart Rx chain
write_to_register( REG_RXCONFIG,
read_register(REG_RXCONFIG) |
RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK);
} else {
_rf_settings.state = RF_IDLE;
}

// DIO4 must have been asserted to set preamble_detected to true
if( ( _rf_settings.fsk_packet_handler.preamble_detected == 1 ) && ( _rf_settings.fsk_packet_handler.sync_word_detected == 0 ) )
{
if (_rf_settings.fsk.rx_continuous == false) {
rx_timeout_sync_word.detach( );
}

_rf_settings.fsk_packet_handler.sync_word_detected = 1;

_rf_settings.fsk_packet_handler.rssi_value = -( read_register( REG_RSSIVALUE ) >> 1 );

_rf_settings.fsk_packet_handler.afc_value = ( int32_t )( double )( ( ( uint16_t )read_register( REG_AFCMSB ) << 8 ) |
( uint16_t )read_register( REG_AFCLSB ) ) *
( double )FREQ_STEP;
_rf_settings.fsk_packet_handler.rx_gain = ( read_register( REG_LNA ) >> 5 ) & 0x07;
if ((_radio_events != NULL)
&& (_radio_events->rx_timeout)) {
_radio_events->rx_timeout();
}

break;
case MODEM_LORA:
if( _rf_settings.lora.freq_hop_on == true )
Expand Down Expand Up @@ -2117,8 +2109,6 @@ void SX1272_LoRaRadio::handle_timeout_irq()
else
{
_rf_settings.state = RF_IDLE;
rx_timeout_sync_word.attach_us(callback(this, &SX1272_LoRaRadio::timeout_irq_isr),
_rf_settings.fsk.rx_single_timeout * 1e3);
}
}

Expand Down
30 changes: 17 additions & 13 deletions SX1272/SX1272_LoRaRadio.h
Original file line number Diff line number Diff line change
Expand Up @@ -192,18 +192,21 @@ class SX1272_LoRaRadio: public LoRaRadio {
virtual void send(uint8_t *buffer, uint8_t size);

/**
* Sets the radio in reception mode for the given time
*
* It should be noted that if the timeout is set to 0, it essentially
* puts the receiver in continuous mode and hence from thereon it should
* be treated as if in continuous mode. However, an appropriate way of
* setting the receiver in continuous mode is by using set_rx_config()
* API.
*
* @param timeout Reception timeout [ms]
* For backwards compatibility
*/
virtual void receive(uint32_t timeout)
{
(void) timeout;
receive();
}

/**
* Sets the radio to receive
*
* All necessary configuration options for receptions are set in
* 'set_rx_config(parameters)' API.
*/
virtual void receive(uint32_t timeout);
virtual void receive(void);

/**
* Sets the carrier frequency
Expand Down Expand Up @@ -360,10 +363,11 @@ class SX1272_LoRaRadio: public LoRaRadio {
// Default is 256 bytes
uint8_t _data_buffer[MAX_DATA_BUFFER_SIZE_SX172];

// TX/RX Timers - all use milisecond units
// TX timer in ms. This timer is used as a fail safe for TX.
// If the chip fails to transmit, its a fatal error, reflecting
// some catastrophic bus failure etc. We wish to have the control
// back from the driver in such a case.
mbed::Timeout tx_timeout_timer;
mbed::Timeout rx_timeout_timer;
mbed::Timeout rx_timeout_sync_word;

#ifdef MBED_CONF_RTOS_PRESENT
// Thread to handle interrupts
Expand Down
Loading