Merge pull request #7806 from hasnainvirk/fix_for_cn470

LoRaWAN: Fixing Hard fault in CN470 PHY layer
pull/7960/head
Martin Kojtal 2018-09-02 15:56:33 +02:00 committed by GitHub
commit c7d6560571
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 116 additions and 35 deletions

View File

@ -1,35 +1,52 @@
Frequency sub-bands in US915/AU915:
US915/AU915 PHYs define channel structures which can support up-to 72 channels for upstream.
First 64 channels (0-63), occupy 125 kHz and the last 8 channels (64-71) occupy 500 kHz.
US915/AU915 PHYs define channel structures that can support up to 72 channels for upstream.
The first 64 channels (0-63), occupy 125 kHz and the last 8 channels (64-71) occupy 500 kHz.
However, most of the base stations available in the market support 8 or 16 channels.
Network acquisition can become costly if the device have no prior knowledge of active channel plan and it enables
Network acquisition can become costly if the device has no prior knowledge of the active channel plan and it enables
all 72 channels to begin with.
LoRaWAN 1.0.2 Regional parameters specification refers to a strategy of probing a set of nine channels (8 + 1) for
joining process. According to that strategy the device is supposed to alternatively select a channel from a set of
8, 125 kHz channels and a 500 kHz channel.
For example send a join request alternatively on a randomly selected channel from a set of 0-7 channels and
channel 64 which is the first 500 kHz channel.
The LoRaWAN 1.0.2 Regional parameters specification refers to a strategy of probing a set of nine channels (8 + 1) for
the joining process. According to that strategy, the device alternatively selects a channel from a set of
8 125 kHz channels and a 500 kHz channel.
For example, send a join request alternatively on a randomly selected channel from a set of 0-7 channels and
channel 64, which is the first 500 kHz channel.
Once the device has joined the network (in case of OTAA) or have sent the first uplink (in case of ABP), the network
may send a LinkAdrReq mac command to set the channel mask to be used. Please note that these PHY layers do not
support CFList so LinkAdrReq is the way the network tells you what channel plan to use.
Once the device has joined the network (in case of OTAA) or has sent the first uplink (in the case of ABP), the network
may send a LinkAdrReq MAC command to set the channel mask to be used. Please note that these PHY layers do not
support CFList, so LinkAdrReq is the way the network tells you what channel plan to use.
Mbed LoRaWAN stack can be configured to use a particular frequency sub-band (FSB) which means that we don't have to
probe all sets of channels. "fsb-mask" in lorawan/mbed_lib.json is the parameter which can be used to tell the
system which FSB or a set of FSBs to use. By default the "fsb-mask" is set to "{0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x00FF}"
that means all channels are active, i.e., 64 125 kHz channels and 8 500 kHz channels are active. If the user wishes
to use a custom FSB, he/she needs to set appropriate mask as the value of "fsb-mask". For example:
If the user wishes to use the first FSB, i.e., first 8 125 kHz channels (0-7) and the first 500 kHz channel:
You can configure the Mbed LoRaWAN stack to use a particular frequency sub-band (FSB), which means that you don't have to
probe all sets of channels. "fsb-mask" in lorawan/mbed_lib.json is the parameter that you can use to tell the
system which FSB or set of FSBs to use. By default, the "fsb-mask" is set to "{0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x00FF}".
That means all channels are active. In other words, 64 125 kHz channels and 8 500 kHz channels are active. If you wish
to use a custom FSB, you need to set an appropriate mask as the value of "fsb-mask". For example, if you wish to use the
first FSB, in other words, the first 8 125 kHz channels (0-7) and the first 500 kHz channel:
"fsb-mask" = "{0x00FF, 0x0000, 0x0000, 0x0000, 0x0001}"
Similarly, if the user wishes to use second FSB, i.e., 2nd set of 8 125 kHz channels (8-15) and the 2nd 500 kHz
Similarly, if you wish to use the second FSB, in other words, the second set of 8 125 kHz channels (8-15) and the 2nd 500 kHz
channel:
"fsb-mask" = "{0xFF00, 0x0000, 0x0000, 0x0000, 0x0002}"
You can also combine FSBs if your base station supports more than 8 channels. For example:
"fsb-mask" = "{0x00FF, 0x0000, 0x0000, 0xFF00, 0x0081}"
will mean use channels 0-7(125 kHz) + channel 64 (500 KHz) and channels 56-63 (125 kHz) + channel 71 (500 kHz).
means 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, so before joining,
do not set a mask that enables only 500 kHz or only 125 kHz channels.
Frequency sub-bands in CN470 PHY:
The LoRaPHYCN470 class defines 96 channels in total, as per the 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 that lorawan/mbed_lib.json defines. It 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 that do not support all 96 channels. Therefore, network acquisition
can become cumbersome if the device hops on random channels. The probability of finding a correct channel for a base station
that supports 8 channels would be 1/12.
For example, if your base station supports 16 channels (channels 0-15), set the "fsb-mask-china" as:
"fsb-mask-china" = "{0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}"
Similarly, if your base station supports 8 channels (channels 0-7), set the "fsb-mask-china" as:
"fsb-mask-china" = "{0x00FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}"
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.

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}"
}
}
}