mirror of https://github.com/ARMmbed/mbed-os.git
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
parent
ce28c91405
commit
5cca2f2e76
|
@ -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}"
|
||||
|
|
@ -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 ) {
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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}"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue