mirror of
https://github.com/manuelbl/ttn-esp32.git
synced 2025-05-09 11:24:28 +02:00
Upgrade to version 2.3.2 of mcci-catena/arduino-lmic
This commit is contained in:
parent
d7e8a920c8
commit
f01b29a3b2
1
.gitignore
vendored
1
.gitignore
vendored
@ -3,3 +3,4 @@ sdkconfig
|
|||||||
sdkconfig.old
|
sdkconfig.old
|
||||||
dev_keys.txt
|
dev_keys.txt
|
||||||
ttn-esp32
|
ttn-esp32
|
||||||
|
.vscode/
|
||||||
|
@ -262,9 +262,6 @@ u4_t os_aes (u1_t mode, xref2u1_t buf, u2_t len) {
|
|||||||
u4_t a0, a1, a2, a3;
|
u4_t a0, a1, a2, a3;
|
||||||
u4_t t0, t1, t2, t3;
|
u4_t t0, t1, t2, t3;
|
||||||
u4_t *ki, *ke;
|
u4_t *ki, *ke;
|
||||||
// ttn-esp32 change: prevent error 'x' may be used uninitialized in this function
|
|
||||||
a0 = a1 = a2 = a3 = 0;
|
|
||||||
t0 = t1 = 0;
|
|
||||||
|
|
||||||
// load input block
|
// load input block
|
||||||
if( (mode & AES_CTR) || ((mode & AES_MIC) && (mode & AES_MICNOAUX)==0) ) { // load CTR block or first MIC block
|
if( (mode & AES_CTR) || ((mode & AES_MIC) && (mode & AES_MICNOAUX)==0) ) { // load CTR block or first MIC block
|
||||||
|
0
src/aes/other.c
Normal file → Executable file
0
src/aes/other.c
Normal file → Executable file
@ -130,6 +130,17 @@ s1_t hal_getRssiCal (void)
|
|||||||
return lmic_pins.rssi_cal;
|
return lmic_pins.rssi_cal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ostime_t hal_setModuleActive (bit_t val)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bit_t hal_queryUsingTcxo(void)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// SPI
|
// SPI
|
||||||
|
|
||||||
@ -152,12 +163,12 @@ void HAL_ESP32::spiInit()
|
|||||||
ESP_LOGI(TAG, "SPI initialized");
|
ESP_LOGI(TAG, "SPI initialized");
|
||||||
}
|
}
|
||||||
|
|
||||||
void hal_spi_write(u1_t cmd, const u1_t *buf, int len)
|
void hal_spi_write(u1_t cmd, const u1_t *buf, size_t len)
|
||||||
{
|
{
|
||||||
ttn_hal.spiWrite(cmd, buf, len);
|
ttn_hal.spiWrite(cmd, buf, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HAL_ESP32::spiWrite(uint8_t cmd, const uint8_t *buf, int len)
|
void HAL_ESP32::spiWrite(uint8_t cmd, const uint8_t *buf, size_t len)
|
||||||
{
|
{
|
||||||
memset(&spiTransaction, 0, sizeof(spiTransaction));
|
memset(&spiTransaction, 0, sizeof(spiTransaction));
|
||||||
spiTransaction.addr = cmd;
|
spiTransaction.addr = cmd;
|
||||||
@ -167,12 +178,12 @@ void HAL_ESP32::spiWrite(uint8_t cmd, const uint8_t *buf, int len)
|
|||||||
ESP_ERROR_CHECK(err);
|
ESP_ERROR_CHECK(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hal_spi_read(u1_t cmd, u1_t *buf, int len)
|
void hal_spi_read(u1_t cmd, u1_t *buf, size_t len)
|
||||||
{
|
{
|
||||||
ttn_hal.spiRead(cmd, buf, len);
|
ttn_hal.spiRead(cmd, buf, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HAL_ESP32::spiRead(uint8_t cmd, uint8_t *buf, int len)
|
void HAL_ESP32::spiRead(uint8_t cmd, uint8_t *buf, size_t len)
|
||||||
{
|
{
|
||||||
memset(buf, 0, len);
|
memset(buf, 0, len);
|
||||||
memset(&spiTransaction, 0, sizeof(spiTransaction));
|
memset(&spiTransaction, 0, sizeof(spiTransaction));
|
||||||
|
@ -63,8 +63,8 @@ public:
|
|||||||
void initCriticalSection();
|
void initCriticalSection();
|
||||||
void enterCriticalSection();
|
void enterCriticalSection();
|
||||||
void leaveCriticalSection();
|
void leaveCriticalSection();
|
||||||
void spiWrite(uint8_t cmd, const uint8_t *buf, int len);
|
void spiWrite(uint8_t cmd, const uint8_t *buf, size_t len);
|
||||||
void spiRead(uint8_t cmd, uint8_t *buf, int len);
|
void spiRead(uint8_t cmd, uint8_t *buf, size_t len);
|
||||||
uint8_t checkTimer(uint32_t time);
|
uint8_t checkTimer(uint32_t time);
|
||||||
void sleep();
|
void sleep();
|
||||||
void waitUntil(uint32_t time);
|
void waitUntil(uint32_t time);
|
||||||
|
@ -171,4 +171,11 @@
|
|||||||
# endif // defined(LMIC_DISABLE_DR_LEGACY)
|
# endif // defined(LMIC_DISABLE_DR_LEGACY)
|
||||||
#endif // LMIC_DR_LEGACY
|
#endif // LMIC_DR_LEGACY
|
||||||
|
|
||||||
|
// LMIC_ENABLE_DeviceTimeReq
|
||||||
|
// enable support for MCMD_DeviceTimeReq and MCMD_DeviceTimeAns
|
||||||
|
// this is always defined, and non-zero to enable it.
|
||||||
|
#if !defined(LMIC_ENABLE_DeviceTimeReq)
|
||||||
|
# define LMIC_ENABLE_DeviceTimeReq 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // _lmic_config_h_
|
#endif // _lmic_config_h_
|
||||||
|
@ -26,8 +26,12 @@
|
|||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _hal_hpp_
|
#ifndef _lmic_hal_h_
|
||||||
#define _hal_hpp_
|
#define _lmic_hal_h_
|
||||||
|
|
||||||
|
#ifndef _oslmic_types_h_
|
||||||
|
# include "oslmic_types.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C"{
|
extern "C"{
|
||||||
@ -35,21 +39,20 @@ extern "C"{
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* initialize hardware (IO, SPI, TIMER, IRQ).
|
* initialize hardware (IO, SPI, TIMER, IRQ).
|
||||||
|
* This API is deprecated as it uses the const global lmic_pins,
|
||||||
|
* which the platform can't control or change.
|
||||||
*/
|
*/
|
||||||
void hal_init (void);
|
void hal_init (void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* initialize hardware, passing in platform-specific context
|
* Initialize hardware, passing in platform-specific context
|
||||||
|
* The pointer is to a HalPinmap_t.
|
||||||
*/
|
*/
|
||||||
void hal_init_ex (const void *pContext);
|
void hal_init_ex (const void *pContext);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* drive radio NSS pin (0=low, 1=high).
|
* drive radio RX/TX pins (0=rx, 1=tx). Actual polarity
|
||||||
*/
|
* is determined by the value of HalPinmap_t::rxtx_rx_active.
|
||||||
void hal_pin_nss (u1_t val);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* drive radio RX/TX pins (0=rx, 1=tx).
|
|
||||||
*/
|
*/
|
||||||
void hal_pin_rxtx (u1_t val);
|
void hal_pin_rxtx (u1_t val);
|
||||||
|
|
||||||
@ -58,29 +61,19 @@ void hal_pin_rxtx (u1_t val);
|
|||||||
*/
|
*/
|
||||||
void hal_pin_rst (u1_t val);
|
void hal_pin_rst (u1_t val);
|
||||||
|
|
||||||
// BEGIN ttn-esp32 change
|
|
||||||
// use higher level SPI functions
|
|
||||||
/*
|
/*
|
||||||
* Perform SPI write transaction with radio chip
|
* Perform SPI write transaction with radio chip
|
||||||
* - write the command byte 'cmd'
|
* - write the command byte 'cmd'
|
||||||
* - write 'len' bytes out of 'buf'
|
* - write 'len' bytes out of 'buf'
|
||||||
*/
|
*/
|
||||||
void hal_spi_write(u1_t cmd, const u1_t* buf, int len);
|
void hal_spi_write(u1_t cmd, const u1_t* buf, size_t len);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Perform SPI read transaction with radio chip
|
* Perform SPI read transaction with radio chip
|
||||||
* - write the command byte 'cmd'
|
* - write the command byte 'cmd'
|
||||||
* - read 'len' bytes into 'buf'
|
* - read 'len' bytes into 'buf'
|
||||||
*/
|
*/
|
||||||
void hal_spi_read(u1_t cmd, u1_t* buf, int len);
|
void hal_spi_read(u1_t cmd, u1_t* buf, size_t len);
|
||||||
|
|
||||||
/*
|
|
||||||
* perform 8-bit SPI transaction with radio.
|
|
||||||
* - write given byte 'outval'
|
|
||||||
* - read byte and return value
|
|
||||||
*/
|
|
||||||
//u1_t hal_spi (u1_t outval);
|
|
||||||
// END ttn-esp32 change
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* disable all CPU interrupts.
|
* disable all CPU interrupts.
|
||||||
@ -128,8 +121,18 @@ void hal_failed (const char *file, u2_t line);
|
|||||||
*/
|
*/
|
||||||
s1_t hal_getRssiCal (void);
|
s1_t hal_getRssiCal (void);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* control the radio state
|
||||||
|
* - if val == 0, turn tcxo off and otherwise prepare for sleep
|
||||||
|
* - if val == 1, turn tcxo on and otherwise prep for activity
|
||||||
|
* - return the number of ticks that we need to wait
|
||||||
|
*/
|
||||||
|
ostime_t hal_setModuleActive (bit_t val);
|
||||||
|
|
||||||
|
bit_t hal_queryUsingTcxo(void);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // _hal_hpp_
|
#endif // _lmic_hal_h_
|
||||||
|
104
src/lmic/lmic.c
Normal file → Executable file
104
src/lmic/lmic.c
Normal file → Executable file
@ -713,6 +713,38 @@ scan_mac_cmds(
|
|||||||
oidx += 2;
|
oidx += 2;
|
||||||
continue;
|
continue;
|
||||||
} /* end case */
|
} /* end case */
|
||||||
|
case MCMD_DeviceTimeAns: {
|
||||||
|
#if LMIC_ENABLE_DeviceTimeReq
|
||||||
|
// don't process a spurious downlink.
|
||||||
|
if ( LMIC.txDeviceTimeReqState == lmic_RequestTimeState_rx ) {
|
||||||
|
// remember that it's time to notify the client.
|
||||||
|
LMIC.txDeviceTimeReqState = lmic_RequestTimeState_success;
|
||||||
|
|
||||||
|
// the network time is linked to the time of the last TX.
|
||||||
|
LMIC.localDeviceTime = LMIC.txend;
|
||||||
|
|
||||||
|
// save the network time.
|
||||||
|
// The first 4 bytes contain the seconds since the GPS epoch
|
||||||
|
// (i.e January the 6th 1980 at 00:00:00 UTC).
|
||||||
|
// Note: as per the LoRaWAN specs, the octet order for all
|
||||||
|
// multi-octet fields is little endian
|
||||||
|
// Note: the casts are necessary, because opts is an array of
|
||||||
|
// single byte values, and they might overflow when shifted
|
||||||
|
LMIC.netDeviceTime = ( (lmic_gpstime_t) opts[oidx + 1] ) |
|
||||||
|
(((lmic_gpstime_t) opts[oidx + 2]) << 8) |
|
||||||
|
(((lmic_gpstime_t) opts[oidx + 3]) << 16) |
|
||||||
|
(((lmic_gpstime_t) opts[oidx + 4]) << 24);
|
||||||
|
|
||||||
|
// The 5th byte contains the fractional seconds in 2^-8 second steps
|
||||||
|
LMIC.netDeviceTimeFrac = opts[oidx + 5];
|
||||||
|
#if LMIC_DEBUG_LEVEL > 0
|
||||||
|
LMIC_DEBUG_PRINTF("%"LMIC_PRId_ostime_t": MAC command DeviceTimeAns received: seconds_since_gps_epoch=%"PRIu32", fractional_seconds=%d\n", os_getTime(), LMIC.netDeviceTime, LMIC.netDeviceTimeFrac);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif // LMIC_ENABLE_DeviceTimeReq
|
||||||
|
oidx += 6;
|
||||||
|
continue;
|
||||||
|
} /* end case */
|
||||||
} /* end switch */
|
} /* end switch */
|
||||||
/* unrecognized mac commands fall out of switch to here */
|
/* unrecognized mac commands fall out of switch to here */
|
||||||
EV(specCond, ERR, (e_.reason = EV::specCond_t::BAD_MAC_CMD,
|
EV(specCond, ERR, (e_.reason = EV::specCond_t::BAD_MAC_CMD,
|
||||||
@ -1139,7 +1171,8 @@ static bit_t processJoinAccept (void) {
|
|||||||
LMIC.datarate = AS923_DR_SF10;
|
LMIC.datarate = AS923_DR_SF10;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
LMIC.opmode &= ~(OP_JOINING|OP_TRACK|OP_REJOIN|OP_TXRXPEND|OP_PINGINI) | OP_NEXTCHNL;
|
LMIC.opmode &= ~(OP_JOINING|OP_TRACK|OP_REJOIN|OP_TXRXPEND|OP_PINGINI);
|
||||||
|
LMIC.opmode |= OP_NEXTCHNL;
|
||||||
LMIC.txCnt = 0;
|
LMIC.txCnt = 0;
|
||||||
stateJustJoined();
|
stateJustJoined();
|
||||||
LMIC.dn2Dr = LMIC.frame[OFF_JA_DLSET] & 0x0F;
|
LMIC.dn2Dr = LMIC.frame[OFF_JA_DLSET] & 0x0F;
|
||||||
@ -1328,6 +1361,13 @@ static void buildDataFrame (void) {
|
|||||||
LMIC.txParamSetupAns = 0;
|
LMIC.txParamSetupAns = 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#if LMIC_ENABLE_DeviceTimeReq
|
||||||
|
if ( LMIC.txDeviceTimeReqState == lmic_RequestTimeState_tx ) {
|
||||||
|
LMIC.frame[end+0] = MCMD_DeviceTimeReq;
|
||||||
|
end += 1;
|
||||||
|
LMIC.txDeviceTimeReqState = lmic_RequestTimeState_rx;
|
||||||
|
}
|
||||||
|
#endif // LMIC_ENABLE_DeviceTimeReq
|
||||||
ASSERT(end <= OFF_DAT_OPTS+16);
|
ASSERT(end <= OFF_DAT_OPTS+16);
|
||||||
|
|
||||||
u1_t flen = end + (txdata ? 5+dlen : 4);
|
u1_t flen = end + (txdata ? 5+dlen : 4);
|
||||||
@ -1587,6 +1627,24 @@ static bit_t processDnData (void) {
|
|||||||
LMIC.dataBeg = LMIC.dataLen = 0;
|
LMIC.dataBeg = LMIC.dataLen = 0;
|
||||||
txcomplete:
|
txcomplete:
|
||||||
LMIC.opmode &= ~(OP_TXDATA|OP_TXRXPEND);
|
LMIC.opmode &= ~(OP_TXDATA|OP_TXRXPEND);
|
||||||
|
|
||||||
|
#if LMIC_ENABLE_DeviceTimeReq
|
||||||
|
lmic_request_time_state_t const requestTimeState = LMIC.txDeviceTimeReqState;
|
||||||
|
if ( requestTimeState != lmic_RequestTimeState_idle ) {
|
||||||
|
lmic_request_network_time_cb_t * const pNetworkTimeCb = LMIC.pNetworkTimeCb;
|
||||||
|
int flagSuccess = (LMIC.txDeviceTimeReqState == lmic_RequestTimeState_success);
|
||||||
|
LMIC.txDeviceTimeReqState = lmic_RequestTimeState_idle;
|
||||||
|
if (pNetworkTimeCb != NULL) {
|
||||||
|
// reset the callback, so that the user's routine
|
||||||
|
// can post another request if desired.
|
||||||
|
LMIC.pNetworkTimeCb = NULL;
|
||||||
|
|
||||||
|
// call the user's notification routine.
|
||||||
|
(*pNetworkTimeCb)(LMIC.pNetworkTimeUserData, flagSuccess);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // LMIC_ENABLE_DeviceTimeReq
|
||||||
|
|
||||||
if( (LMIC.txrxFlags & (TXRX_DNW1|TXRX_DNW2|TXRX_PING)) != 0 && (LMIC.opmode & OP_LINKDEAD) != 0 ) {
|
if( (LMIC.txrxFlags & (TXRX_DNW1|TXRX_DNW2|TXRX_PING)) != 0 && (LMIC.opmode & OP_LINKDEAD) != 0 ) {
|
||||||
LMIC.opmode &= ~OP_LINKDEAD;
|
LMIC.opmode &= ~OP_LINKDEAD;
|
||||||
reportEvent(EV_LINK_ALIVE);
|
reportEvent(EV_LINK_ALIVE);
|
||||||
@ -1728,12 +1786,11 @@ static void engineUpdate (void) {
|
|||||||
#endif // !DISABLE_JOIN
|
#endif // !DISABLE_JOIN
|
||||||
|
|
||||||
ostime_t now = os_getTime();
|
ostime_t now = os_getTime();
|
||||||
ostime_t rxtime = 0;
|
|
||||||
ostime_t txbeg = 0;
|
ostime_t txbeg = 0;
|
||||||
// ttn-esp32: suppress unused variable
|
|
||||||
LMIC_UNREFERENCED_VARIABLE(rxtime);
|
|
||||||
|
|
||||||
#if !defined(DISABLE_BEACONS)
|
#if !defined(DISABLE_BEACONS)
|
||||||
|
ostime_t rxtime = 0;
|
||||||
|
|
||||||
if( (LMIC.opmode & OP_TRACK) != 0 ) {
|
if( (LMIC.opmode & OP_TRACK) != 0 ) {
|
||||||
// We are tracking a beacon
|
// We are tracking a beacon
|
||||||
ASSERT( now + RX_RAMPUP - LMIC.bcnRxtime <= 0 );
|
ASSERT( now + RX_RAMPUP - LMIC.bcnRxtime <= 0 );
|
||||||
@ -1929,6 +1986,11 @@ void LMIC_reset (void) {
|
|||||||
DO_DEVDB(LMIC.ping.dr, pingDr);
|
DO_DEVDB(LMIC.ping.dr, pingDr);
|
||||||
DO_DEVDB(LMIC.ping.intvExp, pingIntvExp);
|
DO_DEVDB(LMIC.ping.intvExp, pingIntvExp);
|
||||||
#endif // !DISABLE_PING
|
#endif // !DISABLE_PING
|
||||||
|
#if LMIC_ENABLE_DeviceTimeReq
|
||||||
|
LMIC.txDeviceTimeReqState = lmic_RequestTimeState_idle;
|
||||||
|
LMIC.netDeviceTime = 0; // the "invalid" time.
|
||||||
|
LMIC.netDeviceTimeFrac = 0;
|
||||||
|
#endif // LMIC_ENABLE_DeviceTimeReq
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1970,7 +2032,6 @@ int LMIC_setTxData2 (u1_t port, xref2u1_t data, u1_t dlen, u1_t confirmed) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Send a payload-less message to signal device is alive
|
// Send a payload-less message to signal device is alive
|
||||||
void LMIC_sendAlive (void) {
|
void LMIC_sendAlive (void) {
|
||||||
LMIC.opmode |= OP_POLL;
|
LMIC.opmode |= OP_POLL;
|
||||||
@ -2068,3 +2129,36 @@ void LMIC_getSessionKeys (u4_t *netid, devaddr_t *devaddr, xref2u1_t nwkKey, xre
|
|||||||
memcpy(artKey, LMIC.artKey, sizeof(LMIC.artKey));
|
memcpy(artKey, LMIC.artKey, sizeof(LMIC.artKey));
|
||||||
memcpy(nwkKey, LMIC.nwkKey, sizeof(LMIC.nwkKey));
|
memcpy(nwkKey, LMIC.nwkKey, sizeof(LMIC.nwkKey));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// \brief post an asynchronous request for the network time.
|
||||||
|
void LMIC_requestNetworkTime(lmic_request_network_time_cb_t *pCallbackfn, void *pUserData) {
|
||||||
|
#if LMIC_ENABLE_DeviceTimeReq
|
||||||
|
if (LMIC.txDeviceTimeReqState == lmic_RequestTimeState_idle) {
|
||||||
|
LMIC.txDeviceTimeReqState = lmic_RequestTimeState_tx;
|
||||||
|
LMIC.pNetworkTimeCb = pCallbackfn;
|
||||||
|
LMIC.pNetworkTimeUserData = pUserData;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif // LMIC_ENABLE_DeviceTimeReq
|
||||||
|
// if no device time support, or if not in proper state,
|
||||||
|
// report a failure.
|
||||||
|
if (pCallbackfn != NULL)
|
||||||
|
(*pCallbackfn)(pUserData, /* false */ 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// \brief return local/remote time pair (if valid, and DeviceTimeReq enabled),
|
||||||
|
// return true for success, false for error. We adjust the sampled OS time
|
||||||
|
// back in time to the nearest second boundary.
|
||||||
|
int LMIC_getNetworkTimeReference(lmic_time_reference_t *pReference) {
|
||||||
|
#if LMIC_ENABLE_DeviceTimeReq
|
||||||
|
if (pReference != NULL && // valid parameter, and
|
||||||
|
LMIC.netDeviceTime != 0) { // ... we have a reasonable answer.
|
||||||
|
const ostime_t tAdjust = LMIC.netDeviceTimeFrac * ms2osticks(1000) / 256;
|
||||||
|
|
||||||
|
pReference->tLocal = LMIC.localDeviceTime - tAdjust;
|
||||||
|
pReference->tNetwork = LMIC.netDeviceTime;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#endif // LMIC_ENABLE_DeviceTimeReq
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
49
src/lmic/lmic.h
Normal file → Executable file
49
src/lmic/lmic.h
Normal file → Executable file
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2016 IBM Corporation.
|
* Copyright (c) 2014-2016 IBM Corporation.
|
||||||
* Copyright (c) 2016 Matthijs Kooijman.
|
* Copyright (c) 2016 Matthijs Kooijman.
|
||||||
* Copyright (c) 2016-2018 MCCI Corporation.
|
* Copyright (c) 2016-2019 MCCI Corporation.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -105,7 +105,7 @@ extern "C"{
|
|||||||
#define ARDUINO_LMIC_VERSION_CALC(major, minor, patch, local) \
|
#define ARDUINO_LMIC_VERSION_CALC(major, minor, patch, local) \
|
||||||
(((major) << 24u) | ((minor) << 16u) | ((patch) << 8u) | (local))
|
(((major) << 24u) | ((minor) << 16u) | ((patch) << 8u) | (local))
|
||||||
|
|
||||||
#define ARDUINO_LMIC_VERSION ARDUINO_LMIC_VERSION_CALC(2, 2, 2, 0)
|
#define ARDUINO_LMIC_VERSION ARDUINO_LMIC_VERSION_CALC(2, 3, 2, 0) /* v2.3.2 */
|
||||||
|
|
||||||
#define ARDUINO_LMIC_VERSION_GET_MAJOR(v) \
|
#define ARDUINO_LMIC_VERSION_GET_MAJOR(v) \
|
||||||
(((v) >> 24u) & 0xFFu)
|
(((v) >> 24u) & 0xFFu)
|
||||||
@ -243,6 +243,35 @@ enum {
|
|||||||
MAX_CLOCK_ERROR = 65536,
|
MAX_CLOCK_ERROR = 65536,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 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
|
||||||
|
// without time request, "completing" the pending time request.
|
||||||
|
typedef void LMIC_ABI_STD lmic_request_network_time_cb_t(void *pUserData, int flagSuccess);
|
||||||
|
|
||||||
|
// how the network represents time.
|
||||||
|
typedef u4_t lmic_gpstime_t;
|
||||||
|
|
||||||
|
// rather than deal with 1/256 second tick, we adjust ostime back
|
||||||
|
// (as it's high res) to match tNetwork.
|
||||||
|
typedef struct lmic_time_reference_s lmic_time_reference_t;
|
||||||
|
|
||||||
|
struct lmic_time_reference_s {
|
||||||
|
// our best idea of when we sent the uplink (end of packet).
|
||||||
|
ostime_t tLocal;
|
||||||
|
// the network's best idea of when we sent the uplink.
|
||||||
|
lmic_gpstime_t tNetwork;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum lmic_request_time_state_e {
|
||||||
|
lmic_RequestTimeState_idle = 0, // we're not doing anything
|
||||||
|
lmic_RequestTimeState_tx, // we want to tx a time request on next uplink
|
||||||
|
lmic_RequestTimeState_rx, // we have tx'ed, next downlink completes.
|
||||||
|
lmic_RequestTimeState_success // we sucessfully got time.
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef u1_t lmic_request_time_state_t;
|
||||||
|
|
||||||
struct lmic_t {
|
struct lmic_t {
|
||||||
// Radio settings TX/RX (also accessed by HAL)
|
// Radio settings TX/RX (also accessed by HAL)
|
||||||
ostime_t txend;
|
ostime_t txend;
|
||||||
@ -306,6 +335,14 @@ struct lmic_t {
|
|||||||
devaddr_t devaddr;
|
devaddr_t devaddr;
|
||||||
u4_t seqnoDn; // device level down stream seqno
|
u4_t seqnoDn; // device level down stream seqno
|
||||||
u4_t seqnoUp;
|
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
|
u1_t dnConf; // dn frame confirm pending: LORA::FCT_ACK or 0
|
||||||
s1_t adrAckReq; // counter until we reset data rate (0=off)
|
s1_t adrAckReq; // counter until we reset data rate (0=off)
|
||||||
@ -329,6 +366,10 @@ struct lmic_t {
|
|||||||
bit_t txParamSetupAns; // transmit setup answer pending.
|
bit_t txParamSetupAns; // transmit setup answer pending.
|
||||||
u1_t txParam; // the saved TX param byte.
|
u1_t txParam; // the saved TX param byte.
|
||||||
#endif
|
#endif
|
||||||
|
#if LMIC_ENABLE_DeviceTimeReq
|
||||||
|
lmic_request_time_state_t txDeviceTimeReqState; // current state, initially idle.
|
||||||
|
u1_t netDeviceTimeFrac; // updated on any DeviceTimeAns.
|
||||||
|
#endif
|
||||||
|
|
||||||
// rx1DrOffset is the offset from uplink to downlink datarate
|
// rx1DrOffset is the offset from uplink to downlink datarate
|
||||||
u1_t rx1DrOffset; // captured from join. zero by default.
|
u1_t rx1DrOffset; // captured from join. zero by default.
|
||||||
@ -368,6 +409,7 @@ struct lmic_t {
|
|||||||
|
|
||||||
u1_t noRXIQinversion;
|
u1_t noRXIQinversion;
|
||||||
};
|
};
|
||||||
|
|
||||||
//! \var struct lmic_t LMIC
|
//! \var struct lmic_t LMIC
|
||||||
//! The state of LMIC MAC layer is encapsulated in this variable.
|
//! The state of LMIC MAC layer is encapsulated in this variable.
|
||||||
DECLARE_LMIC; //!< \internal
|
DECLARE_LMIC; //!< \internal
|
||||||
@ -417,6 +459,9 @@ u4_t LMIC_getSeqnoUp (void);
|
|||||||
u4_t LMIC_setSeqnoUp (u4_t);
|
u4_t LMIC_setSeqnoUp (u4_t);
|
||||||
void LMIC_getSessionKeys (u4_t *netid, devaddr_t *devaddr, xref2u1_t nwkKey, xref2u1_t artKey);
|
void LMIC_getSessionKeys (u4_t *netid, devaddr_t *devaddr, xref2u1_t nwkKey, xref2u1_t artKey);
|
||||||
|
|
||||||
|
void LMIC_requestNetworkTime(lmic_request_network_time_cb_t *pCallbackfn, void *pUserData);
|
||||||
|
int LMIC_getNetworkTimeReference(lmic_time_reference_t *pReference);
|
||||||
|
|
||||||
// Declare onEvent() function, to make sure any definition will have the
|
// Declare onEvent() function, to make sure any definition will have the
|
||||||
// C conventions, even when in a C++ file.
|
// C conventions, even when in a C++ file.
|
||||||
DECL_ON_LMIC_EVENT;
|
DECL_ON_LMIC_EVENT;
|
||||||
|
0
src/lmic/lmic_as923.c
Normal file → Executable file
0
src/lmic/lmic_as923.c
Normal file → Executable file
0
src/lmic/lmic_au921.c
Normal file → Executable file
0
src/lmic/lmic_au921.c
Normal file → Executable file
31
src/lmic/lmic_config_preconditions.h
Normal file → Executable file
31
src/lmic/lmic_config_preconditions.h
Normal file → Executable file
@ -114,6 +114,12 @@ Revision history:
|
|||||||
// following values. These are in order of the sections in the manual. Not all of the
|
// following values. These are in order of the sections in the manual. Not all of the
|
||||||
// below are supported yet.
|
// below are supported yet.
|
||||||
//
|
//
|
||||||
|
// CFG_as923jp is treated as a special case of CFG_as923, so it's not included in
|
||||||
|
// the below.
|
||||||
|
//
|
||||||
|
// TODO(tmm@mcci.com) consider moving this block to a central file as it's not
|
||||||
|
// user-editable.
|
||||||
|
//
|
||||||
# define CFG_LMIC_REGION_MASK \
|
# define CFG_LMIC_REGION_MASK \
|
||||||
((defined(CFG_eu868) << LMIC_REGION_eu868) | \
|
((defined(CFG_eu868) << LMIC_REGION_eu868) | \
|
||||||
(defined(CFG_us915) << LMIC_REGION_us915) | \
|
(defined(CFG_us915) << LMIC_REGION_us915) | \
|
||||||
@ -127,6 +133,8 @@ Revision history:
|
|||||||
0)
|
0)
|
||||||
|
|
||||||
// the selected region.
|
// the selected region.
|
||||||
|
// TODO(tmm@mcci.com) consider moving this block to a central file as it's not
|
||||||
|
// user-editable.
|
||||||
#if defined(CFG_eu868)
|
#if defined(CFG_eu868)
|
||||||
# define CFG_region LMIC_REGION_eu868
|
# define CFG_region LMIC_REGION_eu868
|
||||||
#elif defined(CFG_us915)
|
#elif defined(CFG_us915)
|
||||||
@ -139,6 +147,10 @@ Revision history:
|
|||||||
# define CFG_region LMIC_REGION_au921
|
# define CFG_region LMIC_REGION_au921
|
||||||
#elif defined(CFG_cn490)
|
#elif defined(CFG_cn490)
|
||||||
# define CFG_region LMIC_REGION_cn490
|
# define CFG_region LMIC_REGION_cn490
|
||||||
|
#elif defined(CFG_as923jp)
|
||||||
|
# define CFG_as923 1 /* CFG_as923jp implies CFG_as923 */
|
||||||
|
# define CFG_region LMIC_REGION_as923
|
||||||
|
# define LMIC_COUNTRY_CODE LMIC_COUNTRY_CODE_JP
|
||||||
#elif defined(CFG_as923)
|
#elif defined(CFG_as923)
|
||||||
# define CFG_region LMIC_REGION_as923
|
# define CFG_region LMIC_REGION_as923
|
||||||
#elif defined(CFG_kr921)
|
#elif defined(CFG_kr921)
|
||||||
@ -149,7 +161,11 @@ Revision history:
|
|||||||
# define CFG_region 0
|
# define CFG_region 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// finally the mask of` US-like and EU-like regions
|
// a bitmask of EU-like regions -- these are regions which have up to 16
|
||||||
|
// channels indidually programmable via downloink.
|
||||||
|
//
|
||||||
|
// TODO(tmm@mcci.com) consider moving this block to a central file as it's not
|
||||||
|
// user-editable.
|
||||||
#define CFG_LMIC_EU_like_MASK ( \
|
#define CFG_LMIC_EU_like_MASK ( \
|
||||||
(1 << LMIC_REGION_eu868) | \
|
(1 << LMIC_REGION_eu868) | \
|
||||||
/* (1 << LMIC_REGION_us915) | */ \
|
/* (1 << LMIC_REGION_us915) | */ \
|
||||||
@ -162,6 +178,12 @@ Revision history:
|
|||||||
(1 << LMIC_REGION_in866) | \
|
(1 << LMIC_REGION_in866) | \
|
||||||
0)
|
0)
|
||||||
|
|
||||||
|
// a bitmask of` US-like regions -- these are regions with 64 fixed 125 kHz channels
|
||||||
|
// overlaid by 8 500 kHz channels. The channel frequencies can't be changed, but
|
||||||
|
// subsets of channels can be selected via masks.
|
||||||
|
//
|
||||||
|
// TODO(tmm@mcci.com) consider moving this block to a central file as it's not
|
||||||
|
// user-editable.
|
||||||
#define CFG_LMIC_US_like_MASK ( \
|
#define CFG_LMIC_US_like_MASK ( \
|
||||||
/* (1 << LMIC_REGION_eu868) | */ \
|
/* (1 << LMIC_REGION_eu868) | */ \
|
||||||
(1 << LMIC_REGION_us915) | \
|
(1 << LMIC_REGION_us915) | \
|
||||||
@ -174,9 +196,12 @@ Revision history:
|
|||||||
/* (1 << LMIC_REGION_in866) | */ \
|
/* (1 << LMIC_REGION_in866) | */ \
|
||||||
0)
|
0)
|
||||||
|
|
||||||
|
//
|
||||||
|
// booleans that are true if the configured region is EU-like or US-like.
|
||||||
|
// TODO(tmm@mcci.com) consider moving this block to a central file as it's not
|
||||||
|
// user-editable.
|
||||||
|
//
|
||||||
#define CFG_LMIC_EU_like (!!(CFG_LMIC_REGION_MASK & CFG_LMIC_EU_like_MASK))
|
#define CFG_LMIC_EU_like (!!(CFG_LMIC_REGION_MASK & CFG_LMIC_EU_like_MASK))
|
||||||
#define CFG_LMIC_US_like (!!(CFG_LMIC_REGION_MASK & CFG_LMIC_US_like_MASK))
|
#define CFG_LMIC_US_like (!!(CFG_LMIC_REGION_MASK & CFG_LMIC_US_like_MASK))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* _LMIC_CONFIG_PRECONDITIONS_H_ */
|
#endif /* _LMIC_CONFIG_PRECONDITIONS_H_ */
|
||||||
|
217
src/lmic/lmic_env.h
Executable file
217
src/lmic/lmic_env.h
Executable file
@ -0,0 +1,217 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Module: lmic_env.h
|
||||||
|
|
||||||
|
Function:
|
||||||
|
Sets up macros etc. to make things a little easier for portabilty
|
||||||
|
|
||||||
|
Copyright notice and license info:
|
||||||
|
See LICENSE file accompanying this project.
|
||||||
|
|
||||||
|
Author:
|
||||||
|
Terry Moore, MCCI Corporation November 2018
|
||||||
|
|
||||||
|
Description:
|
||||||
|
This file is an adaptation of MCCI's standard IOCTL framework.
|
||||||
|
We duplicate a bit of functionality that we might get from other
|
||||||
|
libraries, so that the LMIC library can continue to stand alone.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _lmic_env_h_ /* prevent multiple includes */
|
||||||
|
#define _lmic_env_h_
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
Macro: LMIC_C_ASSERT()
|
||||||
|
|
||||||
|
Function:
|
||||||
|
Declaration-like macro that will cause a compile error if arg is FALSE.
|
||||||
|
|
||||||
|
Definition:
|
||||||
|
LMIC_C_ASSERT(
|
||||||
|
BOOL fErrorIfFalse
|
||||||
|
);
|
||||||
|
|
||||||
|
Description:
|
||||||
|
This macro, if used where an external reference declarataion is
|
||||||
|
permitted, will either compile cleanly, or will cause a compilation
|
||||||
|
error. The results of using this macro where a declaration is not
|
||||||
|
permitted are unspecified.
|
||||||
|
|
||||||
|
This is different from #if !(fErrorIfFalse) / #error in that the
|
||||||
|
expression is evaluated by the compiler rather than by the pre-
|
||||||
|
processor. Therefore things like sizeof() can be used.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
No explicit result -- either compiles cleanly or causes a compile
|
||||||
|
error.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LMIC_C_ASSERT
|
||||||
|
# define LMIC_C_ASSERT(e) \
|
||||||
|
void LMIC_C_ASSERT__(int LMIC_C_ASSERT_x[(e) ? 1: -1])
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/****************************************************************************\
|
||||||
|
|
|
||||||
|
| Define the begin/end declaration tags for C++ co-existance
|
||||||
|
|
|
||||||
|
\****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
# define LMIC_BEGIN_DECLS extern "C" {
|
||||||
|
# define LMIC_END_DECLS }
|
||||||
|
#else
|
||||||
|
# define LMIC_BEGIN_DECLS /* nothing */
|
||||||
|
# define LMIC_END_DECLS /* nothing */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// Annotations to avoid various "unused" warnings. These must appear as a
|
||||||
|
// statement in the function body; the macro annotates the variable to quiet
|
||||||
|
// compiler warnings. The way this is done is compiler-specific, and so these
|
||||||
|
// definitions are fall-backs, which might be overridden.
|
||||||
|
//
|
||||||
|
// Although these are all similar, we don't want extra macro expansions,
|
||||||
|
// so we define each one explicitly rather than relying on a common macro.
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// signal that a parameter is intentionally unused.
|
||||||
|
#ifndef LMIC_UNREFERENCED_PARAMETER
|
||||||
|
# define LMIC_UNREFERENCED_PARAMETER(v) do { (void) (v); } while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// an API parameter is a parameter that is required by an API definition, but
|
||||||
|
// happens to be unreferenced in this implementation. This is a stronger
|
||||||
|
// assertion than LMIC_UNREFERENCED_PARAMETER(): this parameter is here
|
||||||
|
// becuase of an API contract, but we have no use for it in this function.
|
||||||
|
#ifndef LMIC_API_PARAMETER
|
||||||
|
# define LMIC_API_PARAMETER(v) do { (void) (v); } while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// an intentionally-unreferenced variable.
|
||||||
|
#ifndef LMIC_UNREFERENCED_VARIABLE
|
||||||
|
# define LMIC_UNREFERENCED_VARIABLE(v) do { (void) (v); } while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// we have three (!) debug levels (LMIC_DEBUG_LEVEL > 0, LMIC_DEBUG_LEVEL > 1,
|
||||||
|
// and LMIC_X_DEBUG_LEVEL > 0. In each case we might have parameters or
|
||||||
|
// or varables that are only refereneced at the target debug level.
|
||||||
|
|
||||||
|
// Parameter referenced only if debugging at level > 0.
|
||||||
|
#ifndef LMIC_DEBUG1_PARAMETER
|
||||||
|
# if LMIC_DEBUG_LEVEL > 0
|
||||||
|
# define LMIC_DEBUG1_PARAMETER(v) do { ; } while (0)
|
||||||
|
# else
|
||||||
|
# define LMIC_DEBUG1_PARAMETER(v) do { (void) (v); } while (0)
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// variable referenced only if debugging at level > 0
|
||||||
|
#ifndef LMIC_DEBUG1_VARIABLE
|
||||||
|
# if LMIC_DEBUG_LEVEL > 0
|
||||||
|
# define LMIC_DEBUG1_VARIABLE(v) do { ; } while (0)
|
||||||
|
# else
|
||||||
|
# define LMIC_DEBUG1_VARIABLE(v) do { (void) (v); } while (0)
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// parameter referenced only if debugging at level > 1
|
||||||
|
#ifndef LMIC_DEBUG2_PARAMETER
|
||||||
|
# if LMIC_DEBUG_LEVEL > 1
|
||||||
|
# define LMIC_DEBUG2_PARAMETER(v) do { ; } while (0)
|
||||||
|
# else
|
||||||
|
# define LMIC_DEBUG2_PARAMETER(v) do { (void) (v); } while (0)
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// variable referenced only if debugging at level > 1
|
||||||
|
#ifndef LMIC_DEBUG2_VARIABLE
|
||||||
|
# if LMIC_DEBUG_LEVEL > 1
|
||||||
|
# define LMIC_DEBUG2_VARIABLE(v) do { ; } while (0)
|
||||||
|
# else
|
||||||
|
# define LMIC_DEBUG2_VARIABLE(v) do { (void) (v); } while (0)
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// parameter referenced only if LMIC_X_DEBUG_LEVEL > 0
|
||||||
|
#ifndef LMIC_X_DEBUG_PARAMETER
|
||||||
|
# if LMIC_X_DEBUG_LEVEL > 0
|
||||||
|
# define LMIC_X_DEBUG_PARAMETER(v) do { ; } while (0)
|
||||||
|
# else
|
||||||
|
# define LMIC_X_DEBUG_PARAMETER(v) do { (void) (v); } while (0)
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// variable referenced only if LMIC_X_DEBUG_LEVEL > 0
|
||||||
|
#ifndef LMIC_X_DEBUG_VARIABLE
|
||||||
|
# if LMIC_X_DEBUG_LEVEL > 0
|
||||||
|
# define LMIC_X_DEBUG_VARIABLE(v) do { ; } while (0)
|
||||||
|
# else
|
||||||
|
# define LMIC_X_DEBUG_VARIABLE(v) do { (void) (v); } while (0)
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// parameter referenced only if EV() macro is enabled (which it never is)
|
||||||
|
// TODO(tmm@mcci.com) take out the EV() framework as it reuqires C++, and
|
||||||
|
// this code is really C-99 to its bones.
|
||||||
|
#ifndef LMIC_EV_PARAMETER
|
||||||
|
# define LMIC_EV_PARAMETER(v) do { (void) (v); } while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// variable referenced only if EV() macro is defined.
|
||||||
|
#ifndef LMIC_EV_VARIABLE
|
||||||
|
# define LMIC_EV_VARIABLE(v) do { (void) (v); } while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
Macro: LMIC_ABI_STD
|
||||||
|
|
||||||
|
Index: Macro: LMIC_ABI_VARARGS
|
||||||
|
|
||||||
|
Function:
|
||||||
|
Annotation macros to force a particular binary calling sequence.
|
||||||
|
|
||||||
|
Definition:
|
||||||
|
#define LMIC_ABI_STD compiler-specific
|
||||||
|
#define LMIC_ABI_VARARGS compiler-specific
|
||||||
|
|
||||||
|
Description:
|
||||||
|
These macros are used when declaring a function type, and indicate
|
||||||
|
that a particular calling sequence is to be used. They are normally
|
||||||
|
used between the type portion of the function declaration and the
|
||||||
|
name of the function. For example:
|
||||||
|
|
||||||
|
typedef void LMIC_ABI_STD myCallBack_t(void);
|
||||||
|
|
||||||
|
It's important to use this in libraries on platforms with multiple
|
||||||
|
calling sequences, because different components can be compiled with
|
||||||
|
different defaults.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Not applicable.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* ABI marker for normal (fixed parameter count) functions -- used for function types */
|
||||||
|
#ifndef LMIC_ABI_STD
|
||||||
|
# ifdef _MSC_VER
|
||||||
|
# define LMIC_ABI_STD __stdcall
|
||||||
|
# else
|
||||||
|
# define LMIC_ABI_STD /* nothing */
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* ABI marker for VARARG functions -- used for function types */
|
||||||
|
#ifndef LMIC_ABI_VARARGS
|
||||||
|
# ifdef _MSC_VER
|
||||||
|
# define LMIC_ABI_VARARGS __cdecl
|
||||||
|
# else
|
||||||
|
# define LMIC_ABI_VARARGS /* nothing */
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _lmic_env_h_ */
|
0
src/lmic/lmic_eu_like.c
Normal file → Executable file
0
src/lmic/lmic_eu_like.c
Normal file → Executable file
0
src/lmic/lmic_in866.c
Normal file → Executable file
0
src/lmic/lmic_in866.c
Normal file → Executable file
0
src/lmic/lmic_us915.c
Normal file → Executable file
0
src/lmic/lmic_us915.c
Normal file → Executable file
0
src/lmic/lmic_us_like.c
Normal file → Executable file
0
src/lmic/lmic_us_like.c
Normal file → Executable file
@ -9,7 +9,7 @@ Copyright & License:
|
|||||||
See accompanying LICENSE file.
|
See accompanying LICENSE file.
|
||||||
|
|
||||||
Author:
|
Author:
|
||||||
Terry Moore, MCCI September 2019
|
Terry Moore, MCCI September 2018
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
2
src/lmic/lorabase.h
Normal file → Executable file
2
src/lmic/lorabase.h
Normal file → Executable file
@ -449,6 +449,7 @@ enum {
|
|||||||
MCMD_RXTimingSetupAns = 0x08, // : -
|
MCMD_RXTimingSetupAns = 0x08, // : -
|
||||||
MCMD_TxParamSetupAns = 0x09, // : -
|
MCMD_TxParamSetupAns = 0x09, // : -
|
||||||
MCMD_DIChannelAns = 0x0A, // : u1: [7-2]:RFU 1:exists 0:OK
|
MCMD_DIChannelAns = 0x0A, // : u1: [7-2]:RFU 1:exists 0:OK
|
||||||
|
MCMD_DeviceTimeReq = 0x0D,
|
||||||
|
|
||||||
// Class B
|
// Class B
|
||||||
MCMD_PING_IND = 0x10, // - pingability indic : u1: 7=RFU, 6-4:interval, 3-0:datarate
|
MCMD_PING_IND = 0x10, // - pingability indic : u1: 7=RFU, 6-4:interval, 3-0:datarate
|
||||||
@ -468,6 +469,7 @@ enum {
|
|||||||
MCMD_RXTimingSetupReq = 0x08, // : u1: [7-4]:RFU [3-0]: Delay 1-15s (0 => 1)
|
MCMD_RXTimingSetupReq = 0x08, // : u1: [7-4]:RFU [3-0]: Delay 1-15s (0 => 1)
|
||||||
MCMD_TxParamSetupReq = 0x09, // : u1: [7-6]:RFU [5:4]: dl dwell/ul dwell [3:0] max EIRP
|
MCMD_TxParamSetupReq = 0x09, // : u1: [7-6]:RFU [5:4]: dl dwell/ul dwell [3:0] max EIRP
|
||||||
MCMD_DIChannelReq = 0x0A, // : u1: channel, u3: frequency
|
MCMD_DIChannelReq = 0x0A, // : u1: channel, u3: frequency
|
||||||
|
MCMD_DeviceTimeAns = 0x0D,
|
||||||
|
|
||||||
// Class B
|
// Class B
|
||||||
MCMD_PING_SET = 0x11, // set ping freq : u3: freq
|
MCMD_PING_SET = 0x11, // set ping freq : u3: freq
|
||||||
|
0
src/lmic/oslmic.c
Normal file → Executable file
0
src/lmic/oslmic.c
Normal file → Executable file
132
src/lmic/oslmic.h
Normal file → Executable file
132
src/lmic/oslmic.h
Normal file → Executable file
@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2016 IBM Corporation.
|
* Copyright (c) 2014-2016 IBM Corporation.
|
||||||
|
* Copyright (c) 2018 MCCI Corporation
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -29,29 +30,22 @@
|
|||||||
#ifndef _oslmic_h_
|
#ifndef _oslmic_h_
|
||||||
#define _oslmic_h_
|
#define _oslmic_h_
|
||||||
|
|
||||||
// Dependencies required for the LoRa MAC in C to run.
|
// Dependencies required for the LMIC to run.
|
||||||
// These settings can be adapted to the underlying system.
|
// These settings can be adapted to the underlying system.
|
||||||
// You should not, however, change the lmic.[hc]
|
// You should not, however, change the lmic merely for porting purposes.[hc]
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifndef _lmic_env_h_
|
||||||
extern "C"{
|
# include "lmic_env.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//================================================================================
|
#ifndef _oslmic_types_h_
|
||||||
//================================================================================
|
# include "oslmic_types.h"
|
||||||
// Target platform as C library
|
#endif
|
||||||
typedef uint8_t bit_t;
|
|
||||||
typedef uint8_t u1_t;
|
LMIC_BEGIN_DECLS
|
||||||
typedef int8_t s1_t;
|
|
||||||
typedef uint16_t u2_t;
|
|
||||||
typedef int16_t s2_t;
|
|
||||||
typedef uint32_t u4_t;
|
|
||||||
typedef int32_t s4_t;
|
|
||||||
typedef unsigned int uint;
|
|
||||||
typedef const char* str_t;
|
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "hal.h"
|
#include "hal.h"
|
||||||
@ -73,7 +67,6 @@ typedef struct rxsched_t rxsched_t;
|
|||||||
typedef struct bcninfo_t bcninfo_t;
|
typedef struct bcninfo_t bcninfo_t;
|
||||||
typedef const u1_t* xref2cu1_t;
|
typedef const u1_t* xref2cu1_t;
|
||||||
typedef u1_t* xref2u1_t;
|
typedef u1_t* xref2u1_t;
|
||||||
typedef s4_t ostime_t;
|
|
||||||
|
|
||||||
// int32_t == s4_t is long on some platforms; and someday
|
// int32_t == s4_t is long on some platforms; and someday
|
||||||
// we will want 64-bit ostime_t. So, we will use a macro for the
|
// we will want 64-bit ostime_t. So, we will use a macro for the
|
||||||
@ -91,105 +84,6 @@ typedef s4_t ostime_t;
|
|||||||
|
|
||||||
#define SIZEOFEXPR(x) sizeof(x)
|
#define SIZEOFEXPR(x) sizeof(x)
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
// Annotations to avoid various "unused" warnings. These must appear as a
|
|
||||||
// statement in the function body; the macro annotates the variable to quiet
|
|
||||||
// compiler warnings. The way this is done is compiler-specific, and so these
|
|
||||||
// definitions are fall-backs, which might be overridden.
|
|
||||||
//
|
|
||||||
// Although these are all similar, we don't want extra macro expansions,
|
|
||||||
// so we define each one explicitly rather than relying on a common macro.
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// signal that a parameter is intentionally unused.
|
|
||||||
#ifndef LMIC_UNREFERENCED_PARAMETER
|
|
||||||
# define LMIC_UNREFERENCED_PARAMETER(v) do { (void) (v); } while (0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// an API parameter is a parameter that is required by an API definition, but
|
|
||||||
// happens to be unreferenced in this implementation. This is a stronger
|
|
||||||
// assertion than LMIC_UNREFERENCED_PARAMETER(): this parameter is here
|
|
||||||
// becuase of an API contract, but we have no use for it in this function.
|
|
||||||
#ifndef LMIC_API_PARAMETER
|
|
||||||
# define LMIC_API_PARAMETER(v) do { (void) (v); } while (0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// an intentionally-unreferenced variable.
|
|
||||||
#ifndef LMIC_UNREFERENCED_VARIABLE
|
|
||||||
# define LMIC_UNREFERENCED_VARIABLE(v) do { (void) (v); } while (0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// we have three (!) debug levels (LMIC_DEBUG_LEVEL > 0, LMIC_DEBUG_LEVEL > 1,
|
|
||||||
// and LMIC_X_DEBUG_LEVEL > 0. In each case we might have parameters or
|
|
||||||
// or varables that are only refereneced at the target debug level.
|
|
||||||
|
|
||||||
// Parameter referenced only if debugging at level > 0.
|
|
||||||
#ifndef LMIC_DEBUG1_PARAMETER
|
|
||||||
# if LMIC_DEBUG_LEVEL > 0
|
|
||||||
# define LMIC_DEBUG1_PARAMETER(v) do { ; } while (0)
|
|
||||||
# else
|
|
||||||
# define LMIC_DEBUG1_PARAMETER(v) do { (void) (v); } while (0)
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// variable referenced only if debugging at level > 0
|
|
||||||
#ifndef LMIC_DEBUG1_VARIABLE
|
|
||||||
# if LMIC_DEBUG_LEVEL > 0
|
|
||||||
# define LMIC_DEBUG1_VARIABLE(v) do { ; } while (0)
|
|
||||||
# else
|
|
||||||
# define LMIC_DEBUG1_VARIABLE(v) do { (void) (v); } while (0)
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// parameter referenced only if debugging at level > 1
|
|
||||||
#ifndef LMIC_DEBUG2_PARAMETER
|
|
||||||
# if LMIC_DEBUG_LEVEL > 1
|
|
||||||
# define LMIC_DEBUG2_PARAMETER(v) do { ; } while (0)
|
|
||||||
# else
|
|
||||||
# define LMIC_DEBUG2_PARAMETER(v) do { (void) (v); } while (0)
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// variable referenced only if debugging at level > 1
|
|
||||||
#ifndef LMIC_DEBUG2_VARIABLE
|
|
||||||
# if LMIC_DEBUG_LEVEL > 1
|
|
||||||
# define LMIC_DEBUG2_VARIABLE(v) do { ; } while (0)
|
|
||||||
# else
|
|
||||||
# define LMIC_DEBUG2_VARIABLE(v) do { (void) (v); } while (0)
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// parameter referenced only if LMIC_X_DEBUG_LEVEL > 0
|
|
||||||
#ifndef LMIC_X_DEBUG_PARAMETER
|
|
||||||
# if LMIC_X_DEBUG_LEVEL > 0
|
|
||||||
# define LMIC_X_DEBUG_PARAMETER(v) do { ; } while (0)
|
|
||||||
# else
|
|
||||||
# define LMIC_X_DEBUG_PARAMETER(v) do { (void) (v); } while (0)
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// variable referenced only if LMIC_X_DEBUG_LEVEL > 0
|
|
||||||
#ifndef LMIC_X_DEBUG_VARIABLE
|
|
||||||
# if LMIC_X_DEBUG_LEVEL > 0
|
|
||||||
# define LMIC_X_DEBUG_VARIABLE(v) do { ; } while (0)
|
|
||||||
# else
|
|
||||||
# define LMIC_X_DEBUG_VARIABLE(v) do { (void) (v); } while (0)
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// parameter referenced only if EV() macro is enabled (which it never is)
|
|
||||||
// TODO(tmm@mcci.com) take out the EV() framework as it reuqires C++, and
|
|
||||||
// this code is really C-99 to its bones.
|
|
||||||
#ifndef LMIC_EV_PARAMETER
|
|
||||||
# define LMIC_EV_PARAMETER(v) do { (void) (v); } while (0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// variable referenced only if EV() macro is defined.
|
|
||||||
#ifndef LMIC_EV_VARIABLE
|
|
||||||
# define LMIC_EV_VARIABLE(v) do { (void) (v); } while (0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#define ON_LMIC_EVENT(ev) onEvent(ev)
|
#define ON_LMIC_EVENT(ev) onEvent(ev)
|
||||||
#define DECL_ON_LMIC_EVENT void onEvent(ev_t e)
|
#define DECL_ON_LMIC_EVENT void onEvent(ev_t e)
|
||||||
|
|
||||||
@ -416,8 +310,6 @@ extern xref2u1_t AESaux;
|
|||||||
u4_t os_aes (u1_t mode, xref2u1_t buf, u2_t len);
|
u4_t os_aes (u1_t mode, xref2u1_t buf, u2_t len);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
LMIC_END_DECLS
|
||||||
} // extern "C"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // _oslmic_h_
|
#endif // _oslmic_h_
|
||||||
|
47
src/lmic/oslmic_types.h
Executable file
47
src/lmic/oslmic_types.h
Executable file
@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Module: oslmic_types.h
|
||||||
|
|
||||||
|
Function:
|
||||||
|
Basic types from oslmic.h, shared by all layers.
|
||||||
|
|
||||||
|
Copyright & License:
|
||||||
|
See accompanying LICENSE file.
|
||||||
|
|
||||||
|
Author:
|
||||||
|
Terry Moore, MCCI November 2018
|
||||||
|
(based on oslmic.h from IBM).
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _oslmic_types_h_
|
||||||
|
# define _oslmic_types_h_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//================================================================================
|
||||||
|
//================================================================================
|
||||||
|
// Target platform as C library
|
||||||
|
typedef uint8_t bit_t;
|
||||||
|
typedef uint8_t u1_t;
|
||||||
|
typedef int8_t s1_t;
|
||||||
|
typedef uint16_t u2_t;
|
||||||
|
typedef int16_t s2_t;
|
||||||
|
typedef uint32_t u4_t;
|
||||||
|
typedef int32_t s4_t;
|
||||||
|
typedef unsigned int uint;
|
||||||
|
typedef const char* str_t;
|
||||||
|
|
||||||
|
// the HAL needs to give us ticks, so it ought to know the right type.
|
||||||
|
typedef s4_t ostime_t;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* end of oslmic_types.h */
|
||||||
|
#endif /* _oslmic_types_h_ */
|
72
src/lmic/radio.c
Normal file → Executable file
72
src/lmic/radio.c
Normal file → Executable file
@ -135,13 +135,22 @@
|
|||||||
// #define RegAgcThresh2 0x45 // common
|
// #define RegAgcThresh2 0x45 // common
|
||||||
// #define RegAgcThresh3 0x46 // common
|
// #define RegAgcThresh3 0x46 // common
|
||||||
// #define RegPllHop 0x4B // common
|
// #define RegPllHop 0x4B // common
|
||||||
#define RegPaDac 0x4D // common
|
|
||||||
// #define RegTcxo 0x58 // common
|
// #define RegTcxo 0x58 // common
|
||||||
// #define RegPll 0x5C // common
|
// #define RegPll 0x5C // common
|
||||||
// #define RegPllLowPn 0x5E // common
|
// #define RegPllLowPn 0x5E // common
|
||||||
// #define RegFormerTemp 0x6C // common
|
// #define RegFormerTemp 0x6C // common
|
||||||
// #define RegBitRateFrac 0x70 // common
|
// #define RegBitRateFrac 0x70 // common
|
||||||
|
|
||||||
|
#if defined(CFG_sx1276_radio)
|
||||||
|
#define RegTcxo 0x4B // common
|
||||||
|
#define RegPaDac 0x4D // common
|
||||||
|
#elif defined(CFG_sx1272_radio)
|
||||||
|
#define RegTcxo 0x58 // common
|
||||||
|
#define RegPaDac 0x5A // common
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define RegTcxo_TcxoInputOn (1u << 4)
|
||||||
|
|
||||||
// ----------------------------------------
|
// ----------------------------------------
|
||||||
// spread factors and mode for RegModemConfig2
|
// spread factors and mode for RegModemConfig2
|
||||||
#define SX1272_MC2_FSK 0x00
|
#define SX1272_MC2_FSK 0x00
|
||||||
@ -290,58 +299,41 @@ static u1_t randbuf[16];
|
|||||||
|
|
||||||
|
|
||||||
static void writeReg (u1_t addr, u1_t data ) {
|
static void writeReg (u1_t addr, u1_t data ) {
|
||||||
// ttn-esp32 change: higher level SPI interface
|
|
||||||
hal_spi_write(addr | 0x80, &data, 1);
|
hal_spi_write(addr | 0x80, &data, 1);
|
||||||
/*
|
|
||||||
hal_pin_nss(0);
|
|
||||||
hal_spi(addr | 0x80);
|
|
||||||
hal_spi(data);
|
|
||||||
hal_pin_nss(1);
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static u1_t readReg (u1_t addr) {
|
static u1_t readReg (u1_t addr) {
|
||||||
// ttn-esp32 change: higher level SPI interface
|
|
||||||
u1_t buf[1];
|
u1_t buf[1];
|
||||||
hal_spi_read(addr & 0x7f, buf, 1);
|
hal_spi_read(addr & 0x7f, buf, 1);
|
||||||
return buf[0];
|
return buf[0];
|
||||||
/*
|
|
||||||
hal_pin_nss(0);
|
|
||||||
hal_spi(addr & 0x7F);
|
|
||||||
u1_t val = hal_spi(0x00);
|
|
||||||
hal_pin_nss(1);
|
|
||||||
return val;
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void writeBuf (u1_t addr, xref2u1_t buf, u1_t len) {
|
static void writeBuf (u1_t addr, xref2u1_t buf, u1_t len) {
|
||||||
// ttn-esp32 change: higher level SPI interface
|
|
||||||
hal_spi_write(addr | 0x80, buf, len);
|
hal_spi_write(addr | 0x80, buf, len);
|
||||||
/*
|
|
||||||
hal_pin_nss(0);
|
|
||||||
hal_spi(addr | 0x80);
|
|
||||||
for (u1_t i=0; i<len; i++) {
|
|
||||||
hal_spi(buf[i]);
|
|
||||||
}
|
|
||||||
hal_pin_nss(1);
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void readBuf (u1_t addr, xref2u1_t buf, u1_t len) {
|
static void readBuf (u1_t addr, xref2u1_t buf, u1_t len) {
|
||||||
// ttn-esp32 change: higher level SPI interface
|
|
||||||
hal_spi_read(addr & 0x7f, buf, len);
|
hal_spi_read(addr & 0x7f, buf, len);
|
||||||
/*
|
|
||||||
hal_pin_nss(0);
|
|
||||||
hal_spi(addr & 0x7F);
|
|
||||||
for (u1_t i=0; i<len; i++) {
|
|
||||||
buf[i] = hal_spi(0x00);
|
|
||||||
}
|
}
|
||||||
hal_pin_nss(1);
|
|
||||||
*/
|
static void requestModuleActive(bit_t state) {
|
||||||
|
ostime_t const ticks = hal_setModuleActive(state);
|
||||||
|
|
||||||
|
if (ticks)
|
||||||
|
hal_waitUntil(os_getTime() + ticks);;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void writeOpmode(u1_t mode) {
|
||||||
|
u1_t const maskedMode = mode & OPMODE_MASK;
|
||||||
|
if (maskedMode != OPMODE_SLEEP)
|
||||||
|
requestModuleActive(1);
|
||||||
|
writeReg(RegOpMode, mode);
|
||||||
|
if (maskedMode == OPMODE_SLEEP)
|
||||||
|
requestModuleActive(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void opmode (u1_t mode) {
|
static void opmode (u1_t mode) {
|
||||||
writeReg(RegOpMode, (readReg(RegOpMode) & ~OPMODE_MASK) | mode);
|
writeOpmode((readReg(RegOpMode) & ~OPMODE_MASK) | mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void opmodeLora() {
|
static void opmodeLora() {
|
||||||
@ -349,7 +341,7 @@ static void opmodeLora() {
|
|||||||
#ifdef CFG_sx1276_radio
|
#ifdef CFG_sx1276_radio
|
||||||
u |= 0x8; // TBD: sx1276 high freq
|
u |= 0x8; // TBD: sx1276 high freq
|
||||||
#endif
|
#endif
|
||||||
writeReg(RegOpMode, u);
|
writeOpmode(u);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void opmodeFSK() {
|
static void opmodeFSK() {
|
||||||
@ -357,7 +349,7 @@ static void opmodeFSK() {
|
|||||||
#ifdef CFG_sx1276_radio
|
#ifdef CFG_sx1276_radio
|
||||||
u |= 0x8; // TBD: sx1276 high freq
|
u |= 0x8; // TBD: sx1276 high freq
|
||||||
#endif
|
#endif
|
||||||
writeReg(RegOpMode, u);
|
writeOpmode(u);
|
||||||
}
|
}
|
||||||
|
|
||||||
// configure LoRa modem (cfg1, cfg2)
|
// configure LoRa modem (cfg1, cfg2)
|
||||||
@ -483,7 +475,7 @@ static void configPower () {
|
|||||||
|
|
||||||
static void txfsk () {
|
static void txfsk () {
|
||||||
// select FSK modem (from sleep mode)
|
// select FSK modem (from sleep mode)
|
||||||
writeReg(RegOpMode, 0x10); // FSK, BT=0.5
|
writeOpmode(0x10); // FSK, BT=0.5
|
||||||
ASSERT(readReg(RegOpMode) == 0x10);
|
ASSERT(readReg(RegOpMode) == 0x10);
|
||||||
// enter standby mode (required for FIFO loading))
|
// enter standby mode (required for FIFO loading))
|
||||||
opmode(OPMODE_STANDBY);
|
opmode(OPMODE_STANDBY);
|
||||||
@ -765,6 +757,8 @@ static void startrx (u1_t rxmode) {
|
|||||||
int radio_init () {
|
int radio_init () {
|
||||||
hal_disableIRQs();
|
hal_disableIRQs();
|
||||||
|
|
||||||
|
requestModuleActive(1);
|
||||||
|
|
||||||
// manually reset radio
|
// manually reset radio
|
||||||
#ifdef CFG_sx1276_radio
|
#ifdef CFG_sx1276_radio
|
||||||
hal_pin_rst(0); // drive RST pin low
|
hal_pin_rst(0); // drive RST pin low
|
||||||
@ -788,6 +782,10 @@ int radio_init () {
|
|||||||
#else
|
#else
|
||||||
#error Missing CFG_sx1272_radio/CFG_sx1276_radio
|
#error Missing CFG_sx1272_radio/CFG_sx1276_radio
|
||||||
#endif
|
#endif
|
||||||
|
// set the tcxo input, if needed
|
||||||
|
if (hal_queryUsingTcxo())
|
||||||
|
writeReg(RegTcxo, readReg(RegTcxo) | RegTcxo_TcxoInputOn);
|
||||||
|
|
||||||
// seed 15-byte randomness via noise rssi
|
// seed 15-byte randomness via noise rssi
|
||||||
rxlora(RXMODE_RSSI);
|
rxlora(RXMODE_RSSI);
|
||||||
while( (readReg(RegOpMode) & OPMODE_MASK) != OPMODE_RX ); // continuous rx
|
while( (readReg(RegOpMode) & OPMODE_MASK) != OPMODE_RX ); // continuous rx
|
||||||
|
Loading…
Reference in New Issue
Block a user