Adding override for TX ch. selection in CN470 PHY

set_next_channel() is the base function provided by LoRaPHY class and should be overridden
by the PHYs who behave differently as compared to EU868 like PHY layers.
CN470 PHY had been missing such an override.
In addition to that we have provided a parameter "fsb-mask-china" that can be used to
enforce a custom frequency sub-band of operation as most of the base stations in the market
may not support all 96 channels. Such a strategy will help in rapid network acquisition.
pull/7806/head
Hasnain Virk 2018-08-16 16:17:59 +03:00
parent ce28c91405
commit 5cca2f2e76
4 changed files with 96 additions and 15 deletions

View File

@ -32,4 +32,21 @@ Frequency sub-bands in US915/AU915:
will mean use channels 0-7(125 kHz) + channel 64 (500 KHz) and channels 56-63 (125 kHz) + channel 71 (500 kHz).
Please note that for Certification requirements, you need to alternate between 125 kHz and 500 kHz channels and that's
why before joining you should not set a mask that enables only 500 kHz or only 125 kHz channels.
why before joining you should not set a mask that enables only 500 kHz or only 125 kHz channels.
Frequency sub-bands in CN470 PHY:
There are 96 channels in total defined in LoRaPHYCN470 class as per LoRaWAN Regional Specification. These 96 channels
are 125 kHz wide each and can be subdivided into 6 sub-bands containing 16 channels each.
"fsb-mask-china" is the parameter defined in lorawan/mbed_lib.json which can be used to enforce an FSB. It is defined
as a c-style array and the first element of the array corresponds to first 8 channels (0-7) and so on. By default all
96 channels are enabled but there may be base stations who do not support all 96 channels and hence network acquisition
can become cumbersome if the device hops on random channels. The probability of finding a correct channel for a base station
who support 8 channels would be 1/12.
For example, say your base station supports 16 channels (channels 0-15), you would set the "fsb-mask-china" as:
"fsb-mask-china" = "{0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}"
Yet another example, say your base station supports 8 channels (channels 0-7), you would set the "fsb-mask-china" as:
"fsb-mask-china" = "{0x00FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}"

View File

