mirror of
https://github.com/manuelbl/ttn-esp32.git
synced 2025-06-14 20:14:27 +02:00
Latest LMIC code from https://github.com/mcci-catena/arduino-lmic
This commit is contained in:
parent
31b859cdf4
commit
27b63d955a
@ -123,15 +123,7 @@
|
||||
//#define DISABLE_MCMD_PING_SET // set ping freq, automatically disabled by DISABLE_PING
|
||||
//#define DISABLE_MCMD_BCNI_ANS // next beacon start, automatically disabled by DISABLE_BEACON
|
||||
|
||||
// In LoRaWAN, a gateway applies I/Q inversion on TX, and nodes do the
|
||||
// same on RX. This ensures that gateways can talk to nodes and vice
|
||||
// versa, but gateways will not hear other gateways and nodes will not
|
||||
// hear other nodes. By defining this macro in lmic_project_config.h,
|
||||
// this inversion is disabled and this node can hear other nodes. If
|
||||
// two nodes both have this macro set, they can talk to each other
|
||||
// (but they can no longer hear gateways). This should probably only
|
||||
// be used when debugging and/or when talking to the radio directly
|
||||
// (e.g. like in the "raw" example).
|
||||
// DEPRECATED(tmm@mcci.com); replaced by LMIC.noRXIQinversion (dynamic). Don't define this.
|
||||
//#define DISABLE_INVERT_IQ_ON_RX
|
||||
|
||||
// This allows choosing between multiple included AES implementations.
|
||||
@ -178,4 +170,24 @@
|
||||
# define LMIC_ENABLE_DeviceTimeReq 0
|
||||
#endif
|
||||
|
||||
// LMIC_ENABLE_user_events
|
||||
// Enable/disable support for programmable callbacks for events, rx, and tx.
|
||||
// This is always defined, and non-zero to enable. Default is enabled.
|
||||
#if !defined(LMIC_ENABLE_user_events)
|
||||
# define LMIC_ENABLE_user_events 1
|
||||
#endif
|
||||
|
||||
// LMIC_ENABLE_onEvent
|
||||
// Enable/disable support for out-call to user-supplied `onEvent()` function.
|
||||
// This is always defined, and non-zero to enable. Default is enabled.
|
||||
#if !defined(LMIC_ENABLE_onEvent)
|
||||
# define LMIC_ENABLE_onEvent 1
|
||||
#endif
|
||||
|
||||
// LMIC_ENABLE_long_messages
|
||||
// LMIC certification requires that this be enabled.
|
||||
#if !defined(LMIC_ENABLE_long_messages)
|
||||
# define LMIC_ENABLE_long_messages 1 /* PARAM */
|
||||
#endif
|
||||
|
||||
#endif // _lmic_config_h_
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2016 IBM Corporation.
|
||||
* Copyright (c) 2016, 2018 MCCI Corporation.
|
||||
* Copyright (c) 2016, 2018-2019 MCCI Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -33,10 +33,17 @@
|
||||
# include "oslmic_types.h"
|
||||
#endif
|
||||
|
||||
#ifndef _lmic_env_h_
|
||||
# include "lmic_env.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
// The type of an optional user-defined failure handler routine
|
||||
typedef void LMIC_ABI_STD hal_failure_handler_t(const char* const file, const uint16_t line);
|
||||
|
||||
/*
|
||||
* initialize hardware (IO, SPI, TIMER, IRQ).
|
||||
* This API is deprecated as it uses the const global lmic_pins,
|
||||
@ -87,6 +94,11 @@ void hal_disableIRQs (void);
|
||||
*/
|
||||
void hal_enableIRQs (void);
|
||||
|
||||
/*
|
||||
* return CPU interrupt nesting count
|
||||
*/
|
||||
uint8_t hal_getIrqLevel (void);
|
||||
|
||||
/*
|
||||
* put system and CPU in low-power mode, sleep until interrupt.
|
||||
*/
|
||||
@ -116,6 +128,12 @@ u1_t hal_checkTimer (u4_t targettime);
|
||||
*/
|
||||
void hal_failed (const char *file, u2_t line);
|
||||
|
||||
/*
|
||||
* set a custom hal failure handler routine. The default behaviour, defined in
|
||||
* hal_failed(), is to halt by looping infintely.
|
||||
*/
|
||||
void hal_set_failure_handler(const hal_failure_handler_t* const);
|
||||
|
||||
/*
|
||||
* get the calibration value for radio_rssi
|
||||
*/
|
||||
|
633
src/lmic/lmic.c
633
src/lmic/lmic.c
File diff suppressed because it is too large
Load Diff
227
src/lmic/lmic.h
227
src/lmic/lmic.h
@ -105,7 +105,7 @@ extern "C"{
|
||||
#define ARDUINO_LMIC_VERSION_CALC(major, minor, patch, local) \
|
||||
(((major) << 24u) | ((minor) << 16u) | ((patch) << 8u) | (local))
|
||||
|
||||
#define ARDUINO_LMIC_VERSION ARDUINO_LMIC_VERSION_CALC(2, 3, 2, 0) /* v2.3.2 */
|
||||
#define ARDUINO_LMIC_VERSION ARDUINO_LMIC_VERSION_CALC(2, 3, 2, 50) /* v2.3.2.50 */
|
||||
|
||||
#define ARDUINO_LMIC_VERSION_GET_MAJOR(v) \
|
||||
(((v) >> 24u) & 0xFFu)
|
||||
@ -122,14 +122,17 @@ extern "C"{
|
||||
//! Only For Antenna Tuning Tests !
|
||||
//#define CFG_TxContinuousMode 1
|
||||
|
||||
enum { MAX_FRAME_LEN = 64 }; //!< Library cap on max frame length
|
||||
// since this was annouunced as the API variable, we keep it. But it's not used,
|
||||
// MAX_LEN_FRAME is what the code uses.
|
||||
enum { MAX_FRAME_LEN = MAX_LEN_FRAME }; //!< Library cap on max frame length
|
||||
|
||||
enum { TXCONF_ATTEMPTS = 8 }; //!< Transmit attempts for confirmed frames
|
||||
enum { MAX_MISSED_BCNS = 20 }; // threshold for triggering rejoin requests
|
||||
enum { MAX_RXSYMS = 100 }; // stop tracking beacon beyond this
|
||||
|
||||
enum { LINK_CHECK_CONT = 12 , // continue with this after reported dead link
|
||||
LINK_CHECK_DEAD = 24 , // after this UP frames and no response from NWK assume link is dead
|
||||
LINK_CHECK_INIT = -12 , // UP frame count until we inc datarate
|
||||
enum { LINK_CHECK_CONT = 0 , // continue with this after reported dead link
|
||||
LINK_CHECK_DEAD = 32 , // after this UP frames and no response to ack from NWK assume link is dead (ADR_ACK_DELAY)
|
||||
LINK_CHECK_INIT = -64 , // UP frame count until we ask for ack (ADR_ACK_LIMIT)
|
||||
LINK_CHECK_OFF =-128 }; // link check disabled
|
||||
|
||||
enum { TIME_RESYNC = 6*128 }; // secs
|
||||
@ -153,12 +156,23 @@ struct band_t {
|
||||
};
|
||||
TYPEDEF_xref2band_t; //!< \internal
|
||||
|
||||
struct lmic_saved_adr_state_s {
|
||||
u4_t channelFreq[MAX_CHANNELS];
|
||||
u2_t channelMap;
|
||||
};
|
||||
|
||||
#elif CFG_LMIC_US_like // US915 spectrum =================================================
|
||||
|
||||
enum { MAX_XCHANNELS = 2 }; // extra channels in RAM, channels 0-71 are immutable
|
||||
|
||||
struct lmic_saved_adr_state_s {
|
||||
u2_t channelMap[(72+MAX_XCHANNELS+15)/16]; // enabled bits
|
||||
};
|
||||
|
||||
#endif // ==========================================================================
|
||||
|
||||
typedef struct lmic_saved_adr_state_s lmic_saved_adr_state_t;
|
||||
|
||||
// Keep in sync with evdefs.hpp::drChange
|
||||
enum { DRCHG_SET, DRCHG_NOJACC, DRCHG_NOACK, DRCHG_NOADRACK, DRCHG_NWKCMD };
|
||||
enum { KEEP_TXPOW = -128 };
|
||||
@ -189,14 +203,14 @@ enum { BCN_NONE = 0x00, //!< No beacon received
|
||||
//! Information about the last and previous beacons.
|
||||
struct bcninfo_t {
|
||||
ostime_t txtime; //!< Time when the beacon was sent
|
||||
u4_t time; //!< GPS time in seconds of last beacon (received or surrogate)
|
||||
s4_t lat; //!< Lat field of last beacon (valid only if BCN_FULL set)
|
||||
s4_t lon; //!< Lon field of last beacon (valid only if BCN_FULL set)
|
||||
s1_t rssi; //!< Adjusted RSSI value of last received beacon
|
||||
s1_t snr; //!< Scaled SNR value of last received beacon
|
||||
u1_t flags; //!< Last beacon reception and tracking states. See BCN_* values.
|
||||
u4_t time; //!< GPS time in seconds of last beacon (received or surrogate)
|
||||
//
|
||||
u1_t info; //!< Info field of last beacon (valid only if BCN_FULL set)
|
||||
s4_t lat; //!< Lat field of last beacon (valid only if BCN_FULL set)
|
||||
s4_t lon; //!< Lon field of last beacon (valid only if BCN_FULL set)
|
||||
};
|
||||
#endif // !DISABLE_BEACONS
|
||||
|
||||
@ -235,7 +249,7 @@ enum _ev_t { EV_SCAN_TIMEOUT=1, EV_BEACON_FOUND,
|
||||
EV_JOINED, EV_RFU1, EV_JOIN_FAILED, EV_REJOIN_FAILED,
|
||||
EV_TXCOMPLETE, EV_LOST_TSYNC, EV_RESET,
|
||||
EV_RXCOMPLETE, EV_LINK_DEAD, EV_LINK_ALIVE, EV_SCAN_FOUND,
|
||||
EV_TXSTART };
|
||||
EV_TXSTART, EV_TXCANCELED, EV_RXSTART, EV_JOIN_TXCOMPLETE };
|
||||
typedef enum _ev_t ev_t;
|
||||
|
||||
enum {
|
||||
@ -243,6 +257,12 @@ enum {
|
||||
MAX_CLOCK_ERROR = 65536,
|
||||
};
|
||||
|
||||
// callbacks for client alerts.
|
||||
// types and functions are always defined, to reduce #ifs in example code and libraries.
|
||||
typedef void LMIC_ABI_STD lmic_rxmessage_cb_t(void *pUserData, uint8_t port, const uint8_t *pMessage, size_t nMessage);
|
||||
typedef void LMIC_ABI_STD lmic_txmessage_cb_t(void *pUserData, int fSuccess);
|
||||
typedef void LMIC_ABI_STD lmic_event_cb_t(void *pUserData, ev_t e);
|
||||
|
||||
// network time request callback function
|
||||
// defined unconditionally, because APIs and types can't change based on config.
|
||||
// This is called when a time-request succeeds or when we get a downlink
|
||||
@ -272,26 +292,108 @@ enum lmic_request_time_state_e {
|
||||
|
||||
typedef u1_t lmic_request_time_state_t;
|
||||
|
||||
/*
|
||||
|
||||
Structure: lmic_client_data_t
|
||||
|
||||
Function:
|
||||
Holds LMIC client data that must live through LMIC_reset().
|
||||
|
||||
Description:
|
||||
There are a variety of client registration linkage items that
|
||||
must live through LMIC_reset(), because LMIC_reset() is called
|
||||
at frame rollover time. We group them together into a structure
|
||||
to make copies easy.
|
||||
|
||||
*/
|
||||
|
||||
//! abstract type for collection of client data that survives LMIC_reset().
|
||||
typedef struct lmic_client_data_s lmic_client_data_t;
|
||||
|
||||
//! contents of lmic_client_data_t
|
||||
struct lmic_client_data_s {
|
||||
|
||||
/* pointer-width things come first */
|
||||
#if LMIC_ENABLE_DeviceTimeReq
|
||||
lmic_request_network_time_cb_t *pNetworkTimeCb; //! call-back routine for network time
|
||||
void *pNetworkTimeUserData; //! call-back data for network time.
|
||||
#endif
|
||||
|
||||
#if LMIC_ENABLE_user_events
|
||||
lmic_event_cb_t *eventCb; //! user-supplied callback function for events.
|
||||
void *eventUserData; //! data for eventCb
|
||||
lmic_rxmessage_cb_t *rxMessageCb; //! user-supplied message-received callback
|
||||
void *rxMessageUserData; //! data for rxMessageCb
|
||||
lmic_txmessage_cb_t *txMessageCb; //! transmit-complete message handler; reset on each tx complete.
|
||||
void *txMessageUserData; //! data for txMessageCb.
|
||||
#endif // LMIC_ENABLE_user_events
|
||||
|
||||
/* next we have things that are (u)int32_t */
|
||||
/* none at the moment */
|
||||
|
||||
/* next we have things that are (u)int16_t */
|
||||
|
||||
u2_t clockError; //! Inaccuracy in the clock. CLOCK_ERROR_MAX represents +/-100% error
|
||||
|
||||
/* finally, things that are (u)int8_t */
|
||||
/* none at the moment */
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
Structure: lmic_t
|
||||
|
||||
Function:
|
||||
Provides the instance data for the LMIC.
|
||||
|
||||
*/
|
||||
|
||||
struct lmic_t {
|
||||
// client setup data, survives LMIC_reset().
|
||||
lmic_client_data_t client;
|
||||
|
||||
// the OS job object. pointer alignment.
|
||||
osjob_t osjob;
|
||||
|
||||
#if !defined(DISABLE_BEACONS)
|
||||
bcninfo_t bcninfo; // Last received beacon info
|
||||
#endif
|
||||
|
||||
#if !defined(DISABLE_PING)
|
||||
rxsched_t ping; // pingable setup
|
||||
#endif
|
||||
|
||||
/* (u)int32_t things */
|
||||
|
||||
// Radio settings TX/RX (also accessed by HAL)
|
||||
ostime_t txend;
|
||||
ostime_t rxtime;
|
||||
|
||||
// LBT info
|
||||
ostime_t lbt_ticks; // ticks to listen
|
||||
s1_t lbt_dbmax; // max permissible dB on our channel (eg -80)
|
||||
|
||||
u4_t freq;
|
||||
s1_t rssi;
|
||||
s1_t snr; // LMIC.snr is SNR times 4
|
||||
rps_t rps;
|
||||
u1_t rxsyms;
|
||||
u1_t dndr;
|
||||
s1_t txpow; // dBm
|
||||
|
||||
osjob_t osjob;
|
||||
ostime_t globalDutyAvail; // time device can send again
|
||||
|
||||
// Channel scheduling
|
||||
u4_t netid; // current network id (~0 - none)
|
||||
devaddr_t devaddr;
|
||||
u4_t seqnoDn; // device level down stream seqno
|
||||
u4_t seqnoUp;
|
||||
u4_t dn2Freq;
|
||||
|
||||
#if !defined(DISABLE_BEACONS)
|
||||
ostime_t bcnRxtime;
|
||||
#endif
|
||||
|
||||
#if LMIC_ENABLE_DeviceTimeReq
|
||||
// put here for alignment, to reduce RAM use.
|
||||
ostime_t localDeviceTime; // the LMIC.txend value for last DeviceTimeAns
|
||||
lmic_gpstime_t netDeviceTime; // the netDeviceTime for lastDeviceTimeAns
|
||||
// zero ==> not valid.
|
||||
#endif // LMIC_ENABLE_DeviceTimeReq
|
||||
|
||||
// Channel scheduling -- very much private
|
||||
#if CFG_LMIC_EU_like
|
||||
band_t bands[MAX_BANDS];
|
||||
u4_t channelFreq[MAX_CHANNELS];
|
||||
@ -304,45 +406,46 @@ struct lmic_t {
|
||||
u2_t activeChannels125khz;
|
||||
u2_t activeChannels500khz;
|
||||
#endif
|
||||
|
||||
/* (u)int16_t things */
|
||||
|
||||
rps_t rps; // radio parameter selections: SF, BW, CodingRate, NoCrc, implicit hdr
|
||||
u2_t opmode; // engineUpdate() operating mode flags
|
||||
u2_t devNonce; // last generated nonce
|
||||
|
||||
#if !defined(DISABLE_BEACONS)
|
||||
s2_t drift; // last measured drift
|
||||
s2_t lastDriftDiff;
|
||||
s2_t maxDriftDiff;
|
||||
#endif
|
||||
|
||||
/* (u)int8_t things */
|
||||
s1_t rssi;
|
||||
s1_t snr; // LMIC.snr is SNR times 4
|
||||
u1_t rxsyms;
|
||||
u1_t dndr;
|
||||
s1_t txpow; // transmit dBm (administrative)
|
||||
s1_t radio_txpow; // the radio driver's copy of txpow, limited by adrTxPow.
|
||||
s1_t lbt_dbmax; // max permissible dB on our channel (eg -80)
|
||||
|
||||
u1_t txChnl; // channel for next TX
|
||||
u1_t globalDutyRate; // max rate: 1/2^k
|
||||
ostime_t globalDutyAvail; // time device can send again
|
||||
|
||||
u4_t netid; // current network id (~0 - none)
|
||||
u2_t opmode;
|
||||
u1_t upRepeat; // configured up repeat
|
||||
s1_t adrTxPow; // ADR adjusted TX power
|
||||
u1_t datarate; // current data rate
|
||||
u1_t errcr; // error coding rate (used for TX only)
|
||||
u1_t rejoinCnt; // adjustment for rejoin datarate
|
||||
#if !defined(DISABLE_BEACONS)
|
||||
s2_t drift; // last measured drift
|
||||
s2_t lastDriftDiff;
|
||||
s2_t maxDriftDiff;
|
||||
#endif
|
||||
|
||||
u2_t clockError; // Inaccuracy in the clock. CLOCK_ERROR_MAX
|
||||
// represents +/-100% error
|
||||
bit_t initBandplanAfterReset; // cleared by LMIC_reset(), set by first join. See issue #244
|
||||
|
||||
u1_t pendTxPort;
|
||||
u1_t pendTxConf; // confirmed data
|
||||
u1_t pendTxLen; // +0x80 = confirmed
|
||||
u1_t pendTxData[MAX_LEN_PAYLOAD];
|
||||
|
||||
u2_t devNonce; // last generated nonce
|
||||
u1_t nwkKey[16]; // network session key
|
||||
u1_t artKey[16]; // application router session key
|
||||
devaddr_t devaddr;
|
||||
u4_t seqnoDn; // device level down stream seqno
|
||||
u4_t seqnoUp;
|
||||
#if LMIC_ENABLE_DeviceTimeReq
|
||||
// put here for alignment, to reduce RAM use.
|
||||
ostime_t localDeviceTime; // the LMIC.txend value for last DeviceTimeAns
|
||||
lmic_gpstime_t netDeviceTime; // the netDeviceTime for lastDeviceTimeAns
|
||||
// zero ==> not valid.
|
||||
lmic_request_network_time_cb_t *pNetworkTimeCb; // call-back routine
|
||||
void *pNetworkTimeUserData; // call-back data
|
||||
#endif // LMIC_ENABLE_DeviceTimeReq
|
||||
|
||||
u1_t dnConf; // dn frame confirm pending: LORA::FCT_ACK or 0
|
||||
s1_t adrAckReq; // counter until we reset data rate (0=off)
|
||||
@ -376,7 +479,6 @@ struct lmic_t {
|
||||
|
||||
// 2nd RX window (after up stream)
|
||||
u1_t dn2Dr;
|
||||
u4_t dn2Freq;
|
||||
#if !defined(DISABLE_MCMD_DN2P_SET)
|
||||
u1_t dn2Ans; // 0=no answer pend, 0x80+ACKs
|
||||
#endif
|
||||
@ -389,10 +491,6 @@ struct lmic_t {
|
||||
#if !defined(DISABLE_MCMD_PING_SET) && !defined(DISABLE_PING)
|
||||
u1_t pingSetAns; // answer set cmd and ACK bits
|
||||
#endif
|
||||
#if !defined(DISABLE_PING)
|
||||
rxsched_t ping; // pingable setup
|
||||
#endif
|
||||
|
||||
// Public part of MAC state
|
||||
u1_t txCnt;
|
||||
u1_t txrxFlags; // transaction flags (TX-RX combo)
|
||||
@ -403,11 +501,10 @@ struct lmic_t {
|
||||
#if !defined(DISABLE_BEACONS)
|
||||
u1_t bcnChnl;
|
||||
u1_t bcnRxsyms; //
|
||||
ostime_t bcnRxtime;
|
||||
bcninfo_t bcninfo; // Last received beacon info
|
||||
#endif
|
||||
|
||||
u1_t noRXIQinversion;
|
||||
u1_t saveIrqFlags; // last LoRa IRQ flags
|
||||
};
|
||||
|
||||
//! \var struct lmic_t LMIC
|
||||
@ -418,16 +515,19 @@ DECLARE_LMIC; //!< \internal
|
||||
#define DR_RANGE_MAP(drlo,drhi) (((u2_t)0xFFFF<<(drlo)) & ((u2_t)0xFFFF>>(15-(drhi))))
|
||||
bit_t LMIC_setupBand (u1_t bandidx, s1_t txpow, u2_t txcap);
|
||||
bit_t LMIC_setupChannel (u1_t channel, u4_t freq, u2_t drmap, s1_t band);
|
||||
void LMIC_disableChannel (u1_t channel);
|
||||
void LMIC_enableSubBand(u1_t band);
|
||||
void LMIC_enableChannel(u1_t channel);
|
||||
void LMIC_disableSubBand(u1_t band);
|
||||
void LMIC_selectSubBand(u1_t band);
|
||||
bit_t LMIC_disableChannel (u1_t channel);
|
||||
bit_t LMIC_enableSubBand(u1_t band);
|
||||
bit_t LMIC_enableChannel(u1_t channel);
|
||||
bit_t LMIC_disableSubBand(u1_t band);
|
||||
bit_t LMIC_selectSubBand(u1_t band);
|
||||
|
||||
void LMIC_setDrTxpow (dr_t dr, s1_t txpow); // set default/start DR/txpow
|
||||
void LMIC_setAdrMode (bit_t enabled); // set ADR mode (if mobile turn off)
|
||||
|
||||
#if !defined(DISABLE_JOIN)
|
||||
bit_t LMIC_startJoining (void);
|
||||
void LMIC_tryRejoin (void);
|
||||
void LMIC_unjoin (void);
|
||||
#endif
|
||||
|
||||
void LMIC_shutdown (void);
|
||||
@ -436,6 +536,7 @@ void LMIC_reset (void);
|
||||
void LMIC_clrTxData (void);
|
||||
void LMIC_setTxData (void);
|
||||
int LMIC_setTxData2 (u1_t port, xref2u1_t data, u1_t dlen, u1_t confirmed);
|
||||
int LMIC_sendWithCallback(u1_t port, xref2u1_t data, u1_t dlen, u1_t confirmed, lmic_txmessage_cb_t *pCb, void *pUserData);
|
||||
void LMIC_sendAlive (void);
|
||||
|
||||
#if !defined(DISABLE_BEACONS)
|
||||
@ -447,9 +548,6 @@ void LMIC_disableTracking (void);
|
||||
void LMIC_stopPingable (void);
|
||||
void LMIC_setPingable (u1_t intvExp);
|
||||
#endif
|
||||
#if !defined(DISABLE_JOIN)
|
||||
void LMIC_tryRejoin (void);
|
||||
#endif
|
||||
|
||||
void LMIC_setSession (u4_t netid, devaddr_t devaddr, xref2u1_t nwkKey, xref2u1_t artKey);
|
||||
void LMIC_setLinkCheckMode (bit_t enabled);
|
||||
@ -462,11 +560,26 @@ void LMIC_getSessionKeys (u4_t *netid, devaddr_t *devaddr, xref2u1_t nwkKey, xre
|
||||
void LMIC_requestNetworkTime(lmic_request_network_time_cb_t *pCallbackfn, void *pUserData);
|
||||
int LMIC_getNetworkTimeReference(lmic_time_reference_t *pReference);
|
||||
|
||||
int LMIC_registerRxMessageCb(lmic_rxmessage_cb_t *pRxMessageCb, void *pUserData);
|
||||
int LMIC_registerEventCb(lmic_event_cb_t *pEventCb, void *pUserData);
|
||||
|
||||
// APIs for client half of compliance.
|
||||
typedef u1_t lmic_compliance_rx_action_t;
|
||||
|
||||
enum lmic_compliance_rx_action_e {
|
||||
LMIC_COMPLIANCE_RX_ACTION_PROCESS = 0, // process this message normally
|
||||
LMIC_COMPLIANCE_RX_ACTION_START, // enter compliance mode, discard this message
|
||||
LMIC_COMPLIANCE_RX_ACTION_IGNORE, // continue in compliance mode, discard this message
|
||||
LMIC_COMPLIANCE_RX_ACTION_END // exit compliance mode, discard this message
|
||||
};
|
||||
|
||||
lmic_compliance_rx_action_t LMIC_complianceRxMessage(u1_t port, const u1_t *pMessage, size_t nMessage);
|
||||
|
||||
// Declare onEvent() function, to make sure any definition will have the
|
||||
// C conventions, even when in a C++ file.
|
||||
#if LMIC_ENABLE_onEvent
|
||||
DECL_ON_LMIC_EVENT;
|
||||
|
||||
|
||||
#endif /* LMIC_ENABLE_onEvent */
|
||||
|
||||
// Special APIs - for development or testing
|
||||
// !!!See implementation for caveats!!!
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2016 IBM Corporation.
|
||||
* Copyright (c) 2017 MCCI Corporation.
|
||||
* Copyright (c) 2017, 2019 MCCI Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -138,7 +138,7 @@ int8_t LMICas923_pow2dBm(uint8_t mcmd_ladr_p1) {
|
||||
(mcmd_ladr_p1&MCMD_LADR_POW_MASK)>>MCMD_LADR_POW_SHIFT
|
||||
);
|
||||
|
||||
return adj;
|
||||
return LMICas923_getMaxEIRP(LMIC.txParam) + adj;
|
||||
}
|
||||
|
||||
// only used in this module, but used by variant macro dr2hsym().
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2016 IBM Corporation.
|
||||
* Copyright (c) 2017 MCCI Corporation.
|
||||
* Copyright (c) 2017, 2019 MCCI Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -109,9 +109,11 @@ bit_t LMIC_setupChannel(u1_t chidx, u4_t freq, u2_t drmap, s1_t band) {
|
||||
return 0; // all channels are hardwired.
|
||||
}
|
||||
|
||||
void LMIC_disableChannel(u1_t channel) {
|
||||
bit_t LMIC_disableChannel(u1_t channel) {
|
||||
bit_t result = 0;
|
||||
if (channel < 72) {
|
||||
if (ENABLED_CHANNEL(channel)) {
|
||||
result = 1;
|
||||
if (IS_CHANNEL_125khz(channel))
|
||||
LMIC.activeChannels125khz--;
|
||||
else if (IS_CHANNEL_500khz(channel))
|
||||
@ -119,11 +121,14 @@ void LMIC_disableChannel(u1_t channel) {
|
||||
}
|
||||
LMIC.channelMap[channel >> 4] &= ~(1 << (channel & 0xF));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void LMIC_enableChannel(u1_t channel) {
|
||||
bit_t LMIC_enableChannel(u1_t channel) {
|
||||
bit_t result = 0;
|
||||
if (channel < 72) {
|
||||
if (!ENABLED_CHANNEL(channel)) {
|
||||
result = 1;
|
||||
if (IS_CHANNEL_125khz(channel))
|
||||
LMIC.activeChannels125khz++;
|
||||
else if (IS_CHANNEL_500khz(channel))
|
||||
@ -131,42 +136,52 @@ void LMIC_enableChannel(u1_t channel) {
|
||||
}
|
||||
LMIC.channelMap[channel >> 4] |= (1 << (channel & 0xF));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void LMIC_enableSubBand(u1_t band) {
|
||||
bit_t LMIC_enableSubBand(u1_t band) {
|
||||
ASSERT(band < 8);
|
||||
u1_t start = band * 8;
|
||||
u1_t end = start + 8;
|
||||
bit_t result = 0;
|
||||
|
||||
// enable all eight 125 kHz channels in this subband
|
||||
for (int channel = start; channel < end; ++channel)
|
||||
LMIC_enableChannel(channel);
|
||||
result |= LMIC_enableChannel(channel);
|
||||
|
||||
// there's a single 500 kHz channel associated with
|
||||
// each group of 8 125 kHz channels. Enable it, too.
|
||||
LMIC_enableChannel(64 + band);
|
||||
result |= LMIC_enableChannel(64 + band);
|
||||
return result;
|
||||
}
|
||||
void LMIC_disableSubBand(u1_t band) {
|
||||
|
||||
bit_t LMIC_disableSubBand(u1_t band) {
|
||||
ASSERT(band < 8);
|
||||
u1_t start = band * 8;
|
||||
u1_t end = start + 8;
|
||||
bit_t result = 0;
|
||||
|
||||
// disable all eight 125 kHz channels in this subband
|
||||
for (int channel = start; channel < end; ++channel)
|
||||
LMIC_disableChannel(channel);
|
||||
result |= LMIC_disableChannel(channel);
|
||||
|
||||
// there's a single 500 kHz channel associated with
|
||||
// each group of 8 125 kHz channels. Disable it, too.
|
||||
LMIC_disableChannel(64 + band);
|
||||
result |= LMIC_disableChannel(64 + band);
|
||||
return result;
|
||||
}
|
||||
void LMIC_selectSubBand(u1_t band) {
|
||||
|
||||
bit_t LMIC_selectSubBand(u1_t band) {
|
||||
bit_t result = 0;
|
||||
|
||||
ASSERT(band < 8);
|
||||
for (int b = 0; b<8; ++b) {
|
||||
if (band == b)
|
||||
LMIC_enableSubBand(b);
|
||||
result |= LMIC_enableSubBand(b);
|
||||
else
|
||||
LMIC_disableSubBand(b);
|
||||
result |= LMIC_disableSubBand(b);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void LMICau921_updateTx(ostime_t txbeg) {
|
||||
@ -213,6 +228,13 @@ void LMICau921_setRx1Params(void) {
|
||||
LMIC.rps = dndr2rps(LMIC.dndr);
|
||||
}
|
||||
|
||||
void LMICau921_initJoinLoop(void) {
|
||||
LMICuslike_initJoinLoop();
|
||||
|
||||
// initialize the adrTxPower.
|
||||
LMIC.adrTxPow = 30; // dBm
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
// END: AU921 related stuff
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2016 IBM Corporation.
|
||||
* Copyright (c) 2017 MCCI Corporation.
|
||||
* Copyright (c) 2017, 2019 MCCI Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -104,6 +104,10 @@
|
||||
# error "LMICbandplan_setBcnRxParams() not defined by bandplan"
|
||||
#endif
|
||||
|
||||
#if !defined(LMICbandplan_canMapChannels)
|
||||
# error "LMICbandplan_canMapChannels() not defined by bandplan"
|
||||
#endif
|
||||
|
||||
#if !defined(LMICbandplan_mapChannels)
|
||||
# error "LMICbandplan_mapChannels() not defined by bandplan"
|
||||
#endif
|
||||
@ -143,6 +147,15 @@
|
||||
#if !defined(LMICbandplan_init)
|
||||
# error "LMICbandplan_init() not defined by bandplan"
|
||||
#endif
|
||||
|
||||
#if !defined(LMICbandplan_saveAdrState)
|
||||
# error "LMICbandplan_saveAdrState() not defined by bandplan"
|
||||
#endif
|
||||
|
||||
#if !defined(LMICbandplan_compareAdrState)
|
||||
# error "LMICbandplan_compareAdrState() not defined by bandplan"
|
||||
#endif
|
||||
|
||||
//
|
||||
// Things common to lmic.c code
|
||||
//
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2016 IBM Corporation.
|
||||
* Copyright (c) 2017 MCCI Corporation.
|
||||
* Copyright (c) 2017, 2019 MCCI Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -26,8 +26,8 @@
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _lmic_as923_h_
|
||||
# define _lmic_as923_h_
|
||||
#ifndef _lmic_bandplan_as923_h_
|
||||
# define _lmic_bandplan_as923_h_
|
||||
|
||||
#ifndef _lmic_eu_like_h_
|
||||
# include "lmic_eu_like.h"
|
||||
@ -112,4 +112,4 @@ void LMICas923_updateTx(ostime_t txbeg);
|
||||
ostime_t LMICas923_nextJoinTime(ostime_t now);
|
||||
#define LMICbandplan_nextJoinTime(now) LMICas923_nextJoinTime(now)
|
||||
|
||||
#endif // _lmic_as923_h_
|
||||
#endif // _lmic_bandplan_as923_h_
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2016 IBM Corporation.
|
||||
* Copyright (c) 2017 MCCI Corporation.
|
||||
* Copyright (c) 2017, 2019 MCCI Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -26,12 +26,12 @@
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _lmic_au921_h_
|
||||
# define _lmic_au921_h_
|
||||
#ifndef _lmic_bandplan_au921_h_
|
||||
# define _lmic_bandplan_au921_h_
|
||||
|
||||
// preconditions for lmic_us_like.h
|
||||
#define LMICuslike_getFirst500kHzDR() (AU921_DR_SF8C)
|
||||
|
||||
#define LMICuslike_getFirst500kHzDR() (LORAWAN_DR6)
|
||||
#define LMICuslike_getJoin125kHzDR() (LORAWAN_DR2)
|
||||
|
||||
#ifndef _lmic_us_like_h_
|
||||
# include "lmic_us_like.h"
|
||||
@ -46,7 +46,10 @@ ostime_t LMICau921_dr2hsym(uint8_t dr);
|
||||
#define dr2hsym(dr) LMICau921_dr2hsym(dr)
|
||||
|
||||
|
||||
#define LMICbandplan_getInitialDrJoin() (EU868_DR_SF7)
|
||||
#define LMICbandplan_getInitialDrJoin() (LORAWAN_DR2)
|
||||
|
||||
void LMICau921_initJoinLoop(void);
|
||||
#define LMICbandplan_initJoinLoop() LMICau921_initJoinLoop()
|
||||
|
||||
void LMICau921_setBcnRxParams(void);
|
||||
#define LMICbandplan_setBcnRxParams() LMICau921_setBcnRxParams()
|
||||
@ -60,4 +63,4 @@ void LMICau921_setRx1Params(void);
|
||||
void LMICau921_updateTx(ostime_t txbeg);
|
||||
#define LMICbandplan_updateTx(txbeg) LMICau921_updateTx(txbeg)
|
||||
|
||||
#endif // _lmic_au921_h_
|
||||
#endif // _lmic_bandplan_au921_h_
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2016 IBM Corporation.
|
||||
* Copyright (c) 2017 MCCI Corporation.
|
||||
* Copyright (c) 2017, 2019 MCCI Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -89,4 +89,7 @@ void LMICeu868_initDefaultChannels(bit_t join);
|
||||
ostime_t LMICeu868_nextJoinTime(ostime_t now);
|
||||
#define LMICbandplan_nextJoinTime(now) LMICeu868_nextJoinTime(now)
|
||||
|
||||
void LMICeu868_setRx1Params(void);
|
||||
#define LMICbandplan_setRx1Params() LMICeu868_setRx1Params()
|
||||
|
||||
#endif // _lmic_eu868_h_
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2016 IBM Corporation.
|
||||
* Copyright (c) 2017 MCCI Corporation.
|
||||
* Copyright (c) 2017, 2019 MCCI Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -26,8 +26,8 @@
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _lmic_in866_h_
|
||||
# define _lmic_in866_h_
|
||||
#ifndef _lmic_bandplan_in866_h_
|
||||
# define _lmic_bandplan_in866_h_
|
||||
|
||||
#ifndef _lmic_eu_like_h_
|
||||
# include "lmic_eu_like.h"
|
||||
@ -82,4 +82,7 @@ ostime_t LMICin866_nextJoinState(void);
|
||||
void LMICin866_initDefaultChannels(bit_t join);
|
||||
#define LMICbandplan_initDefaultChannels(join) LMICin866_initDefaultChannels(join)
|
||||
|
||||
#endif // _lmic_in866_h_
|
||||
void LMICin866_setRx1Params(void);
|
||||
#define LMICbandplan_setRx1Params() LMICin866_setRx1Params()
|
||||
|
||||
#endif // _lmic_bandplan_in866_h_
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2016 IBM Corporation.
|
||||
* Copyright (c) 2017 MCCI Corporation.
|
||||
* Copyright (c) 2017, 2019 MCCI Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -26,11 +26,12 @@
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _lmic_us915_h_
|
||||
# define _lmic_us915_h_
|
||||
#ifndef _lmic_bandplan_us915_h_
|
||||
# define _lmic_bandplan_us915_h_
|
||||
|
||||
// preconditions for lmic_us_like.h
|
||||
#define LMICuslike_getFirst500kHzDR() (US915_DR_SF8C)
|
||||
#define LMICuslike_getFirst500kHzDR() (LORAWAN_DR4)
|
||||
#define LMICuslike_getJoin125kHzDR() (LORAWAN_DR0)
|
||||
|
||||
#ifndef _lmic_us_like_h_
|
||||
# include "lmic_us_like.h"
|
||||
@ -45,7 +46,7 @@ ostime_t LMICus915_dr2hsym(uint8_t dr);
|
||||
#define dr2hsym(dr) LMICus915_dr2hsym(dr)
|
||||
|
||||
|
||||
#define LMICbandplan_getInitialDrJoin() (US915_DR_SF7)
|
||||
#define LMICbandplan_getInitialDrJoin() (LORAWAN_DR0)
|
||||
|
||||
void LMICus915_setBcnRxParams(void);
|
||||
#define LMICbandplan_setBcnRxParams() LMICus915_setBcnRxParams()
|
||||
@ -53,10 +54,13 @@ void LMICus915_setBcnRxParams(void);
|
||||
u4_t LMICus915_convFreq(xref2cu1_t ptr);
|
||||
#define LMICbandplan_convFreq(ptr) LMICus915_convFreq(ptr)
|
||||
|
||||
void LMICus915_initJoinLoop(void);
|
||||
#define LMICbandplan_initJoinLoop() LMICus915_initJoinLoop()
|
||||
|
||||
void LMICus915_setRx1Params(void);
|
||||
#define LMICbandplan_setRx1Params() LMICus915_setRx1Params()
|
||||
|
||||
void LMICus915_updateTx(ostime_t txbeg);
|
||||
#define LMICbandplan_updateTx(txbeg) LMICus915_updateTx(txbeg)
|
||||
|
||||
#endif // _lmic_us915_h_
|
||||
#endif // _lmic_bandplan_us915_h_
|
||||
|
@ -214,4 +214,38 @@ Returns:
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
||||
Macro: LMIC_DECLARE_FUNCTION_WEAK()
|
||||
|
||||
Function:
|
||||
Declare an external function as a weak reference.
|
||||
|
||||
Definition:
|
||||
#define LMIC_DECLARE_FUNCTION_WEAK(ReturnType, FunctionName, Params) ...
|
||||
|
||||
Description:
|
||||
This macro generates a weak reference to the specified function.
|
||||
|
||||
Example:
|
||||
LMIC_DECLARE_FUNCTION_WEAK(void, onEvent, (ev_t e));
|
||||
|
||||
This saya that onEvent is a weak external reference. When calling
|
||||
onEvent, you must always first check whether it's supplied:
|
||||
|
||||
if (onEvent != NULL)
|
||||
onEvent(e);
|
||||
|
||||
Returns:
|
||||
This macro expands to a declaration, without a trailing semicolon.
|
||||
|
||||
Notes:
|
||||
This form allows for compilers that use _Pragma(weak, name) instead
|
||||
of inline attributes.
|
||||
|
||||
*/
|
||||
|
||||
#define LMIC_DECLARE_FUNCTION_WEAK(a_ReturnType, a_FunctionName, a_Params) \
|
||||
a_ReturnType __attribute__((__weak__)) a_FunctionName a_Params
|
||||
|
||||
#endif /* _lmic_env_h_ */
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2016 IBM Corporation.
|
||||
* Copyright (c) 2017 MCCI Corporation.
|
||||
* Copyright (c) 2017, 2019 MCCI Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -59,7 +59,7 @@ uint8_t LMICeu868_maxFrameLen(uint8_t dr) {
|
||||
}
|
||||
|
||||
static CONST_TABLE(s1_t, TXPOWLEVELS)[] = {
|
||||
20, 14, 11, 8, 5, 2, 0,0, 0,0,0,0, 0,0,0,0
|
||||
16, 14, 12, 10, 8, 6, 4, 2, 0,0,0,0, 0,0,0,0
|
||||
};
|
||||
|
||||
int8_t LMICeu868_pow2dBm(uint8_t mcmd_ladr_p1) {
|
||||
@ -221,6 +221,28 @@ LMICeu868_txDoneFSK(ostime_t delay, osjobcb_t func) {
|
||||
os_setTimedCallback(&LMIC.osjob, LMIC.rxtime - RX_RAMPUP, func);
|
||||
}
|
||||
|
||||
// set the Rx1 dndr, rps.
|
||||
void LMICeu868_setRx1Params(void) {
|
||||
u1_t const txdr = LMIC.dndr;
|
||||
s1_t drOffset;
|
||||
s1_t candidateDr;
|
||||
|
||||
if ( LMIC.rx1DrOffset <= 5)
|
||||
drOffset = (s1_t) LMIC.rx1DrOffset;
|
||||
else
|
||||
// make a reasonable assumption for unspecified value.
|
||||
drOffset = 5;
|
||||
|
||||
candidateDr = (s1_t) txdr - drOffset;
|
||||
if (candidateDr < LORAWAN_DR0)
|
||||
candidateDr = 0;
|
||||
else if (candidateDr > LORAWAN_DR7)
|
||||
candidateDr = LORAWAN_DR7;
|
||||
|
||||
LMIC.dndr = (u1_t) candidateDr;
|
||||
LMIC.rps = dndr2rps(LMIC.dndr);
|
||||
}
|
||||
|
||||
void
|
||||
LMICeu868_initJoinLoop(void) {
|
||||
LMICeulike_initJoinLoop(NUM_DEFAULT_CHANNELS, /* adr dBm */ EU868_TX_EIRP_MAX_DBM);
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2016 IBM Corporation.
|
||||
* Copyright (c) 2017 MCCI Corporation.
|
||||
* Copyright (c) 2017, 2019 MCCI Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -32,37 +32,47 @@
|
||||
|
||||
#if CFG_LMIC_EU_like
|
||||
|
||||
void LMIC_enableSubBand(u1_t band) {
|
||||
bit_t LMIC_enableSubBand(u1_t band) {
|
||||
LMIC_API_PARAMETER(band);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void LMIC_disableSubBand(u1_t band) {
|
||||
bit_t LMIC_disableSubBand(u1_t band) {
|
||||
LMIC_API_PARAMETER(band);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void LMIC_disableChannel(u1_t channel) {
|
||||
bit_t LMIC_disableChannel(u1_t channel) {
|
||||
u2_t old_chmap = LMIC.channelMap;
|
||||
LMIC.channelFreq[channel] = 0;
|
||||
LMIC.channelDrMap[channel] = 0;
|
||||
LMIC.channelMap &= ~(1 << channel);
|
||||
LMIC.channelMap = old_chmap & ~(1 << channel);
|
||||
return LMIC.channelMap != old_chmap;
|
||||
}
|
||||
|
||||
// this is a no-op provided for compatibilty
|
||||
void LMIC_enableChannel(u1_t channel) {
|
||||
bit_t LMIC_enableChannel(u1_t channel) {
|
||||
LMIC_API_PARAMETER(channel);
|
||||
return 0;
|
||||
}
|
||||
|
||||
u1_t LMICeulike_mapChannels(u1_t chpage, u2_t chmap) {
|
||||
// Bad page, disable all channel, enable non-existent
|
||||
bit_t LMICeulike_canMapChannels(u1_t chpage, u2_t chmap) {
|
||||
if (chpage != 0 || chmap == 0 || (chmap & ~LMIC.channelMap) != 0)
|
||||
return 0; // illegal input
|
||||
for (u1_t chnl = 0; chnl<MAX_CHANNELS; chnl++) {
|
||||
if ((chmap & (1 << chnl)) != 0 && LMIC.channelFreq[chnl] == 0)
|
||||
chmap &= ~(1 << chnl); // ignore - channel is not defined
|
||||
return 0; // fail - channel is not defined
|
||||
}
|
||||
LMIC.channelMap = chmap;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// assumes that LMICeulike_canMapChannels passed. Return true if something changed.
|
||||
bit_t LMICeulike_mapChannels(u1_t chpage, u2_t chmap) {
|
||||
u2_t const old_chmap = LMIC.channelMap;
|
||||
LMIC.channelMap = chmap;
|
||||
return old_chmap != chmap;
|
||||
}
|
||||
|
||||
#if !defined(DISABLE_JOIN)
|
||||
void LMICeulike_initJoinLoop(uint8_t nDefaultChannels, s1_t adrTxPow) {
|
||||
#if CFG_TxContinuousMode
|
||||
@ -159,4 +169,19 @@ ostime_t LMICeulike_nextJoinState(uint8_t nDefaultChannels) {
|
||||
}
|
||||
#endif // !DISABLE_JOIN
|
||||
|
||||
void LMICeulike_saveAdrState(lmic_saved_adr_state_t *pStateBuffer) {
|
||||
memcpy(
|
||||
pStateBuffer->channelFreq,
|
||||
LMIC.channelFreq,
|
||||
sizeof(LMIC.channelFreq)
|
||||
);
|
||||
pStateBuffer->channelMap = LMIC.channelMap;
|
||||
}
|
||||
|
||||
bit_t LMICeulike_compareAdrState(const lmic_saved_adr_state_t *pStateBuffer) {
|
||||
if (memcmp(pStateBuffer->channelFreq, LMIC.channelFreq, sizeof(LMIC.channelFreq)) != 0)
|
||||
return 1;
|
||||
return pStateBuffer->channelMap != LMIC.channelMap;
|
||||
}
|
||||
|
||||
#endif // CFG_LMIC_EU_like
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2016 IBM Corporation.
|
||||
* Copyright (c) 2017 MCCI Corporation.
|
||||
* Copyright (c) 2017, 2019 MCCI Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -74,14 +74,14 @@ enum { BAND_MILLI = 0, BAND_CENTI = 1, BAND_DECI = 2, BAND_AUX = 3 };
|
||||
#define LMICbandplan_setSessionInitDefaultChannels() \
|
||||
do { LMICbandplan_initDefaultChannels(/* normal, not join */ 0); } while (0)
|
||||
|
||||
u1_t LMICeulike_mapChannels(u1_t chpage, u2_t chmap);
|
||||
bit_t LMICeulike_canMapChannels(u1_t chpage, u2_t chmap);
|
||||
#define LMICbandplan_canMapChannels(c, m) LMICeulike_canMapChannels(c, m)
|
||||
|
||||
bit_t LMICeulike_mapChannels(u1_t chpage, u2_t chmap);
|
||||
#define LMICbandplan_mapChannels(c, m) LMICeulike_mapChannels(c, m)
|
||||
|
||||
void LMICeulike_initJoinLoop(u1_t nDefaultChannels, s1_t adrTxPow);
|
||||
|
||||
#define LMICbandplan_setRx1Params() \
|
||||
do { /*LMIC.freq/rps remain unchanged*/ } while (0)
|
||||
|
||||
void LMICeulike_updateTx(ostime_t txbeg);
|
||||
#define LMICbandplan_updateTx(t) LMICeulike_updateTx(t)
|
||||
|
||||
@ -95,4 +95,10 @@ static inline ostime_t LMICeulike_nextJoinTime(ostime_t now) {
|
||||
#define LMICbandplan_init() \
|
||||
do { /* nothing */ } while (0)
|
||||
|
||||
void LMICeulike_saveAdrState(lmic_saved_adr_state_t *pStateBuffer);
|
||||
#define LMICbandplan_saveAdrState(pState) LMICeulike_saveAdrState(pState)
|
||||
|
||||
bit_t LMICeulike_compareAdrState(const lmic_saved_adr_state_t *pStateBuffer);
|
||||
#define LMICbandplan_compareAdrState(pState) LMICeulike_compareAdrState(pState)
|
||||
|
||||
#endif // _lmic_eu_like_h_
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2016 IBM Corporation.
|
||||
* Copyright (c) 2017 MCCI Corporation.
|
||||
* Copyright (c) 2017, 2019 MCCI Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -59,7 +59,7 @@ uint8_t LMICin866_maxFrameLen(uint8_t dr) {
|
||||
}
|
||||
|
||||
static CONST_TABLE(s1_t, TXPOWLEVELS)[] = {
|
||||
20, 14, 11, 8, 5, 2, 0,0, 0,0,0,0, 0,0,0,0
|
||||
30, 28, 26, 24, 22, 20, 18, 16, 14, 12, 10, 0, 0,0,0,0
|
||||
};
|
||||
|
||||
int8_t LMICin866_pow2dBm(uint8_t mcmd_ladr_p1) {
|
||||
@ -195,6 +195,27 @@ LMICin866_txDoneFSK(ostime_t delay, osjobcb_t func) {
|
||||
os_setTimedCallback(&LMIC.osjob, LMIC.rxtime - RX_RAMPUP, func);
|
||||
}
|
||||
|
||||
// set the Rx1 dndr, rps.
|
||||
void LMICin866_setRx1Params(void) {
|
||||
u1_t const txdr = LMIC.dndr;
|
||||
s1_t drOffset;
|
||||
s1_t candidateDr;
|
||||
|
||||
if ( LMIC.rx1DrOffset <= 5)
|
||||
drOffset = (s1_t) LMIC.rx1DrOffset;
|
||||
else
|
||||
drOffset = 5 - (s1_t) LMIC.rx1DrOffset;
|
||||
|
||||
candidateDr = (s1_t) txdr - drOffset;
|
||||
if (candidateDr < LORAWAN_DR0)
|
||||
candidateDr = 0;
|
||||
else if (candidateDr > LORAWAN_DR5)
|
||||
candidateDr = LORAWAN_DR5;
|
||||
|
||||
LMIC.dndr = (u1_t) candidateDr;
|
||||
LMIC.rps = dndr2rps(LMIC.dndr);
|
||||
}
|
||||
|
||||
void
|
||||
LMICin866_initJoinLoop(void) {
|
||||
LMICeulike_initJoinLoop(NUM_DEFAULT_CHANNELS, /* adr dBm */ IN866_TX_EIRP_MAX_DBM);
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2016 IBM Corporation.
|
||||
* Copyright (c) 2017 MCCI Corporation.
|
||||
* Copyright (c) 2017, 2019 MCCI Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -98,9 +98,11 @@ bit_t LMIC_setupChannel(u1_t chidx, u4_t freq, u2_t drmap, s1_t band) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
void LMIC_disableChannel(u1_t channel) {
|
||||
bit_t LMIC_disableChannel(u1_t channel) {
|
||||
bit_t result = 0;
|
||||
if (channel < 72 + MAX_XCHANNELS) {
|
||||
if (ENABLED_CHANNEL(channel)) {
|
||||
result = 1;
|
||||
if (IS_CHANNEL_125khz(channel))
|
||||
LMIC.activeChannels125khz--;
|
||||
else if (IS_CHANNEL_500khz(channel))
|
||||
@ -108,11 +110,14 @@ void LMIC_disableChannel(u1_t channel) {
|
||||
}
|
||||
LMIC.channelMap[channel >> 4] &= ~(1 << (channel & 0xF));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void LMIC_enableChannel(u1_t channel) {
|
||||
bit_t LMIC_enableChannel(u1_t channel) {
|
||||
bit_t result = 0;
|
||||
if (channel < 72 + MAX_XCHANNELS) {
|
||||
if (!ENABLED_CHANNEL(channel)) {
|
||||
result = 1;
|
||||
if (IS_CHANNEL_125khz(channel))
|
||||
LMIC.activeChannels125khz++;
|
||||
else if (IS_CHANNEL_500khz(channel))
|
||||
@ -120,42 +125,52 @@ void LMIC_enableChannel(u1_t channel) {
|
||||
}
|
||||
LMIC.channelMap[channel >> 4] |= (1 << (channel & 0xF));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void LMIC_enableSubBand(u1_t band) {
|
||||
bit_t LMIC_enableSubBand(u1_t band) {
|
||||
ASSERT(band < 8);
|
||||
u1_t start = band * 8;
|
||||
u1_t end = start + 8;
|
||||
bit_t result = 0;
|
||||
|
||||
// enable all eight 125 kHz channels in this subband
|
||||
for (int channel = start; channel < end; ++channel)
|
||||
LMIC_enableChannel(channel);
|
||||
result |= LMIC_enableChannel(channel);
|
||||
|
||||
// there's a single 500 kHz channel associated with
|
||||
// each group of 8 125 kHz channels. Enable it, too.
|
||||
LMIC_enableChannel(64 + band);
|
||||
result |= LMIC_enableChannel(64 + band);
|
||||
return result;
|
||||
}
|
||||
void LMIC_disableSubBand(u1_t band) {
|
||||
|
||||
bit_t LMIC_disableSubBand(u1_t band) {
|
||||
ASSERT(band < 8);
|
||||
u1_t start = band * 8;
|
||||
u1_t end = start + 8;
|
||||
bit_t result = 0;
|
||||
|
||||
// disable all eight 125 kHz channels in this subband
|
||||
for (int channel = start; channel < end; ++channel)
|
||||
LMIC_disableChannel(channel);
|
||||
result |= LMIC_disableChannel(channel);
|
||||
|
||||
// there's a single 500 kHz channel associated with
|
||||
// each group of 8 125 kHz channels. Disable it, too.
|
||||
LMIC_disableChannel(64 + band);
|
||||
result |= LMIC_disableChannel(64 + band);
|
||||
return result;
|
||||
}
|
||||
void LMIC_selectSubBand(u1_t band) {
|
||||
|
||||
bit_t LMIC_selectSubBand(u1_t band) {
|
||||
bit_t result = 0;
|
||||
|
||||
ASSERT(band < 8);
|
||||
for (int b = 0; b<8; ++b) {
|
||||
if (band == b)
|
||||
LMIC_enableSubBand(b);
|
||||
result |= LMIC_enableSubBand(b);
|
||||
else
|
||||
LMIC_disableSubBand(b);
|
||||
result |= LMIC_disableSubBand(b);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void LMICus915_updateTx(ostime_t txbeg) {
|
||||
@ -193,16 +208,31 @@ void LMICus915_setBcnRxParams(void) {
|
||||
}
|
||||
#endif // !DISABLE_BEACONS
|
||||
|
||||
// TODO(tmm@mcci.com): parmeterize for US-like
|
||||
// set the Rx1 dndr, rps.
|
||||
void LMICus915_setRx1Params(void) {
|
||||
u1_t const txdr = LMIC.dndr;
|
||||
u1_t candidateDr;
|
||||
LMIC.freq = US915_500kHz_DNFBASE + (LMIC.txChnl & 0x7) * US915_500kHz_DNFSTEP;
|
||||
if( /* TX datarate */LMIC.dndr < US915_DR_SF8C )
|
||||
LMIC.dndr += US915_DR_SF10CR - US915_DR_SF10;
|
||||
else if( LMIC.dndr == US915_DR_SF8C )
|
||||
LMIC.dndr = US915_DR_SF7CR;
|
||||
if ( /* TX datarate */txdr < LORAWAN_DR4)
|
||||
candidateDr = txdr + 10 - LMIC.rx1DrOffset;
|
||||
else
|
||||
candidateDr = LORAWAN_DR13 - LMIC.rx1DrOffset;
|
||||
|
||||
if (candidateDr < LORAWAN_DR8)
|
||||
candidateDr = LORAWAN_DR8;
|
||||
else if (candidateDr > LORAWAN_DR13)
|
||||
candidateDr = LORAWAN_DR13;
|
||||
|
||||
LMIC.dndr = candidateDr;
|
||||
LMIC.rps = dndr2rps(LMIC.dndr);
|
||||
}
|
||||
|
||||
void LMICus915_initJoinLoop(void) {
|
||||
LMICuslike_initJoinLoop();
|
||||
|
||||
// initialize the adrTxPower.
|
||||
LMIC.adrTxPow = 20; // dBm
|
||||
}
|
||||
|
||||
//
|
||||
// END: US915 related stuff
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2016 IBM Corporation.
|
||||
* Copyright (c) 2017 MCCI Corporation.
|
||||
* Copyright (c) 2017, 2019 MCCI Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -91,7 +91,46 @@ void LMICuslike_initDefaultChannels(bit_t fJoin) {
|
||||
LMIC.activeChannels500khz = 8;
|
||||
}
|
||||
|
||||
u1_t LMICuslike_mapChannels(u1_t chpage, u2_t chmap) {
|
||||
// verify that a given setting is permitted
|
||||
bit_t LMICuslike_canMapChannels(u1_t chpage, u2_t chmap) {
|
||||
/*
|
||||
|| MCMD_LADR_CHP_125ON and MCMD_LADR_CHP_125OFF are special. The
|
||||
|| channel map appllies to 500kHz (ch 64..71) and in addition
|
||||
|| all channels 0..63 are turned off or on. MCMC_LADR_CHP_BANK
|
||||
|| is also special, in that it enables subbands.
|
||||
*/
|
||||
if (chpage < MCMD_LADR_CHP_USLIKE_SPECIAL) {
|
||||
if (chmap == 0)
|
||||
return 0;
|
||||
|
||||
// operate on channels 0..15, 16..31, 32..47, 48..63, 64..71
|
||||
if (chpage == (64 >> 4)) {
|
||||
if (chmap & 0xFF00) {
|
||||
// those are reserved bits, fail.
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
} else if (chpage == MCMD_LADR_CHP_BANK) {
|
||||
if (chmap == 0 || (chmap & 0xFF00) != 0) {
|
||||
// no bits set, or reserved bitsset , fail.
|
||||
return 0;
|
||||
}
|
||||
} else if (chpage == MCMD_LADR_CHP_125ON || chpage == MCMD_LADR_CHP_125OFF) {
|
||||
u1_t const en125 = chpage == MCMD_LADR_CHP_125ON;
|
||||
|
||||
// if disabling all 125kHz chans, must have at least one 500kHz chan
|
||||
// don't allow reserved bits to be set in chmap.
|
||||
if ((! en125 && chmap == 0) || (chmap & 0xFF00) != 0)
|
||||
return 0;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// if we get here, it looks legal.
|
||||
return 1;
|
||||
}
|
||||
|
||||
bit_t LMICuslike_mapChannels(u1_t chpage, u2_t chmap) {
|
||||
/*
|
||||
|| MCMD_LADR_CHP_125ON and MCMD_LADR_CHP_125OFF are special. The
|
||||
|| channel map appllies to 500kHz (ch 64..71) and in addition
|
||||
@ -99,61 +138,53 @@ u1_t LMICuslike_mapChannels(u1_t chpage, u2_t chmap) {
|
||||
|| is also special, in that it enables subbands.
|
||||
*/
|
||||
u1_t base, top;
|
||||
bit_t result = 0;
|
||||
|
||||
if (chpage == MCMD_LADR_CHP_BANK) {
|
||||
// each bit enables a bank of channels
|
||||
for (u1_t subband = 0; subband < 8; ++subband, chmap >>= 1) {
|
||||
if (chmap & 1) {
|
||||
result |= LMIC_enableSubBand(subband);
|
||||
} else {
|
||||
result |= LMIC_disableSubBand(subband);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
if (chpage < MCMD_LADR_CHP_USLIKE_SPECIAL) {
|
||||
// operate on channels 0..15, 16..31, 32..47, 48..63
|
||||
base = chpage << 4;
|
||||
top = base + 16;
|
||||
if (base == 64) {
|
||||
if (chmap & 0xFF00) {
|
||||
// those are reserved bits, fail.
|
||||
return 0;
|
||||
}
|
||||
top = 72;
|
||||
}
|
||||
} else if (chpage == MCMD_LADR_CHP_BANK) {
|
||||
if (chmap & 0xFF00) {
|
||||
// those are resreved bits, fail.
|
||||
return 0;
|
||||
}
|
||||
// each bit enables a bank of channels
|
||||
for (u1_t subband = 0; subband < 8; ++subband, chmap >>= 1) {
|
||||
if (chmap & 1) {
|
||||
LMIC_enableSubBand(subband);
|
||||
} else {
|
||||
LMIC_disableSubBand(subband);
|
||||
}
|
||||
|
||||
// don't change any channels below
|
||||
base = top = 0;
|
||||
}
|
||||
} else if (chpage == MCMD_LADR_CHP_125ON || chpage == MCMD_LADR_CHP_125OFF) {
|
||||
} else /* if (chpage == MCMD_LADR_CHP_125ON || chpage == MCMD_LADR_CHP_125OFF) */ {
|
||||
u1_t const en125 = chpage == MCMD_LADR_CHP_125ON;
|
||||
|
||||
// enable or disable all 125kHz channels
|
||||
for (u1_t chnl = 0; chnl < 64; ++chnl) {
|
||||
if (en125)
|
||||
LMIC_enableChannel(chnl);
|
||||
result |= LMIC_enableChannel(chnl);
|
||||
else
|
||||
LMIC_disableChannel(chnl);
|
||||
result |= LMIC_disableChannel(chnl);
|
||||
}
|
||||
|
||||
// then apply mask to top 8 channels.
|
||||
base = 64;
|
||||
top = 72;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// apply chmap to channels in [base..top-1].
|
||||
// Use enable/disable channel to keep activeChannel counts in sync.
|
||||
for (u1_t chnl = base; chnl < top; ++chnl, chmap >>= 1) {
|
||||
if (chmap & 0x0001)
|
||||
LMIC_enableChannel(chnl);
|
||||
result |= LMIC_enableChannel(chnl);
|
||||
else
|
||||
LMIC_disableChannel(chnl);
|
||||
result |= LMIC_disableChannel(chnl);
|
||||
}
|
||||
return 1;
|
||||
return result;
|
||||
}
|
||||
|
||||
// US does not have duty cycling - return now as earliest TX time
|
||||
@ -183,18 +214,13 @@ void LMICuslike_initJoinLoop(void) {
|
||||
// starting point.
|
||||
setNextChannel(0, 64, LMIC.activeChannels125khz);
|
||||
|
||||
// initialize the adrTxPower.
|
||||
// TODO(tmm@mcci.com): is this right for all US-like regions
|
||||
LMIC.adrTxPow = 20; // dBm
|
||||
ASSERT((LMIC.opmode & OP_NEXTCHNL) == 0);
|
||||
|
||||
// make sure LMIC.txend is valid.
|
||||
LMIC.txend = os_getTime();
|
||||
ASSERT((LMIC.opmode & OP_NEXTCHNL) == 0);
|
||||
|
||||
// make sure the datarate is set to DR0 per LoRaWAN regional reqts V1.0.2,
|
||||
// section 2.2.2
|
||||
// TODO(tmm@mcci.com): parameterize this for US-like
|
||||
LMICcore_setDrJoin(DRCHG_SET, LORAWAN_DR0);
|
||||
// make sure the datarate is set to DR2 per LoRaWAN regional reqts V1.0.2,
|
||||
// section 2.*.2
|
||||
LMICcore_setDrJoin(DRCHG_SET, LMICbandplan_getInitialDrJoin());
|
||||
|
||||
// TODO(tmm@mcci.com) need to implement the transmit randomization and
|
||||
// duty cycle restrictions from LoRaWAN V1.0.2 section 7.
|
||||
@ -233,7 +259,7 @@ ostime_t LMICuslike_nextJoinState(void) {
|
||||
setNextChannel(0, 64, LMIC.activeChannels125khz);
|
||||
|
||||
// TODO(tmm@mcci.com) parameterize
|
||||
s1_t dr = LORAWAN_DR0;
|
||||
s1_t dr = LMICuslike_getJoin125kHzDR();
|
||||
if ((++LMIC.txCnt & 0x7) == 0) {
|
||||
failed = 1; // All DR exhausted - signal failed
|
||||
}
|
||||
@ -260,4 +286,16 @@ ostime_t LMICuslike_nextJoinState(void) {
|
||||
}
|
||||
#endif
|
||||
|
||||
void LMICuslike_saveAdrState(lmic_saved_adr_state_t *pStateBuffer) {
|
||||
memcpy(
|
||||
pStateBuffer->channelMap,
|
||||
LMIC.channelMap,
|
||||
sizeof(LMIC.channelMap)
|
||||
);
|
||||
}
|
||||
|
||||
bit_t LMICuslike_compareAdrState(const lmic_saved_adr_state_t *pStateBuffer) {
|
||||
return memcmp(pStateBuffer->channelMap, LMIC.channelMap, sizeof(LMIC.channelMap)) != 0;
|
||||
}
|
||||
|
||||
#endif // CFG_LMIC_US_like
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2016 IBM Corporation.
|
||||
* Copyright (c) 2017 MCCI Corporation.
|
||||
* Copyright (c) 2017, 2019 MCCI Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -43,6 +43,9 @@
|
||||
#define IS_CHANNEL_500khz(c) (c>=64 && c<72)
|
||||
#define ENABLED_CHANNEL(chnl) ((LMIC.channelMap[(chnl >> 4)] & (1<<(chnl & 0x0F))) != 0)
|
||||
|
||||
// library functions: called from bandplan
|
||||
void LMICuslike_initJoinLoop(void);
|
||||
|
||||
// provide the isValidBeacon1 function -- int for bool.
|
||||
static inline int
|
||||
LMICuslike_isValidBeacon1(const uint8_t *d) {
|
||||
@ -77,24 +80,30 @@ void LMICuslike_initDefaultChannels(bit_t fJoin);
|
||||
#define LMICbandplan_setSessionInitDefaultChannels() \
|
||||
do { /* nothing */} while (0)
|
||||
|
||||
u1_t LMICuslike_mapChannels(u1_t chpage, u2_t chmap);
|
||||
bit_t LMICuslike_canMapChannels(u1_t chpage, u2_t chmap);
|
||||
#define LMICbandplan_canMapChannels(chpage, chmap) LMICuslike_canMapChannels(chpage, chmap)
|
||||
|
||||
bit_t LMICuslike_mapChannels(u1_t chpage, u2_t chmap);
|
||||
#define LMICbandplan_mapChannels(chpage, chmap) LMICuslike_mapChannels(chpage, chmap)
|
||||
|
||||
ostime_t LMICuslike_nextTx(ostime_t now);
|
||||
#define LMICbandplan_nextTx(now) LMICuslike_nextTx(now)
|
||||
|
||||
void LMICuslike_initJoinLoop(void);
|
||||
#define LMICbandplan_initJoinLoop() LMICuslike_initJoinLoop()
|
||||
|
||||
ostime_t LMICuslike_nextJoinState(void);
|
||||
#define LMICbandplan_nextJoinState() LMICuslike_nextJoinState();
|
||||
|
||||
static inline ostime_t LMICeulike_nextJoinTime(ostime_t now) {
|
||||
static inline ostime_t LMICuslike_nextJoinTime(ostime_t now) {
|
||||
return now;
|
||||
}
|
||||
#define LMICbandplan_nextJoinTime(now) LMICeulike_nextJoinTime(now)
|
||||
#define LMICbandplan_nextJoinTime(now) LMICuslike_nextJoinTime(now)
|
||||
|
||||
#define LMICbandplan_init() \
|
||||
do { /* nothing */ } while (0)
|
||||
|
||||
void LMICuslike_saveAdrState(lmic_saved_adr_state_t *pStateBuffer);
|
||||
#define LMICbandplan_saveAdrState(pState) LMICuslike_saveAdrState(pState)
|
||||
|
||||
bit_t LMICuslike_compareAdrState(const lmic_saved_adr_state_t *pStateBuffer);
|
||||
#define LMICbandplan_compareAdrState(pState) LMICuslike_compareAdrState(pState)
|
||||
|
||||
#endif // _lmic_us_like_h_
|
||||
|
@ -44,7 +44,14 @@ typedef u1_t cr_t;
|
||||
typedef u1_t sf_t;
|
||||
typedef u1_t bw_t;
|
||||
typedef u1_t dr_t;
|
||||
|
||||
// Radio parameter set (encodes SF/BW/CR/IH/NOCRC)
|
||||
// 2..0: Spreading factor
|
||||
// 4..3: bandwidth: 0 == 125kHz, 1 == 250 kHz, 2 == 500 kHz. 3 == reserved.
|
||||
// 6..5: coding rate: 0 == 4/5, 1 == 4/6, 2 == 4/7, 3 == 4/8
|
||||
// 7: nocrc: 0 == with crc, 1 == without crc
|
||||
// 15..8: Implicit header control: 0 ==> none, 1..0xFF ==> length in bytes.
|
||||
|
||||
typedef u2_t rps_t;
|
||||
TYPEDEF_xref2rps_t;
|
||||
|
||||
@ -52,7 +59,7 @@ enum { ILLEGAL_RPS = 0xFF };
|
||||
|
||||
// Global maximum frame length
|
||||
enum { STD_PREAMBLE_LEN = 8 };
|
||||
enum { MAX_LEN_FRAME = 64 };
|
||||
enum { MAX_LEN_FRAME = LMIC_ENABLE_long_messages ? 255 : 64 };
|
||||
enum { LEN_DEVNONCE = 2 };
|
||||
enum { LEN_ARTNONCE = 3 };
|
||||
enum { LEN_NETID = 3 };
|
||||
@ -414,7 +421,6 @@ enum {
|
||||
HDR_FTYPE_DADN = 0x60, // data (unconfirmed) dn
|
||||
HDR_FTYPE_DCUP = 0x80, // data confirmed up
|
||||
HDR_FTYPE_DCDN = 0xA0, // data confirmed dn
|
||||
HDR_FTYPE_REJOIN = 0xC0, // rejoin for roaming
|
||||
HDR_FTYPE_PROP = 0xE0
|
||||
};
|
||||
enum {
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2016 IBM Corporation.
|
||||
* Copyright (c) 2016-2017 MCCI Corporation.
|
||||
* Copyright (c) 2016-2017, 2019 MCCI Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -68,13 +68,15 @@ static int unlinkjob (osjob_t** pnext, osjob_t* job) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static osjob_t** getJobQueue(osjob_t* job) {
|
||||
return os_jobIsTimed(job) ? &OS.scheduledjobs : &OS.runnablejobs;
|
||||
}
|
||||
|
||||
// clear scheduled job
|
||||
void os_clearCallback (osjob_t* job) {
|
||||
hal_disableIRQs();
|
||||
|
||||
// if it's not in the scheduled jobs, look in the runnable...
|
||||
if (! unlinkjob(&OS.scheduledjobs, job))
|
||||
unlinkjob(&OS.runnablejobs, job);
|
||||
unlinkjob(getJobQueue(job), job);
|
||||
|
||||
hal_enableIRQs();
|
||||
}
|
||||
@ -83,11 +85,15 @@ void os_clearCallback (osjob_t* job) {
|
||||
void os_setCallback (osjob_t* job, osjobcb_t cb) {
|
||||
osjob_t** pnext;
|
||||
hal_disableIRQs();
|
||||
|
||||
// remove if job was already queued
|
||||
unlinkjob(&OS.runnablejobs, job);
|
||||
// fill-in job
|
||||
job->func = cb;
|
||||
unlinkjob(getJobQueue(job), job);
|
||||
|
||||
// fill-in job. Ascending memory order is write-queue friendly
|
||||
job->next = NULL;
|
||||
job->deadline = 0;
|
||||
job->func = cb;
|
||||
|
||||
// add to end of run queue
|
||||
for(pnext=&OS.runnablejobs; *pnext; pnext=&((*pnext)->next));
|
||||
*pnext = job;
|
||||
@ -97,13 +103,21 @@ void os_setCallback (osjob_t* job, osjobcb_t cb) {
|
||||
// schedule timed job
|
||||
void os_setTimedCallback (osjob_t* job, ostime_t time, osjobcb_t cb) {
|
||||
osjob_t** pnext;
|
||||
|
||||
// special case time 0 -- it will be one tick late.
|
||||
if (time == 0)
|
||||
time = 1;
|
||||
|
||||
hal_disableIRQs();
|
||||
|
||||
// remove if job was already queued
|
||||
unlinkjob(&OS.scheduledjobs, job);
|
||||
unlinkjob(getJobQueue(job), job);
|
||||
|
||||
// fill-in job
|
||||
job->next = NULL;
|
||||
job->deadline = time;
|
||||
job->func = cb;
|
||||
job->next = NULL;
|
||||
|
||||
// insert into schedule
|
||||
for(pnext=&OS.scheduledjobs; *pnext; pnext=&((*pnext)->next)) {
|
||||
if((*pnext)->deadline - time > 0) { // (cmp diff, not abs!)
|
||||
@ -141,3 +155,13 @@ void os_runloop_once() {
|
||||
j->func(j);
|
||||
}
|
||||
}
|
||||
|
||||
// return true if there are any jobs scheduled within time ticks from now.
|
||||
// return false if any jobs scheduled are at least time ticks in the future.
|
||||
bit_t os_queryTimeCriticalJobs(ostime_t time) {
|
||||
if (OS.scheduledjobs &&
|
||||
OS.scheduledjobs->deadline - os_getTime() < time)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2016 IBM Corporation.
|
||||
* Copyright (c) 2018 MCCI Corporation
|
||||
* Copyright (c) 2018, 2019 MCCI Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -84,8 +84,7 @@ typedef u1_t* xref2u1_t;
|
||||
|
||||
#define SIZEOFEXPR(x) sizeof(x)
|
||||
|
||||
#define ON_LMIC_EVENT(ev) onEvent(ev)
|
||||
#define DECL_ON_LMIC_EVENT void onEvent(ev_t e)
|
||||
#define DECL_ON_LMIC_EVENT LMIC_DECLARE_FUNCTION_WEAK(void, onEvent, (ev_t e))
|
||||
|
||||
extern u4_t AESAUX[];
|
||||
extern u4_t AESKEY[];
|
||||
@ -149,7 +148,13 @@ void radio_monitor_rssi(ostime_t n, oslmic_radio_rssi_t *pRssi);
|
||||
|
||||
|
||||
struct osjob_t; // fwd decl.
|
||||
typedef void (*osjobcb_t) (struct osjob_t*);
|
||||
|
||||
//! the function type for osjob_t callbacks
|
||||
typedef void (osjobcbfn_t)(struct osjob_t*);
|
||||
|
||||
//! the pointer-to-function for osjob_t callbacks
|
||||
typedef osjobcbfn_t *osjobcb_t;
|
||||
|
||||
struct osjob_t {
|
||||
struct osjob_t* next;
|
||||
ostime_t deadline;
|
||||
@ -157,6 +162,11 @@ struct osjob_t {
|
||||
};
|
||||
TYPEDEF_xref2osjob_t;
|
||||
|
||||
//! determine whether a job is timed or immediate. os_setTimedCallback()
|
||||
// must treat incoming == 0 as being 1 instead.
|
||||
static inline int os_jobIsTimed(xref2osjob_t job) {
|
||||
return (job->deadline != 0);
|
||||
}
|
||||
|
||||
#ifndef HAS_os_calls
|
||||
|
||||
@ -190,6 +200,10 @@ void os_radio (u1_t mode);
|
||||
#ifndef os_getBattLevel
|
||||
u1_t os_getBattLevel (void);
|
||||
#endif
|
||||
#ifndef os_queryTimeCriticalJobs
|
||||
//! Return non-zero if any jobs are scheduled between now and now+time.
|
||||
bit_t os_queryTimeCriticalJobs(ostime_t time);
|
||||
#endif
|
||||
|
||||
#ifndef os_rlsbf4
|
||||
//! Read 32-bit quantity from given pointer in little endian byte order.
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2016 IBM Corporation.
|
||||
* Copyright (c) 2016-2018 MCCI Corporation.
|
||||
* Copyright (c) 2016-2019 MCCI Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -188,6 +188,12 @@
|
||||
|
||||
#define SX1276_MC1_IMPLICIT_HEADER_MODE_ON 0x01
|
||||
|
||||
#ifdef CFG_sx1276_radio
|
||||
# define SX127X_MC1_IMPLICIT_HEADER_MODE_ON SX1276_MC1_IMPLICIT_HEADER_MODE_ON
|
||||
#else
|
||||
# define SX127X_MC1_IMPLICIT_HEADER_MODE_ON SX1272_MC1_IMPLICIT_HEADER_MODE_ON
|
||||
#endif
|
||||
|
||||
// sx1276 RegModemConfig2
|
||||
#define SX1276_MC2_RX_PAYLOAD_CRCON 0x04
|
||||
|
||||
@ -264,7 +270,7 @@
|
||||
#define MAP_DIO0_LORA_TXDONE 0x40 // 01------
|
||||
#define MAP_DIO1_LORA_RXTOUT 0x00 // --00----
|
||||
#define MAP_DIO1_LORA_NOP 0x30 // --11----
|
||||
#define MAP_DIO2_LORA_NOP 0xC0 // ----11--
|
||||
#define MAP_DIO2_LORA_NOP 0x0C // ----11--
|
||||
|
||||
#define MAP_DIO0_FSK_READY 0x00 // 00------ (packet sent / payload ready)
|
||||
#define MAP_DIO1_FSK_NOP 0x30 // --11----
|
||||
@ -445,7 +451,7 @@ static void configChannel () {
|
||||
static void configPower () {
|
||||
#ifdef CFG_sx1276_radio
|
||||
// PA_BOOST output is assumed but not 20 dBm.
|
||||
s1_t pw = (s1_t)LMIC.txpow;
|
||||
s1_t pw = (s1_t)LMIC.radio_txpow;
|
||||
if(pw > 17) {
|
||||
pw = 17;
|
||||
} else if(pw < 2) {
|
||||
@ -461,7 +467,7 @@ static void configPower () {
|
||||
|
||||
#elif CFG_sx1272_radio
|
||||
// set PA config (2-17 dBm using PA_BOOST)
|
||||
s1_t pw = (s1_t)LMIC.txpow;
|
||||
s1_t pw = (s1_t)LMIC.radio_txpow;
|
||||
if(pw > 17) {
|
||||
pw = 17;
|
||||
} else if(pw < 2) {
|
||||
@ -634,8 +640,8 @@ static void rxlora (u1_t rxmode) {
|
||||
// set LNA gain
|
||||
writeReg(RegLna, LNA_RX_GAIN);
|
||||
// set max payload size
|
||||
writeReg(LORARegPayloadMaxLength, 64);
|
||||
#if !defined(DISABLE_INVERT_IQ_ON_RX)
|
||||
writeReg(LORARegPayloadMaxLength, MAX_LEN_FRAME);
|
||||
#if !defined(DISABLE_INVERT_IQ_ON_RX) /* DEPRECATED(tmm@mcci.com); #250. remove test, always include code in V3 */
|
||||
// use inverted I/Q signal (prevent mote-to-mote communication)
|
||||
|
||||
// XXX: use flag to switch on/off inversion
|
||||
@ -660,6 +666,9 @@ static void rxlora (u1_t rxmode) {
|
||||
// enable antenna switch for RX
|
||||
hal_pin_rxtx(0);
|
||||
|
||||
writeReg(LORARegFifoAddrPtr, 0);
|
||||
writeReg(LORARegFifoRxBaseAddr, 0);
|
||||
|
||||
// now instruct the radio to receive
|
||||
if (rxmode == RXMODE_SINGLE) { // single rx
|
||||
hal_waitUntil(LMIC.rxtime); // busy wait until exact rx time
|
||||
@ -958,6 +967,7 @@ void radio_irq_handler_v2 (u1_t dio, ostime_t now) {
|
||||
#endif
|
||||
if( (readReg(RegOpMode) & OPMODE_LORA) != 0) { // LORA modem
|
||||
u1_t flags = readReg(LORARegIrqFlags);
|
||||
LMIC.saveIrqFlags = flags;
|
||||
LMIC_X_DEBUG_PRINTF("IRQ=%02x\n", flags);
|
||||
if( flags & IRQ_LORA_TXDONE_MASK ) {
|
||||
// save exact tx time
|
||||
@ -969,7 +979,7 @@ void radio_irq_handler_v2 (u1_t dio, ostime_t now) {
|
||||
}
|
||||
LMIC.rxtime = now;
|
||||
// read the PDU and inform the MAC that we received something
|
||||
LMIC.dataLen = (readReg(LORARegModemConfig1) & SX1272_MC1_IMPLICIT_HEADER_MODE_ON) ?
|
||||
LMIC.dataLen = (readReg(LORARegModemConfig1) & SX127X_MC1_IMPLICIT_HEADER_MODE_ON) ?
|
||||
readReg(LORARegPayloadLength) : readReg(LORARegRxNbBytes);
|
||||
// set FIFO read address pointer
|
||||
writeReg(LORARegFifoAddrPtr, readReg(LORARegFifoRxCurrentAddr));
|
||||
|
Loading…
Reference in New Issue
Block a user