1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

Merge pull request #16188 from aabadie/semtech-loramac_netdev

pkg/semtech-loramac: refactor to use netdev API only
This commit is contained in:
José Alamos 2021-03-18 13:11:32 +01:00 committed by GitHub
commit 21390849bf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 203 additions and 123 deletions

View File

@ -338,6 +338,11 @@ static int _get(netdev_t *netdev, netopt_t opt, void *val, size_t max_len)
*((netopt_enable_t*) val) = sx127x_get_iq_invert(dev) ? NETOPT_ENABLE : NETOPT_DISABLE;
return sizeof(netopt_enable_t);
case NETOPT_RSSI:
assert(max_len >= sizeof(int8_t));
*((int8_t*) val) = sx127x_read_rssi(dev);
return sizeof(int8_t);
default:
break;
}

View File

@ -32,6 +32,10 @@
#include "net/loramac.h"
#include "semtech_loramac.h"
#include "sx127x.h"
#include "sx127x_netdev.h"
#include "sx127x_params.h"
/* Messages are sent every 20s to respect the duty cycle on each channel */
#define PERIOD (20U)
@ -39,7 +43,8 @@
static kernel_pid_t sender_pid;
static char sender_stack[THREAD_STACKSIZE_MAIN / 2];
semtech_loramac_t loramac;
static semtech_loramac_t loramac;
static sx127x_t sx127x;
static const char *message = "This is RIOT!";
@ -108,6 +113,11 @@ int main(void)
fmt_hex_bytes(appeui, CONFIG_LORAMAC_APP_EUI_DEFAULT);
fmt_hex_bytes(appkey, CONFIG_LORAMAC_APP_KEY_DEFAULT);
/* Initialize the radio driver */
sx127x_setup(&sx127x, &sx127x_params[0], 0);
loramac.netdev = (netdev_t *)&sx127x;
loramac.netdev->driver = &sx127x_driver;
/* Initialize the loramac stack */
semtech_loramac_init(&loramac);
semtech_loramac_set_deveui(&loramac, deveui);

View File