@ -206,6 +206,8 @@ static const uint8_t max_payloads_with_repeater_CN470[] = {51, 51, 51, 115, 222,
LoRaPHYCN470::LoRaPHYCN470()
{
static const uint16_t fsb_mask[] = MBED_CONF_LORA_FSB_MASK_CHINA;
bands[0] = CN470_BAND0;
// Channels
@ -218,12 +220,9 @@ LoRaPHYCN470::LoRaPHYCN470()
}
// Initialize the channels default mask
default_channel_mask[0] = 0xFFFF;
default_channel_mask[1] = 0xFFFF;
default_channel_mask[2] = 0xFFFF;
default_channel_mask[3] = 0xFFFF;
default_channel_mask[4] = 0xFFFF;
default_channel_mask[5] = 0xFFFF;
for (uint8_t i = 0; i < CN470_MAX_NB_CHANNELS; i++) {
default_channel_mask[i] = 0xFFFF & fsb_mask[i];
}
// Update the channels mask
copy_channel_mask(channel_mask, default_channel_mask, CN470_CHANNEL_MASK_SIZE);
@ -302,6 +301,64 @@ LoRaPHYCN470::~LoRaPHYCN470()
{
}
lorawan_status_t LoRaPHYCN470::set_next_channel(channel_selection_params_t *params,
uint8_t *channel, lorawan_time_t *time,
lorawan_time_t *aggregate_timeoff)
{
uint8_t channel_count = 0;
uint8_t delay_tx = 0;
uint8_t enabled_channels[CN470_MAX_NB_CHANNELS] = {0};
lorawan_time_t next_tx_delay = 0;
band_t *band_table = (band_t *) phy_params.bands.table;
if (num_active_channels(phy_params.channels.mask, 0,
phy_params.channels.mask_size) == 0) {
// Reactivate default channels
copy_channel_mask(phy_params.channels.mask,
phy_params.channels.default_mask,
phy_params.channels.mask_size);
}
if (params->aggregate_timeoff
<= _lora_time->get_elapsed_time(params->last_aggregate_tx_time)) {
// Reset Aggregated time off
*aggregate_timeoff = 0;
// Update bands Time OFF
next_tx_delay = update_band_timeoff(params->joined,
params->dc_enabled,
band_table, phy_params.bands.size);
// Search how many channels are enabled
channel_count = enabled_channel_count(params->current_datarate,
phy_params.channels.mask,
enabled_channels, &delay_tx);
} else {
delay_tx++;
next_tx_delay = params->aggregate_timeoff -
_lora_time->get_elapsed_time(params->last_aggregate_tx_time);
}
if (channel_count > 0) {
// We found a valid channel
*channel = enabled_channels[get_random(0, channel_count - 1)];
*time = 0;
return LORAWAN_STATUS_OK;
}
if (delay_tx > 0) {
// Delay transmission due to AggregatedTimeOff or to a band time off
*time = next_tx_delay;
return LORAWAN_STATUS_DUTYCYCLE_RESTRICTED;
}
*time = 0;
return LORAWAN_STATUS_NO_CHANNEL_FOUND;
}
bool LoRaPHYCN470::rx_config(rx_config_params_t* config)
{
int8_t dr = config->datarate;
@ -332,7 +389,8 @@ bool LoRaPHYCN470::rx_config(rx_config_params_t* config)
_radio->set_channel(frequency);
// Radio configuration
_radio->set_rx_config(MODEM_LORA, config->bandwidth, phy_dr, 1, 0, 8,
_radio->set_rx_config(MODEM_LORA, config->bandwidth, phy_dr, 1, 0,
MBED_CONF_LORA_DOWNLINK_PREAMBLE_LENGTH,
config->window_timeout, false, 0, false, 0, 0, true,
config->is_rx_continuous);
@ -371,7 +429,8 @@ bool LoRaPHYCN470::tx_config(tx_config_params_t* config, int8_t* tx_power,
_radio->set_channel(channels[config->channel].frequency);
_radio->set_tx_config(MODEM_LORA, phy_tx_power, 0, 0, phy_dr, 1, 8, false, true,
_radio->set_tx_config(MODEM_LORA, phy_tx_power, 0, 0, phy_dr, 1,
MBED_CONF_LORA_UPLINK_PREAMBLE_LENGTH, false, true,
0, 0, false, 3000);
// Setup maximum payload lenght of the radio driver
_radio->set_max_payload_length(MODEM_LORA, config->pkt_len);
@ -421,12 +480,9 @@ uint8_t LoRaPHYCN470::link_ADR_request(adr_req_params_t* params,
if (adr_settings.ch_mask_ctrl == 6) {
// Enable all 125 kHz channels
temp_channel_masks[0] = 0xFFFF;
temp_channel_masks[1] = 0xFFFF;
temp_channel_masks[2] = 0xFFFF;
temp_channel_masks[3] = 0xFFFF;
temp_channel_masks[4] = 0xFFFF;
temp_channel_masks[5] = 0xFFFF;
for (uint8_t i = 0; i < CN470_CHANNEL_MASK_SIZE; i++) {
temp_channel_masks[i] = 0xFFFF;
}
} else if( adr_settings.ch_mask_ctrl == 7 ) {

View File

@ -56,6 +56,10 @@ public:
LoRaPHYCN470();
virtual ~LoRaPHYCN470();
virtual lorawan_status_t set_next_channel(channel_selection_params_t *params,
uint8_t *channel, lorawan_time_t *time,
lorawan_time_t *aggregate_timeoff);
virtual bool rx_config(rx_config_params_t* config);
virtual bool tx_config(tx_config_params_t* config, int8_t* tx_power,

View File

@ -84,6 +84,10 @@
"fsb-mask": {
"help": "FSB mask for upstream [Only for US915 & AU915] Check lorawan/FSB_Usage.txt for more details",
"value": "{0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x00FF}"
},
"fsb-mask-china": {
"help": "FSB mask for upstream [CN470 PHY] Check lorawan/FSB_Usage.txt for more details",
"value": "{0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF}"
}
}
}