@ -35,15 +35,15 @@
#include "net/netdev/lora.h"
#include "net/loramac.h"
#include "sx127x.h"
#include "sx127x_params.h"
#include "sx127x_netdev.h"
#include "semtech_loramac.h"
#include "LoRaMac.h"
#include "LoRaMacTest.h"
#include "region/Region.h"
#if IS_USED(MODULE_SX127X)
#include "sx127x.h"
#endif
#ifdef MODULE_PERIPH_EEPROM
#include "periph/eeprom.h"
#endif
@ -51,18 +51,20 @@
#define ENABLE_DEBUG 0
#include "debug.h"
#define LORAMAC_RX_BUFFER_SIZE (256U)
#define SEMTECH_LORAMAC_MSG_QUEUE (4U)
#define SEMTECH_LORAMAC_LORAMAC_STACKSIZE (THREAD_STACKSIZE_DEFAULT)
static msg_t _semtech_loramac_msg_queue[SEMTECH_LORAMAC_MSG_QUEUE];
static char _semtech_loramac_stack[SEMTECH_LORAMAC_LORAMAC_STACKSIZE];
kernel_pid_t semtech_loramac_pid;
sx127x_t sx127x;
RadioEvents_t semtech_loramac_radio_events;
LoRaMacPrimitives_t semtech_loramac_primitives;
LoRaMacCallback_t semtech_loramac_callbacks;
extern LoRaMacParams_t LoRaMacParams;
netdev_t *loramac_netdev_ptr = 0;
typedef struct {
uint8_t *payload;
uint8_t len;
@ -520,11 +522,13 @@ static void _semtech_loramac_event_cb(netdev_t *dev, netdev_event_t event)
break;
case NETDEV_EVENT_TX_COMPLETE:
sx127x_set_sleep((sx127x_t *)dev);
{
netopt_state_t sleep_state = NETOPT_STATE_SLEEP;
dev->driver->set(dev, NETOPT_STATE, &sleep_state, sizeof(netopt_state_t));
semtech_loramac_radio_events.TxDone();
DEBUG("[semtech-loramac] Transmission completed\n");
break;
}
case NETDEV_EVENT_TX_TIMEOUT:
msg.type = MSG_TYPE_TX_TIMEOUT;
if (msg_send(&msg, semtech_loramac_pid) <= 0) {
@ -541,7 +545,7 @@ static void _semtech_loramac_event_cb(netdev_t *dev, netdev_event_t event)
int len;
len = dev->driver->recv(dev, NULL, 0, 0);
if (len > 0) {
uint8_t radio_payload[SX127X_RX_BUFFER_SIZE];
uint8_t radio_payload[LORAMAC_RX_BUFFER_SIZE];
dev->driver->recv(dev, radio_payload, len, &packet_info);
semtech_loramac_radio_events.RxDone(radio_payload,
len, packet_info.rssi,
@ -561,6 +565,7 @@ static void _semtech_loramac_event_cb(netdev_t *dev, netdev_event_t event)
semtech_loramac_radio_events.RxError();
break;
#if IS_USED(MODULE_SX127X)
case NETDEV_EVENT_FHSS_CHANGE_CHANNEL:
DEBUG("[semtech-loramac] FHSS channel change\n");
if(semtech_loramac_radio_events.FhssChangeChannel) {
@ -576,6 +581,7 @@ static void _semtech_loramac_event_cb(netdev_t *dev, netdev_event_t event)
(sx127x_t *)dev)->_internal.is_last_cad_success);
}
break;
#endif
default:
DEBUG("[semtech-loramac] unexpected netdev event received: %d\n",
@ -829,9 +835,8 @@ void *_semtech_loramac_event_loop(void *arg)
int semtech_loramac_init(semtech_loramac_t *mac)
{
sx127x_setup(&sx127x, &sx127x_params[0], 0);
sx127x.netdev.driver = &sx127x_driver;
sx127x.netdev.event_callback = _semtech_loramac_event_cb;
loramac_netdev_ptr = mac->netdev;
mac->netdev->event_callback = _semtech_loramac_event_cb;
semtech_loramac_pid = thread_create(_semtech_loramac_stack,
sizeof(_semtech_loramac_stack),

View File

@ -19,19 +19,24 @@
* @}
*/
#include <assert.h>
#include "ztimer.h"
#include "net/netopt.h"
#include "net/lora.h"
#include "net/netdev.h"
#include "net/loramac.h"
#include "LoRaMac.h"
#include "radio/radio.h"
#include "sx127x.h"
#include "sx127x_internal.h"
#include "sx127x_netdev.h"
#include "radio/radio.h"
#define ENABLE_DEBUG 0
#include "debug.h"
extern sx127x_t sx127x;
extern netdev_t *loramac_netdev_ptr;
/*
* Radio driver functions implementation wrappers, the netdev2 object
@ -40,7 +45,8 @@ extern sx127x_t sx127x;
void SX127XInit(RadioEvents_t *events)
{
(void) events;
if (sx127x_init(&sx127x) < 0) {
assert(loramac_netdev_ptr);
if (loramac_netdev_ptr->driver->init(loramac_netdev_ptr) < 0) {
DEBUG("[semtech-loramac] radio: failed to initialize radio\n");
}
@ -49,30 +55,49 @@ void SX127XInit(RadioEvents_t *events)
RadioState_t SX127XGetStatus(void)
{
return (RadioState_t)sx127x_get_state(&sx127x);
netopt_state_t state;
loramac_netdev_ptr->driver->get(loramac_netdev_ptr, NETOPT_STATE, &state, sizeof(netopt_state_t));
switch (state) {
case NETOPT_STATE_RX:
case NETOPT_STATE_IDLE:
return RF_RX_RUNNING;
case NETOPT_STATE_TX:
return RF_TX_RUNNING;
default:
return RF_IDLE;
}
}
void SX127XSetModem(RadioModems_t modem)
{
sx127x_set_modem(&sx127x, (uint8_t)modem);
(void)modem;
uint16_t modem_val = NETDEV_TYPE_LORA;
loramac_netdev_ptr->driver->set(loramac_netdev_ptr, NETOPT_DEVICE_TYPE, &modem_val, sizeof(uint16_t));
}
void SX127XSetChannel(uint32_t freq)
{
sx127x_set_channel(&sx127x, freq);
loramac_netdev_ptr->driver->set(loramac_netdev_ptr, NETOPT_CHANNEL_FREQUENCY, &freq, sizeof(uint32_t));
}
bool SX127XIsChannelFree(RadioModems_t modem, uint32_t freq,
int16_t rssiThresh, uint32_t maxCarrierSenseTime )
{
(void) modem;
(void) maxCarrierSenseTime;
return sx127x_is_channel_free(&sx127x, freq, rssiThresh);
Radio.SetChannel(freq);
netopt_state_t state = NETOPT_STATE_IDLE;
loramac_netdev_ptr->driver->set(loramac_netdev_ptr, NETOPT_STATE, &state, sizeof(netopt_state_t));
ztimer_sleep(ZTIMER_MSEC, 1); /* wait 1 millisecond */
int16_t rssi = Radio.Rssi(modem);
Radio.Sleep();
return (rssi <= rssiThresh);
}
uint32_t SX127XRandom(void)
{
return sx127x_random(&sx127x);
uint32_t random;
loramac_netdev_ptr->driver->get(loramac_netdev_ptr, NETOPT_RANDOM, &random, sizeof(uint32_t));
return random;
}
void SX127XSetRxConfig(RadioModems_t modem, uint32_t bandwidth,
@ -83,21 +108,28 @@ void SX127XSetRxConfig(RadioModems_t modem, uint32_t bandwidth,
bool crcOn, bool freqHopOn, uint8_t hopPeriod,
bool iqInverted, bool rxContinuous)
{
(void) bandwidthAfc;
(void) fixLen;
sx127x_set_modem(&sx127x, modem);
sx127x_set_bandwidth(&sx127x, bandwidth);
sx127x_set_spreading_factor(&sx127x, spreading_factor);
sx127x_set_coding_rate(&sx127x, coding_rate);
sx127x_set_preamble_length(&sx127x, preambleLen);
sx127x_set_fixed_header_len_mode(&sx127x, false);
sx127x_set_payload_length(&sx127x, payloadLen);
sx127x_set_crc(&sx127x, crcOn);
sx127x_set_freq_hop(&sx127x, freqHopOn);
sx127x_set_hop_period(&sx127x, hopPeriod);
sx127x_set_iq_invert(&sx127x, iqInverted);
sx127x_set_symbol_timeout(&sx127x, symbTimeout);
sx127x_set_rx_single(&sx127x, !rxContinuous);
(void)bandwidthAfc;
(void)fixLen;
(void)modem;
uint16_t modem_val = NETDEV_TYPE_LORA;
loramac_netdev_ptr->driver->set(loramac_netdev_ptr, NETOPT_DEVICE_TYPE, &modem_val, sizeof(uint16_t));
loramac_netdev_ptr->driver->set(loramac_netdev_ptr, NETOPT_BANDWIDTH, &bandwidth, sizeof(uint8_t));
loramac_netdev_ptr->driver->set(loramac_netdev_ptr, NETOPT_CODING_RATE, &coding_rate, sizeof(uint8_t));
loramac_netdev_ptr->driver->set(loramac_netdev_ptr, NETOPT_SPREADING_FACTOR, &spreading_factor, sizeof(uint8_t));
loramac_netdev_ptr->driver->set(loramac_netdev_ptr, NETOPT_PREAMBLE_LENGTH, &preambleLen, sizeof(uint16_t));
netopt_enable_t fixed_header = NETOPT_DISABLE;
loramac_netdev_ptr->driver->set(loramac_netdev_ptr, NETOPT_FIXED_HEADER, &fixed_header, sizeof(netopt_enable_t));
loramac_netdev_ptr->driver->set(loramac_netdev_ptr, NETOPT_PDU_SIZE, &payloadLen, sizeof(uint8_t));
netopt_enable_t enable_crc = (crcOn) ? NETOPT_ENABLE : NETOPT_DISABLE;
loramac_netdev_ptr->driver->set(loramac_netdev_ptr, NETOPT_INTEGRITY_CHECK, &enable_crc, sizeof(netopt_enable_t));
netopt_enable_t enable_freq_hop = (freqHopOn) ? NETOPT_ENABLE : NETOPT_DISABLE;
loramac_netdev_ptr->driver->set(loramac_netdev_ptr, NETOPT_CHANNEL_HOP, &enable_freq_hop, sizeof(netopt_enable_t));
loramac_netdev_ptr->driver->set(loramac_netdev_ptr, NETOPT_CHANNEL_HOP_PERIOD, &hopPeriod, sizeof(uint8_t));
netopt_enable_t iq_inverted = (iqInverted) ? NETOPT_ENABLE : NETOPT_DISABLE;
loramac_netdev_ptr->driver->set(loramac_netdev_ptr, NETOPT_IQ_INVERT, &iq_inverted, sizeof(netopt_enable_t));
loramac_netdev_ptr->driver->set(loramac_netdev_ptr, NETOPT_RX_SYMBOL_TIMEOUT, &symbTimeout, sizeof(uint16_t));
netopt_enable_t single_rx = rxContinuous ? NETOPT_DISABLE : NETOPT_ENABLE;
loramac_netdev_ptr->driver->set(loramac_netdev_ptr, NETOPT_SINGLE_RECEIVE, &single_rx, sizeof(netopt_enable_t));
}
void SX127XSetTxConfig(RadioModems_t modem, int8_t power, uint32_t fdev,
@ -106,92 +138,108 @@ void SX127XSetTxConfig(RadioModems_t modem, int8_t power, uint32_t fdev,
bool fixLen, bool crcOn, bool freqHopOn,
uint8_t hopPeriod, bool iqInverted, uint32_t timeout)
{
(void) fdev;
(void) fixLen;
sx127x_set_modem(&sx127x, modem);
sx127x_set_freq_hop(&sx127x, freqHopOn);
sx127x_set_bandwidth(&sx127x, bandwidth);
sx127x_set_coding_rate(&sx127x, coding_rate);
sx127x_set_spreading_factor(&sx127x, spreading_factor);
sx127x_set_crc(&sx127x, crcOn);
sx127x_set_freq_hop(&sx127x, freqHopOn);
sx127x_set_hop_period(&sx127x, hopPeriod);
sx127x_set_fixed_header_len_mode(&sx127x, false);
sx127x_set_iq_invert(&sx127x, iqInverted);
sx127x_set_payload_length(&sx127x, 0);
sx127x_set_tx_power(&sx127x, power);
sx127x_set_preamble_length(&sx127x, preambleLen);
sx127x_set_rx_single(&sx127x, false);
sx127x_set_tx_timeout(&sx127x, timeout); /* base unit ms, LoRaMAC ms */
(void)fdev;
(void)fixLen;
(void)modem;
uint16_t modem_val = NETDEV_TYPE_LORA;
loramac_netdev_ptr->driver->set(loramac_netdev_ptr, NETOPT_DEVICE_TYPE, &modem_val, sizeof(uint16_t));
loramac_netdev_ptr->driver->set(loramac_netdev_ptr, NETOPT_BANDWIDTH, &bandwidth, sizeof(uint8_t));
loramac_netdev_ptr->driver->set(loramac_netdev_ptr, NETOPT_CODING_RATE, &coding_rate, sizeof(uint8_t));
loramac_netdev_ptr->driver->set(loramac_netdev_ptr, NETOPT_SPREADING_FACTOR, &spreading_factor, sizeof(uint8_t));
netopt_enable_t enable_crc = (crcOn) ? NETOPT_ENABLE : NETOPT_DISABLE;
loramac_netdev_ptr->driver->set(loramac_netdev_ptr, NETOPT_INTEGRITY_CHECK, &enable_crc, sizeof(netopt_enable_t));
netopt_enable_t enable_freq_hop = (freqHopOn) ? NETOPT_ENABLE : NETOPT_DISABLE;
loramac_netdev_ptr->driver->set(loramac_netdev_ptr, NETOPT_CHANNEL_HOP, &enable_freq_hop, sizeof(netopt_enable_t));
loramac_netdev_ptr->driver->set(loramac_netdev_ptr, NETOPT_CHANNEL_HOP_PERIOD, &hopPeriod, sizeof(uint8_t));
netopt_enable_t fixed_header = NETOPT_DISABLE;
loramac_netdev_ptr->driver->set(loramac_netdev_ptr, NETOPT_FIXED_HEADER, &fixed_header, sizeof(netopt_enable_t));
netopt_enable_t iq_inverted = (iqInverted) ? NETOPT_ENABLE : NETOPT_DISABLE;
loramac_netdev_ptr->driver->set(loramac_netdev_ptr, NETOPT_IQ_INVERT, &iq_inverted, sizeof(netopt_enable_t));
int16_t power_val = power;
loramac_netdev_ptr->driver->set(loramac_netdev_ptr, NETOPT_TX_POWER, &power_val, sizeof(int16_t));
loramac_netdev_ptr->driver->set(loramac_netdev_ptr, NETOPT_PREAMBLE_LENGTH, &preambleLen, sizeof(uint16_t));
loramac_netdev_ptr->driver->set(loramac_netdev_ptr, NETOPT_TX_TIMEOUT, &timeout, sizeof(uint32_t)); /* base unit ms, LoRaMAC ms */
}
uint32_t SX127XTimeOnAir(RadioModems_t modem, uint8_t pktLen)
{
(void) modem;
return sx127x_get_time_on_air(&sx127x, pktLen);
uint8_t cr;
loramac_netdev_ptr->driver->get(loramac_netdev_ptr, NETOPT_CODING_RATE, &cr, sizeof(uint8_t));
MibRequestConfirm_t mibReq;
mibReq.Type = MIB_CHANNELS_DATARATE;
LoRaMacMibGetRequestConfirm(&mibReq);
uint8_t dr = (uint8_t)mibReq.Param.ChannelsDatarate;
return lora_time_on_air(pktLen, dr, cr) >> 10; /* divide by 1024: return value in ms */
}
void SX127XSend(uint8_t *buffer, uint8_t size)
{
netdev_t *dev = (netdev_t *)&sx127x;
iolist_t iol = {
.iol_base = buffer,
.iol_len = size
};
dev->driver->send(dev, &iol);
iolist_t iol = { .iol_base = buffer, .iol_len = size };
loramac_netdev_ptr->driver->send(loramac_netdev_ptr, &iol);
}
void SX127XSleep(void)
{
sx127x_set_sleep(&sx127x);
netopt_state_t state = NETOPT_STATE_SLEEP;
loramac_netdev_ptr->driver->set(loramac_netdev_ptr, NETOPT_STATE, &state, sizeof(netopt_state_t));
}
void SX127XStandby(void)
{
sx127x_set_standby(&sx127x);
netopt_state_t state = NETOPT_STATE_STANDBY;
loramac_netdev_ptr->driver->set(loramac_netdev_ptr, NETOPT_STATE, &state, sizeof(netopt_state_t));
}
void SX127XRx(uint32_t timeout)
{
sx127x_set_rx_timeout(&sx127x, timeout);
sx127x_set_rx(&sx127x);
loramac_netdev_ptr->driver->set(loramac_netdev_ptr, NETOPT_RX_TIMEOUT, &timeout, sizeof(uint32_t));
netopt_state_t state = NETOPT_STATE_RX;
loramac_netdev_ptr->driver->set(loramac_netdev_ptr, NETOPT_STATE, &state, sizeof(netopt_state_t));
}
void SX127XStartCad(void)
{
sx127x_start_cad(&sx127x);
}
int16_t SX127XRssi(RadioModems_t modem)
{
sx127x_set_modem(&sx127x, (uint8_t)modem);
return sx127x_read_rssi(&sx127x);
(void)modem;
int8_t rssi;
loramac_netdev_ptr->driver->get(loramac_netdev_ptr, NETOPT_RSSI, &rssi, sizeof(int8_t));
return rssi;
}
void SX127XWrite(uint16_t addr, uint8_t data)
{
sx127x_reg_write(&sx127x, addr, data);
(void)addr;
(void)data;
}
uint8_t SX127XRead(uint16_t addr)
{
return sx127x_reg_read(&sx127x, addr);
(void)addr;
return 0;
}
void SX127XWriteBuffer(uint16_t addr, uint8_t *buffer, uint8_t size)
{
sx127x_reg_write_burst(&sx127x, addr, buffer, size);
(void)addr;
(void)buffer;
(void)size;
}
void SX127XReadBuffer(uint16_t addr, uint8_t *buffer, uint8_t size)
{
sx127x_reg_read_burst(&sx127x, addr, buffer, size);
(void)addr;
(void)buffer;
(void)size;
}
void SX127XSetMaxPayloadLength(RadioModems_t modem, uint8_t max)
{
(void) modem;
sx127x_set_max_payload_len(&sx127x, max);
loramac_netdev_ptr->driver->set(loramac_netdev_ptr, NETOPT_MAX_PDU_SIZE, &max, sizeof(uint8_t));
}
bool SX127XCheckRfFrequency(uint32_t frequency)
@ -211,14 +259,8 @@ void SX127XSetTxContinuousWave(uint32_t freq, int8_t power, uint16_t time)
void SX127XSetPublicNetwork(bool enable)
{
if (enable) {
/* Use public network syncword */
sx127x_set_syncword(&sx127x, LORA_SYNCWORD_PUBLIC);
}
else {
/* Use private network syncword */
sx127x_set_syncword(&sx127x, LORA_SYNCWORD_PRIVATE);
}
uint8_t syncword = (enable) ? LORA_SYNCWORD_PUBLIC : LORA_SYNCWORD_PRIVATE;
loramac_netdev_ptr->driver->set(loramac_netdev_ptr, NETOPT_SYNCWORD, &syncword, sizeof(uint8_t));
}
uint32_t SX127XGetWakeupTime(void)

View File

@ -30,8 +30,6 @@ extern "C" {
#include "net/netdev.h"
#include "net/loramac.h"
#include "sx127x.h"
/**
* @name Definitions for messages exchanged between the MAC and call threads
* @{
@ -113,6 +111,7 @@ typedef struct {
* @brief Semtech LoRaMAC descriptor
*/
typedef struct {
netdev_t *netdev; /**< pointer to internal radio device */
mutex_t lock; /**< loramac access lock */
uint8_t tx_pid; /**< pid of sender thread */
#if defined(MODULE_SEMTECH_LORAMAC_RX) || DOXYGEN

View File

@ -18,12 +18,19 @@
*/
#include "log.h"
#include "sx127x.h"
#include "sx127x_netdev.h"
#include "sx127x_params.h"
#include "semtech_loramac.h"
semtech_loramac_t loramac;
static sx127x_t sx127x;
void auto_init_loramac(void)
{
sx127x_setup(&sx127x, &sx127x_params[0], 0);
loramac.netdev = (netdev_t *)&sx127x;
loramac.netdev->driver = &sx127x_driver;
semtech_loramac_init(&loramac);
}
/** @} */

View File

@ -22,6 +22,7 @@
#ifndef NET_LORAMAC_H
#define NET_LORAMAC_H
#include <assert.h>
#include <stdint.h>
#include <stdlib.h>
@ -966,6 +967,54 @@ typedef enum {
uint8_t dcycle; /**< Duty cycle to use on this channel (1 to 100) */
} loramac_channel_t;
/**
* @brief Compute the time on air of a LoRa packet
*
* This function uses a precomputed table to calculate time on air without
* using floating point arithmetic
*
* @param[in] pkt_len Length of a packet in bytes
* @param[in] dr Datarate used to send the packet
* @param[in] cr Coding rate used to send the packet
* @return time on air in us
*/
static inline uint32_t lora_time_on_air(size_t pkt_len, uint8_t dr, uint8_t cr)
{
assert(dr <= LORAMAC_DR_6);
const uint8_t _K[6][4] = {
{ 0, 1, 5, 5 }, /* DR0 */
{ 0, 1, 4, 5 }, /* DR1 */
{ 1, 5, 5, 5 }, /* DR2 */
{ 1, 4, 5, 4 }, /* DR3 */
{ 1, 3, 4, 4 }, /* DR4 */
{ 1, 2, 4, 3 } /* DR5 */
};
uint32_t t_sym = 1 << (15 - dr);
uint32_t t_preamble = (t_sym << 3) + (t_sym << 2) + (t_sym >> 2);
uint8_t index = (dr < LORAMAC_DR_6) ? dr : LORAMAC_DR_5;
uint8_t n0 = _K[index][0];
uint32_t nb_symbols;
uint8_t offset = _K[index][1];
if (pkt_len < offset) {
nb_symbols = 8 + n0 * (cr + 4);
}
else {
uint8_t c1 = _K[index][2];
uint8_t c2 = _K[index][3];
uint8_t pos = (pkt_len - offset) % (c1 + c2);
uint8_t cycle = (pkt_len - offset) / (c1 + c2);
nb_symbols = 8 + (n0 + 2 * cycle + 1 + (pos > (c1 - 1))) * (cr + 4);
}
uint32_t t_payload = t_sym * nb_symbols;
return t_preamble + t_payload;
}
#ifdef __cplusplus
}
#endif

View File

@ -207,43 +207,6 @@ void gnrc_lorawan_radio_rx_timeout_cb(gnrc_lorawan_t *mac)
_sleep_radio(mac);
}
/* This function uses a precomputed table to calculate time on air without
* using floating point arithmetic */
static uint32_t lora_time_on_air(size_t payload_size, uint8_t dr, uint8_t cr)
{
assert(dr <= LORAMAC_DR_6);
uint8_t _K[6][4] = { { 0, 1, 5, 5 },
{ 0, 1, 4, 5 },
{ 1, 5, 5, 5 },
{ 1, 4, 5, 4 },
{ 1, 3, 4, 4 },
{ 1, 2, 4, 3 } };
uint32_t t_sym = 1 << (15 - dr);
uint32_t t_preamble = (t_sym << 3) + (t_sym << 2) + (t_sym >> 2);
int index = (dr < LORAMAC_DR_6) ? dr : LORAMAC_DR_5;
uint8_t n0 = _K[index][0];
int nb_symbols;
uint8_t offset = _K[index][1];
if (payload_size < offset) {
nb_symbols = 8 + n0 * cr;
}
else {
uint8_t c1 = _K[index][2];
uint8_t c2 = _K[index][3];
uint8_t pos = (payload_size - offset) % (c1 + c2);
uint8_t cycle = (payload_size - offset) / (c1 + c2);
nb_symbols = 8 + (n0 + 2 * cycle + 1 + (pos > (c1 - 1))) * cr;
}
uint32_t t_payload = t_sym * nb_symbols;
return t_preamble + t_payload;
}
void gnrc_lorawan_send_pkt(gnrc_lorawan_t *mac, iolist_t *psdu, uint8_t dr)
{
netdev_t *dev = gnrc_lorawan_get_netdev(mac);
@ -260,7 +223,7 @@ void gnrc_lorawan_send_pkt(gnrc_lorawan_t *mac, iolist_t *psdu, uint8_t dr)
dev->driver->get(dev, NETOPT_CODING_RATE, &cr, sizeof(cr));
mac->toa = lora_time_on_air(iolist_size(psdu), dr, cr + 4);
mac->toa = lora_time_on_air(iolist_size(psdu), dr, cr);
if (dev->driver->send(dev, psdu) == -ENOTSUP) {
DEBUG("gnrc_lorawan: Cannot send: radio is still transmitting");