first commit
This commit is contained in:
commit
31950351c0
5
.gitignore
vendored
Executable file
5
.gitignore
vendored
Executable file
@ -0,0 +1,5 @@
|
||||
.pio
|
||||
.vscode/.browse.c_cpp.db*
|
||||
.vscode/c_cpp_properties.json
|
||||
.vscode/launch.json
|
||||
.vscode/ipch
|
10
.vscode/extensions.json
vendored
Executable file
10
.vscode/extensions.json
vendored
Executable file
@ -0,0 +1,10 @@
|
||||
{
|
||||
// See http://go.microsoft.com/fwlink/?LinkId=827846
|
||||
// for the documentation about the extensions.json format
|
||||
"recommendations": [
|
||||
"platformio.platformio-ide"
|
||||
],
|
||||
"unwantedRecommendations": [
|
||||
"ms-vscode.cpptools-extension-pack"
|
||||
]
|
||||
}
|
6
.vscode/settings.json
vendored
Normal file
6
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"files.associations": {
|
||||
"stm32l0xx_hal.h": "c",
|
||||
"lmic.h": "c"
|
||||
}
|
||||
}
|
39
include/README
Executable file
39
include/README
Executable file
@ -0,0 +1,39 @@
|
||||
|
||||
This directory is intended for project header files.
|
||||
|
||||
A header file is a file containing C declarations and macro definitions
|
||||
to be shared between several project source files. You request the use of a
|
||||
header file in your project source file (C, C++, etc) located in `src` folder
|
||||
by including it, with the C preprocessing directive `#include'.
|
||||
|
||||
```src/main.c
|
||||
|
||||
#include "header.h"
|
||||
|
||||
int main (void)
|
||||
{
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
Including a header file produces the same results as copying the header file
|
||||
into each source file that needs it. Such copying would be time-consuming
|
||||
and error-prone. With a header file, the related declarations appear
|
||||
in only one place. If they need to be changed, they can be changed in one
|
||||
place, and programs that include the header file will automatically use the
|
||||
new version when next recompiled. The header file eliminates the labor of
|
||||
finding and changing all the copies as well as the risk that a failure to
|
||||
find one copy will result in inconsistencies within a program.
|
||||
|
||||
In C, the usual convention is to give header files names that end with `.h'.
|
||||
It is most portable to use only letters, digits, dashes, and underscores in
|
||||
header file names, and at most one dot.
|
||||
|
||||
Read more about using header files in official GCC documentation:
|
||||
|
||||
* Include Syntax
|
||||
* Include Operation
|
||||
* Once-Only Headers
|
||||
* Computed Includes
|
||||
|
||||
https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html
|
64
include/debug.h
Normal file
64
include/debug.h
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2016 IBM Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the <organization> nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "oslmic.h"
|
||||
// intialize debug library
|
||||
void debug_init (void);
|
||||
|
||||
// set LED state
|
||||
void debug_led (int val);
|
||||
|
||||
// write character to USART
|
||||
void debug_char (char c);
|
||||
|
||||
// write byte as two hex digits to USART
|
||||
void debug_hex (u1_t b);
|
||||
|
||||
// write buffer as hex dump to USART
|
||||
void debug_buf (const u1_t* buf, int len);
|
||||
|
||||
// write 32-bit integer as eight hex digits to USART
|
||||
void debug_uint (u4_t v);
|
||||
|
||||
// write 32-bit integer as signed decimal digits to USART
|
||||
void debug_int (s4_t v);
|
||||
|
||||
// write nul-terminated string to USART
|
||||
void debug_str (const char* str);
|
||||
|
||||
// write LMiC event name to USART
|
||||
void debug_event (int ev);
|
||||
|
||||
// write label and 32-bit value as hex to USART
|
||||
void debug_val (const char* label, u4_t val);
|
||||
|
||||
// write label and 32-bit value as signed decimal to USART
|
||||
void debug_valdec (const char* label, s4_t val);
|
||||
|
||||
// convert integer 'val' to ASCII string (bin/oct/dec/hex/base36)
|
||||
// store string at 'buf', return number of characters written
|
||||
int debug_fmt (char* buf, int max, s4_t val, int base, int width, char pad);
|
104
include/hal.h
Normal file
104
include/hal.h
Normal file
@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2016 IBM Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the <organization> nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _hal_hpp_
|
||||
#define _hal_hpp_
|
||||
|
||||
#include "oslmic.h"
|
||||
|
||||
/*
|
||||
* initialize hardware (IO, SPI, TIMER, IRQ).
|
||||
*/
|
||||
void hal_init (void);
|
||||
|
||||
/*
|
||||
* drive radio NSS pin (0=low, 1=high).
|
||||
*/
|
||||
void hal_pin_nss (u1_t val);
|
||||
|
||||
/*
|
||||
* drive radio RX/TX pins (0=rx, 1=tx).
|
||||
*/
|
||||
void hal_pin_rxtx (u1_t val);
|
||||
|
||||
/*
|
||||
* control radio RST pin (0=low, 1=high, 2=floating)
|
||||
*/
|
||||
void hal_pin_rst (u1_t val);
|
||||
|
||||
/*
|
||||
* perform 8-bit SPI transaction with radio.
|
||||
* - write given byte 'outval'
|
||||
* - read byte and return value
|
||||
*/
|
||||
u1_t hal_spi (u1_t outval);
|
||||
|
||||
/*
|
||||
* disable all CPU interrupts.
|
||||
* - might be invoked nested
|
||||
* - will be followed by matching call to hal_enableIRQs()
|
||||
*/
|
||||
void hal_disableIRQs (void);
|
||||
|
||||
/*
|
||||
* enable CPU interrupts.
|
||||
*/
|
||||
void hal_enableIRQs (void);
|
||||
|
||||
/*
|
||||
* put system and CPU in low-power mode, sleep until interrupt.
|
||||
*/
|
||||
void hal_sleep (void);
|
||||
|
||||
/*
|
||||
* return 32-bit system time in ticks.
|
||||
*/
|
||||
u4_t hal_ticks (void);
|
||||
|
||||
/*
|
||||
* busy-wait until specified timestamp (in ticks) is reached.
|
||||
*/
|
||||
void hal_waitUntil (u4_t time);
|
||||
|
||||
/*
|
||||
* check and rewind timer for target time.
|
||||
* - return 1 if target time is close
|
||||
* - otherwise rewind timer for target time or full period and return 0
|
||||
*/
|
||||
u1_t hal_checkTimer (u4_t targettime);
|
||||
|
||||
/*
|
||||
* perform fatal failure action.
|
||||
* - called by assertions
|
||||
* - action could be HALT or reboot
|
||||
*/
|
||||
void hal_failed (void);
|
||||
|
||||
|
||||
void LmicTimer_IRQHandler ();
|
||||
|
||||
#endif // _hal_hpp_
|
290
include/lmic.h
Normal file
290
include/lmic.h
Normal file
@ -0,0 +1,290 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2016 IBM Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the <organization> nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
//! @file
|
||||
//! @brief LMIC API
|
||||
|
||||
#ifndef _lmic_h_
|
||||
#define _lmic_h_
|
||||
|
||||
#include "oslmic.h"
|
||||
#include "lorabase.h"
|
||||
|
||||
// LMIC version
|
||||
#define LMIC_VERSION_MAJOR 1
|
||||
#define LMIC_VERSION_MINOR 6
|
||||
#define LMIC_VERSION_BUILD 1468577746
|
||||
|
||||
//! Only For Antenna Tuning Tests !
|
||||
//#define CFG_TxContinuousMode 1
|
||||
|
||||
enum { MAX_FRAME_LEN = 64 }; //!< 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
|
||||
LINK_CHECK_OFF =-128 }; // link check disabled
|
||||
|
||||
enum { TIME_RESYNC = 6*128 }; // secs
|
||||
enum { TXRX_GUARD_ms = 6000 }; // msecs - don't start TX-RX transaction before beacon
|
||||
enum { JOIN_GUARD_ms = 9000 }; // msecs - don't start Join Req/Acc transaction before beacon
|
||||
enum { TXRX_BCNEXT_secs = 2 }; // secs - earliest start after beacon time
|
||||
enum { RETRY_PERIOD_secs = 3 }; // secs - random period for retrying a confirmed send
|
||||
|
||||
#if defined(CFG_eu868) // EU868 spectrum ====================================================
|
||||
|
||||
enum { MAX_CHANNELS = 16 }; //!< Max supported channels
|
||||
enum { MAX_BANDS = 4 };
|
||||
|
||||
enum { LIMIT_CHANNELS = (1<<4) }; // EU868 will never have more channels
|
||||
//! \internal
|
||||
struct band_t {
|
||||
u2_t txcap; // duty cycle limitation: 1/txcap
|
||||
s1_t txpow; // maximum TX power
|
||||
u1_t lastchnl; // last used channel
|
||||
ostime_t avail; // channel is blocked until this time
|
||||
};
|
||||
TYPEDEF_xref2band_t; //!< \internal
|
||||
|
||||
#elif defined(CFG_us915) // US915 spectrum =================================================
|
||||
|
||||
enum { MAX_XCHANNELS = 2 }; // extra channels in RAM, channels 0-71 are immutable
|
||||
enum { MAX_TXPOW_125kHz = 30 };
|
||||
|
||||
#endif // ==========================================================================
|
||||
|
||||
// Keep in sync with evdefs.hpp::drChange
|
||||
enum { DRCHG_SET, DRCHG_NOJACC, DRCHG_NOACK, DRCHG_NOADRACK, DRCHG_NWKCMD };
|
||||
enum { KEEP_TXPOW = -128 };
|
||||
|
||||
|
||||
//! \internal
|
||||
struct rxsched_t {
|
||||
u1_t dr;
|
||||
u1_t intvExp; // 0..7
|
||||
u1_t slot; // runs from 0 to 128
|
||||
u1_t rxsyms;
|
||||
ostime_t rxbase;
|
||||
ostime_t rxtime; // start of next spot
|
||||
u4_t freq;
|
||||
};
|
||||
TYPEDEF_xref2rxsched_t; //!< \internal
|
||||
|
||||
|
||||
//! Parsing and tracking states of beacons.
|
||||
enum { BCN_NONE = 0x00, //!< No beacon received
|
||||
BCN_PARTIAL = 0x01, //!< Only first (common) part could be decoded (info,lat,lon invalid/previous)
|
||||
BCN_FULL = 0x02, //!< Full beacon decoded
|
||||
BCN_NODRIFT = 0x04, //!< No drift value measured yet
|
||||
BCN_NODDIFF = 0x08 }; //!< No differential drift measured yet
|
||||
//! Information about the last and previous beacons.
|
||||
struct bcninfo_t {
|
||||
ostime_t txtime; //!< Time when the beacon was sent
|
||||
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)
|
||||
};
|
||||
|
||||
// purpose of receive window - lmic_t.rxState
|
||||
enum { RADIO_RST=0, RADIO_TX=1, RADIO_RX=2, RADIO_RXON=3 };
|
||||
// Netid values / lmic_t.netid
|
||||
enum { NETID_NONE=(int)~0U, NETID_MASK=(int)0xFFFFFF };
|
||||
// MAC operation modes (lmic_t.opmode).
|
||||
enum { OP_NONE = 0x0000,
|
||||
OP_SCAN = 0x0001, // radio scan to find a beacon
|
||||
OP_TRACK = 0x0002, // track my networks beacon (netid)
|
||||
OP_JOINING = 0x0004, // device joining in progress (blocks other activities)
|
||||
OP_TXDATA = 0x0008, // TX user data (buffered in pendTxData)
|
||||
OP_POLL = 0x0010, // send empty UP frame to ACK confirmed DN/fetch more DN data
|
||||
OP_REJOIN = 0x0020, // occasionally send JOIN REQUEST
|
||||
OP_SHUTDOWN = 0x0040, // prevent MAC from doing anything
|
||||
OP_TXRXPEND = 0x0080, // TX/RX transaction pending
|
||||
OP_RNDTX = 0x0100, // prevent TX lining up after a beacon
|
||||
OP_PINGINI = 0x0200, // pingable is initialized and scheduling active
|
||||
OP_PINGABLE = 0x0400, // we're pingable
|
||||
OP_NEXTCHNL = 0x0800, // find a new channel
|
||||
OP_LINKDEAD = 0x1000, // link was reported as dead
|
||||
OP_TESTMODE = 0x2000, // developer test mode
|
||||
};
|
||||
// TX-RX transaction flags - report back to user
|
||||
enum { TXRX_ACK = 0x80, // confirmed UP frame was acked
|
||||
TXRX_NACK = 0x40, // confirmed UP frame was not acked
|
||||
TXRX_NOPORT = 0x20, // set if a frame with a port was RXed, clr if no frame/no port
|
||||
TXRX_PORT = 0x10, // set if a frame with a port was RXed, LMIC.frame[LMIC.dataBeg-1] => port
|
||||
TXRX_DNW1 = 0x01, // received in 1st DN slot
|
||||
TXRX_DNW2 = 0x02, // received in 2dn DN slot
|
||||
TXRX_PING = 0x04 }; // received in a scheduled RX slot
|
||||
// Event types for event callback
|
||||
enum _ev_t { EV_SCAN_TIMEOUT=1, EV_BEACON_FOUND,
|
||||
EV_BEACON_MISSED, EV_BEACON_TRACKED, EV_JOINING,
|
||||
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 };
|
||||
typedef enum _ev_t ev_t;
|
||||
|
||||
|
||||
struct lmic_t {
|
||||
// Radio settings TX/RX (also accessed by HAL)
|
||||
ostime_t txend;
|
||||
ostime_t rxtime;
|
||||
u4_t freq;
|
||||
s1_t rssi;
|
||||
s1_t snr;
|
||||
rps_t rps;
|
||||
u1_t rxsyms;
|
||||
u1_t dndr;
|
||||
s1_t txpow; // dBm
|
||||
|
||||
osjob_t osjob;
|
||||
|
||||
// Channel scheduling
|
||||
#if defined(CFG_eu868)
|
||||
band_t bands[MAX_BANDS];
|
||||
u4_t channelFreq[MAX_CHANNELS];
|
||||
u2_t channelDrMap[MAX_CHANNELS];
|
||||
u2_t channelMap;
|
||||
#elif defined(CFG_us915)
|
||||
u4_t xchFreq[MAX_XCHANNELS]; // extra channel frequencies (if device is behind a repeater)
|
||||
u2_t xchDrMap[MAX_XCHANNELS]; // extra channel datarate ranges ---XXX: ditto
|
||||
u2_t channelMap[(72+MAX_XCHANNELS+15)/16]; // enabled bits
|
||||
u2_t chRnd; // channel randomizer
|
||||
#endif
|
||||
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
|
||||
s2_t drift; // last measured drift
|
||||
s2_t lastDriftDiff;
|
||||
s2_t maxDriftDiff;
|
||||
|
||||
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;
|
||||
|
||||
u1_t dnConf; // dn frame confirm pending: LORA::FCT_ACK or 0
|
||||
s1_t adrAckReq; // counter until we reset data rate (0=off)
|
||||
u1_t adrChanged;
|
||||
|
||||
u1_t rxDelay; // Rx delay after TX
|
||||
|
||||
u1_t margin;
|
||||
bit_t ladrAns; // link adr adapt answer pending
|
||||
bit_t devsAns; // device status answer pending
|
||||
u1_t adrEnabled;
|
||||
u1_t moreData; // NWK has more data pending
|
||||
bit_t dutyCapAns; // have to ACK duty cycle settings
|
||||
u1_t snchAns; // answer set new channel
|
||||
// 2nd RX window (after up stream)
|
||||
u1_t dn2Dr;
|
||||
u4_t dn2Freq;
|
||||
u1_t dn2Ans; // 0=no answer pend, 0x80+ACKs
|
||||
|
||||
// Class B state
|
||||
u1_t missedBcns; // unable to track last N beacons
|
||||
u1_t bcninfoTries; // how often to try (scan mode only)
|
||||
u1_t pingSetAns; // answer set cmd and ACK bits
|
||||
rxsched_t ping; // pingable setup
|
||||
|
||||
// Public part of MAC state
|
||||
u1_t txCnt;
|
||||
u1_t txrxFlags; // transaction flags (TX-RX combo)
|
||||
u1_t dataBeg; // 0 or start of data (dataBeg-1 is port)
|
||||
u1_t dataLen; // 0 no data or zero length data, >0 byte count of data
|
||||
u1_t frame[MAX_LEN_FRAME];
|
||||
|
||||
u1_t bcnChnl;
|
||||
u1_t bcnRxsyms; //
|
||||
ostime_t bcnRxtime;
|
||||
bcninfo_t bcninfo; // Last received beacon info
|
||||
|
||||
u1_t noRXIQinversion;
|
||||
};
|
||||
//! \var struct lmic_t LMIC
|
||||
//! The state of LMIC MAC layer is encapsulated in this variable.
|
||||
DECLARE_LMIC; //!< \internal
|
||||
|
||||
//! Construct a bit map of allowed datarates from drlo to drhi (both included).
|
||||
#define DR_RANGE_MAP(drlo,drhi) (((u2_t)0xFFFF<<(drlo)) & ((u2_t)0xFFFF>>(15-(drhi))))
|
||||
#if defined(CFG_eu868)
|
||||
enum { BAND_MILLI=0, BAND_CENTI=1, BAND_DECI=2, BAND_AUX=3 };
|
||||
bit_t LMIC_setupBand (u1_t bandidx, s1_t txpow, u2_t txcap);
|
||||
#endif
|
||||
bit_t LMIC_setupChannel (u1_t channel, u4_t freq, u2_t drmap, s1_t band);
|
||||
void LMIC_disableChannel (u1_t channel);
|
||||
|
||||
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)
|
||||
bit_t LMIC_startJoining (void);
|
||||
|
||||
void LMIC_shutdown (void);
|
||||
void LMIC_init (void);
|
||||
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);
|
||||
void LMIC_sendAlive (void);
|
||||
|
||||
bit_t LMIC_enableTracking (u1_t tryBcnInfo);
|
||||
void LMIC_disableTracking (void);
|
||||
|
||||
void LMIC_stopPingable (void);
|
||||
void LMIC_setPingable (u1_t intvExp);
|
||||
void LMIC_tryRejoin (void);
|
||||
|
||||
void LMIC_setSession (u4_t netid, devaddr_t devaddr, xref2u1_t nwkKey, xref2u1_t artKey);
|
||||
void LMIC_setLinkCheckMode (bit_t enabled);
|
||||
|
||||
|
||||
|
||||
// Special APIs - for development or testing
|
||||
// !!!See implementation for caveats!!!
|
||||
|
||||
#endif // _lmic_h_
|
400
include/lorabase.h
Normal file
400
include/lorabase.h
Normal file
@ -0,0 +1,400 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2016 IBM Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the <organization> nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _lorabase_h_
|
||||
#define _lorabase_h_
|
||||
|
||||
// ================================================================================
|
||||
// BEG: Keep in sync with lorabase.hpp
|
||||
//
|
||||
|
||||
enum _cr_t { CR_4_5=0, CR_4_6, CR_4_7, CR_4_8 };
|
||||
enum _sf_t { FSK=0, SF7, SF8, SF9, SF10, SF11, SF12, SFrfu };
|
||||
enum _bw_t { BW125=0, BW250, BW500, BWrfu };
|
||||
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)
|
||||
typedef u2_t rps_t;
|
||||
TYPEDEF_xref2rps_t;
|
||||
|
||||
enum { ILLEGAL_RPS = 0xFF };
|
||||
enum { DR_PAGE_EU868 = 0x00 };
|
||||
enum { DR_PAGE_US915 = 0x10 };
|
||||
|
||||
// Global maximum frame length
|
||||
enum { STD_PREAMBLE_LEN = 8 };
|
||||
enum { MAX_LEN_FRAME = 64 };
|
||||
enum { LEN_DEVNONCE = 2 };
|
||||
enum { LEN_ARTNONCE = 3 };
|
||||
enum { LEN_NETID = 3 };
|
||||
enum { DELAY_JACC1 = 5 }; // in secs
|
||||
enum { DELAY_DNW1 = 1 }; // in secs down window #1
|
||||
enum { DELAY_EXTDNW2 = 1 }; // in secs
|
||||
enum { DELAY_JACC2 = DELAY_JACC1+(int)DELAY_EXTDNW2 }; // in secs
|
||||
enum { DELAY_DNW2 = DELAY_DNW1 +(int)DELAY_EXTDNW2 }; // in secs down window #1
|
||||
enum { BCN_INTV_exp = 7 };
|
||||
enum { BCN_INTV_sec = 1<<BCN_INTV_exp };
|
||||
enum { BCN_INTV_ms = BCN_INTV_sec*1000L };
|
||||
enum { BCN_INTV_us = BCN_INTV_ms*1000L };
|
||||
enum { BCN_RESERVE_ms = 2120 }; // space reserved for beacon and NWK management
|
||||
enum { BCN_GUARD_ms = 3000 }; // end of beacon period to prevent interference with beacon
|
||||
enum { BCN_SLOT_SPAN_ms = 30 }; // 2^12 reception slots a this span
|
||||
enum { BCN_WINDOW_ms = BCN_INTV_ms-(int)BCN_GUARD_ms-(int)BCN_RESERVE_ms };
|
||||
enum { BCN_RESERVE_us = 2120000 };
|
||||
enum { BCN_GUARD_us = 3000000 };
|
||||
enum { BCN_SLOT_SPAN_us = 30000 };
|
||||
|
||||
#if defined(CFG_eu868) // ==============================================
|
||||
|
||||
enum _dr_eu868_t { DR_SF12=0, DR_SF11, DR_SF10, DR_SF9, DR_SF8, DR_SF7, DR_SF7B, DR_FSK, DR_NONE };
|
||||
enum { DR_DFLTMIN = DR_SF7 };
|
||||
enum { DR_PAGE = DR_PAGE_EU868 };
|
||||
|
||||
// Default frequency plan for EU 868MHz ISM band
|
||||
// Bands:
|
||||
// g1 : 1% 14dBm
|
||||
// g2 : 0.1% 14dBm
|
||||
// g3 : 10% 27dBm
|
||||
// freq band datarates
|
||||
enum { EU868_F1 = 868100000, // g1 SF7-12
|
||||
EU868_F2 = 868300000, // g1 SF7-12 FSK SF7/250
|
||||
EU868_F3 = 868500000, // g1 SF7-12
|
||||
EU868_F4 = 868850000, // g2 SF7-12
|
||||
EU868_F5 = 869050000, // g2 SF7-12
|
||||
EU868_F6 = 869525000, // g3 SF7-12
|
||||
EU868_J4 = 864100000, // g2 SF7-12 used during join
|
||||
EU868_J5 = 864300000, // g2 SF7-12 ditto
|
||||
EU868_J6 = 864500000, // g2 SF7-12 ditto
|
||||
};
|
||||
enum { EU868_FREQ_MIN = 863000000,
|
||||
EU868_FREQ_MAX = 870000000 };
|
||||
|
||||
enum { CHNL_PING = 5 };
|
||||
enum { FREQ_PING = EU868_F6 }; // default ping freq
|
||||
enum { DR_PING = DR_SF9 }; // default ping DR
|
||||
enum { CHNL_DNW2 = 5 };
|
||||
enum { FREQ_DNW2 = EU868_F6 };
|
||||
enum { DR_DNW2 = DR_SF12 };
|
||||
enum { CHNL_BCN = 5 };
|
||||
enum { FREQ_BCN = EU868_F6 };
|
||||
enum { DR_BCN = DR_SF9 };
|
||||
enum { AIRTIME_BCN = 144384 }; // micros
|
||||
|
||||
enum {
|
||||
// Beacon frame format EU SF9
|
||||
OFF_BCN_NETID = 0,
|
||||
OFF_BCN_TIME = 3,
|
||||
OFF_BCN_CRC1 = 7,
|
||||
OFF_BCN_INFO = 8,
|
||||
OFF_BCN_LAT = 9,
|
||||
OFF_BCN_LON = 12,
|
||||
OFF_BCN_CRC2 = 15,
|
||||
LEN_BCN = 17
|
||||
};
|
||||
|
||||
#elif defined(CFG_us915) // =========================================
|
||||
|
||||
enum _dr_us915_t { DR_SF10=0, DR_SF9, DR_SF8, DR_SF7, DR_SF8C, DR_NONE,
|
||||
// Devices behind a router:
|
||||
DR_SF12CR=8, DR_SF11CR, DR_SF10CR, DR_SF9CR, DR_SF8CR, DR_SF7CR };
|
||||
enum { DR_DFLTMIN = DR_SF8C };
|
||||
enum { DR_PAGE = DR_PAGE_US915 };
|
||||
|
||||
// Default frequency plan for US 915MHz
|
||||
enum { US915_125kHz_UPFBASE = 902300000,
|
||||
US915_125kHz_UPFSTEP = 200000,
|
||||
US915_500kHz_UPFBASE = 903000000,
|
||||
US915_500kHz_UPFSTEP = 1600000,
|
||||
US915_500kHz_DNFBASE = 923300000,
|
||||
US915_500kHz_DNFSTEP = 600000
|
||||
};
|
||||
enum { US915_FREQ_MIN = 902000000,
|
||||
US915_FREQ_MAX = 928000000 };
|
||||
|
||||
enum { CHNL_PING = 0 }; // used only for default init of state (follows beacon - rotating)
|
||||
enum { FREQ_PING = US915_500kHz_DNFBASE + CHNL_PING*US915_500kHz_DNFSTEP }; // default ping freq
|
||||
enum { DR_PING = DR_SF10CR }; // default ping DR
|
||||
enum { CHNL_DNW2 = 0 };
|
||||
enum { FREQ_DNW2 = US915_500kHz_DNFBASE + CHNL_DNW2*US915_500kHz_DNFSTEP };
|
||||
enum { DR_DNW2 = DR_SF12CR };
|
||||
enum { CHNL_BCN = 0 }; // used only for default init of state (rotating beacon scheme)
|
||||
enum { DR_BCN = DR_SF10CR };
|
||||
enum { AIRTIME_BCN = 72192 }; // micros
|
||||
|
||||
enum {
|
||||
// Beacon frame format US SF10
|
||||
OFF_BCN_NETID = 0,
|
||||
OFF_BCN_TIME = 3,
|
||||
OFF_BCN_CRC1 = 7,
|
||||
OFF_BCN_INFO = 9,
|
||||
OFF_BCN_LAT = 10,
|
||||
OFF_BCN_LON = 13,
|
||||
OFF_BCN_RFU1 = 16,
|
||||
OFF_BCN_CRC2 = 17,
|
||||
LEN_BCN = 19
|
||||
};
|
||||
|
||||
#endif // ===================================================
|
||||
|
||||
enum {
|
||||
// Join Request frame format
|
||||
OFF_JR_HDR = 0,
|
||||
OFF_JR_ARTEUI = 1,
|
||||
OFF_JR_DEVEUI = 9,
|
||||
OFF_JR_DEVNONCE = 17,
|
||||
OFF_JR_MIC = 19,
|
||||
LEN_JR = 23
|
||||
};
|
||||
enum {
|
||||
// Join Accept frame format
|
||||
OFF_JA_HDR = 0,
|
||||
OFF_JA_ARTNONCE = 1,
|
||||
OFF_JA_NETID = 4,
|
||||
OFF_JA_DEVADDR = 7,
|
||||
OFF_JA_RFU = 11,
|
||||
OFF_JA_DLSET = 11,
|
||||
OFF_JA_RXDLY = 12,
|
||||
OFF_CFLIST = 13,
|
||||
LEN_JA = 17,
|
||||
LEN_JAEXT = 17+16
|
||||
};
|
||||
enum {
|
||||
// Data frame format
|
||||
OFF_DAT_HDR = 0,
|
||||
OFF_DAT_ADDR = 1,
|
||||
OFF_DAT_FCT = 5,
|
||||
OFF_DAT_SEQNO = 6,
|
||||
OFF_DAT_OPTS = 8,
|
||||
};
|
||||
enum { MAX_LEN_PAYLOAD = MAX_LEN_FRAME-(int)OFF_DAT_OPTS-4 };
|
||||
enum {
|
||||
// Bitfields in frame format octet
|
||||
HDR_FTYPE = 0xE0,
|
||||
HDR_RFU = 0x1C,
|
||||
HDR_MAJOR = 0x03
|
||||
};
|
||||
enum { HDR_FTYPE_DNFLAG = 0x20 }; // flags DN frame except for HDR_FTYPE_PROP
|
||||
enum {
|
||||
// Values of frame type bit field
|
||||
HDR_FTYPE_JREQ = 0x00,
|
||||
HDR_FTYPE_JACC = 0x20,
|
||||
HDR_FTYPE_DAUP = 0x40, // data (unconfirmed) up
|
||||
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 {
|
||||
HDR_MAJOR_V1 = 0x00,
|
||||
};
|
||||
enum {
|
||||
// Bitfields in frame control octet
|
||||
FCT_ADREN = 0x80,
|
||||
FCT_ADRARQ = 0x40,
|
||||
FCT_ACK = 0x20,
|
||||
FCT_MORE = 0x10, // also in DN direction: Class B indicator
|
||||
FCT_OPTLEN = 0x0F,
|
||||
};
|
||||
enum {
|
||||
// In UP direction: signals class B enabled
|
||||
FCT_CLASSB = FCT_MORE
|
||||
};
|
||||
enum {
|
||||
NWKID_MASK = (int)0xFE000000,
|
||||
NWKID_BITS = 7
|
||||
};
|
||||
|
||||
// MAC uplink commands downwlink too
|
||||
enum {
|
||||
// Class A
|
||||
MCMD_LCHK_REQ = 0x02, // - link check request : -
|
||||
MCMD_LADR_ANS = 0x03, // - link ADR answer : u1:7-3:RFU, 3/2/1: pow/DR/Ch ACK
|
||||
MCMD_DCAP_ANS = 0x04, // - duty cycle answer : -
|
||||
MCMD_DN2P_ANS = 0x05, // - 2nd DN slot status : u1:7-2:RFU 1/0:datarate/channel ack
|
||||
MCMD_DEVS_ANS = 0x06, // - device status ans : u1:battery 0,1-254,255=?, u1:7-6:RFU,5-0:margin(-32..31)
|
||||
MCMD_SNCH_ANS = 0x07, // - set new channel : u1: 7-2=RFU, 1/0:DR/freq ACK
|
||||
// Class B
|
||||
MCMD_PING_IND = 0x10, // - pingability indic : u1: 7=RFU, 6-4:interval, 3-0:datarate
|
||||
MCMD_PING_ANS = 0x11, // - ack ping freq : u1: 7-1:RFU, 0:freq ok
|
||||
MCMD_BCNI_REQ = 0x12, // - next beacon start : -
|
||||
};
|
||||
|
||||
// MAC downlink commands
|
||||
enum {
|
||||
// Class A
|
||||
MCMD_LCHK_ANS = 0x02, // link check answer : u1:margin 0-254,255=unknown margin / u1:gwcnt
|
||||
MCMD_LADR_REQ = 0x03, // link ADR request : u1:DR/TXPow, u2:chmask, u1:chpage/repeat
|
||||
MCMD_DCAP_REQ = 0x04, // duty cycle cap : u1:255 dead [7-4]:RFU, [3-0]:cap 2^-k
|
||||
MCMD_DN2P_SET = 0x05, // 2nd DN window param: u1:7-4:RFU/3-0:datarate, u3:freq
|
||||
MCMD_DEVS_REQ = 0x06, // device status req : -
|
||||
MCMD_SNCH_REQ = 0x07, // set new channel : u1:chidx, u3:freq, u1:DRrange
|
||||
// Class B
|
||||
MCMD_PING_SET = 0x11, // set ping freq : u3: freq
|
||||
MCMD_BCNI_ANS = 0x12, // next beacon start : u2: delay(in TUNIT millis), u1:channel
|
||||
};
|
||||
|
||||
enum {
|
||||
MCMD_BCNI_TUNIT = 30 // time unit of delay value in millis
|
||||
};
|
||||
enum {
|
||||
MCMD_LADR_ANS_RFU = 0xF8, // RFU bits
|
||||
MCMD_LADR_ANS_POWACK = 0x04, // 0=not supported power level
|
||||
MCMD_LADR_ANS_DRACK = 0x02, // 0=unknown data rate
|
||||
MCMD_LADR_ANS_CHACK = 0x01, // 0=unknown channel enabled
|
||||
};
|
||||
enum {
|
||||
MCMD_DN2P_ANS_RFU = 0xFC, // RFU bits
|
||||
MCMD_DN2P_ANS_DRACK = 0x02, // 0=unknown data rate
|
||||
MCMD_DN2P_ANS_CHACK = 0x01, // 0=unknown channel enabled
|
||||
};
|
||||
enum {
|
||||
MCMD_SNCH_ANS_RFU = 0xFC, // RFU bits
|
||||
MCMD_SNCH_ANS_DRACK = 0x02, // 0=unknown data rate
|
||||
MCMD_SNCH_ANS_FQACK = 0x01, // 0=rejected channel frequency
|
||||
};
|
||||
enum {
|
||||
MCMD_PING_ANS_RFU = 0xFE,
|
||||
MCMD_PING_ANS_FQACK = 0x01
|
||||
};
|
||||
|
||||
enum {
|
||||
MCMD_DEVS_EXT_POWER = 0x00, // external power supply
|
||||
MCMD_DEVS_BATT_MIN = 0x01, // min battery value
|
||||
MCMD_DEVS_BATT_MAX = 0xFE, // max battery value
|
||||
MCMD_DEVS_BATT_NOINFO = 0xFF, // unknown battery level
|
||||
};
|
||||
|
||||
// Bit fields byte#3 of MCMD_LADR_REQ payload
|
||||
enum {
|
||||
MCMD_LADR_CHP_125ON = 0x60, // special channel page enable, bits applied to 64..71
|
||||
MCMD_LADR_CHP_125OFF = 0x70, // ditto
|
||||
MCMD_LADR_N3RFU_MASK = 0x80,
|
||||
MCMD_LADR_CHPAGE_MASK = 0xF0,
|
||||
MCMD_LADR_REPEAT_MASK = 0x0F,
|
||||
MCMD_LADR_REPEAT_1 = 0x01,
|
||||
MCMD_LADR_CHPAGE_1 = 0x10
|
||||
};
|
||||
// Bit fields byte#0 of MCMD_LADR_REQ payload
|
||||
enum {
|
||||
MCMD_LADR_DR_MASK = 0xF0,
|
||||
MCMD_LADR_POW_MASK = 0x0F,
|
||||
MCMD_LADR_DR_SHIFT = 4,
|
||||
MCMD_LADR_POW_SHIFT = 0,
|
||||
#if defined(CFG_eu868)
|
||||
MCMD_LADR_SF12 = DR_SF12<<4,
|
||||
MCMD_LADR_SF11 = DR_SF11<<4,
|
||||
MCMD_LADR_SF10 = DR_SF10<<4,
|
||||
MCMD_LADR_SF9 = DR_SF9 <<4,
|
||||
MCMD_LADR_SF8 = DR_SF8 <<4,
|
||||
MCMD_LADR_SF7 = DR_SF7 <<4,
|
||||
MCMD_LADR_SF7B = DR_SF7B<<4,
|
||||
MCMD_LADR_FSK = DR_FSK <<4,
|
||||
|
||||
MCMD_LADR_20dBm = 0,
|
||||
MCMD_LADR_14dBm = 1,
|
||||
MCMD_LADR_11dBm = 2,
|
||||
MCMD_LADR_8dBm = 3,
|
||||
MCMD_LADR_5dBm = 4,
|
||||
MCMD_LADR_2dBm = 5,
|
||||
#elif defined(CFG_us915)
|
||||
MCMD_LADR_SF10 = DR_SF10<<4,
|
||||
MCMD_LADR_SF9 = DR_SF9 <<4,
|
||||
MCMD_LADR_SF8 = DR_SF8 <<4,
|
||||
MCMD_LADR_SF7 = DR_SF7 <<4,
|
||||
MCMD_LADR_SF8C = DR_SF8C<<4,
|
||||
MCMD_LADR_SF12CR = DR_SF12CR<<4,
|
||||
MCMD_LADR_SF11CR = DR_SF11CR<<4,
|
||||
MCMD_LADR_SF10CR = DR_SF10CR<<4,
|
||||
MCMD_LADR_SF9CR = DR_SF9CR<<4,
|
||||
MCMD_LADR_SF8CR = DR_SF8CR<<4,
|
||||
MCMD_LADR_SF7CR = DR_SF7CR<<4,
|
||||
|
||||
MCMD_LADR_30dBm = 0,
|
||||
MCMD_LADR_28dBm = 1,
|
||||
MCMD_LADR_26dBm = 2,
|
||||
MCMD_LADR_24dBm = 3,
|
||||
MCMD_LADR_22dBm = 4,
|
||||
MCMD_LADR_20dBm = 5,
|
||||
MCMD_LADR_18dBm = 6,
|
||||
MCMD_LADR_16dBm = 7,
|
||||
MCMD_LADR_14dBm = 8,
|
||||
MCMD_LADR_12dBm = 9,
|
||||
MCMD_LADR_10dBm = 10
|
||||
#endif
|
||||
};
|
||||
|
||||
// Device address
|
||||
typedef u4_t devaddr_t;
|
||||
|
||||
// RX quality (device)
|
||||
enum { RSSI_OFF=64, SNR_SCALEUP=4 };
|
||||
|
||||
inline sf_t getSf (rps_t params) { return (sf_t)(params & 0x7); }
|
||||
inline rps_t setSf (rps_t params, sf_t sf) { return (rps_t)((params & ~0x7) | sf); }
|
||||
inline bw_t getBw (rps_t params) { return (bw_t)((params >> 3) & 0x3); }
|
||||
inline rps_t setBw (rps_t params, bw_t cr) { return (rps_t)((params & ~0x18) | (cr<<3)); }
|
||||
inline cr_t getCr (rps_t params) { return (cr_t)((params >> 5) & 0x3); }
|
||||
inline rps_t setCr (rps_t params, cr_t cr) { return (rps_t)((params & ~0x60) | (cr<<5)); }
|
||||
inline int getNocrc(rps_t params) { return ((params >> 7) & 0x1); }
|
||||
inline rps_t setNocrc(rps_t params, int nocrc) { return (rps_t)((params & ~0x80) | (nocrc<<7)); }
|
||||
inline int getIh (rps_t params) { return ((params >> 8) & 0xFF); }
|
||||
inline rps_t setIh (rps_t params, int ih) { return (rps_t)((params & ~0xFF00) | (ih<<8)); }
|
||||
inline rps_t makeRps (sf_t sf, bw_t bw, cr_t cr, int ih, int nocrc) {
|
||||
return sf | (bw<<3) | (cr<<5) | (nocrc?(1<<7):0) | ((ih&0xFF)<<8);
|
||||
}
|
||||
#define MAKERPS(sf,bw,cr,ih,nocrc) ((rps_t)((sf) | ((bw)<<3) | ((cr)<<5) | ((nocrc)?(1<<7):0) | ((ih&0xFF)<<8)))
|
||||
// Two frames with params r1/r2 would interfere on air: same SFx + BWx
|
||||
inline int sameSfBw(rps_t r1, rps_t r2) { return ((r1^r2)&0x1F) == 0; }
|
||||
|
||||
extern const u1_t _DR2RPS_CRC[];
|
||||
inline rps_t updr2rps (dr_t dr) { return (rps_t)_DR2RPS_CRC[dr+1]; }
|
||||
inline rps_t dndr2rps (dr_t dr) { return setNocrc(updr2rps(dr),1); }
|
||||
inline int isFasterDR (dr_t dr1, dr_t dr2) { return dr1 > dr2; }
|
||||
inline int isSlowerDR (dr_t dr1, dr_t dr2) { return dr1 < dr2; }
|
||||
inline dr_t incDR (dr_t dr) { return _DR2RPS_CRC[dr+2]==ILLEGAL_RPS ? dr : (dr_t)(dr+1); } // increase data rate
|
||||
inline dr_t decDR (dr_t dr) { return _DR2RPS_CRC[dr ]==ILLEGAL_RPS ? dr : (dr_t)(dr-1); } // decrease data rate
|
||||
inline dr_t assertDR (dr_t dr) { return _DR2RPS_CRC[dr+1]==ILLEGAL_RPS ? DR_DFLTMIN : dr; } // force into a valid DR
|
||||
inline bit_t validDR (dr_t dr) { return _DR2RPS_CRC[dr+1]!=ILLEGAL_RPS; } // in range
|
||||
inline dr_t lowerDR (dr_t dr, u1_t n) { while(n--){dr=decDR(dr);} return dr; } // decrease data rate by n steps
|
||||
|
||||
//
|
||||
// BEG: Keep in sync with lorabase.hpp
|
||||
// ================================================================================
|
||||
|
||||
|
||||
// Convert between dBm values and power codes (MCMD_LADR_XdBm)
|
||||
s1_t pow2dBm (u1_t mcmd_ladr_p1);
|
||||
// Calculate airtime
|
||||
ostime_t calcAirTime (rps_t rps, u1_t plen);
|
||||
// Sensitivity at given SF/BW
|
||||
int getSensitivity (rps_t rps);
|
||||
|
||||
|
||||
#endif // _lorabase_h_
|
88
include/main.h
Normal file
88
include/main.h
Normal file
@ -0,0 +1,88 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file : main.h
|
||||
* @brief : Header for main.c file.
|
||||
* This file contains the common defines of the application.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2023 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __MAIN_H
|
||||
#define __MAIN_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32l0xx_hal.h"
|
||||
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Includes */
|
||||
|
||||
/* USER CODE END Includes */
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN ET */
|
||||
TIM_HandleTypeDef htim2;
|
||||
|
||||
SPI_HandleTypeDef hspi1;
|
||||
|
||||
UART_HandleTypeDef huart1;
|
||||
UART_HandleTypeDef huart2;
|
||||
/* USER CODE END ET */
|
||||
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/* USER CODE BEGIN EC */
|
||||
|
||||
/* USER CODE END EC */
|
||||
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN EM */
|
||||
|
||||
/* USER CODE END EM */
|
||||
|
||||
/* Exported functions prototypes ---------------------------------------------*/
|
||||
void Error_Handler(void);
|
||||
|
||||
/* USER CODE BEGIN EFP */
|
||||
|
||||
/* USER CODE END EFP */
|
||||
|
||||
/* Private defines -----------------------------------------------------------*/
|
||||
#define LED_Pin GPIO_PIN_1
|
||||
#define LED_GPIO_Port GPIOA
|
||||
#define NSS_Pin GPIO_PIN_4
|
||||
#define NSS_GPIO_Port GPIOA
|
||||
#define RST_Pin GPIO_PIN_9
|
||||
#define RST_GPIO_Port GPIOA
|
||||
#define DIO0_Pin GPIO_PIN_10
|
||||
#define DIO0_GPIO_Port GPIOA
|
||||
#define DIO0_EXTI_IRQn EXTI4_15_IRQn
|
||||
#define DIO1_Pin GPIO_PIN_4
|
||||
#define DIO1_GPIO_Port GPIOB
|
||||
#define DIO1_EXTI_IRQn EXTI4_15_IRQn
|
||||
#define DIO2_Pin GPIO_PIN_5
|
||||
#define DIO2_GPIO_Port GPIOB
|
||||
#define DIO2_EXTI_IRQn EXTI4_15_IRQn
|
||||
/* USER CODE BEGIN Private defines */
|
||||
|
||||
/* USER CODE END Private defines */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __MAIN_H */
|
232
include/oslmic.h
Normal file
232
include/oslmic.h
Normal file
@ -0,0 +1,232 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2016 IBM Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the <organization> nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
//! \file
|
||||
#ifndef _oslmic_h_
|
||||
#define _oslmic_h_
|
||||
|
||||
// Dependencies required for the LoRa MAC in C to run.
|
||||
// These settings can be adapted to the underlying system.
|
||||
// You should not, however, change the lmic.[hc]
|
||||
|
||||
|
||||
|
||||
//================================================================================
|
||||
//================================================================================
|
||||
// Target platform as C library
|
||||
typedef unsigned char bit_t;
|
||||
typedef unsigned char u1_t;
|
||||
typedef signed char s1_t;
|
||||
typedef unsigned short u2_t;
|
||||
typedef short s2_t;
|
||||
typedef unsigned int u4_t;
|
||||
typedef int s4_t;
|
||||
typedef unsigned long long u8_t;
|
||||
typedef long long s8_t;
|
||||
typedef unsigned int uint;
|
||||
typedef const char* str_t;
|
||||
|
||||
#include <string.h>
|
||||
#include "hal.h"
|
||||
#define EV(a,b,c) /**/
|
||||
#define DO_DEVDB(field1,field2) /**/
|
||||
#if !defined(CFG_noassert)
|
||||
#define ASSERT(cond) if(!(cond)) hal_failed()
|
||||
#else
|
||||
#define ASSERT(cond) /**/
|
||||
#endif
|
||||
|
||||
#define os_clearMem(a,b) memset(a,0,b)
|
||||
#define os_copyMem(a,b,c) memcpy(a,b,c)
|
||||
|
||||
typedef struct osjob_t osjob_t;
|
||||
typedef struct band_t band_t;
|
||||
typedef struct chnldef_t chnldef_t;
|
||||
typedef struct rxsched_t rxsched_t;
|
||||
typedef struct bcninfo_t bcninfo_t;
|
||||
typedef const u1_t* xref2cu1_t;
|
||||
typedef u1_t* xref2u1_t;
|
||||
#define TYPEDEF_xref2rps_t typedef rps_t* xref2rps_t
|
||||
#define TYPEDEF_xref2rxsched_t typedef rxsched_t* xref2rxsched_t
|
||||
#define TYPEDEF_xref2chnldef_t typedef chnldef_t* xref2chnldef_t
|
||||
#define TYPEDEF_xref2band_t typedef band_t* xref2band_t
|
||||
#define TYPEDEF_xref2osjob_t typedef osjob_t* xref2osjob_t
|
||||
|
||||
#define SIZEOFEXPR(x) sizeof(x)
|
||||
|
||||
#define ON_LMIC_EVENT(ev) onEvent(ev)
|
||||
#define DECL_ON_LMIC_EVENT void onEvent(ev_t e)
|
||||
|
||||
extern u4_t AESAUX[];
|
||||
extern u4_t AESKEY[];
|
||||
#define AESkey ((u1_t*)AESKEY)
|
||||
#define AESaux ((u1_t*)AESAUX)
|
||||
#define FUNC_ADDR(func) (&(func))
|
||||
|
||||
u1_t radio_rand1 (void);
|
||||
#define os_getRndU1() radio_rand1()
|
||||
|
||||
#define DEFINE_LMIC struct lmic_t LMIC
|
||||
#define DECLARE_LMIC extern struct lmic_t LMIC
|
||||
|
||||
void radio_init (void);
|
||||
void radio_irq_handler (u1_t dio);
|
||||
void os_init (void);
|
||||
void os_runloop (void);
|
||||
|
||||
//================================================================================
|
||||
|
||||
|
||||
#ifndef RX_RAMPUP
|
||||
#define RX_RAMPUP (us2osticks(2000))
|
||||
#endif
|
||||
#ifndef TX_RAMPUP
|
||||
#define TX_RAMPUP (us2osticks(2000))
|
||||
#endif
|
||||
|
||||
#ifndef OSTICKS_PER_SEC
|
||||
#define OSTICKS_PER_SEC 32000
|
||||
#elif OSTICKS_PER_SEC < 10000 || OSTICKS_PER_SEC > 64516
|
||||
#error Illegal OSTICKS_PER_SEC - must be in range [10000:64516]. One tick must be 15.5us .. 100us long.
|
||||
#endif
|
||||
|
||||
typedef s4_t ostime_t;
|
||||
|
||||
#if !HAS_ostick_conv
|
||||
#define us2osticks(us) ((ostime_t)( ((s8_t)(us) * OSTICKS_PER_SEC) / 1000000))
|
||||
#define ms2osticks(ms) ((ostime_t)( ((s8_t)(ms) * OSTICKS_PER_SEC) / 1000))
|
||||
#define sec2osticks(sec) ((ostime_t)( (s8_t)(sec) * OSTICKS_PER_SEC))
|
||||
#define osticks2ms(os) ((s4_t)(((os)*(s8_t)1000 ) / OSTICKS_PER_SEC))
|
||||
#define osticks2us(os) ((s4_t)(((os)*(s8_t)1000000 ) / OSTICKS_PER_SEC))
|
||||
// Special versions
|
||||
#define us2osticksCeil(us) ((ostime_t)( ((s8_t)(us) * OSTICKS_PER_SEC + 999999) / 1000000))
|
||||
#define us2osticksRound(us) ((ostime_t)( ((s8_t)(us) * OSTICKS_PER_SEC + 500000) / 1000000))
|
||||
#define ms2osticksCeil(ms) ((ostime_t)( ((s8_t)(ms) * OSTICKS_PER_SEC + 999) / 1000))
|
||||
#define ms2osticksRound(ms) ((ostime_t)( ((s8_t)(ms) * OSTICKS_PER_SEC + 500) / 1000))
|
||||
#endif
|
||||
|
||||
|
||||
struct osjob_t; // fwd decl.
|
||||
typedef void (*osjobcb_t) (struct osjob_t*);
|
||||
struct osjob_t {
|
||||
struct osjob_t* next;
|
||||
ostime_t deadline;
|
||||
osjobcb_t func;
|
||||
};
|
||||
TYPEDEF_xref2osjob_t;
|
||||
|
||||
|
||||
#ifndef HAS_os_calls
|
||||
|
||||
#ifndef os_getDevKey
|
||||
void os_getDevKey (xref2u1_t buf);
|
||||
#endif
|
||||
#ifndef os_getArtEui
|
||||
void os_getArtEui (xref2u1_t buf);
|
||||
#endif
|
||||
#ifndef os_getDevEui
|
||||
void os_getDevEui (xref2u1_t buf);
|
||||
#endif
|
||||
#ifndef os_setCallback
|
||||
void os_setCallback (xref2osjob_t job, osjobcb_t cb);
|
||||
#endif
|
||||
#ifndef os_setTimedCallback
|
||||
void os_setTimedCallback (xref2osjob_t job, ostime_t time, osjobcb_t cb);
|
||||
#endif
|
||||
#ifndef os_clearCallback
|
||||
void os_clearCallback (xref2osjob_t job);
|
||||
#endif
|
||||
#ifndef os_getTime
|
||||
ostime_t os_getTime (void);
|
||||
#endif
|
||||
#ifndef os_getTimeSecs
|
||||
uint os_getTimeSecs (void);
|
||||
#endif
|
||||
#ifndef os_radio
|
||||
void os_radio (u1_t mode);
|
||||
#endif
|
||||
#ifndef os_getBattLevel
|
||||
u1_t os_getBattLevel (void);
|
||||
#endif
|
||||
|
||||
#ifndef os_rlsbf4
|
||||
//! Read 32-bit quantity from given pointer in little endian byte order.
|
||||
u4_t os_rlsbf4 (xref2cu1_t buf);
|
||||
#endif
|
||||
#ifndef os_wlsbf4
|
||||
//! Write 32-bit quntity into buffer in little endian byte order.
|
||||
void os_wlsbf4 (xref2u1_t buf, u4_t value);
|
||||
#endif
|
||||
#ifndef os_rmsbf4
|
||||
//! Read 32-bit quantity from given pointer in big endian byte order.
|
||||
u4_t os_rmsbf4 (xref2cu1_t buf);
|
||||
#endif
|
||||
#ifndef os_wmsbf4
|
||||
//! Write 32-bit quntity into buffer in big endian byte order.
|
||||
void os_wmsbf4 (xref2u1_t buf, u4_t value);
|
||||
#endif
|
||||
#ifndef os_rlsbf2
|
||||
//! Read 16-bit quantity from given pointer in little endian byte order.
|
||||
u2_t os_rlsbf2 (xref2cu1_t buf);
|
||||
#endif
|
||||
#ifndef os_wlsbf2
|
||||
//! Write 16-bit quntity into buffer in little endian byte order.
|
||||
void os_wlsbf2 (xref2u1_t buf, u2_t value);
|
||||
#endif
|
||||
|
||||
//! Get random number (default impl for u2_t).
|
||||
#ifndef os_getRndU2
|
||||
#define os_getRndU2() ((u2_t)((os_getRndU1()<<8)|os_getRndU1()))
|
||||
#endif
|
||||
#ifndef os_crc16
|
||||
u2_t os_crc16 (xref2u1_t d, uint len);
|
||||
#endif
|
||||
|
||||
#endif // !HAS_os_calls
|
||||
|
||||
// ======================================================================
|
||||
// AES support
|
||||
// !!Keep in sync with lorabase.hpp!!
|
||||
|
||||
#ifndef AES_ENC // if AES_ENC is defined as macro all other values must be too
|
||||
#define AES_ENC 0x00
|
||||
#define AES_DEC 0x01
|
||||
#define AES_MIC 0x02
|
||||
#define AES_CTR 0x04
|
||||
#define AES_MICNOAUX 0x08
|
||||
#endif
|
||||
#ifndef AESkey // if AESkey is defined as macro all other values must be too
|
||||
extern xref2u1_t AESkey;
|
||||
extern xref2u1_t AESaux;
|
||||
#endif
|
||||
#ifndef os_aes
|
||||
u4_t os_aes (u1_t mode, xref2u1_t buf, u2_t len);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#endif // _oslmic_h_
|
37
include/secconfig.h
Normal file
37
include/secconfig.h
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
secconfig.h
|
||||
configuration file with security information, not shared on the internet.
|
||||
|
||||
THIS IS AN EXAMPLE FILE, PLEASE RENAME TO secconfig.h
|
||||
|
||||
*/
|
||||
|
||||
#include "oslmic.h"
|
||||
|
||||
// When Using OTAA as activation type (default)
|
||||
|
||||
// This EUI must be in little-endian format, so least-significant-byte
|
||||
// first. When copying an EUI from ttnctl output, this means to reverse
|
||||
// the bytes. For TTN issued EUIs the last bytes should be 0xD5, 0xB3,
|
||||
// 0x70.
|
||||
static const u1_t APPEUI[8]={ 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x23, 0x45 };
|
||||
|
||||
// This should also be in little endian format, see above.
|
||||
static const u1_t DEVEUI[8]={ 0xD6, 0x33, 0x06, 0xD0, 0x7E, 0xD5, 0xB3, 0x70 };
|
||||
|
||||
// This key should be in big endian format (or, since it is not really a
|
||||
// number but a block of memory, endianness does not really apply). In
|
||||
// practice, a key taken from ttnctl can be copied as-is.
|
||||
// The key shown here is the semtech default key.
|
||||
static const u1_t APPKEY[16] = { 0x44, 0x99, 0xB4, 0xD3, 0xDB, 0x02, 0x07, 0xE3, 0xD6, 0x1A, 0x06, 0x6E, 0xCB, 0x26, 0xFC, 0xA2 };
|
||||
|
||||
|
||||
// When using ABP as activation type
|
||||
// set DISABLE_JOIN in config.h in the lmic library
|
||||
|
||||
// LoRaWAN NwkSKey, network session key (TTN msb first)
|
||||
static const u1_t NWKSKEY[16] = { 0xE0, 0x92, 0xEA, 0x35, 0x7C, 0x80, 0xA8, 0x26, 0xAE, 0xB0, 0x7C, 0xF3, 0xD7, 0xCA, 0xAD, 0x85 };
|
||||
// LoRaWAN AppSKey, application session key (TTN msn first)
|
||||
static const u1_t APPSKEY[16] = { 0xB2, 0xB5, 0xC8, 0xDF, 0x37, 0x3F, 0xFF, 0x37, 0x39, 0x86, 0xAD, 0x48, 0x51, 0x96, 0xDD, 0x01 };
|
||||
// LoRaWAN DevAddr, end-device address (TTN msb first)
|
||||
static const u4_t DEVADDR = 0x260B5215 ;
|
329
include/stm32l0xx_hal_conf.h
Normal file
329
include/stm32l0xx_hal_conf.h
Normal file
@ -0,0 +1,329 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32l0xx_hal_conf.h
|
||||
* @author MCD Application Team
|
||||
* @brief HAL configuration template file.
|
||||
* This file should be copied to the application folder and renamed
|
||||
* to stm32l0xx_hal_conf.h.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2016 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __STM32L0xx_HAL_CONF_H
|
||||
#define __STM32L0xx_HAL_CONF_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
|
||||
/* ########################## Module Selection ############################## */
|
||||
/**
|
||||
* @brief This is the list of modules to be used in the HAL driver
|
||||
*/
|
||||
|
||||
#define HAL_MODULE_ENABLED
|
||||
/*#define HAL_ADC_MODULE_ENABLED */
|
||||
/*#define HAL_CRYP_MODULE_ENABLED */
|
||||
/*#define HAL_COMP_MODULE_ENABLED */
|
||||
/*#define HAL_CRC_MODULE_ENABLED */
|
||||
/*#define HAL_CRYP_MODULE_ENABLED */
|
||||
/*#define HAL_DAC_MODULE_ENABLED */
|
||||
/*#define HAL_FIREWALL_MODULE_ENABLED */
|
||||
/*#define HAL_I2S_MODULE_ENABLED */
|
||||
/*#define HAL_IWDG_MODULE_ENABLED */
|
||||
/*#define HAL_LCD_MODULE_ENABLED */
|
||||
/*#define HAL_LPTIM_MODULE_ENABLED */
|
||||
/*#define HAL_RNG_MODULE_ENABLED */
|
||||
/*#define HAL_RTC_MODULE_ENABLED */
|
||||
#define HAL_SPI_MODULE_ENABLED
|
||||
#define HAL_TIM_MODULE_ENABLED
|
||||
/*#define HAL_TSC_MODULE_ENABLED */
|
||||
#define HAL_UART_MODULE_ENABLED
|
||||
/*#define HAL_USART_MODULE_ENABLED */
|
||||
/*#define HAL_IRDA_MODULE_ENABLED */
|
||||
/*#define HAL_SMARTCARD_MODULE_ENABLED */
|
||||
/*#define HAL_SMBUS_MODULE_ENABLED */
|
||||
/*#define HAL_WWDG_MODULE_ENABLED */
|
||||
/*#define HAL_PCD_MODULE_ENABLED */
|
||||
#define HAL_GPIO_MODULE_ENABLED
|
||||
#define HAL_EXTI_MODULE_ENABLED
|
||||
#define HAL_DMA_MODULE_ENABLED
|
||||
#define HAL_I2C_MODULE_ENABLED
|
||||
#define HAL_RCC_MODULE_ENABLED
|
||||
#define HAL_FLASH_MODULE_ENABLED
|
||||
#define HAL_PWR_MODULE_ENABLED
|
||||
#define HAL_CORTEX_MODULE_ENABLED
|
||||
|
||||
/* ########################## Oscillator Values adaptation ####################*/
|
||||
/**
|
||||
* @brief Adjust the value of External High Speed oscillator (HSE) used in your application.
|
||||
* This value is used by the RCC HAL module to compute the system frequency
|
||||
* (when HSE is used as system clock source, directly or through the PLL).
|
||||
*/
|
||||
#if !defined (HSE_VALUE)
|
||||
#define HSE_VALUE ((uint32_t)8000000U) /*!< Value of the External oscillator in Hz */
|
||||
#endif /* HSE_VALUE */
|
||||
|
||||
#if !defined (HSE_STARTUP_TIMEOUT)
|
||||
#define HSE_STARTUP_TIMEOUT ((uint32_t)100U) /*!< Time out for HSE start up, in ms */
|
||||
#endif /* HSE_STARTUP_TIMEOUT */
|
||||
|
||||
/**
|
||||
* @brief Internal Multiple Speed oscillator (MSI) default value.
|
||||
* This value is the default MSI range value after Reset.
|
||||
*/
|
||||
#if !defined (MSI_VALUE)
|
||||
#define MSI_VALUE ((uint32_t)2097000U) /*!< Value of the Internal oscillator in Hz*/
|
||||
#endif /* MSI_VALUE */
|
||||
|
||||
/**
|
||||
* @brief Internal High Speed oscillator (HSI) value.
|
||||
* This value is used by the RCC HAL module to compute the system frequency
|
||||
* (when HSI is used as system clock source, directly or through the PLL).
|
||||
*/
|
||||
#if !defined (HSI_VALUE)
|
||||
#define HSI_VALUE ((uint32_t)16000000U) /*!< Value of the Internal oscillator in Hz*/
|
||||
#endif /* HSI_VALUE */
|
||||
|
||||
/**
|
||||
* @brief Internal High Speed oscillator for USB (HSI48) value.
|
||||
*/
|
||||
#if !defined (HSI48_VALUE)
|
||||
#define HSI48_VALUE ((uint32_t)48000000U) /*!< Value of the Internal High Speed oscillator for USB in Hz.
|
||||
The real value may vary depending on the variations
|
||||
in voltage and temperature. */
|
||||
#endif /* HSI48_VALUE */
|
||||
|
||||
/**
|
||||
* @brief Internal Low Speed oscillator (LSI) value.
|
||||
*/
|
||||
#if !defined (LSI_VALUE)
|
||||
#define LSI_VALUE ((uint32_t)37000U) /*!< LSI Typical Value in Hz*/
|
||||
#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz
|
||||
The real value may vary depending on the variations
|
||||
in voltage and temperature.*/
|
||||
/**
|
||||
* @brief External Low Speed oscillator (LSE) value.
|
||||
* This value is used by the UART, RTC HAL module to compute the system frequency
|
||||
*/
|
||||
#if !defined (LSE_VALUE)
|
||||
#define LSE_VALUE ((uint32_t)32768U) /*!< Value of the External oscillator in Hz*/
|
||||
#endif /* LSE_VALUE */
|
||||
|
||||
#if !defined (LSE_STARTUP_TIMEOUT)
|
||||
#define LSE_STARTUP_TIMEOUT ((uint32_t)5000U) /*!< Time out for LSE start up, in ms */
|
||||
#endif /* LSE_STARTUP_TIMEOUT */
|
||||
|
||||
/* Tip: To avoid modifying this file each time you need to use different HSE,
|
||||
=== you can define the HSE value in your toolchain compiler preprocessor. */
|
||||
|
||||
/* ########################### System Configuration ######################### */
|
||||
/**
|
||||
* @brief This is the HAL system configuration section
|
||||
*/
|
||||
#define VDD_VALUE ((uint32_t)3300U) /*!< Value of VDD in mv */
|
||||
#define TICK_INT_PRIORITY ((uint32_t)3U) /*!< tick interrupt priority */
|
||||
#define USE_RTOS 0U
|
||||
#define PREFETCH_ENABLE 0U
|
||||
#define PREREAD_ENABLE 1U
|
||||
#define BUFFER_CACHE_DISABLE 0U
|
||||
|
||||
/* ########################## Assert Selection ############################## */
|
||||
/**
|
||||
* @brief Uncomment the line below to expanse the "assert_param" macro in the
|
||||
* HAL drivers code
|
||||
*/
|
||||
/* #define USE_FULL_ASSERT 1U */
|
||||
|
||||
/* ################## Register callback feature configuration ############### */
|
||||
/**
|
||||
* @brief Set below the peripheral configuration to "1U" to add the support
|
||||
* of HAL callback registration/deregistration feature for the HAL
|
||||
* driver(s). This allows user application to provide specific callback
|
||||
* functions thanks to HAL_PPP_RegisterCallback() rather than overwriting
|
||||
* the default weak callback functions (see each stm32l0xx_hal_ppp.h file
|
||||
* for possible callback identifiers defined in HAL_PPP_CallbackIDTypeDef
|
||||
* for each PPP peripheral).
|
||||
*/
|
||||
#define USE_HAL_ADC_REGISTER_CALLBACKS 0U
|
||||
#define USE_HAL_COMP_REGISTER_CALLBACKS 0U
|
||||
#define USE_HAL_DAC_REGISTER_CALLBACKS 0U
|
||||
#define USE_HAL_I2C_REGISTER_CALLBACKS 0U
|
||||
#define USE_HAL_I2S_REGISTER_CALLBACKS 0U
|
||||
#define USE_HAL_IRDA_REGISTER_CALLBACKS 0U
|
||||
#define USE_HAL_LPTIM_REGISTER_CALLBACKS 0U
|
||||
#define USE_HAL_PCD_REGISTER_CALLBACKS 0U
|
||||
#define USE_HAL_RNG_REGISTER_CALLBACKS 0U
|
||||
#define USE_HAL_RTC_REGISTER_CALLBACKS 0U
|
||||
#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U
|
||||
#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U
|
||||
#define USE_HAL_SPI_REGISTER_CALLBACKS 0U
|
||||
#define USE_HAL_TIM_REGISTER_CALLBACKS 0U
|
||||
#define USE_HAL_TSC_REGISTER_CALLBACKS 0U
|
||||
#define USE_HAL_UART_REGISTER_CALLBACKS 0U
|
||||
#define USE_HAL_USART_REGISTER_CALLBACKS 0U
|
||||
#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief Include module's header file
|
||||
*/
|
||||
|
||||
#ifdef HAL_RCC_MODULE_ENABLED
|
||||
#include "stm32l0xx_hal_rcc.h"
|
||||
#endif /* HAL_RCC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_EXTI_MODULE_ENABLED
|
||||
#include "stm32l0xx_hal_exti.h"
|
||||
#endif /* HAL_EXTI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_GPIO_MODULE_ENABLED
|
||||
#include "stm32l0xx_hal_gpio.h"
|
||||
#endif /* HAL_GPIO_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DMA_MODULE_ENABLED
|
||||
#include "stm32l0xx_hal_dma.h"
|
||||
#endif /* HAL_DMA_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CORTEX_MODULE_ENABLED
|
||||
#include "stm32l0xx_hal_cortex.h"
|
||||
#endif /* HAL_CORTEX_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_ADC_MODULE_ENABLED
|
||||
#include "stm32l0xx_hal_adc.h"
|
||||
#endif /* HAL_ADC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_COMP_MODULE_ENABLED
|
||||
#include "stm32l0xx_hal_comp.h"
|
||||
#endif /* HAL_COMP_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CRC_MODULE_ENABLED
|
||||
#include "stm32l0xx_hal_crc.h"
|
||||
#endif /* HAL_CRC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CRYP_MODULE_ENABLED
|
||||
#include "stm32l0xx_hal_cryp.h"
|
||||
#endif /* HAL_CRYP_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DAC_MODULE_ENABLED
|
||||
#include "stm32l0xx_hal_dac.h"
|
||||
#endif /* HAL_DAC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_FIREWALL_MODULE_ENABLED
|
||||
#include "stm32l0xx_hal_firewall.h"
|
||||
#endif /* HAL_FIREWALL_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_FLASH_MODULE_ENABLED
|
||||
#include "stm32l0xx_hal_flash.h"
|
||||
#endif /* HAL_FLASH_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_I2C_MODULE_ENABLED
|
||||
#include "stm32l0xx_hal_i2c.h"
|
||||
#endif /* HAL_I2C_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_I2S_MODULE_ENABLED
|
||||
#include "stm32l0xx_hal_i2s.h"
|
||||
#endif /* HAL_I2S_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_IWDG_MODULE_ENABLED
|
||||
#include "stm32l0xx_hal_iwdg.h"
|
||||
#endif /* HAL_IWDG_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_LCD_MODULE_ENABLED
|
||||
#include "stm32l0xx_hal_lcd.h"
|
||||
#endif /* HAL_LCD_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_LPTIM_MODULE_ENABLED
|
||||
#include "stm32l0xx_hal_lptim.h"
|
||||
#endif /* HAL_LPTIM_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_PWR_MODULE_ENABLED
|
||||
#include "stm32l0xx_hal_pwr.h"
|
||||
#endif /* HAL_PWR_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_RNG_MODULE_ENABLED
|
||||
#include "stm32l0xx_hal_rng.h"
|
||||
#endif /* HAL_RNG_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_RTC_MODULE_ENABLED
|
||||
#include "stm32l0xx_hal_rtc.h"
|
||||
|
||||
#endif /* HAL_RTC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SPI_MODULE_ENABLED
|
||||
#include "stm32l0xx_hal_spi.h"
|
||||
#endif /* HAL_SPI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_TIM_MODULE_ENABLED
|
||||
#include "stm32l0xx_hal_tim.h"
|
||||
#endif /* HAL_TIM_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_TSC_MODULE_ENABLED
|
||||
#include "stm32l0xx_hal_tsc.h"
|
||||
#endif /* HAL_TSC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_UART_MODULE_ENABLED
|
||||
#include "stm32l0xx_hal_uart.h"
|
||||
#endif /* HAL_UART_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_USART_MODULE_ENABLED
|
||||
#include "stm32l0xx_hal_usart.h"
|
||||
#endif /* HAL_USART_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_IRDA_MODULE_ENABLED
|
||||
#include "stm32l0xx_hal_irda.h"
|
||||
#endif /* HAL_IRDA_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SMARTCARD_MODULE_ENABLED
|
||||
#include "stm32l0xx_hal_smartcard.h"
|
||||
#endif /* HAL_SMARTCARD_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SMBUS_MODULE_ENABLED
|
||||
#include "stm32l0xx_hal_smbus.h"
|
||||
#endif /* HAL_SMBUS_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_WWDG_MODULE_ENABLED
|
||||
#include "stm32l0xx_hal_wwdg.h"
|
||||
#endif /* HAL_WWDG_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_PCD_MODULE_ENABLED
|
||||
#include "stm32l0xx_hal_pcd.h"
|
||||
#endif /* HAL_PCD_MODULE_ENABLED */
|
||||
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
#ifdef USE_FULL_ASSERT
|
||||
/**
|
||||
* @brief The assert_param macro is used for function's parameters check.
|
||||
* @param expr: If expr is false, it calls assert_failed function
|
||||
* which reports the name of the source file and the source
|
||||
* line number of the call that failed.
|
||||
* If expr is true, it returns no value.
|
||||
* @retval None
|
||||
*/
|
||||
#define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__))
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
void assert_failed(uint8_t* file, uint32_t line);
|
||||
#else
|
||||
#define assert_param(expr) ((void)0U)
|
||||
#endif /* USE_FULL_ASSERT */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __STM32L0xx_HAL_CONF_H */
|
64
include/stm32l0xx_it.h
Normal file
64
include/stm32l0xx_it.h
Normal file
@ -0,0 +1,64 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32l0xx_it.h
|
||||
* @brief This file contains the headers of the interrupt handlers.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2023 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __STM32L0xx_IT_H
|
||||
#define __STM32L0xx_IT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Includes */
|
||||
|
||||
/* USER CODE END Includes */
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN ET */
|
||||
|
||||
/* USER CODE END ET */
|
||||
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/* USER CODE BEGIN EC */
|
||||
|
||||
/* USER CODE END EC */
|
||||
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN EM */
|
||||
|
||||
/* USER CODE END EM */
|
||||
|
||||
/* Exported functions prototypes ---------------------------------------------*/
|
||||
void NMI_Handler(void);
|
||||
void HardFault_Handler(void);
|
||||
void SVC_Handler(void);
|
||||
void PendSV_Handler(void);
|
||||
void SysTick_Handler(void);
|
||||
void EXTI4_15_IRQHandler(void);
|
||||
void TIM2_IRQHandler(void);
|
||||
/* USER CODE BEGIN EFP */
|
||||
|
||||
/* USER CODE END EFP */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __STM32L0xx_IT_H */
|
46
lib/README
Executable file
46
lib/README
Executable file
@ -0,0 +1,46 @@
|
||||
|
||||
This directory is intended for project specific (private) libraries.
|
||||
PlatformIO will compile them to static libraries and link into executable file.
|
||||
|
||||
The source code of each library should be placed in a an own separate directory
|
||||
("lib/your_library_name/[here are source files]").
|
||||
|
||||
For example, see a structure of the following two libraries `Foo` and `Bar`:
|
||||
|
||||
|--lib
|
||||
| |
|
||||
| |--Bar
|
||||
| | |--docs
|
||||
| | |--examples
|
||||
| | |--src
|
||||
| | |- Bar.c
|
||||
| | |- Bar.h
|
||||
| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
|
||||
| |
|
||||
| |--Foo
|
||||
| | |- Foo.c
|
||||
| | |- Foo.h
|
||||
| |
|
||||
| |- README --> THIS FILE
|
||||
|
|
||||
|- platformio.ini
|
||||
|--src
|
||||
|- main.c
|
||||
|
||||
and a contents of `src/main.c`:
|
||||
```
|
||||
#include <Foo.h>
|
||||
#include <Bar.h>
|
||||
|
||||
int main (void)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
PlatformIO Library Dependency Finder will find automatically dependent
|
||||
libraries scanning project source files.
|
||||
|
||||
More information about PlatformIO Library Dependency Finder
|
||||
- https://docs.platformio.org/page/librarymanager/ldf.html
|
23
platformio.ini
Executable file
23
platformio.ini
Executable file
@ -0,0 +1,23 @@
|
||||
; PlatformIO Project Configuration File
|
||||
;
|
||||
; Build options: build flags, source filter
|
||||
; Upload options: custom upload port, speed and extra flags
|
||||
; Library options: dependencies, extra library storages
|
||||
; Advanced options: extra scripting
|
||||
;
|
||||
; Please visit documentation for the other options and examples
|
||||
; https://docs.platformio.org/page/projectconf.html
|
||||
|
||||
[env:minipill_l051c8_lora_stm32cube]
|
||||
platform = ststm32
|
||||
board = minipill_l051c8_lora_stm32cube
|
||||
framework = stm32cube
|
||||
board_build.stm32cube.startup_file = startup_stm32l051xx.s
|
||||
build_flags=
|
||||
-D CFG_eu868
|
||||
-D CFG_sx1276_radio
|
||||
-D DISABLE_JOIN
|
||||
upload_protocol=custom
|
||||
upload_command = st-flash write $SOURCE 0x8000000
|
||||
debug_tool=stlink
|
||||
monitor_port=/dev/ttyUSB0
|
383
src/aes.c
Normal file
383
src/aes.c
Normal file
@ -0,0 +1,383 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2016 IBM Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the <organization> nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "oslmic.h"
|
||||
|
||||
#define AES_MICSUB 0x30 // internal use only
|
||||
|
||||
static const u4_t AES_RCON[10] = {
|
||||
0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000,
|
||||
0x20000000, 0x40000000, 0x80000000, 0x1B000000, 0x36000000
|
||||
};
|
||||
|
||||
static const u1_t AES_S[256] = {
|
||||
0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
|
||||
0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
|
||||
0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
|
||||
0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
|
||||
0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
|
||||
0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
|
||||
0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
|
||||
0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
|
||||
0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
|
||||
0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
|
||||
0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
|
||||
0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
|
||||
0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
|
||||
0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
|
||||
0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
|
||||
0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16,
|
||||
};
|
||||
|
||||
static const u4_t AES_E1[256] = {
|
||||
0xC66363A5, 0xF87C7C84, 0xEE777799, 0xF67B7B8D, 0xFFF2F20D, 0xD66B6BBD, 0xDE6F6FB1, 0x91C5C554,
|
||||
0x60303050, 0x02010103, 0xCE6767A9, 0x562B2B7D, 0xE7FEFE19, 0xB5D7D762, 0x4DABABE6, 0xEC76769A,
|
||||
0x8FCACA45, 0x1F82829D, 0x89C9C940, 0xFA7D7D87, 0xEFFAFA15, 0xB25959EB, 0x8E4747C9, 0xFBF0F00B,
|
||||
0x41ADADEC, 0xB3D4D467, 0x5FA2A2FD, 0x45AFAFEA, 0x239C9CBF, 0x53A4A4F7, 0xE4727296, 0x9BC0C05B,
|
||||
0x75B7B7C2, 0xE1FDFD1C, 0x3D9393AE, 0x4C26266A, 0x6C36365A, 0x7E3F3F41, 0xF5F7F702, 0x83CCCC4F,
|
||||
0x6834345C, 0x51A5A5F4, 0xD1E5E534, 0xF9F1F108, 0xE2717193, 0xABD8D873, 0x62313153, 0x2A15153F,
|
||||
0x0804040C, 0x95C7C752, 0x46232365, 0x9DC3C35E, 0x30181828, 0x379696A1, 0x0A05050F, 0x2F9A9AB5,
|
||||
0x0E070709, 0x24121236, 0x1B80809B, 0xDFE2E23D, 0xCDEBEB26, 0x4E272769, 0x7FB2B2CD, 0xEA75759F,
|
||||
0x1209091B, 0x1D83839E, 0x582C2C74, 0x341A1A2E, 0x361B1B2D, 0xDC6E6EB2, 0xB45A5AEE, 0x5BA0A0FB,
|
||||
0xA45252F6, 0x763B3B4D, 0xB7D6D661, 0x7DB3B3CE, 0x5229297B, 0xDDE3E33E, 0x5E2F2F71, 0x13848497,
|
||||
0xA65353F5, 0xB9D1D168, 0x00000000, 0xC1EDED2C, 0x40202060, 0xE3FCFC1F, 0x79B1B1C8, 0xB65B5BED,
|
||||
0xD46A6ABE, 0x8DCBCB46, 0x67BEBED9, 0x7239394B, 0x944A4ADE, 0x984C4CD4, 0xB05858E8, 0x85CFCF4A,
|
||||
0xBBD0D06B, 0xC5EFEF2A, 0x4FAAAAE5, 0xEDFBFB16, 0x864343C5, 0x9A4D4DD7, 0x66333355, 0x11858594,
|
||||
0x8A4545CF, 0xE9F9F910, 0x04020206, 0xFE7F7F81, 0xA05050F0, 0x783C3C44, 0x259F9FBA, 0x4BA8A8E3,
|
||||
0xA25151F3, 0x5DA3A3FE, 0x804040C0, 0x058F8F8A, 0x3F9292AD, 0x219D9DBC, 0x70383848, 0xF1F5F504,
|
||||
0x63BCBCDF, 0x77B6B6C1, 0xAFDADA75, 0x42212163, 0x20101030, 0xE5FFFF1A, 0xFDF3F30E, 0xBFD2D26D,
|
||||
0x81CDCD4C, 0x180C0C14, 0x26131335, 0xC3ECEC2F, 0xBE5F5FE1, 0x359797A2, 0x884444CC, 0x2E171739,
|
||||
0x93C4C457, 0x55A7A7F2, 0xFC7E7E82, 0x7A3D3D47, 0xC86464AC, 0xBA5D5DE7, 0x3219192B, 0xE6737395,
|
||||
0xC06060A0, 0x19818198, 0x9E4F4FD1, 0xA3DCDC7F, 0x44222266, 0x542A2A7E, 0x3B9090AB, 0x0B888883,
|
||||
0x8C4646CA, 0xC7EEEE29, 0x6BB8B8D3, 0x2814143C, 0xA7DEDE79, 0xBC5E5EE2, 0x160B0B1D, 0xADDBDB76,
|
||||
0xDBE0E03B, 0x64323256, 0x743A3A4E, 0x140A0A1E, 0x924949DB, 0x0C06060A, 0x4824246C, 0xB85C5CE4,
|
||||
0x9FC2C25D, 0xBDD3D36E, 0x43ACACEF, 0xC46262A6, 0x399191A8, 0x319595A4, 0xD3E4E437, 0xF279798B,
|
||||
0xD5E7E732, 0x8BC8C843, 0x6E373759, 0xDA6D6DB7, 0x018D8D8C, 0xB1D5D564, 0x9C4E4ED2, 0x49A9A9E0,
|
||||
0xD86C6CB4, 0xAC5656FA, 0xF3F4F407, 0xCFEAEA25, 0xCA6565AF, 0xF47A7A8E, 0x47AEAEE9, 0x10080818,
|
||||
0x6FBABAD5, 0xF0787888, 0x4A25256F, 0x5C2E2E72, 0x381C1C24, 0x57A6A6F1, 0x73B4B4C7, 0x97C6C651,
|
||||
0xCBE8E823, 0xA1DDDD7C, 0xE874749C, 0x3E1F1F21, 0x964B4BDD, 0x61BDBDDC, 0x0D8B8B86, 0x0F8A8A85,
|
||||
0xE0707090, 0x7C3E3E42, 0x71B5B5C4, 0xCC6666AA, 0x904848D8, 0x06030305, 0xF7F6F601, 0x1C0E0E12,
|
||||
0xC26161A3, 0x6A35355F, 0xAE5757F9, 0x69B9B9D0, 0x17868691, 0x99C1C158, 0x3A1D1D27, 0x279E9EB9,
|
||||
0xD9E1E138, 0xEBF8F813, 0x2B9898B3, 0x22111133, 0xD26969BB, 0xA9D9D970, 0x078E8E89, 0x339494A7,
|
||||
0x2D9B9BB6, 0x3C1E1E22, 0x15878792, 0xC9E9E920, 0x87CECE49, 0xAA5555FF, 0x50282878, 0xA5DFDF7A,
|
||||
0x038C8C8F, 0x59A1A1F8, 0x09898980, 0x1A0D0D17, 0x65BFBFDA, 0xD7E6E631, 0x844242C6, 0xD06868B8,
|
||||
0x824141C3, 0x299999B0, 0x5A2D2D77, 0x1E0F0F11, 0x7BB0B0CB, 0xA85454FC, 0x6DBBBBD6, 0x2C16163A,
|
||||
};
|
||||
|
||||
static const u4_t AES_E2[256] = {
|
||||
0xA5C66363, 0x84F87C7C, 0x99EE7777, 0x8DF67B7B, 0x0DFFF2F2, 0xBDD66B6B, 0xB1DE6F6F, 0x5491C5C5,
|
||||
0x50603030, 0x03020101, 0xA9CE6767, 0x7D562B2B, 0x19E7FEFE, 0x62B5D7D7, 0xE64DABAB, 0x9AEC7676,
|
||||
0x458FCACA, 0x9D1F8282, 0x4089C9C9, 0x87FA7D7D, 0x15EFFAFA, 0xEBB25959, 0xC98E4747, 0x0BFBF0F0,
|
||||
0xEC41ADAD, 0x67B3D4D4, 0xFD5FA2A2, 0xEA45AFAF, 0xBF239C9C, 0xF753A4A4, 0x96E47272, 0x5B9BC0C0,
|
||||
0xC275B7B7, 0x1CE1FDFD, 0xAE3D9393, 0x6A4C2626, 0x5A6C3636, 0x417E3F3F, 0x02F5F7F7, 0x4F83CCCC,
|
||||
0x5C683434, 0xF451A5A5, 0x34D1E5E5, 0x08F9F1F1, 0x93E27171, 0x73ABD8D8, 0x53623131, 0x3F2A1515,
|
||||
0x0C080404, 0x5295C7C7, 0x65462323, 0x5E9DC3C3, 0x28301818, 0xA1379696, 0x0F0A0505, 0xB52F9A9A,
|
||||
0x090E0707, 0x36241212, 0x9B1B8080, 0x3DDFE2E2, 0x26CDEBEB, 0x694E2727, 0xCD7FB2B2, 0x9FEA7575,
|
||||
0x1B120909, 0x9E1D8383, 0x74582C2C, 0x2E341A1A, 0x2D361B1B, 0xB2DC6E6E, 0xEEB45A5A, 0xFB5BA0A0,
|
||||
0xF6A45252, 0x4D763B3B, 0x61B7D6D6, 0xCE7DB3B3, 0x7B522929, 0x3EDDE3E3, 0x715E2F2F, 0x97138484,
|
||||
0xF5A65353, 0x68B9D1D1, 0x00000000, 0x2CC1EDED, 0x60402020, 0x1FE3FCFC, 0xC879B1B1, 0xEDB65B5B,
|
||||
0xBED46A6A, 0x468DCBCB, 0xD967BEBE, 0x4B723939, 0xDE944A4A, 0xD4984C4C, 0xE8B05858, 0x4A85CFCF,
|
||||
0x6BBBD0D0, 0x2AC5EFEF, 0xE54FAAAA, 0x16EDFBFB, 0xC5864343, 0xD79A4D4D, 0x55663333, 0x94118585,
|
||||
0xCF8A4545, 0x10E9F9F9, 0x06040202, 0x81FE7F7F, 0xF0A05050, 0x44783C3C, 0xBA259F9F, 0xE34BA8A8,
|
||||
0xF3A25151, 0xFE5DA3A3, 0xC0804040, 0x8A058F8F, 0xAD3F9292, 0xBC219D9D, 0x48703838, 0x04F1F5F5,
|
||||
0xDF63BCBC, 0xC177B6B6, 0x75AFDADA, 0x63422121, 0x30201010, 0x1AE5FFFF, 0x0EFDF3F3, 0x6DBFD2D2,
|
||||
0x4C81CDCD, 0x14180C0C, 0x35261313, 0x2FC3ECEC, 0xE1BE5F5F, 0xA2359797, 0xCC884444, 0x392E1717,
|
||||
0x5793C4C4, 0xF255A7A7, 0x82FC7E7E, 0x477A3D3D, 0xACC86464, 0xE7BA5D5D, 0x2B321919, 0x95E67373,
|
||||
0xA0C06060, 0x98198181, 0xD19E4F4F, 0x7FA3DCDC, 0x66442222, 0x7E542A2A, 0xAB3B9090, 0x830B8888,
|
||||
0xCA8C4646, 0x29C7EEEE, 0xD36BB8B8, 0x3C281414, 0x79A7DEDE, 0xE2BC5E5E, 0x1D160B0B, 0x76ADDBDB,
|
||||
0x3BDBE0E0, 0x56643232, 0x4E743A3A, 0x1E140A0A, 0xDB924949, 0x0A0C0606, 0x6C482424, 0xE4B85C5C,
|
||||
0x5D9FC2C2, 0x6EBDD3D3, 0xEF43ACAC, 0xA6C46262, 0xA8399191, 0xA4319595, 0x37D3E4E4, 0x8BF27979,
|
||||
0x32D5E7E7, 0x438BC8C8, 0x596E3737, 0xB7DA6D6D, 0x8C018D8D, 0x64B1D5D5, 0xD29C4E4E, 0xE049A9A9,
|
||||
0xB4D86C6C, 0xFAAC5656, 0x07F3F4F4, 0x25CFEAEA, 0xAFCA6565, 0x8EF47A7A, 0xE947AEAE, 0x18100808,
|
||||
0xD56FBABA, 0x88F07878, 0x6F4A2525, 0x725C2E2E, 0x24381C1C, 0xF157A6A6, 0xC773B4B4, 0x5197C6C6,
|
||||
0x23CBE8E8, 0x7CA1DDDD, 0x9CE87474, 0x213E1F1F, 0xDD964B4B, 0xDC61BDBD, 0x860D8B8B, 0x850F8A8A,
|
||||
0x90E07070, 0x427C3E3E, 0xC471B5B5, 0xAACC6666, 0xD8904848, 0x05060303, 0x01F7F6F6, 0x121C0E0E,
|
||||
0xA3C26161, 0x5F6A3535, 0xF9AE5757, 0xD069B9B9, 0x91178686, 0x5899C1C1, 0x273A1D1D, 0xB9279E9E,
|
||||
0x38D9E1E1, 0x13EBF8F8, 0xB32B9898, 0x33221111, 0xBBD26969, 0x70A9D9D9, 0x89078E8E, 0xA7339494,
|
||||
0xB62D9B9B, 0x223C1E1E, 0x92158787, 0x20C9E9E9, 0x4987CECE, 0xFFAA5555, 0x78502828, 0x7AA5DFDF,
|
||||
0x8F038C8C, 0xF859A1A1, 0x80098989, 0x171A0D0D, 0xDA65BFBF, 0x31D7E6E6, 0xC6844242, 0xB8D06868,
|
||||
0xC3824141, 0xB0299999, 0x775A2D2D, 0x111E0F0F, 0xCB7BB0B0, 0xFCA85454, 0xD66DBBBB, 0x3A2C1616,
|
||||
};
|
||||
|
||||
static const u4_t AES_E3[256] = {
|
||||
0x63A5C663, 0x7C84F87C, 0x7799EE77, 0x7B8DF67B, 0xF20DFFF2, 0x6BBDD66B, 0x6FB1DE6F, 0xC55491C5,
|
||||
0x30506030, 0x01030201, 0x67A9CE67, 0x2B7D562B, 0xFE19E7FE, 0xD762B5D7, 0xABE64DAB, 0x769AEC76,
|
||||
0xCA458FCA, 0x829D1F82, 0xC94089C9, 0x7D87FA7D, 0xFA15EFFA, 0x59EBB259, 0x47C98E47, 0xF00BFBF0,
|
||||
0xADEC41AD, 0xD467B3D4, 0xA2FD5FA2, 0xAFEA45AF, 0x9CBF239C, 0xA4F753A4, 0x7296E472, 0xC05B9BC0,
|
||||
0xB7C275B7, 0xFD1CE1FD, 0x93AE3D93, 0x266A4C26, 0x365A6C36, 0x3F417E3F, 0xF702F5F7, 0xCC4F83CC,
|
||||
0x345C6834, 0xA5F451A5, 0xE534D1E5, 0xF108F9F1, 0x7193E271, 0xD873ABD8, 0x31536231, 0x153F2A15,
|
||||
0x040C0804, 0xC75295C7, 0x23654623, 0xC35E9DC3, 0x18283018, 0x96A13796, 0x050F0A05, 0x9AB52F9A,
|
||||
0x07090E07, 0x12362412, 0x809B1B80, 0xE23DDFE2, 0xEB26CDEB, 0x27694E27, 0xB2CD7FB2, 0x759FEA75,
|
||||
0x091B1209, 0x839E1D83, 0x2C74582C, 0x1A2E341A, 0x1B2D361B, 0x6EB2DC6E, 0x5AEEB45A, 0xA0FB5BA0,
|
||||
0x52F6A452, 0x3B4D763B, 0xD661B7D6, 0xB3CE7DB3, 0x297B5229, 0xE33EDDE3, 0x2F715E2F, 0x84971384,
|
||||
0x53F5A653, 0xD168B9D1, 0x00000000, 0xED2CC1ED, 0x20604020, 0xFC1FE3FC, 0xB1C879B1, 0x5BEDB65B,
|
||||
0x6ABED46A, 0xCB468DCB, 0xBED967BE, 0x394B7239, 0x4ADE944A, 0x4CD4984C, 0x58E8B058, 0xCF4A85CF,
|
||||
0xD06BBBD0, 0xEF2AC5EF, 0xAAE54FAA, 0xFB16EDFB, 0x43C58643, 0x4DD79A4D, 0x33556633, 0x85941185,
|
||||
0x45CF8A45, 0xF910E9F9, 0x02060402, 0x7F81FE7F, 0x50F0A050, 0x3C44783C, 0x9FBA259F, 0xA8E34BA8,
|
||||
0x51F3A251, 0xA3FE5DA3, 0x40C08040, 0x8F8A058F, 0x92AD3F92, 0x9DBC219D, 0x38487038, 0xF504F1F5,
|
||||
0xBCDF63BC, 0xB6C177B6, 0xDA75AFDA, 0x21634221, 0x10302010, 0xFF1AE5FF, 0xF30EFDF3, 0xD26DBFD2,
|
||||
0xCD4C81CD, 0x0C14180C, 0x13352613, 0xEC2FC3EC, 0x5FE1BE5F, 0x97A23597, 0x44CC8844, 0x17392E17,
|
||||
0xC45793C4, 0xA7F255A7, 0x7E82FC7E, 0x3D477A3D, 0x64ACC864, 0x5DE7BA5D, 0x192B3219, 0x7395E673,
|
||||
0x60A0C060, 0x81981981, 0x4FD19E4F, 0xDC7FA3DC, 0x22664422, 0x2A7E542A, 0x90AB3B90, 0x88830B88,
|
||||
0x46CA8C46, 0xEE29C7EE, 0xB8D36BB8, 0x143C2814, 0xDE79A7DE, 0x5EE2BC5E, 0x0B1D160B, 0xDB76ADDB,
|
||||
0xE03BDBE0, 0x32566432, 0x3A4E743A, 0x0A1E140A, 0x49DB9249, 0x060A0C06, 0x246C4824, 0x5CE4B85C,
|
||||
0xC25D9FC2, 0xD36EBDD3, 0xACEF43AC, 0x62A6C462, 0x91A83991, 0x95A43195, 0xE437D3E4, 0x798BF279,
|
||||
0xE732D5E7, 0xC8438BC8, 0x37596E37, 0x6DB7DA6D, 0x8D8C018D, 0xD564B1D5, 0x4ED29C4E, 0xA9E049A9,
|
||||
0x6CB4D86C, 0x56FAAC56, 0xF407F3F4, 0xEA25CFEA, 0x65AFCA65, 0x7A8EF47A, 0xAEE947AE, 0x08181008,
|
||||
0xBAD56FBA, 0x7888F078, 0x256F4A25, 0x2E725C2E, 0x1C24381C, 0xA6F157A6, 0xB4C773B4, 0xC65197C6,
|
||||
0xE823CBE8, 0xDD7CA1DD, 0x749CE874, 0x1F213E1F, 0x4BDD964B, 0xBDDC61BD, 0x8B860D8B, 0x8A850F8A,
|
||||
0x7090E070, 0x3E427C3E, 0xB5C471B5, 0x66AACC66, 0x48D89048, 0x03050603, 0xF601F7F6, 0x0E121C0E,
|
||||
0x61A3C261, 0x355F6A35, 0x57F9AE57, 0xB9D069B9, 0x86911786, 0xC15899C1, 0x1D273A1D, 0x9EB9279E,
|
||||
0xE138D9E1, 0xF813EBF8, 0x98B32B98, 0x11332211, 0x69BBD269, 0xD970A9D9, 0x8E89078E, 0x94A73394,
|
||||
0x9BB62D9B, 0x1E223C1E, 0x87921587, 0xE920C9E9, 0xCE4987CE, 0x55FFAA55, 0x28785028, 0xDF7AA5DF,
|
||||
0x8C8F038C, 0xA1F859A1, 0x89800989, 0x0D171A0D, 0xBFDA65BF, 0xE631D7E6, 0x42C68442, 0x68B8D068,
|
||||
0x41C38241, 0x99B02999, 0x2D775A2D, 0x0F111E0F, 0xB0CB7BB0, 0x54FCA854, 0xBBD66DBB, 0x163A2C16,
|
||||
};
|
||||
|
||||
static const u4_t AES_E4[256] = {
|
||||
0x6363A5C6, 0x7C7C84F8, 0x777799EE, 0x7B7B8DF6, 0xF2F20DFF, 0x6B6BBDD6, 0x6F6FB1DE, 0xC5C55491,
|
||||
0x30305060, 0x01010302, 0x6767A9CE, 0x2B2B7D56, 0xFEFE19E7, 0xD7D762B5, 0xABABE64D, 0x76769AEC,
|
||||
0xCACA458F, 0x82829D1F, 0xC9C94089, 0x7D7D87FA, 0xFAFA15EF, 0x5959EBB2, 0x4747C98E, 0xF0F00BFB,
|
||||
0xADADEC41, 0xD4D467B3, 0xA2A2FD5F, 0xAFAFEA45, 0x9C9CBF23, 0xA4A4F753, 0x727296E4, 0xC0C05B9B,
|
||||
0xB7B7C275, 0xFDFD1CE1, 0x9393AE3D, 0x26266A4C, 0x36365A6C, 0x3F3F417E, 0xF7F702F5, 0xCCCC4F83,
|
||||
0x34345C68, 0xA5A5F451, 0xE5E534D1, 0xF1F108F9, 0x717193E2, 0xD8D873AB, 0x31315362, 0x15153F2A,
|
||||
0x04040C08, 0xC7C75295, 0x23236546, 0xC3C35E9D, 0x18182830, 0x9696A137, 0x05050F0A, 0x9A9AB52F,
|
||||
0x0707090E, 0x12123624, 0x80809B1B, 0xE2E23DDF, 0xEBEB26CD, 0x2727694E, 0xB2B2CD7F, 0x75759FEA,
|
||||
0x09091B12, 0x83839E1D, 0x2C2C7458, 0x1A1A2E34, 0x1B1B2D36, 0x6E6EB2DC, 0x5A5AEEB4, 0xA0A0FB5B,
|
||||
0x5252F6A4, 0x3B3B4D76, 0xD6D661B7, 0xB3B3CE7D, 0x29297B52, 0xE3E33EDD, 0x2F2F715E, 0x84849713,
|
||||
0x5353F5A6, 0xD1D168B9, 0x00000000, 0xEDED2CC1, 0x20206040, 0xFCFC1FE3, 0xB1B1C879, 0x5B5BEDB6,
|
||||
0x6A6ABED4, 0xCBCB468D, 0xBEBED967, 0x39394B72, 0x4A4ADE94, 0x4C4CD498, 0x5858E8B0, 0xCFCF4A85,
|
||||
0xD0D06BBB, 0xEFEF2AC5, 0xAAAAE54F, 0xFBFB16ED, 0x4343C586, 0x4D4DD79A, 0x33335566, 0x85859411,
|
||||
0x4545CF8A, 0xF9F910E9, 0x02020604, 0x7F7F81FE, 0x5050F0A0, 0x3C3C4478, 0x9F9FBA25, 0xA8A8E34B,
|
||||
0x5151F3A2, 0xA3A3FE5D, 0x4040C080, 0x8F8F8A05, 0x9292AD3F, 0x9D9DBC21, 0x38384870, 0xF5F504F1,
|
||||
0xBCBCDF63, 0xB6B6C177, 0xDADA75AF, 0x21216342, 0x10103020, 0xFFFF1AE5, 0xF3F30EFD, 0xD2D26DBF,
|
||||
0xCDCD4C81, 0x0C0C1418, 0x13133526, 0xECEC2FC3, 0x5F5FE1BE, 0x9797A235, 0x4444CC88, 0x1717392E,
|
||||
0xC4C45793, 0xA7A7F255, 0x7E7E82FC, 0x3D3D477A, 0x6464ACC8, 0x5D5DE7BA, 0x19192B32, 0x737395E6,
|
||||
0x6060A0C0, 0x81819819, 0x4F4FD19E, 0xDCDC7FA3, 0x22226644, 0x2A2A7E54, 0x9090AB3B, 0x8888830B,
|
||||
0x4646CA8C, 0xEEEE29C7, 0xB8B8D36B, 0x14143C28, 0xDEDE79A7, 0x5E5EE2BC, 0x0B0B1D16, 0xDBDB76AD,
|
||||
0xE0E03BDB, 0x32325664, 0x3A3A4E74, 0x0A0A1E14, 0x4949DB92, 0x06060A0C, 0x24246C48, 0x5C5CE4B8,
|
||||
0xC2C25D9F, 0xD3D36EBD, 0xACACEF43, 0x6262A6C4, 0x9191A839, 0x9595A431, 0xE4E437D3, 0x79798BF2,
|
||||
0xE7E732D5, 0xC8C8438B, 0x3737596E, 0x6D6DB7DA, 0x8D8D8C01, 0xD5D564B1, 0x4E4ED29C, 0xA9A9E049,
|
||||
0x6C6CB4D8, 0x5656FAAC, 0xF4F407F3, 0xEAEA25CF, 0x6565AFCA, 0x7A7A8EF4, 0xAEAEE947, 0x08081810,
|
||||
0xBABAD56F, 0x787888F0, 0x25256F4A, 0x2E2E725C, 0x1C1C2438, 0xA6A6F157, 0xB4B4C773, 0xC6C65197,
|
||||
0xE8E823CB, 0xDDDD7CA1, 0x74749CE8, 0x1F1F213E, 0x4B4BDD96, 0xBDBDDC61, 0x8B8B860D, 0x8A8A850F,
|
||||
0x707090E0, 0x3E3E427C, 0xB5B5C471, 0x6666AACC, 0x4848D890, 0x03030506, 0xF6F601F7, 0x0E0E121C,
|
||||
0x6161A3C2, 0x35355F6A, 0x5757F9AE, 0xB9B9D069, 0x86869117, 0xC1C15899, 0x1D1D273A, 0x9E9EB927,
|
||||
0xE1E138D9, 0xF8F813EB, 0x9898B32B, 0x11113322, 0x6969BBD2, 0xD9D970A9, 0x8E8E8907, 0x9494A733,
|
||||
0x9B9BB62D, 0x1E1E223C, 0x87879215, 0xE9E920C9, 0xCECE4987, 0x5555FFAA, 0x28287850, 0xDFDF7AA5,
|
||||
0x8C8C8F03, 0xA1A1F859, 0x89898009, 0x0D0D171A, 0xBFBFDA65, 0xE6E631D7, 0x4242C684, 0x6868B8D0,
|
||||
0x4141C382, 0x9999B029, 0x2D2D775A, 0x0F0F111E, 0xB0B0CB7B, 0x5454FCA8, 0xBBBBD66D, 0x16163A2C,
|
||||
};
|
||||
|
||||
#define msbf4_read(p) ((p)[0]<<24 | (p)[1]<<16 | (p)[2]<<8 | (p)[3])
|
||||
#define msbf4_write(p,v) (p)[0]=(v)>>24,(p)[1]=(v)>>16,(p)[2]=(v)>>8,(p)[3]=(v)
|
||||
#define swapmsbf(x) ( (x&0xFF)<<24 | (x&0xFF00)<<8 | (x&0xFF0000)>>8 | (x>>24) )
|
||||
|
||||
#define u1(v) ((u1_t)(v))
|
||||
|
||||
#define AES_key4(r1,r2,r3,r0,i) r1 = ki[i+1]; \
|
||||
r2 = ki[i+2]; \
|
||||
r3 = ki[i+3]; \
|
||||
r0 = ki[i]
|
||||
|
||||
#define AES_expr4(r1,r2,r3,r0,i) r1 ^= AES_E4[u1(i)]; \
|
||||
r2 ^= AES_E3[u1(i>>8)]; \
|
||||
r3 ^= AES_E2[u1(i>>16)]; \
|
||||
r0 ^= AES_E1[ (i>>24)]
|
||||
|
||||
#define AES_expr(a,r0,r1,r2,r3,i) a = ki[i]; \
|
||||
a ^= (AES_S[ r0>>24 ]<<24); \
|
||||
a ^= (AES_S[u1(r1>>16)]<<16); \
|
||||
a ^= (AES_S[u1(r2>> 8)]<< 8); \
|
||||
a ^= AES_S[u1(r3) ]
|
||||
|
||||
// global area for passing parameters (aux, key) and for storing round keys
|
||||
u4_t AESAUX[16/sizeof(u4_t)];
|
||||
u4_t AESKEY[11*16/sizeof(u4_t)];
|
||||
|
||||
// generate 1+10 roundkeys for encryption with 128-bit key
|
||||
// read 128-bit key from AESKEY in MSBF, generate roundkey words in place
|
||||
static void aesroundkeys () {
|
||||
int i;
|
||||
u4_t b;
|
||||
|
||||
for( i=0; i<4; i++) {
|
||||
AESKEY[i] = swapmsbf(AESKEY[i]);
|
||||
}
|
||||
|
||||
b = AESKEY[3];
|
||||
for( ; i<44; i++ ) {
|
||||
if( i%4==0 ) {
|
||||
// b = SubWord(RotWord(b)) xor Rcon[i/4]
|
||||
b = (AES_S[u1(b >> 16)] << 24) ^
|
||||
(AES_S[u1(b >> 8)] << 16) ^
|
||||
(AES_S[u1(b) ] << 8) ^
|
||||
(AES_S[ b >> 24 ] ) ^
|
||||
AES_RCON[(i-4)/4];
|
||||
}
|
||||
AESKEY[i] = b ^= AESKEY[i-4];
|
||||
}
|
||||
}
|
||||
|
||||
u4_t os_aes (u1_t mode, xref2u1_t buf, u2_t len) {
|
||||
|
||||
aesroundkeys();
|
||||
|
||||
if( mode & AES_MICNOAUX ) {
|
||||
AESAUX[0] = AESAUX[1] = AESAUX[2] = AESAUX[3] = 0;
|
||||
} else {
|
||||
AESAUX[0] = swapmsbf(AESAUX[0]);
|
||||
AESAUX[1] = swapmsbf(AESAUX[1]);
|
||||
AESAUX[2] = swapmsbf(AESAUX[2]);
|
||||
AESAUX[3] = swapmsbf(AESAUX[3]);
|
||||
}
|
||||
|
||||
while( (signed char)len > 0 ) {
|
||||
u4_t a0, a1, a2, a3;
|
||||
u4_t t0, t1, t2, t3;
|
||||
u4_t *ki, *ke;
|
||||
|
||||
// load input block
|
||||
if( (mode & AES_CTR) || ((mode & AES_MIC) && (mode & AES_MICNOAUX)==0) ) { // load CTR block or first MIC block
|
||||
a0 = AESAUX[0];
|
||||
a1 = AESAUX[1];
|
||||
a2 = AESAUX[2];
|
||||
a3 = AESAUX[3];
|
||||
}
|
||||
else if( (mode & AES_MIC) && len <= 16 ) { // last MIC block
|
||||
a0 = a1 = a2 = a3 = 0; // load null block
|
||||
mode |= ((len == 16) ? 1 : 2) << 4; // set MICSUB: CMAC subkey K1 or K2
|
||||
} else
|
||||
LOADDATA: { // load data block (partially)
|
||||
for(t0=0; t0<16; t0++) {
|
||||
t1 = (t1<<8) | ((t0<len) ? buf[t0] : (t0==len) ? 0x80 : 0x00);
|
||||
if((t0&3)==3) {
|
||||
a0 = a1;
|
||||
a1 = a2;
|
||||
a2 = a3;
|
||||
a3 = t1;
|
||||
}
|
||||
}
|
||||
if( mode & AES_MIC ) {
|
||||
a0 ^= AESAUX[0];
|
||||
a1 ^= AESAUX[1];
|
||||
a2 ^= AESAUX[2];
|
||||
a3 ^= AESAUX[3];
|
||||
}
|
||||
}
|
||||
|
||||
// perform AES encryption on block in a0-a3
|
||||
ki = AESKEY;
|
||||
ke = ki + 8*4;
|
||||
a0 ^= ki[0];
|
||||
a1 ^= ki[1];
|
||||
a2 ^= ki[2];
|
||||
a3 ^= ki[3];
|
||||
do {
|
||||
AES_key4 (t1,t2,t3,t0,4);
|
||||
AES_expr4(t1,t2,t3,t0,a0);
|
||||
AES_expr4(t2,t3,t0,t1,a1);
|
||||
AES_expr4(t3,t0,t1,t2,a2);
|
||||
AES_expr4(t0,t1,t2,t3,a3);
|
||||
|
||||
AES_key4 (a1,a2,a3,a0,8);
|
||||
AES_expr4(a1,a2,a3,a0,t0);
|
||||
AES_expr4(a2,a3,a0,a1,t1);
|
||||
AES_expr4(a3,a0,a1,a2,t2);
|
||||
AES_expr4(a0,a1,a2,a3,t3);
|
||||
} while( (ki+=8) < ke );
|
||||
|
||||
AES_key4 (t1,t2,t3,t0,4);
|
||||
AES_expr4(t1,t2,t3,t0,a0);
|
||||
AES_expr4(t2,t3,t0,t1,a1);
|
||||
AES_expr4(t3,t0,t1,t2,a2);
|
||||
AES_expr4(t0,t1,t2,t3,a3);
|
||||
|
||||
AES_expr(a0,t0,t1,t2,t3,8);
|
||||
AES_expr(a1,t1,t2,t3,t0,9);
|
||||
AES_expr(a2,t2,t3,t0,t1,10);
|
||||
AES_expr(a3,t3,t0,t1,t2,11);
|
||||
// result of AES encryption in a0-a3
|
||||
|
||||
if( mode & AES_MIC ) {
|
||||
if( (t1 = (mode & AES_MICSUB) >> 4) != 0 ) { // last block
|
||||
do {
|
||||
// compute CMAC subkey K1 and K2
|
||||
t0 = a0 >> 31; // save MSB
|
||||
a0 = (a0 << 1) | (a1 >> 31);
|
||||
a1 = (a1 << 1) | (a2 >> 31);
|
||||
a2 = (a2 << 1) | (a3 >> 31);
|
||||
a3 = (a3 << 1);
|
||||
if( t0 ) a3 ^= 0x87;
|
||||
} while( --t1 );
|
||||
|
||||
AESAUX[0] ^= a0;
|
||||
AESAUX[1] ^= a1;
|
||||
AESAUX[2] ^= a2;
|
||||
AESAUX[3] ^= a3;
|
||||
mode &= ~AES_MICSUB;
|
||||
goto LOADDATA;
|
||||
} else {
|
||||
// save cipher block as new iv
|
||||
AESAUX[0] = a0;
|
||||
AESAUX[1] = a1;
|
||||
AESAUX[2] = a2;
|
||||
AESAUX[3] = a3;
|
||||
}
|
||||
} else { // CIPHER
|
||||
if( mode & AES_CTR ) { // xor block (partially)
|
||||
t0 = (len > 16) ? 16: len;
|
||||
for(t1=0; t1<t0; t1++) {
|
||||
buf[t1] ^= (a0>>24);
|
||||
a0 <<= 8;
|
||||
if((t1&3)==3) {
|
||||
a0 = a1;
|
||||
a1 = a2;
|
||||
a2 = a3;
|
||||
}
|
||||
}
|
||||
// update counter
|
||||
AESAUX[3]++;
|
||||
} else { // ECB
|
||||
// store block
|
||||
msbf4_write(buf+0, a0);
|
||||
msbf4_write(buf+4, a1);
|
||||
msbf4_write(buf+8, a2);
|
||||
msbf4_write(buf+12, a3);
|
||||
}
|
||||
}
|
||||
|
||||
// update block state
|
||||
if( (mode & AES_MIC)==0 || (mode & AES_MICNOAUX) ) {
|
||||
buf += 16;
|
||||
len -= 16;
|
||||
}
|
||||
mode |= AES_MICNOAUX;
|
||||
}
|
||||
return AESAUX[0];
|
||||
}
|
||||
|
152
src/debug.c
Normal file
152
src/debug.c
Normal file
@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2016 IBM Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the <organization> nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "main.h"
|
||||
#include "debug.h"
|
||||
#include "lmic.h"
|
||||
|
||||
#define myUART huart1 // <--------- change to your setup
|
||||
|
||||
/* ************************************** */
|
||||
/* DO NOT CHANGE BELOW THIS LINE */
|
||||
/* ************************************** */
|
||||
|
||||
void debug_init () {
|
||||
// configure LED pin as output
|
||||
debug_led(0);
|
||||
|
||||
// configure USART1 (115200/8N1, tx-only)
|
||||
|
||||
// print banner
|
||||
debug_str("\r\n============== DEBUG STARTED ==============\r\n");
|
||||
}
|
||||
|
||||
void debug_led (int val) {
|
||||
HAL_GPIO_WritePin(LED_GPIO_Port,LED_Pin,val);
|
||||
}
|
||||
|
||||
void debug_char (char c) {
|
||||
char buffer[] = "";
|
||||
buffer[0]= c;
|
||||
HAL_UART_Transmit(&myUART,(uint8_t*)buffer,sizeof(buffer),HAL_MAX_DELAY);
|
||||
}
|
||||
|
||||
void debug_hex (u1_t b) {
|
||||
debug_char("0123456789ABCDEF"[b>>4]);
|
||||
debug_char("0123456789ABCDEF"[b&0xF]);
|
||||
}
|
||||
|
||||
void debug_buf (const u1_t* buf, int len) {
|
||||
while(len--) {
|
||||
debug_hex(*buf++);
|
||||
debug_char(' ');
|
||||
}
|
||||
debug_char('\r');
|
||||
debug_char('\n');
|
||||
}
|
||||
|
||||
void debug_uint (u4_t v) {
|
||||
for(s1_t n=24; n>=0; n-=8) {
|
||||
debug_hex(v>>n);
|
||||
}
|
||||
}
|
||||
|
||||
void debug_int (s4_t v) {
|
||||
char buf[10], *p = buf;
|
||||
int n = debug_fmt(buf, sizeof(buf), v, 10, 0, 0);
|
||||
while(n--)
|
||||
debug_char(*p++);
|
||||
}
|
||||
|
||||
void debug_str (const char* str) {
|
||||
while(*str) {
|
||||
debug_char(*str++);
|
||||
}
|
||||
}
|
||||
|
||||
void debug_val (const char* label, u4_t val) {
|
||||
debug_str(label);
|
||||
debug_uint(val);
|
||||
debug_char('\r');
|
||||
debug_char('\n');
|
||||
}
|
||||
|
||||
void debug_valdec (const char* label, s4_t val) {
|
||||
debug_str(label);
|
||||
debug_int(val);
|
||||
debug_char('\r');
|
||||
debug_char('\n');
|
||||
}
|
||||
|
||||
int debug_fmt (char* buf, int max, s4_t val, int base, int width, char pad) {
|
||||
char num[33], *p = num, *b = buf;
|
||||
u4_t m, v;
|
||||
// special handling of negative decimals
|
||||
v = (base == 10 && val < 0) ? -val : val;
|
||||
// generate digits backwards
|
||||
do {
|
||||
*p++ = ((m=v%base) <= 9) ? m+'0' : m+'A'-10;
|
||||
} while( v /= base );
|
||||
// prefix negative decimals with '-'
|
||||
if(base == 10 && val < 0) {
|
||||
*p++ = '-';
|
||||
}
|
||||
// add leading zeroes or spaces
|
||||
while( b-buf < max-1 && b-buf < width-(p-num) ) {
|
||||
*b++ = pad;
|
||||
}
|
||||
// copy digits and sign forwards
|
||||
do *b++ = *--p;
|
||||
while( b-buf < max && p > num );
|
||||
// return number of characters written
|
||||
return b - buf;
|
||||
}
|
||||
|
||||
void debug_event (int ev) {
|
||||
static const char* evnames[] = {
|
||||
[EV_SCAN_TIMEOUT] = "SCAN_TIMEOUT",
|
||||
[EV_BEACON_FOUND] = "BEACON_FOUND",
|
||||
[EV_BEACON_MISSED] = "BEACON_MISSED",
|
||||
[EV_BEACON_TRACKED] = "BEACON_TRACKED",
|
||||
[EV_JOINING] = "JOINING",
|
||||
[EV_JOINED] = "JOINED",
|
||||
[EV_RFU1] = "RFU1",
|
||||
[EV_JOIN_FAILED] = "JOIN_FAILED",
|
||||
[EV_REJOIN_FAILED] = "REJOIN_FAILED",
|
||||
[EV_TXCOMPLETE] = "TXCOMPLETE",
|
||||
[EV_LOST_TSYNC] = "LOST_TSYNC",
|
||||
[EV_RESET] = "RESET",
|
||||
[EV_RXCOMPLETE] = "RXCOMPLETE",
|
||||
[EV_LINK_DEAD] = "LINK_DEAD",
|
||||
[EV_LINK_ALIVE] = "LINK_ALIVE",
|
||||
[EV_SCAN_FOUND] = "SCAN_FOUND",
|
||||
[EV_TXSTART] = "EV_TXSTART",
|
||||
};
|
||||
debug_str((ev < sizeof(evnames)/sizeof(evnames[0])) ? evnames[ev] : "EV_UNKNOWN" );
|
||||
debug_char('\r');
|
||||
debug_char('\n');
|
||||
}
|
228
src/hal.c
Normal file
228
src/hal.c
Normal file
@ -0,0 +1,228 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2016 IBM Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the <organization> nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is a futher development from the great IBM LMIC
|
||||
* made by Hjalmar SkovHolm Hansen
|
||||
* Denmark
|
||||
*/
|
||||
|
||||
#include "lmic.h"
|
||||
#include "main.h"
|
||||
|
||||
#define myTIMER htim2 // <--------- change to your setup
|
||||
#define mySPI hspi1 // <--------- change to your setup
|
||||
|
||||
/* ************************************** */
|
||||
/* DO NOT CHANGE BELOW THIS LINE */
|
||||
/* ************************************** */
|
||||
|
||||
|
||||
// HAL state
|
||||
static struct {
|
||||
int irqlevel;
|
||||
u4_t ticks;
|
||||
} HAL;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// I/O
|
||||
|
||||
static void hal_io_init () {
|
||||
//already done by cubemx
|
||||
}
|
||||
|
||||
// val ==1 => tx 1, rx 0 ; val == 0 => tx 0, rx 1
|
||||
void hal_pin_rxtx (u1_t val) {
|
||||
#ifdef RX_GPIO_Port
|
||||
#ifdef TX_GPIO_Port
|
||||
HAL_GPIO_WritePin(RX_GPIO_Port,RX_Pin,~val);
|
||||
HAL_GPIO_WritePin(TX_GPIO_Port,TX_Pin,val);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
// set radio NSS pin to given value
|
||||
void hal_pin_nss (u1_t val) {
|
||||
HAL_GPIO_WritePin(NSS_GPIO_Port,NSS_Pin,val);
|
||||
}
|
||||
|
||||
// set radio RST pin to given value (or keep floating!)
|
||||
void hal_pin_rst (u1_t val) {
|
||||
if(val == 0 || val == 1) { // drive pin
|
||||
GPIO_InitTypeDef GPIO_InitStruct;
|
||||
GPIO_InitStruct.Pin = RST_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
HAL_GPIO_Init(RST_GPIO_Port, &GPIO_InitStruct);
|
||||
|
||||
HAL_GPIO_WritePin(RST_GPIO_Port,RST_Pin,val);
|
||||
|
||||
} else { // keep pin floating
|
||||
GPIO_InitTypeDef GPIO_InitStruct;
|
||||
GPIO_InitStruct.Pin = RST_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
HAL_GPIO_Init(RST_GPIO_Port, &GPIO_InitStruct);
|
||||
}
|
||||
}
|
||||
|
||||
extern void radio_irq_handler(u1_t dio);
|
||||
|
||||
// generic EXTI IRQ handler for all channels
|
||||
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin_int){
|
||||
// DIO 0
|
||||
if(GPIO_Pin_int == DIO0_Pin) {
|
||||
// invoke radio handler (on IRQ!)
|
||||
radio_irq_handler(0);
|
||||
}
|
||||
// DIO 1
|
||||
if(GPIO_Pin_int == DIO1_Pin) {
|
||||
// invoke radio handler (on IRQ!)
|
||||
radio_irq_handler(1);
|
||||
}
|
||||
// DIO 2
|
||||
if(GPIO_Pin_int == DIO2_Pin) {
|
||||
// invoke radio handler (on IRQ!)
|
||||
radio_irq_handler(2);
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// SPI
|
||||
void hal_spi_init () {
|
||||
// already done by cube mx
|
||||
}
|
||||
|
||||
// perform SPI transaction with radio
|
||||
u1_t hal_spi (u1_t out) {
|
||||
char outbuffer[] ="";
|
||||
char inbuffer[] ="";
|
||||
outbuffer[0] = out;
|
||||
HAL_SPI_TransmitReceive(&mySPI,outbuffer,inbuffer,sizeof(outbuffer),HAL_MAX_DELAY);
|
||||
return inbuffer[0];
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// TIME
|
||||
static void hal_time_init () {
|
||||
// already done by cubemx
|
||||
}
|
||||
|
||||
u4_t hal_ticks () {
|
||||
hal_disableIRQs();
|
||||
u4_t t = HAL.ticks;
|
||||
u2_t cnt = __HAL_TIM_GET_COUNTER(&myTIMER);
|
||||
if(__HAL_TIM_GET_FLAG(&myTIMER, TIM_FLAG_CC1) != RESET){
|
||||
if(__HAL_TIM_GET_IT_SOURCE(&myTIMER, TIM_IT_CC1) !=RESET){
|
||||
cnt = __HAL_TIM_GET_COUNTER(&myTIMER);
|
||||
t++;
|
||||
}
|
||||
}
|
||||
hal_enableIRQs();
|
||||
return (t<<16)|cnt;
|
||||
}
|
||||
|
||||
// return modified delta ticks from now to specified ticktime (0 for past, FFFF for far future)
|
||||
static u2_t deltaticks (u4_t time) {
|
||||
u4_t t = hal_ticks();
|
||||
s4_t d = time - t;
|
||||
if( d<=0 ) return 0; // in the past
|
||||
if( (d>>16)!=0 ) return 0xFFFF; // far ahead
|
||||
return (u2_t)d;
|
||||
}
|
||||
|
||||
void hal_waitUntil (u4_t time) {
|
||||
while( deltaticks(time) != 0 ); // busy wait until timestamp is reached
|
||||
}
|
||||
|
||||
// check and rewind for target time
|
||||
u1_t hal_checkTimer (u4_t time) {
|
||||
u2_t dt;
|
||||
myTIMER.Instance->SR &= ~TIM_SR_CC1IF; // clear any pending interrupts
|
||||
if((dt = deltaticks(time)) < 5) { // event is now (a few ticks ahead)
|
||||
myTIMER.Instance->DIER &= ~TIM_DIER_CC1IE; // disable IE
|
||||
return 1;
|
||||
} else { // rewind timer (fully or to exact time))
|
||||
myTIMER.Instance->CCR1 = myTIMER.Instance->CNT + dt; // set comparator
|
||||
myTIMER.Instance->DIER |= TIM_DIER_CC1IE; // enable IE
|
||||
myTIMER.Instance->CCER |= TIM_CCER_CC1E; // enable capture/compare uint 2
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
|
||||
if(htim->Instance == myTIMER.Instance){
|
||||
HAL.ticks++;
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// IRQ
|
||||
void hal_disableIRQs () {
|
||||
__disable_irq();
|
||||
//__set_BASEPRI(1 << 4);
|
||||
HAL.irqlevel++;
|
||||
}
|
||||
|
||||
void hal_enableIRQs () {
|
||||
if(--HAL.irqlevel == 0) {
|
||||
__enable_irq();
|
||||
//__set_BASEPRI(0);
|
||||
}
|
||||
}
|
||||
|
||||
void hal_sleep () {
|
||||
// low power sleep mode
|
||||
#ifndef CFG_no_low_power_sleep_mode
|
||||
// PWR->CR |= PWR_CR_LPSDSR;
|
||||
#endif
|
||||
// suspend execution until IRQ, regardless of the CPSR I-bit
|
||||
__WFI();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void hal_init () {
|
||||
memset(&HAL, 0x00, sizeof(HAL));
|
||||
hal_disableIRQs();
|
||||
// configure radio I/O and interrupt handler
|
||||
hal_io_init();
|
||||
// configure radio SPI
|
||||
hal_spi_init();
|
||||
// configure timer and interrupt handler
|
||||
hal_time_init();
|
||||
hal_enableIRQs();
|
||||
}
|
||||
|
||||
void hal_failed () {
|
||||
// HALT...
|
||||
hal_disableIRQs();
|
||||
hal_sleep();
|
||||
while(1);
|
||||
}
|
||||
|
2229
src/lmic.c
Normal file
2229
src/lmic.c
Normal file
File diff suppressed because it is too large
Load Diff
573
src/main.c
Normal file
573
src/main.c
Normal file
@ -0,0 +1,573 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file : main.c
|
||||
* @brief : Main program body
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2023 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "main.h"
|
||||
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Includes */
|
||||
#include "lmic.h"
|
||||
#include "debug.h"
|
||||
/* USER CODE END Includes */
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PTD */
|
||||
|
||||
/* USER CODE END PTD */
|
||||
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PD */
|
||||
|
||||
/* USER CODE END PD */
|
||||
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PM */
|
||||
|
||||
/* USER CODE END PM */
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PV */
|
||||
char floatBuffer[20];
|
||||
/* USER CODE END PV */
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
void SystemClock_Config(void);
|
||||
static void MX_GPIO_Init(void);
|
||||
static void MX_SPI1_Init(void);
|
||||
static void MX_USART1_UART_Init(void);
|
||||
static void MX_USART2_UART_Init(void);
|
||||
static void MX_TIM2_Init(void);
|
||||
/* USER CODE BEGIN PFP */
|
||||
|
||||
/* USER CODE END PFP */
|
||||
|
||||
/* Private user code ---------------------------------------------------------*/
|
||||
/* USER CODE BEGIN 0 */
|
||||
|
||||
// include security credentials OTAA, check secconfig_example.h for more information
|
||||
#include "secconfig.h"
|
||||
|
||||
#ifdef DISABLE_JOIN
|
||||
// These callbacks are only used in over-the-air activation, so they are
|
||||
// left empty here. We cannot leave them out completely otherwise the linker will complain.
|
||||
// DISABLE_JOIN is set in config.h for using ABP
|
||||
void os_getArtEui (u1_t* buf) { }
|
||||
void os_getDevEui (u1_t* buf) { }
|
||||
void os_getDevKey (u1_t* buf) { }
|
||||
#else
|
||||
void os_getArtEui (u1_t* buf) { memcpy(buf, APPEUI, 8);}
|
||||
void os_getDevEui (u1_t* buf) { memcpy(buf, DEVEUI, 8);}
|
||||
void os_getDevKey (u1_t* buf) { memcpy(buf, APPKEY, 16);}
|
||||
#endif
|
||||
|
||||
void initsensor(){
|
||||
// Here you init your sensors
|
||||
}
|
||||
|
||||
void initfunc (osjob_t* j) {
|
||||
// intialize sensor hardware
|
||||
initsensor();
|
||||
// reset MAC state
|
||||
LMIC_reset();
|
||||
|
||||
// Set static session parameters when using ABP.
|
||||
// Instead of dynamically establishing a session
|
||||
// by joining the network, precomputed session parameters are be provided.
|
||||
#ifdef DISABLE_JOIN
|
||||
uint8_t appskey[sizeof(APPSKEY)];
|
||||
uint8_t nwkskey[sizeof(NWKSKEY)];
|
||||
memcpy(appskey, APPSKEY, sizeof(APPSKEY));
|
||||
memcpy(nwkskey, NWKSKEY, sizeof(NWKSKEY));
|
||||
LMIC_setSession(0x1, DEVADDR, nwkskey, appskey);
|
||||
// These settings are needed for correct communication. By removing them you
|
||||
// get empty downlink messages
|
||||
// Disable ADR
|
||||
LMIC_setAdrMode(0);
|
||||
// TTN uses SF9 for its RX2 window.
|
||||
LMIC.dn2Dr = DR_SF9;
|
||||
// prevent some downlink messages, TTN advanced setup is set to the default 5
|
||||
LMIC.rxDelay = 5;
|
||||
// Set data rate and transmit power for uplink (note: txpow seems to be ignored by the library)
|
||||
LMIC_setDrTxpow(DR_SF12, 14);
|
||||
#else
|
||||
// start joining
|
||||
LMIC_startJoining();
|
||||
#endif
|
||||
|
||||
// init done - onEvent() callback will be invoked...
|
||||
|
||||
}
|
||||
|
||||
u2_t readsensor(){
|
||||
u2_t value = 0xDF; /// read from evrything ...make your own sensor
|
||||
return value;
|
||||
}
|
||||
|
||||
static osjob_t reportjob;
|
||||
|
||||
// report sensor value every minute
|
||||
static void reportfunc (osjob_t* j) {
|
||||
// read sensor
|
||||
u2_t val = readsensor();
|
||||
debug_val("val = ", val);
|
||||
// prepare and schedule data for transmission
|
||||
LMIC.frame[0] = val << 8;
|
||||
LMIC.frame[1] = val;
|
||||
LMIC_setTxData2(1, LMIC.frame, 2, 0); // (port 1, 2 bytes, unconfirmed)
|
||||
// reschedule job in 60 seconds
|
||||
os_setTimedCallback(j, os_getTime()+sec2osticks(300), reportfunc);
|
||||
}
|
||||
|
||||
static osjob_t testjob;
|
||||
|
||||
static void testfunc (osjob_t* j){
|
||||
debug_str("Hallo Welt \n");
|
||||
// reschedule job in 6 seconds
|
||||
os_setTimedCallback(j, os_getTime()+sec2osticks(1), testfunc);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
// LMIC EVENT CALLBACK
|
||||
//////////////////////////////////////////////////
|
||||
|
||||
void onEvent (ev_t ev) {
|
||||
debug_event(ev);
|
||||
|
||||
switch(ev) {
|
||||
|
||||
// network joined, session established
|
||||
case EV_JOINING:
|
||||
debug_str("try joining\r\n");
|
||||
break;
|
||||
case EV_JOINED:
|
||||
debug_led(1);
|
||||
// kick-off periodic sensor job
|
||||
reportfunc(&reportjob);
|
||||
break;
|
||||
case EV_JOIN_FAILED:
|
||||
debug_str("join failed\r\n");
|
||||
break;
|
||||
case EV_SCAN_TIMEOUT:
|
||||
debug_str("EV_SCAN_TIMEOUT\r\n");
|
||||
break;
|
||||
case EV_BEACON_FOUND:
|
||||
debug_str("EV_BEACON_FOUND\r\n");
|
||||
break;
|
||||
case EV_BEACON_MISSED:
|
||||
debug_str("EV_BEACON_MISSED\r\n");
|
||||
break;
|
||||
case EV_BEACON_TRACKED:
|
||||
debug_str("EV_BEACON_TRACKED\r\n");
|
||||
break;
|
||||
case EV_RFU1:
|
||||
debug_str("EV_RFU1\r\n");
|
||||
break;
|
||||
case EV_REJOIN_FAILED:
|
||||
debug_str("EV_REJOIN_FAILED\r\n");
|
||||
break;
|
||||
case EV_TXCOMPLETE:
|
||||
debug_str("EV_TXCOMPLETE (includes waiting for RX windows)\r\n");
|
||||
if (LMIC.txrxFlags & TXRX_ACK)
|
||||
debug_str("Received ack\r\n");
|
||||
if (LMIC.dataLen) {
|
||||
debug_str("Received ");
|
||||
debug_str((const char*)LMIC.dataLen);
|
||||
debug_str(" bytes of payload\r\n");
|
||||
}
|
||||
break;
|
||||
case EV_LOST_TSYNC:
|
||||
debug_str("EV_LOST_TSYNC\r\n");
|
||||
break;
|
||||
case EV_RESET:
|
||||
debug_str("EV_RESET\r\n");
|
||||
break;
|
||||
case EV_RXCOMPLETE:
|
||||
// data received in ping slot
|
||||
debug_str("EV_RXCOMPLETE\r\n");
|
||||
break;
|
||||
case EV_LINK_DEAD:
|
||||
debug_str("EV_LINK_DEAD\r\n");
|
||||
break;
|
||||
case EV_LINK_ALIVE:
|
||||
debug_str("EV_LINK_ALIVE\r\n");
|
||||
break;
|
||||
default:
|
||||
debug_str("Unknown event\r\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* USER CODE END 0 */
|
||||
|
||||
/**
|
||||
* @brief The application entry point.
|
||||
* @retval int
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
/* USER CODE BEGIN 1 */
|
||||
|
||||
/* USER CODE END 1 */
|
||||
|
||||
/* MCU Configuration--------------------------------------------------------*/
|
||||
|
||||
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
|
||||
HAL_Init();
|
||||
|
||||
/* USER CODE BEGIN Init */
|
||||
|
||||
/* USER CODE END Init */
|
||||
|
||||
/* Configure the system clock */
|
||||
SystemClock_Config();
|
||||
|
||||
/* USER CODE BEGIN SysInit */
|
||||
|
||||
/* USER CODE END SysInit */
|
||||
|
||||
/* Initialize all configured peripherals */
|
||||
MX_GPIO_Init();
|
||||
MX_SPI1_Init();
|
||||
MX_USART1_UART_Init();
|
||||
MX_USART2_UART_Init();
|
||||
MX_TIM2_Init();
|
||||
|
||||
/* USER CODE BEGIN 2 */
|
||||
HAL_TIM_Base_Start_IT(&htim2); // <----------- change to your setup
|
||||
__HAL_SPI_ENABLE(&hspi1); // <----------- change to your setup
|
||||
|
||||
osjob_t initjob;
|
||||
|
||||
// initialize runtime env
|
||||
os_init();
|
||||
|
||||
// initialize debug library
|
||||
debug_init();
|
||||
|
||||
|
||||
// setup initial job
|
||||
os_setCallback(&initjob, initfunc);
|
||||
// execute scheduled jobs and events
|
||||
// os_setTimedCallback(&testjob, os_getTime()+sec2osticks(1), testfunc);
|
||||
os_setTimedCallback(&reportjob, os_getTime()+sec2osticks(300), reportfunc);
|
||||
os_runloop();
|
||||
// (not reached)
|
||||
return 0;
|
||||
|
||||
|
||||
/* USER CODE END 2 */
|
||||
|
||||
/* Infinite loop */
|
||||
/* USER CODE BEGIN WHILE */
|
||||
while (1)
|
||||
{
|
||||
/* USER CODE END WHILE */
|
||||
/* USER CODE BEGIN 3 */
|
||||
}
|
||||
/* USER CODE END 3 */
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief System Clock Configuration
|
||||
* @retval None
|
||||
*/
|
||||
void SystemClock_Config(void)
|
||||
{
|
||||
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
|
||||
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
|
||||
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
|
||||
|
||||
/** Configure the main internal regulator output voltage
|
||||
*/
|
||||
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
|
||||
|
||||
/** Initializes the RCC Oscillators according to the specified parameters
|
||||
* in the RCC_OscInitTypeDef structure.
|
||||
*/
|
||||
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
|
||||
RCC_OscInitStruct.HSIState = RCC_HSI_DIV4;
|
||||
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
|
||||
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
|
||||
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
|
||||
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_8;
|
||||
RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_4;
|
||||
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
/** Initializes the CPU, AHB and APB buses clocks
|
||||
*/
|
||||
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|
||||
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
|
||||
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
|
||||
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
|
||||
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
|
||||
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
|
||||
|
||||
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1|RCC_PERIPHCLK_USART2;
|
||||
PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2;
|
||||
PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;
|
||||
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SPI1 Initialization Function
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
static void MX_SPI1_Init(void)
|
||||
{
|
||||
|
||||
/* USER CODE BEGIN SPI1_Init 0 */
|
||||
|
||||
/* USER CODE END SPI1_Init 0 */
|
||||
|
||||
/* USER CODE BEGIN SPI1_Init 1 */
|
||||
|
||||
/* USER CODE END SPI1_Init 1 */
|
||||
/* SPI1 parameter configuration*/
|
||||
hspi1.Instance = SPI1;
|
||||
hspi1.Init.Mode = SPI_MODE_MASTER;
|
||||
hspi1.Init.Direction = SPI_DIRECTION_2LINES;
|
||||
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
|
||||
hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
|
||||
hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
|
||||
hspi1.Init.NSS = SPI_NSS_SOFT;
|
||||
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64;
|
||||
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
|
||||
hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
|
||||
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
|
||||
hspi1.Init.CRCPolynomial = 7;
|
||||
if (HAL_SPI_Init(&hspi1) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
/* USER CODE BEGIN SPI1_Init 2 */
|
||||
|
||||
/* USER CODE END SPI1_Init 2 */
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief TIM2 Initialization Function
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
static void MX_TIM2_Init(void)
|
||||
{
|
||||
|
||||
/* USER CODE BEGIN TIM2_Init 0 */
|
||||
|
||||
/* USER CODE END TIM2_Init 0 */
|
||||
|
||||
TIM_MasterConfigTypeDef sMasterConfig = {0};
|
||||
TIM_OC_InitTypeDef sConfigOC = {0};
|
||||
|
||||
/* USER CODE BEGIN TIM2_Init 1 */
|
||||
|
||||
/* USER CODE END TIM2_Init 1 */
|
||||
htim2.Instance = TIM2;
|
||||
htim2.Init.Prescaler = 250-1;
|
||||
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
|
||||
htim2.Init.Period = 65535-1;
|
||||
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
|
||||
htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
|
||||
if (HAL_TIM_OC_Init(&htim2) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
|
||||
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
|
||||
if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
sConfigOC.OCMode = TIM_OCMODE_TIMING;
|
||||
sConfigOC.Pulse = 0;
|
||||
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
|
||||
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
|
||||
if (HAL_TIM_OC_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
/* USER CODE BEGIN TIM2_Init 2 */
|
||||
|
||||
/* USER CODE END TIM2_Init 2 */
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USART1 Initialization Function
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
static void MX_USART1_UART_Init(void)
|
||||
{
|
||||
|
||||
/* USER CODE BEGIN USART1_Init 0 */
|
||||
|
||||
/* USER CODE END USART1_Init 0 */
|
||||
|
||||
/* USER CODE BEGIN USART1_Init 1 */
|
||||
|
||||
/* USER CODE END USART1_Init 1 */
|
||||
huart1.Instance = USART1;
|
||||
huart1.Init.BaudRate = 9600;
|
||||
huart1.Init.WordLength = UART_WORDLENGTH_8B;
|
||||
huart1.Init.StopBits = UART_STOPBITS_1;
|
||||
huart1.Init.Parity = UART_PARITY_NONE;
|
||||
huart1.Init.Mode = UART_MODE_TX_RX;
|
||||
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
|
||||
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
|
||||
huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
|
||||
huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
|
||||
if (HAL_UART_Init(&huart1) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
/* USER CODE BEGIN USART1_Init 2 */
|
||||
|
||||
/* USER CODE END USART1_Init 2 */
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USART2 Initialization Function
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
static void MX_USART2_UART_Init(void)
|
||||
{
|
||||
|
||||
/* USER CODE BEGIN USART2_Init 0 */
|
||||
|
||||
/* USER CODE END USART2_Init 0 */
|
||||
|
||||
/* USER CODE BEGIN USART2_Init 1 */
|
||||
|
||||
/* USER CODE END USART2_Init 1 */
|
||||
huart2.Instance = USART2;
|
||||
huart2.Init.BaudRate = 9600;
|
||||
huart2.Init.WordLength = UART_WORDLENGTH_8B;
|
||||
huart2.Init.StopBits = UART_STOPBITS_1;
|
||||
huart2.Init.Parity = UART_PARITY_NONE;
|
||||
huart2.Init.Mode = UART_MODE_TX_RX;
|
||||
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
|
||||
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
|
||||
huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
|
||||
huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
|
||||
if (HAL_UART_Init(&huart2) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
/* USER CODE BEGIN USART2_Init 2 */
|
||||
|
||||
/* USER CODE END USART2_Init 2 */
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief GPIO Initialization Function
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
static void MX_GPIO_Init(void)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
/* USER CODE BEGIN MX_GPIO_Init_1 */
|
||||
/* USER CODE END MX_GPIO_Init_1 */
|
||||
|
||||
/* GPIO Ports Clock Enable */
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||||
|
||||
/*Configure GPIO pin Output Level */
|
||||
HAL_GPIO_WritePin(GPIOA, LED_Pin|NSS_Pin|RST_Pin, GPIO_PIN_RESET);
|
||||
|
||||
/*Configure GPIO pins : LED_Pin NSS_Pin RST_Pin */
|
||||
GPIO_InitStruct.Pin = LED_Pin|NSS_Pin|RST_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
/*Configure GPIO pin : DIO0_Pin */
|
||||
GPIO_InitStruct.Pin = DIO0_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
HAL_GPIO_Init(DIO0_GPIO_Port, &GPIO_InitStruct);
|
||||
|
||||
/*Configure GPIO pins : DIO1_Pin DIO2_Pin */
|
||||
GPIO_InitStruct.Pin = DIO1_Pin|DIO2_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||
|
||||
/* EXTI interrupt init*/
|
||||
HAL_NVIC_SetPriority(EXTI4_15_IRQn, 0, 0);
|
||||
HAL_NVIC_EnableIRQ(EXTI4_15_IRQn);
|
||||
|
||||
/* USER CODE BEGIN MX_GPIO_Init_2 */
|
||||
/* USER CODE END MX_GPIO_Init_2 */
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN 4 */
|
||||
|
||||
/* USER CODE END 4 */
|
||||
|
||||
/**
|
||||
* @brief This function is executed in case of error occurrence.
|
||||
* @retval None
|
||||
*/
|
||||
void Error_Handler(void)
|
||||
{
|
||||
/* USER CODE BEGIN Error_Handler_Debug */
|
||||
/* User can add his own implementation to report the HAL error return state */
|
||||
__disable_irq();
|
||||
while (1)
|
||||
{
|
||||
}
|
||||
/* USER CODE END Error_Handler_Debug */
|
||||
}
|
||||
|
||||
#ifdef USE_FULL_ASSERT
|
||||
/**
|
||||
* @brief Reports the name of the source file and the source line number
|
||||
* where the assert_param error has occurred.
|
||||
* @param file: pointer to the source file name
|
||||
* @param line: assert_param error line source number
|
||||
* @retval None
|
||||
*/
|
||||
void assert_failed(uint8_t *file, uint32_t line)
|
||||
{
|
||||
/* USER CODE BEGIN 6 */
|
||||
/* User can add his own implementation to report the file name and line number,
|
||||
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
|
||||
/* USER CODE END 6 */
|
||||
}
|
||||
#endif /* USE_FULL_ASSERT */
|
122
src/oslmic.c
Normal file
122
src/oslmic.c
Normal file
@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2016 IBM Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the <organization> nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "lmic.h"
|
||||
|
||||
// RUNTIME STATE
|
||||
static struct {
|
||||
osjob_t* scheduledjobs;
|
||||
osjob_t* runnablejobs;
|
||||
} OS;
|
||||
|
||||
void os_init () {
|
||||
memset(&OS, 0x00, sizeof(OS));
|
||||
hal_init();
|
||||
radio_init();
|
||||
LMIC_init();
|
||||
}
|
||||
|
||||
ostime_t os_getTime () {
|
||||
return hal_ticks();
|
||||
}
|
||||
|
||||
// unlink job from queue, return if removed
|
||||
static int unlinkjob (osjob_t** pnext, osjob_t* job) {
|
||||
for( ; *pnext; pnext = &((*pnext)->next)) {
|
||||
if(*pnext == job) { // unlink
|
||||
*pnext = job->next;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// clear scheduled job
|
||||
void os_clearCallback (osjob_t* job) {
|
||||
hal_disableIRQs();
|
||||
unlinkjob(&OS.scheduledjobs, job) || unlinkjob(&OS.runnablejobs, job);
|
||||
hal_enableIRQs();
|
||||
}
|
||||
|
||||
// schedule immediately runnable 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;
|
||||
job->next = NULL;
|
||||
// add to end of run queue
|
||||
for(pnext=&OS.runnablejobs; *pnext; pnext=&((*pnext)->next));
|
||||
*pnext = job;
|
||||
hal_enableIRQs();
|
||||
}
|
||||
|
||||
// schedule timed job
|
||||
void os_setTimedCallback (osjob_t* job, ostime_t time, osjobcb_t cb) {
|
||||
osjob_t** pnext;
|
||||
hal_disableIRQs();
|
||||
// remove if job was already queued
|
||||
unlinkjob(&OS.scheduledjobs, job);
|
||||
// fill-in job
|
||||
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!)
|
||||
// enqueue before next element and stop
|
||||
job->next = *pnext;
|
||||
break;
|
||||
}
|
||||
}
|
||||
*pnext = job;
|
||||
hal_enableIRQs();
|
||||
}
|
||||
|
||||
// execute jobs from timer and from run queue
|
||||
void os_runloop () {
|
||||
while(1) {
|
||||
osjob_t* j = NULL;
|
||||
hal_disableIRQs();
|
||||
// check for runnable jobs
|
||||
if(OS.runnablejobs) {
|
||||
j = OS.runnablejobs;
|
||||
OS.runnablejobs = j->next;
|
||||
} else if(OS.scheduledjobs && hal_checkTimer(OS.scheduledjobs->deadline)) { // check for expired timed jobs
|
||||
j = OS.scheduledjobs;
|
||||
OS.scheduledjobs = j->next;
|
||||
} else { // nothing pending
|
||||
hal_sleep(); // wake by irq (timer already restarted)
|
||||
}
|
||||
hal_enableIRQs();
|
||||
if(j) { // run job callback
|
||||
j->func(j);
|
||||
}
|
||||
}
|
||||
}
|
857
src/radio.c
Normal file
857
src/radio.c
Normal file
@ -0,0 +1,857 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2016 IBM Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the <organization> nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "lmic.h"
|
||||
|
||||
// ----------------------------------------
|
||||
// Registers Mapping
|
||||
#define RegFifo 0x00 // common
|
||||
#define RegOpMode 0x01 // common
|
||||
#define FSKRegBitrateMsb 0x02
|
||||
#define FSKRegBitrateLsb 0x03
|
||||
#define FSKRegFdevMsb 0x04
|
||||
#define FSKRegFdevLsb 0x05
|
||||
#define RegFrfMsb 0x06 // common
|
||||
#define RegFrfMid 0x07 // common
|
||||
#define RegFrfLsb 0x08 // common
|
||||
#define RegPaConfig 0x09 // common
|
||||
#define RegPaRamp 0x0A // common
|
||||
#define RegOcp 0x0B // common
|
||||
#define RegLna 0x0C // common
|
||||
#define FSKRegRxConfig 0x0D
|
||||
#define LORARegFifoAddrPtr 0x0D
|
||||
#define FSKRegRssiConfig 0x0E
|
||||
#define LORARegFifoTxBaseAddr 0x0E
|
||||
#define FSKRegRssiCollision 0x0F
|
||||
#define LORARegFifoRxBaseAddr 0x0F
|
||||
#define FSKRegRssiThresh 0x10
|
||||
#define LORARegFifoRxCurrentAddr 0x10
|
||||
#define FSKRegRssiValue 0x11
|
||||
#define LORARegIrqFlagsMask 0x11
|
||||
#define FSKRegRxBw 0x12
|
||||
#define LORARegIrqFlags 0x12
|
||||
#define FSKRegAfcBw 0x13
|
||||
#define LORARegRxNbBytes 0x13
|
||||
#define FSKRegOokPeak 0x14
|
||||
#define LORARegRxHeaderCntValueMsb 0x14
|
||||
#define FSKRegOokFix 0x15
|
||||
#define LORARegRxHeaderCntValueLsb 0x15
|
||||
#define FSKRegOokAvg 0x16
|
||||
#define LORARegRxPacketCntValueMsb 0x16
|
||||
#define LORARegRxpacketCntValueLsb 0x17
|
||||
#define LORARegModemStat 0x18
|
||||
#define LORARegPktSnrValue 0x19
|
||||
#define FSKRegAfcFei 0x1A
|
||||
#define LORARegPktRssiValue 0x1A
|
||||
#define FSKRegAfcMsb 0x1B
|
||||
#define LORARegRssiValue 0x1B
|
||||
#define FSKRegAfcLsb 0x1C
|
||||
#define LORARegHopChannel 0x1C
|
||||
#define FSKRegFeiMsb 0x1D
|
||||
#define LORARegModemConfig1 0x1D
|
||||
#define FSKRegFeiLsb 0x1E
|
||||
#define LORARegModemConfig2 0x1E
|
||||
#define FSKRegPreambleDetect 0x1F
|
||||
#define LORARegSymbTimeoutLsb 0x1F
|
||||
#define FSKRegRxTimeout1 0x20
|
||||
#define LORARegPreambleMsb 0x20
|
||||
#define FSKRegRxTimeout2 0x21
|
||||
#define LORARegPreambleLsb 0x21
|
||||
#define FSKRegRxTimeout3 0x22
|
||||
#define LORARegPayloadLength 0x22
|
||||
#define FSKRegRxDelay 0x23
|
||||
#define LORARegPayloadMaxLength 0x23
|
||||
#define FSKRegOsc 0x24
|
||||
#define LORARegHopPeriod 0x24
|
||||
#define FSKRegPreambleMsb 0x25
|
||||
#define LORARegFifoRxByteAddr 0x25
|
||||
#define LORARegModemConfig3 0x26
|
||||
#define FSKRegPreambleLsb 0x26
|
||||
#define FSKRegSyncConfig 0x27
|
||||
#define LORARegFeiMsb 0x28
|
||||
#define FSKRegSyncValue1 0x28
|
||||
#define LORAFeiMib 0x29
|
||||
#define FSKRegSyncValue2 0x29
|
||||
#define LORARegFeiLsb 0x2A
|
||||
#define FSKRegSyncValue3 0x2A
|
||||
#define FSKRegSyncValue4 0x2B
|
||||
#define LORARegRssiWideband 0x2C
|
||||
#define FSKRegSyncValue5 0x2C
|
||||
#define FSKRegSyncValue6 0x2D
|
||||
#define FSKRegSyncValue7 0x2E
|
||||
#define FSKRegSyncValue8 0x2F
|
||||
#define FSKRegPacketConfig1 0x30
|
||||
#define FSKRegPacketConfig2 0x31
|
||||
#define LORARegDetectOptimize 0x31
|
||||
#define FSKRegPayloadLength 0x32
|
||||
#define FSKRegNodeAdrs 0x33
|
||||
#define LORARegInvertIQ 0x33
|
||||
#define FSKRegBroadcastAdrs 0x34
|
||||
#define FSKRegFifoThresh 0x35
|
||||
#define FSKRegSeqConfig1 0x36
|
||||
#define FSKRegSeqConfig2 0x37
|
||||
#define LORARegDetectionThreshold 0x37
|
||||
#define FSKRegTimerResol 0x38
|
||||
#define FSKRegTimer1Coef 0x39
|
||||
#define LORARegSyncWord 0x39
|
||||
#define FSKRegTimer2Coef 0x3A
|
||||
#define FSKRegImageCal 0x3B
|
||||
#define FSKRegTemp 0x3C
|
||||
#define FSKRegLowBat 0x3D
|
||||
#define FSKRegIrqFlags1 0x3E
|
||||
#define FSKRegIrqFlags2 0x3F
|
||||
#define RegDioMapping1 0x40 // common
|
||||
#define RegDioMapping2 0x41 // common
|
||||
#define RegVersion 0x42 // common
|
||||
// #define RegAgcRef 0x43 // common
|
||||
// #define RegAgcThresh1 0x44 // common
|
||||
// #define RegAgcThresh2 0x45 // common
|
||||
// #define RegAgcThresh3 0x46 // common
|
||||
// #define RegPllHop 0x4B // common
|
||||
// #define RegTcxo 0x58 // common
|
||||
#define RegPaDac 0x5A // common
|
||||
// #define RegPll 0x5C // common
|
||||
// #define RegPllLowPn 0x5E // common
|
||||
// #define RegFormerTemp 0x6C // common
|
||||
// #define RegBitRateFrac 0x70 // common
|
||||
|
||||
// ----------------------------------------
|
||||
// spread factors and mode for RegModemConfig2
|
||||
#define SX1272_MC2_FSK 0x00
|
||||
#define SX1272_MC2_SF7 0x70
|
||||
#define SX1272_MC2_SF8 0x80
|
||||
#define SX1272_MC2_SF9 0x90
|
||||
#define SX1272_MC2_SF10 0xA0
|
||||
#define SX1272_MC2_SF11 0xB0
|
||||
#define SX1272_MC2_SF12 0xC0
|
||||
// bandwidth for RegModemConfig1
|
||||
#define SX1272_MC1_BW_125 0x00
|
||||
#define SX1272_MC1_BW_250 0x40
|
||||
#define SX1272_MC1_BW_500 0x80
|
||||
// coding rate for RegModemConfig1
|
||||
#define SX1272_MC1_CR_4_5 0x08
|
||||
#define SX1272_MC1_CR_4_6 0x10
|
||||
#define SX1272_MC1_CR_4_7 0x18
|
||||
#define SX1272_MC1_CR_4_8 0x20
|
||||
#define SX1272_MC1_IMPLICIT_HEADER_MODE_ON 0x04 // required for receive
|
||||
#define SX1272_MC1_RX_PAYLOAD_CRCON 0x02
|
||||
#define SX1272_MC1_LOW_DATA_RATE_OPTIMIZE 0x01 // mandated for SF11 and SF12
|
||||
// transmit power configuration for RegPaConfig
|
||||
#define SX1272_PAC_PA_SELECT_PA_BOOST 0x80
|
||||
#define SX1272_PAC_PA_SELECT_RFIO_PIN 0x00
|
||||
|
||||
|
||||
// sx1276 RegModemConfig1
|
||||
#define SX1276_MC1_BW_125 0x70
|
||||
#define SX1276_MC1_BW_250 0x80
|
||||
#define SX1276_MC1_BW_500 0x90
|
||||
#define SX1276_MC1_CR_4_5 0x02
|
||||
#define SX1276_MC1_CR_4_6 0x04
|
||||
#define SX1276_MC1_CR_4_7 0x06
|
||||
#define SX1276_MC1_CR_4_8 0x08
|
||||
|
||||
#define SX1276_MC1_IMPLICIT_HEADER_MODE_ON 0x01
|
||||
|
||||
// sx1276 RegModemConfig2
|
||||
#define SX1276_MC2_RX_PAYLOAD_CRCON 0x04
|
||||
|
||||
// sx1276 RegModemConfig3
|
||||
#define SX1276_MC3_LOW_DATA_RATE_OPTIMIZE 0x08
|
||||
#define SX1276_MC3_AGCAUTO 0x04
|
||||
|
||||
// preamble for lora networks (nibbles swapped)
|
||||
#define LORA_MAC_PREAMBLE 0x34
|
||||
|
||||
#define RXLORA_RXMODE_RSSI_REG_MODEM_CONFIG1 0x0A
|
||||
#ifdef CFG_sx1276_radio
|
||||
#define RXLORA_RXMODE_RSSI_REG_MODEM_CONFIG2 0x70
|
||||
#elif CFG_sx1272_radio
|
||||
#define RXLORA_RXMODE_RSSI_REG_MODEM_CONFIG2 0x74
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// ----------------------------------------
|
||||
// Constants for radio registers
|
||||
#define OPMODE_LORA 0x80
|
||||
#define OPMODE_MASK 0x07
|
||||
#define OPMODE_SLEEP 0x00
|
||||
#define OPMODE_STANDBY 0x01
|
||||
#define OPMODE_FSTX 0x02
|
||||
#define OPMODE_TX 0x03
|
||||
#define OPMODE_FSRX 0x04
|
||||
#define OPMODE_RX 0x05
|
||||
#define OPMODE_RX_SINGLE 0x06
|
||||
#define OPMODE_CAD 0x07
|
||||
|
||||
// ----------------------------------------
|
||||
// Bits masking the corresponding IRQs from the radio
|
||||
#define IRQ_LORA_RXTOUT_MASK 0x80
|
||||
#define IRQ_LORA_RXDONE_MASK 0x40
|
||||
#define IRQ_LORA_CRCERR_MASK 0x20
|
||||
#define IRQ_LORA_HEADER_MASK 0x10
|
||||
#define IRQ_LORA_TXDONE_MASK 0x08
|
||||
#define IRQ_LORA_CDDONE_MASK 0x04
|
||||
#define IRQ_LORA_FHSSCH_MASK 0x02
|
||||
#define IRQ_LORA_CDDETD_MASK 0x01
|
||||
|
||||
#define IRQ_FSK1_MODEREADY_MASK 0x80
|
||||
#define IRQ_FSK1_RXREADY_MASK 0x40
|
||||
#define IRQ_FSK1_TXREADY_MASK 0x20
|
||||
#define IRQ_FSK1_PLLLOCK_MASK 0x10
|
||||
#define IRQ_FSK1_RSSI_MASK 0x08
|
||||
#define IRQ_FSK1_TIMEOUT_MASK 0x04
|
||||
#define IRQ_FSK1_PREAMBLEDETECT_MASK 0x02
|
||||
#define IRQ_FSK1_SYNCADDRESSMATCH_MASK 0x01
|
||||
#define IRQ_FSK2_FIFOFULL_MASK 0x80
|
||||
#define IRQ_FSK2_FIFOEMPTY_MASK 0x40
|
||||
#define IRQ_FSK2_FIFOLEVEL_MASK 0x20
|
||||
#define IRQ_FSK2_FIFOOVERRUN_MASK 0x10
|
||||
#define IRQ_FSK2_PACKETSENT_MASK 0x08
|
||||
#define IRQ_FSK2_PAYLOADREADY_MASK 0x04
|
||||
#define IRQ_FSK2_CRCOK_MASK 0x02
|
||||
#define IRQ_FSK2_LOWBAT_MASK 0x01
|
||||
|
||||
// ----------------------------------------
|
||||
// DIO function mappings D0D1D2D3
|
||||
#define MAP_DIO0_LORA_RXDONE 0x00 // 00------
|
||||
#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_DIO0_FSK_READY 0x00 // 00------ (packet sent / payload ready)
|
||||
#define MAP_DIO1_FSK_NOP 0x30 // --11----
|
||||
#define MAP_DIO2_FSK_TXNOP 0x04 // ----01--
|
||||
#define MAP_DIO2_FSK_TIMEOUT 0x08 // ----10--
|
||||
|
||||
|
||||
// FSK IMAGECAL defines
|
||||
#define RF_IMAGECAL_AUTOIMAGECAL_MASK 0x7F
|
||||
#define RF_IMAGECAL_AUTOIMAGECAL_ON 0x80
|
||||
#define RF_IMAGECAL_AUTOIMAGECAL_OFF 0x00 // Default
|
||||
|
||||
#define RF_IMAGECAL_IMAGECAL_MASK 0xBF
|
||||
#define RF_IMAGECAL_IMAGECAL_START 0x40
|
||||
|
||||
#define RF_IMAGECAL_IMAGECAL_RUNNING 0x20
|
||||
#define RF_IMAGECAL_IMAGECAL_DONE 0x00 // Default
|
||||
|
||||
|
||||
// RADIO STATE
|
||||
// (initialized by radio_init(), used by radio_rand1())
|
||||
static u1_t randbuf[16];
|
||||
|
||||
|
||||
#ifdef CFG_sx1276_radio
|
||||
#define LNA_RX_GAIN (0x20|0x1)
|
||||
#elif CFG_sx1272_radio
|
||||
#define LNA_RX_GAIN (0x20|0x03)
|
||||
#else
|
||||
#error Missing CFG_sx1272_radio/CFG_sx1276_radio
|
||||
#endif
|
||||
|
||||
|
||||
static void writeReg (u1_t addr, u1_t data ) {
|
||||
hal_pin_nss(0);
|
||||
hal_spi(addr | 0x80);
|
||||
hal_spi(data);
|
||||
hal_pin_nss(1);
|
||||
}
|
||||
|
||||
static u1_t readReg (u1_t addr) {
|
||||
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) {
|
||||
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) {
|
||||
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 opmode (u1_t mode) {
|
||||
writeReg(RegOpMode, (readReg(RegOpMode) & ~OPMODE_MASK) | mode);
|
||||
}
|
||||
|
||||
static void opmodeLora() {
|
||||
u1_t u = OPMODE_LORA;
|
||||
#ifdef CFG_sx1276_radio
|
||||
u |= 0x8; // TBD: sx1276 high freq
|
||||
#endif
|
||||
writeReg(RegOpMode, u);
|
||||
}
|
||||
|
||||
static void opmodeFSK() {
|
||||
u1_t u = 0;
|
||||
#ifdef CFG_sx1276_radio
|
||||
u |= 0x8; // TBD: sx1276 high freq
|
||||
#endif
|
||||
writeReg(RegOpMode, u);
|
||||
}
|
||||
|
||||
// configure LoRa modem (cfg1, cfg2)
|
||||
static void configLoraModem () {
|
||||
sf_t sf = getSf(LMIC.rps);
|
||||
|
||||
#ifdef CFG_sx1276_radio
|
||||
u1_t mc1 = 0, mc2 = 0, mc3 = 0;
|
||||
|
||||
switch (getBw(LMIC.rps)) {
|
||||
case BW125: mc1 |= SX1276_MC1_BW_125; break;
|
||||
case BW250: mc1 |= SX1276_MC1_BW_250; break;
|
||||
case BW500: mc1 |= SX1276_MC1_BW_500; break;
|
||||
default:
|
||||
ASSERT(0);
|
||||
}
|
||||
switch( getCr(LMIC.rps) ) {
|
||||
case CR_4_5: mc1 |= SX1276_MC1_CR_4_5; break;
|
||||
case CR_4_6: mc1 |= SX1276_MC1_CR_4_6; break;
|
||||
case CR_4_7: mc1 |= SX1276_MC1_CR_4_7; break;
|
||||
case CR_4_8: mc1 |= SX1276_MC1_CR_4_8; break;
|
||||
default:
|
||||
ASSERT(0);
|
||||
}
|
||||
|
||||
if (getIh(LMIC.rps)) {
|
||||
mc1 |= SX1276_MC1_IMPLICIT_HEADER_MODE_ON;
|
||||
writeReg(LORARegPayloadLength, getIh(LMIC.rps)); // required length
|
||||
}
|
||||
// set ModemConfig1
|
||||
writeReg(LORARegModemConfig1, mc1);
|
||||
|
||||
mc2 = (SX1272_MC2_SF7 + ((sf-1)<<4));
|
||||
if (getNocrc(LMIC.rps) == 0) {
|
||||
mc2 |= SX1276_MC2_RX_PAYLOAD_CRCON;
|
||||
}
|
||||
writeReg(LORARegModemConfig2, mc2);
|
||||
|
||||
mc3 = SX1276_MC3_AGCAUTO;
|
||||
if ((sf == SF11 || sf == SF12) && getBw(LMIC.rps) == BW125) {
|
||||
mc3 |= SX1276_MC3_LOW_DATA_RATE_OPTIMIZE;
|
||||
}
|
||||
writeReg(LORARegModemConfig3, mc3);
|
||||
#elif CFG_sx1272_radio
|
||||
u1_t mc1 = (getBw(LMIC.rps)<<6);
|
||||
|
||||
switch( getCr(LMIC.rps) ) {
|
||||
case CR_4_5: mc1 |= SX1272_MC1_CR_4_5; break;
|
||||
case CR_4_6: mc1 |= SX1272_MC1_CR_4_6; break;
|
||||
case CR_4_7: mc1 |= SX1272_MC1_CR_4_7; break;
|
||||
case CR_4_8: mc1 |= SX1272_MC1_CR_4_8; break;
|
||||
}
|
||||
|
||||
if ((sf == SF11 || sf == SF12) && getBw(LMIC.rps) == BW125) {
|
||||
mc1 |= SX1272_MC1_LOW_DATA_RATE_OPTIMIZE;
|
||||
}
|
||||
|
||||
if (getNocrc(LMIC.rps) == 0) {
|
||||
mc1 |= SX1272_MC1_RX_PAYLOAD_CRCON;
|
||||
}
|
||||
|
||||
if (getIh(LMIC.rps)) {
|
||||
mc1 |= SX1272_MC1_IMPLICIT_HEADER_MODE_ON;
|
||||
writeReg(LORARegPayloadLength, getIh(LMIC.rps)); // required length
|
||||
}
|
||||
// set ModemConfig1
|
||||
writeReg(LORARegModemConfig1, mc1);
|
||||
|
||||
// set ModemConfig2 (sf, AgcAutoOn=1 SymbTimeoutHi=00)
|
||||
writeReg(LORARegModemConfig2, (SX1272_MC2_SF7 + ((sf-1)<<4)) | 0x04);
|
||||
|
||||
#if CFG_TxContinuousMode
|
||||
// Only for testing
|
||||
// set ModemConfig2 (sf, TxContinuousMode=1, AgcAutoOn=1 SymbTimeoutHi=00)
|
||||
writeReg(LORARegModemConfig2, (SX1272_MC2_SF7 + ((sf-1)<<4)) | 0x06);
|
||||
#endif
|
||||
|
||||
#else
|
||||
#error Missing CFG_sx1272_radio/CFG_sx1276_radio
|
||||
#endif /* CFG_sx1272_radio */
|
||||
}
|
||||
|
||||
static void configChannel () {
|
||||
// set frequency: FQ = (FRF * 32 Mhz) / (2 ^ 19)
|
||||
u8_t frf = ((u8_t)LMIC.freq << 19) / 32000000;
|
||||
writeReg(RegFrfMsb, (u1_t)(frf>>16));
|
||||
writeReg(RegFrfMid, (u1_t)(frf>> 8));
|
||||
writeReg(RegFrfLsb, (u1_t)(frf>> 0));
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void configPower () {
|
||||
#ifdef CFG_sx1276_radio
|
||||
// no boost used for now
|
||||
s1_t pw = (s1_t)LMIC.txpow;
|
||||
if(pw >= 17) {
|
||||
pw = 15;
|
||||
} else if(pw < 2) {
|
||||
pw = 2;
|
||||
}
|
||||
// check board type for BOOST pin
|
||||
writeReg(RegPaConfig, (u1_t)(0x80|(pw&0xf)));
|
||||
writeReg(RegPaDac, readReg(RegPaDac)|0x4);
|
||||
|
||||
#elif CFG_sx1272_radio
|
||||
// set PA config (2-17 dBm using PA_BOOST)
|
||||
s1_t pw = (s1_t)LMIC.txpow;
|
||||
if(pw > 17) {
|
||||
pw = 17;
|
||||
} else if(pw < 2) {
|
||||
pw = 2;
|
||||
}
|
||||
writeReg(RegPaConfig, (u1_t)(0x80|(pw-2)));
|
||||
#else
|
||||
#error Missing CFG_sx1272_radio/CFG_sx1276_radio
|
||||
#endif /* CFG_sx1272_radio */
|
||||
}
|
||||
|
||||
static void txfsk () {
|
||||
// select FSK modem (from sleep mode)
|
||||
writeReg(RegOpMode, 0x10); // FSK, BT=0.5
|
||||
ASSERT(readReg(RegOpMode) == 0x10);
|
||||
// enter standby mode (required for FIFO loading))
|
||||
opmode(OPMODE_STANDBY);
|
||||
// set bitrate
|
||||
writeReg(FSKRegBitrateMsb, 0x02); // 50kbps
|
||||
writeReg(FSKRegBitrateLsb, 0x80);
|
||||
// set frequency deviation
|
||||
writeReg(FSKRegFdevMsb, 0x01); // +/- 25kHz
|
||||
writeReg(FSKRegFdevLsb, 0x99);
|
||||
// frame and packet handler settings
|
||||
writeReg(FSKRegPreambleMsb, 0x00);
|
||||
writeReg(FSKRegPreambleLsb, 0x05);
|
||||
writeReg(FSKRegSyncConfig, 0x12);
|
||||
writeReg(FSKRegPacketConfig1, 0xD0);
|
||||
writeReg(FSKRegPacketConfig2, 0x40);
|
||||
writeReg(FSKRegSyncValue1, 0xC1);
|
||||
writeReg(FSKRegSyncValue2, 0x94);
|
||||
writeReg(FSKRegSyncValue3, 0xC1);
|
||||
// configure frequency
|
||||
configChannel();
|
||||
// configure output power
|
||||
configPower();
|
||||
|
||||
// set the IRQ mapping DIO0=PacketSent DIO1=NOP DIO2=NOP
|
||||
writeReg(RegDioMapping1, MAP_DIO0_FSK_READY|MAP_DIO1_FSK_NOP|MAP_DIO2_FSK_TXNOP);
|
||||
|
||||
// initialize the payload size and address pointers
|
||||
writeReg(FSKRegPayloadLength, LMIC.dataLen+1); // (insert length byte into payload))
|
||||
|
||||
// download length byte and buffer to the radio FIFO
|
||||
writeReg(RegFifo, LMIC.dataLen);
|
||||
writeBuf(RegFifo, LMIC.frame, LMIC.dataLen);
|
||||
|
||||
// enable antenna switch for TX
|
||||
hal_pin_rxtx(1);
|
||||
|
||||
// now we actually start the transmission
|
||||
opmode(OPMODE_TX);
|
||||
}
|
||||
|
||||
static void txlora () {
|
||||
// select LoRa modem (from sleep mode)
|
||||
//writeReg(RegOpMode, OPMODE_LORA);
|
||||
opmodeLora();
|
||||
ASSERT((readReg(RegOpMode) & OPMODE_LORA) != 0);
|
||||
|
||||
// enter standby mode (required for FIFO loading))
|
||||
opmode(OPMODE_STANDBY);
|
||||
// configure LoRa modem (cfg1, cfg2)
|
||||
configLoraModem();
|
||||
// configure frequency
|
||||
configChannel();
|
||||
// configure output power
|
||||
writeReg(RegPaRamp, (readReg(RegPaRamp) & 0xF0) | 0x08); // set PA ramp-up time 50 uSec
|
||||
configPower();
|
||||
// set sync word
|
||||
writeReg(LORARegSyncWord, LORA_MAC_PREAMBLE);
|
||||
|
||||
// set the IRQ mapping DIO0=TxDone DIO1=NOP DIO2=NOP
|
||||
writeReg(RegDioMapping1, MAP_DIO0_LORA_TXDONE|MAP_DIO1_LORA_NOP|MAP_DIO2_LORA_NOP);
|
||||
// clear all radio IRQ flags
|
||||
writeReg(LORARegIrqFlags, 0xFF);
|
||||
// mask all IRQs but TxDone
|
||||
writeReg(LORARegIrqFlagsMask, ~IRQ_LORA_TXDONE_MASK);
|
||||
|
||||
// initialize the payload size and address pointers
|
||||
writeReg(LORARegFifoTxBaseAddr, 0x00);
|
||||
writeReg(LORARegFifoAddrPtr, 0x00);
|
||||
writeReg(LORARegPayloadLength, LMIC.dataLen);
|
||||
|
||||
// download buffer to the radio FIFO
|
||||
writeBuf(RegFifo, LMIC.frame, LMIC.dataLen);
|
||||
|
||||
// enable antenna switch for TX
|
||||
hal_pin_rxtx(1);
|
||||
|
||||
// now we actually start the transmission
|
||||
opmode(OPMODE_TX);
|
||||
}
|
||||
|
||||
// start transmitter (buf=LMIC.frame, len=LMIC.dataLen)
|
||||
static void starttx () {
|
||||
ASSERT( (readReg(RegOpMode) & OPMODE_MASK) == OPMODE_SLEEP );
|
||||
if(getSf(LMIC.rps) == FSK) { // FSK modem
|
||||
txfsk();
|
||||
} else { // LoRa modem
|
||||
txlora();
|
||||
}
|
||||
// the radio will go back to STANDBY mode as soon as the TX is finished
|
||||
// the corresponding IRQ will inform us about completion.
|
||||
}
|
||||
|
||||
enum { RXMODE_SINGLE, RXMODE_SCAN, RXMODE_RSSI };
|
||||
|
||||
static const u1_t rxlorairqmask[] = {
|
||||
[RXMODE_SINGLE] = IRQ_LORA_RXDONE_MASK|IRQ_LORA_RXTOUT_MASK,
|
||||
[RXMODE_SCAN] = IRQ_LORA_RXDONE_MASK,
|
||||
[RXMODE_RSSI] = 0x00,
|
||||
};
|
||||
|
||||
// start LoRa receiver (time=LMIC.rxtime, timeout=LMIC.rxsyms, result=LMIC.frame[LMIC.dataLen])
|
||||
static void rxlora (u1_t rxmode) {
|
||||
// select LoRa modem (from sleep mode)
|
||||
opmodeLora();
|
||||
ASSERT((readReg(RegOpMode) & OPMODE_LORA) != 0);
|
||||
// enter standby mode (warm up))
|
||||
opmode(OPMODE_STANDBY);
|
||||
// don't use MAC settings at startup
|
||||
if(rxmode == RXMODE_RSSI) { // use fixed settings for rssi scan
|
||||
writeReg(LORARegModemConfig1, RXLORA_RXMODE_RSSI_REG_MODEM_CONFIG1);
|
||||
writeReg(LORARegModemConfig2, RXLORA_RXMODE_RSSI_REG_MODEM_CONFIG2);
|
||||
} else { // single or continuous rx mode
|
||||
// configure LoRa modem (cfg1, cfg2)
|
||||
configLoraModem();
|
||||
// configure frequency
|
||||
configChannel();
|
||||
}
|
||||
// set LNA gain
|
||||
writeReg(RegLna, LNA_RX_GAIN);
|
||||
// set max payload size
|
||||
writeReg(LORARegPayloadMaxLength, 64);
|
||||
// use inverted I/Q signal (prevent mote-to-mote communication)
|
||||
|
||||
// XXX: use flag to switch on/off inversion
|
||||
if (LMIC.noRXIQinversion) {
|
||||
writeReg(LORARegInvertIQ, readReg(LORARegInvertIQ) & ~(1<<6));
|
||||
} else {
|
||||
writeReg(LORARegInvertIQ, readReg(LORARegInvertIQ)|(1<<6));
|
||||
}
|
||||
|
||||
// set symbol timeout (for single rx)
|
||||
writeReg(LORARegSymbTimeoutLsb, LMIC.rxsyms);
|
||||
// set sync word
|
||||
writeReg(LORARegSyncWord, LORA_MAC_PREAMBLE);
|
||||
|
||||
// configure DIO mapping DIO0=RxDone DIO1=RxTout DIO2=NOP
|
||||
writeReg(RegDioMapping1, MAP_DIO0_LORA_RXDONE|MAP_DIO1_LORA_RXTOUT|MAP_DIO2_LORA_NOP);
|
||||
// clear all radio IRQ flags
|
||||
writeReg(LORARegIrqFlags, 0xFF);
|
||||
// enable required radio IRQs
|
||||
writeReg(LORARegIrqFlagsMask, ~rxlorairqmask[rxmode]);
|
||||
|
||||
// enable antenna switch for RX
|
||||
hal_pin_rxtx(0);
|
||||
|
||||
// now instruct the radio to receive
|
||||
if (rxmode == RXMODE_SINGLE) { // single rx
|
||||
hal_waitUntil(LMIC.rxtime); // busy wait until exact rx time
|
||||
opmode(OPMODE_RX_SINGLE);
|
||||
} else { // continous rx (scan or rssi)
|
||||
opmode(OPMODE_RX);
|
||||
}
|
||||
}
|
||||
|
||||
static void rxfsk (u1_t rxmode) {
|
||||
// only single rx (no continuous scanning, no noise sampling)
|
||||
ASSERT( rxmode == RXMODE_SINGLE );
|
||||
// select FSK modem (from sleep mode)
|
||||
//writeReg(RegOpMode, 0x00); // (not LoRa)
|
||||
opmodeFSK();
|
||||
ASSERT((readReg(RegOpMode) & OPMODE_LORA) == 0);
|
||||
// enter standby mode (warm up))
|
||||
opmode(OPMODE_STANDBY);
|
||||
// configure frequency
|
||||
configChannel();
|
||||
// set LNA gain
|
||||
//writeReg(RegLna, 0x20|0x03); // max gain, boost enable
|
||||
writeReg(RegLna, LNA_RX_GAIN);
|
||||
// configure receiver
|
||||
writeReg(FSKRegRxConfig, 0x1E); // AFC auto, AGC, trigger on preamble?!?
|
||||
// set receiver bandwidth
|
||||
writeReg(FSKRegRxBw, 0x0B); // 50kHz SSb
|
||||
// set AFC bandwidth
|
||||
writeReg(FSKRegAfcBw, 0x12); // 83.3kHz SSB
|
||||
// set preamble detection
|
||||
writeReg(FSKRegPreambleDetect, 0xAA); // enable, 2 bytes, 10 chip errors
|
||||
// set sync config
|
||||
writeReg(FSKRegSyncConfig, 0x12); // no auto restart, preamble 0xAA, enable, fill FIFO, 3 bytes sync
|
||||
// set packet config
|
||||
writeReg(FSKRegPacketConfig1, 0xD8); // var-length, whitening, crc, no auto-clear, no adr filter
|
||||
writeReg(FSKRegPacketConfig2, 0x40); // packet mode
|
||||
// set sync value
|
||||
writeReg(FSKRegSyncValue1, 0xC1);
|
||||
writeReg(FSKRegSyncValue2, 0x94);
|
||||
writeReg(FSKRegSyncValue3, 0xC1);
|
||||
// set preamble timeout
|
||||
writeReg(FSKRegRxTimeout2, 0xFF);//(LMIC.rxsyms+1)/2);
|
||||
// set bitrate
|
||||
writeReg(FSKRegBitrateMsb, 0x02); // 50kbps
|
||||
writeReg(FSKRegBitrateLsb, 0x80);
|
||||
// set frequency deviation
|
||||
writeReg(FSKRegFdevMsb, 0x01); // +/- 25kHz
|
||||
writeReg(FSKRegFdevLsb, 0x99);
|
||||
|
||||
// configure DIO mapping DIO0=PayloadReady DIO1=NOP DIO2=TimeOut
|
||||
writeReg(RegDioMapping1, MAP_DIO0_FSK_READY|MAP_DIO1_FSK_NOP|MAP_DIO2_FSK_TIMEOUT);
|
||||
|
||||
// enable antenna switch for RX
|
||||
hal_pin_rxtx(0);
|
||||
|
||||
// now instruct the radio to receive
|
||||
hal_waitUntil(LMIC.rxtime); // busy wait until exact rx time
|
||||
opmode(OPMODE_RX); // no single rx mode available in FSK
|
||||
}
|
||||
|
||||
static void startrx (u1_t rxmode) {
|
||||
ASSERT( (readReg(RegOpMode) & OPMODE_MASK) == OPMODE_SLEEP );
|
||||
if(getSf(LMIC.rps) == FSK) { // FSK modem
|
||||
rxfsk(rxmode);
|
||||
} else { // LoRa modem
|
||||
rxlora(rxmode);
|
||||
}
|
||||
// the radio will go back to STANDBY mode as soon as the RX is finished
|
||||
// or timed out, and the corresponding IRQ will inform us about completion.
|
||||
}
|
||||
|
||||
// get random seed from wideband noise rssi
|
||||
void radio_init () {
|
||||
hal_disableIRQs();
|
||||
|
||||
// manually reset radio
|
||||
#ifdef CFG_sx1276_radio
|
||||
hal_pin_rst(0); // drive RST pin low
|
||||
#else
|
||||
hal_pin_rst(1); // drive RST pin high
|
||||
#endif
|
||||
hal_waitUntil(os_getTime()+ms2osticks(1)); // wait >100us
|
||||
hal_pin_rst(2); // configure RST pin floating!
|
||||
hal_waitUntil(os_getTime()+ms2osticks(5)); // wait 5ms
|
||||
|
||||
opmode(OPMODE_SLEEP);
|
||||
|
||||
// some sanity checks, e.g., read version number
|
||||
u1_t v = readReg(RegVersion);
|
||||
#ifdef CFG_sx1276_radio
|
||||
ASSERT(v == 0x12 );
|
||||
#elif CFG_sx1272_radio
|
||||
ASSERT(v == 0x22);
|
||||
#else
|
||||
#error Missing CFG_sx1272_radio/CFG_sx1276_radio
|
||||
#endif
|
||||
// seed 15-byte randomness via noise rssi
|
||||
rxlora(RXMODE_RSSI);
|
||||
while( (readReg(RegOpMode) & OPMODE_MASK) != OPMODE_RX ); // continuous rx
|
||||
for(int i=1; i<16; i++) {
|
||||
for(int j=0; j<8; j++) {
|
||||
u1_t b; // wait for two non-identical subsequent least-significant bits
|
||||
while( (b = readReg(LORARegRssiWideband) & 0x01) == (readReg(LORARegRssiWideband) & 0x01) );
|
||||
randbuf[i] = (randbuf[i] << 1) | b;
|
||||
}
|
||||
}
|
||||
randbuf[0] = 16; // set initial index
|
||||
|
||||
#ifdef CFG_sx1276mb1_board
|
||||
// chain calibration
|
||||
writeReg(RegPaConfig, 0);
|
||||
|
||||
// Launch Rx chain calibration for LF band
|
||||
writeReg(FSKRegImageCal, (readReg(FSKRegImageCal) & RF_IMAGECAL_IMAGECAL_MASK)|RF_IMAGECAL_IMAGECAL_START);
|
||||
while((readReg(FSKRegImageCal)&RF_IMAGECAL_IMAGECAL_RUNNING) == RF_IMAGECAL_IMAGECAL_RUNNING){ ; }
|
||||
|
||||
// Sets a Frequency in HF band
|
||||
u4_t frf = 868000000;
|
||||
writeReg(RegFrfMsb, (u1_t)(frf>>16));
|
||||
writeReg(RegFrfMid, (u1_t)(frf>> 8));
|
||||
writeReg(RegFrfLsb, (u1_t)(frf>> 0));
|
||||
|
||||
// Launch Rx chain calibration for HF band
|
||||
writeReg(FSKRegImageCal, (readReg(FSKRegImageCal) & RF_IMAGECAL_IMAGECAL_MASK)|RF_IMAGECAL_IMAGECAL_START);
|
||||
while((readReg(FSKRegImageCal) & RF_IMAGECAL_IMAGECAL_RUNNING) == RF_IMAGECAL_IMAGECAL_RUNNING) { ; }
|
||||
#endif /* CFG_sx1276mb1_board */
|
||||
|
||||
opmode(OPMODE_SLEEP);
|
||||
|
||||
hal_enableIRQs();
|
||||
}
|
||||
|
||||
// return next random byte derived from seed buffer
|
||||
// (buf[0] holds index of next byte to be returned)
|
||||
u1_t radio_rand1 () {
|
||||
u1_t i = randbuf[0];
|
||||
ASSERT( i != 0 );
|
||||
if( i==16 ) {
|
||||
os_aes(AES_ENC, randbuf, 16); // encrypt seed with any key
|
||||
i = 0;
|
||||
}
|
||||
u1_t v = randbuf[i++];
|
||||
randbuf[0] = i;
|
||||
return v;
|
||||
}
|
||||
|
||||
u1_t radio_rssi () {
|
||||
hal_disableIRQs();
|
||||
u1_t r = readReg(LORARegRssiValue);
|
||||
hal_enableIRQs();
|
||||
return r;
|
||||
}
|
||||
|
||||
static const u2_t LORA_RXDONE_FIXUP[] = {
|
||||
[FSK] = us2osticks(0), // ( 0 ticks)
|
||||
[SF7] = us2osticks(0), // ( 0 ticks)
|
||||
[SF8] = us2osticks(1648), // ( 54 ticks)
|
||||
[SF9] = us2osticks(3265), // ( 107 ticks)
|
||||
[SF10] = us2osticks(7049), // ( 231 ticks)
|
||||
[SF11] = us2osticks(13641), // ( 447 ticks)
|
||||
[SF12] = us2osticks(31189), // (1022 ticks)
|
||||
};
|
||||
|
||||
// called by hal ext IRQ handler
|
||||
// (radio goes to stanby mode after tx/rx operations)
|
||||
void radio_irq_handler (u1_t dio) {
|
||||
#if CFG_TxContinuousMode
|
||||
// clear radio IRQ flags
|
||||
writeReg(LORARegIrqFlags, 0xFF);
|
||||
u1_t p = readReg(LORARegFifoAddrPtr);
|
||||
writeReg(LORARegFifoAddrPtr, 0x00);
|
||||
u1_t s = readReg(RegOpMode);
|
||||
u1_t c = readReg(LORARegModemConfig2);
|
||||
opmode(OPMODE_TX);
|
||||
return;
|
||||
#else /* ! CFG_TxContinuousMode */
|
||||
ostime_t now = os_getTime();
|
||||
if( (readReg(RegOpMode) & OPMODE_LORA) != 0) { // LORA modem
|
||||
u1_t flags = readReg(LORARegIrqFlags);
|
||||
if( flags & IRQ_LORA_TXDONE_MASK ) {
|
||||
// save exact tx time
|
||||
LMIC.txend = now - us2osticks(43); // TXDONE FIXUP
|
||||
} else if( flags & IRQ_LORA_RXDONE_MASK ) {
|
||||
// save exact rx time
|
||||
if(getBw(LMIC.rps) == BW125) {
|
||||
now -= LORA_RXDONE_FIXUP[getSf(LMIC.rps)];
|
||||
}
|
||||
LMIC.rxtime = now;
|
||||
// read the PDU and inform the MAC that we received something
|
||||
LMIC.dataLen = (readReg(LORARegModemConfig1) & SX1272_MC1_IMPLICIT_HEADER_MODE_ON) ?
|
||||
readReg(LORARegPayloadLength) : readReg(LORARegRxNbBytes);
|
||||
// set FIFO read address pointer
|
||||
writeReg(LORARegFifoAddrPtr, readReg(LORARegFifoRxCurrentAddr));
|
||||
// now read the FIFO
|
||||
readBuf(RegFifo, LMIC.frame, LMIC.dataLen);
|
||||
// read rx quality parameters
|
||||
LMIC.snr = readReg(LORARegPktSnrValue); // SNR [dB] * 4
|
||||
LMIC.rssi = readReg(LORARegPktRssiValue) - 125 + 64; // RSSI [dBm] (-196...+63)
|
||||
} else if( flags & IRQ_LORA_RXTOUT_MASK ) {
|
||||
// indicate timeout
|
||||
LMIC.dataLen = 0;
|
||||
}
|
||||
// mask all radio IRQs
|
||||
writeReg(LORARegIrqFlagsMask, 0xFF);
|
||||
// clear radio IRQ flags
|
||||
writeReg(LORARegIrqFlags, 0xFF);
|
||||
} else { // FSK modem
|
||||
u1_t flags1 = readReg(FSKRegIrqFlags1);
|
||||
u1_t flags2 = readReg(FSKRegIrqFlags2);
|
||||
if( flags2 & IRQ_FSK2_PACKETSENT_MASK ) {
|
||||
// save exact tx time
|
||||
LMIC.txend = now;
|
||||
} else if( flags2 & IRQ_FSK2_PAYLOADREADY_MASK ) {
|
||||
// save exact rx time
|
||||
LMIC.rxtime = now;
|
||||
// read the PDU and inform the MAC that we received something
|
||||
LMIC.dataLen = readReg(FSKRegPayloadLength);
|
||||
// now read the FIFO
|
||||
readBuf(RegFifo, LMIC.frame, LMIC.dataLen);
|
||||
// read rx quality parameters
|
||||
LMIC.snr = 0; // determine snr
|
||||
LMIC.rssi = 0; // determine rssi
|
||||
} else if( flags1 & IRQ_FSK1_TIMEOUT_MASK ) {
|
||||
// indicate timeout
|
||||
LMIC.dataLen = 0;
|
||||
} else {
|
||||
while(1);
|
||||
}
|
||||
}
|
||||
// go from stanby to sleep
|
||||
opmode(OPMODE_SLEEP);
|
||||
// run os job (use preset func ptr)
|
||||
os_setCallback(&LMIC.osjob, LMIC.osjob.func);
|
||||
#endif /* ! CFG_TxContinuousMode */
|
||||
}
|
||||
|
||||
void os_radio (u1_t mode) {
|
||||
hal_disableIRQs();
|
||||
switch (mode) {
|
||||
case RADIO_RST:
|
||||
// put radio to sleep
|
||||
opmode(OPMODE_SLEEP);
|
||||
break;
|
||||
|
||||
case RADIO_TX:
|
||||
// transmit frame now
|
||||
starttx(); // buf=LMIC.frame, len=LMIC.dataLen
|
||||
break;
|
||||
|
||||
case RADIO_RX:
|
||||
// receive frame now (exactly at rxtime)
|
||||
startrx(RXMODE_SINGLE); // buf=LMIC.frame, time=LMIC.rxtime, timeout=LMIC.rxsyms
|
||||
break;
|
||||
|
||||
case RADIO_RXON:
|
||||
// start scanning for beacon now
|
||||
startrx(RXMODE_SCAN); // buf=LMIC.frame
|
||||
break;
|
||||
}
|
||||
hal_enableIRQs();
|
||||
}
|
313
src/stm32l0xx_hal_msp.c
Normal file
313
src/stm32l0xx_hal_msp.c
Normal file
@ -0,0 +1,313 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32l0xx_hal_msp.c
|
||||
* @brief This file provides code for the MSP Initialization
|
||||
* and de-Initialization codes.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2023 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "main.h"
|
||||
|
||||
/* USER CODE BEGIN Includes */
|
||||
|
||||
/* USER CODE END Includes */
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN TD */
|
||||
|
||||
/* USER CODE END TD */
|
||||
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Define */
|
||||
|
||||
/* USER CODE END Define */
|
||||
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Macro */
|
||||
|
||||
/* USER CODE END Macro */
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PV */
|
||||
|
||||
/* USER CODE END PV */
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* USER CODE BEGIN PFP */
|
||||
|
||||
/* USER CODE END PFP */
|
||||
|
||||
/* External functions --------------------------------------------------------*/
|
||||
/* USER CODE BEGIN ExternalFunctions */
|
||||
|
||||
/* USER CODE END ExternalFunctions */
|
||||
|
||||
/* USER CODE BEGIN 0 */
|
||||
|
||||
/* USER CODE END 0 */
|
||||
/**
|
||||
* Initializes the Global MSP.
|
||||
*/
|
||||
void HAL_MspInit(void)
|
||||
{
|
||||
/* USER CODE BEGIN MspInit 0 */
|
||||
|
||||
/* USER CODE END MspInit 0 */
|
||||
|
||||
__HAL_RCC_SYSCFG_CLK_ENABLE();
|
||||
__HAL_RCC_PWR_CLK_ENABLE();
|
||||
|
||||
/* System interrupt init*/
|
||||
|
||||
/* USER CODE BEGIN MspInit 1 */
|
||||
|
||||
/* USER CODE END MspInit 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SPI MSP Initialization
|
||||
* This function configures the hardware resources used in this example
|
||||
* @param hspi: SPI handle pointer
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
if(hspi->Instance==SPI1)
|
||||
{
|
||||
/* USER CODE BEGIN SPI1_MspInit 0 */
|
||||
|
||||
/* USER CODE END SPI1_MspInit 0 */
|
||||
/* Peripheral clock enable */
|
||||
__HAL_RCC_SPI1_CLK_ENABLE();
|
||||
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
/**SPI1 GPIO Configuration
|
||||
PA5 ------> SPI1_SCK
|
||||
PA6 ------> SPI1_MISO
|
||||
PA7 ------> SPI1_MOSI
|
||||
*/
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_7;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF0_SPI1;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_6;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF0_SPI1;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
/* USER CODE BEGIN SPI1_MspInit 1 */
|
||||
|
||||
/* USER CODE END SPI1_MspInit 1 */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SPI MSP De-Initialization
|
||||
* This function freeze the hardware resources used in this example
|
||||
* @param hspi: SPI handle pointer
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_SPI_MspDeInit(SPI_HandleTypeDef* hspi)
|
||||
{
|
||||
if(hspi->Instance==SPI1)
|
||||
{
|
||||
/* USER CODE BEGIN SPI1_MspDeInit 0 */
|
||||
|
||||
/* USER CODE END SPI1_MspDeInit 0 */
|
||||
/* Peripheral clock disable */
|
||||
__HAL_RCC_SPI1_CLK_DISABLE();
|
||||
|
||||
/**SPI1 GPIO Configuration
|
||||
PA5 ------> SPI1_SCK
|
||||
PA6 ------> SPI1_MISO
|
||||
PA7 ------> SPI1_MOSI
|
||||
*/
|
||||
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7);
|
||||
|
||||
/* USER CODE BEGIN SPI1_MspDeInit 1 */
|
||||
|
||||
/* USER CODE END SPI1_MspDeInit 1 */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief TIM_OC MSP Initialization
|
||||
* This function configures the hardware resources used in this example
|
||||
* @param htim_oc: TIM_OC handle pointer
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_TIM_OC_MspInit(TIM_HandleTypeDef* htim_oc)
|
||||
{
|
||||
if(htim_oc->Instance==TIM2)
|
||||
{
|
||||
/* USER CODE BEGIN TIM2_MspInit 0 */
|
||||
|
||||
/* USER CODE END TIM2_MspInit 0 */
|
||||
/* Peripheral clock enable */
|
||||
__HAL_RCC_TIM2_CLK_ENABLE();
|
||||
/* TIM2 interrupt Init */
|
||||
HAL_NVIC_SetPriority(TIM2_IRQn, 0, 0);
|
||||
HAL_NVIC_EnableIRQ(TIM2_IRQn);
|
||||
/* USER CODE BEGIN TIM2_MspInit 1 */
|
||||
|
||||
/* USER CODE END TIM2_MspInit 1 */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief TIM_OC MSP De-Initialization
|
||||
* This function freeze the hardware resources used in this example
|
||||
* @param htim_oc: TIM_OC handle pointer
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_TIM_OC_MspDeInit(TIM_HandleTypeDef* htim_oc)
|
||||
{
|
||||
if(htim_oc->Instance==TIM2)
|
||||
{
|
||||
/* USER CODE BEGIN TIM2_MspDeInit 0 */
|
||||
|
||||
/* USER CODE END TIM2_MspDeInit 0 */
|
||||
/* Peripheral clock disable */
|
||||
__HAL_RCC_TIM2_CLK_DISABLE();
|
||||
|
||||
/* TIM2 interrupt DeInit */
|
||||
HAL_NVIC_DisableIRQ(TIM2_IRQn);
|
||||
/* USER CODE BEGIN TIM2_MspDeInit 1 */
|
||||
|
||||
/* USER CODE END TIM2_MspDeInit 1 */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief UART MSP Initialization
|
||||
* This function configures the hardware resources used in this example
|
||||
* @param huart: UART handle pointer
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_UART_MspInit(UART_HandleTypeDef* huart)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
if(huart->Instance==USART1)
|
||||
{
|
||||
/* USER CODE BEGIN USART1_MspInit 0 */
|
||||
|
||||
/* USER CODE END USART1_MspInit 0 */
|
||||
/* Peripheral clock enable */
|
||||
__HAL_RCC_USART1_CLK_ENABLE();
|
||||
|
||||
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||||
/**USART1 GPIO Configuration
|
||||
PB6 ------> USART1_TX
|
||||
PB7 ------> USART1_RX
|
||||
*/
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF0_USART1;
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||
|
||||
/* USER CODE BEGIN USART1_MspInit 1 */
|
||||
|
||||
/* USER CODE END USART1_MspInit 1 */
|
||||
}
|
||||
else if(huart->Instance==USART2)
|
||||
{
|
||||
/* USER CODE BEGIN USART2_MspInit 0 */
|
||||
|
||||
/* USER CODE END USART2_MspInit 0 */
|
||||
/* Peripheral clock enable */
|
||||
__HAL_RCC_USART2_CLK_ENABLE();
|
||||
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
/**USART2 GPIO Configuration
|
||||
PA2 ------> USART2_TX
|
||||
PA3 ------> USART2_RX
|
||||
*/
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF4_USART2;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
/* USER CODE BEGIN USART2_MspInit 1 */
|
||||
|
||||
/* USER CODE END USART2_MspInit 1 */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief UART MSP De-Initialization
|
||||
* This function freeze the hardware resources used in this example
|
||||
* @param huart: UART handle pointer
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_UART_MspDeInit(UART_HandleTypeDef* huart)
|
||||
{
|
||||
if(huart->Instance==USART1)
|
||||
{
|
||||
/* USER CODE BEGIN USART1_MspDeInit 0 */
|
||||
|
||||
/* USER CODE END USART1_MspDeInit 0 */
|
||||
/* Peripheral clock disable */
|
||||
__HAL_RCC_USART1_CLK_DISABLE();
|
||||
|
||||
/**USART1 GPIO Configuration
|
||||
PB6 ------> USART1_TX
|
||||
PB7 ------> USART1_RX
|
||||
*/
|
||||
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_6|GPIO_PIN_7);
|
||||
|
||||
/* USER CODE BEGIN USART1_MspDeInit 1 */
|
||||
|
||||
/* USER CODE END USART1_MspDeInit 1 */
|
||||
}
|
||||
else if(huart->Instance==USART2)
|
||||
{
|
||||
/* USER CODE BEGIN USART2_MspDeInit 0 */
|
||||
|
||||
/* USER CODE END USART2_MspDeInit 0 */
|
||||
/* Peripheral clock disable */
|
||||
__HAL_RCC_USART2_CLK_DISABLE();
|
||||
|
||||
/**USART2 GPIO Configuration
|
||||
PA2 ------> USART2_TX
|
||||
PA3 ------> USART2_RX
|
||||
*/
|
||||
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2|GPIO_PIN_3);
|
||||
|
||||
/* USER CODE BEGIN USART2_MspDeInit 1 */
|
||||
|
||||
/* USER CODE END USART2_MspDeInit 1 */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN 1 */
|
||||
|
||||
/* USER CODE END 1 */
|
175
src/stm32l0xx_it.c
Normal file
175
src/stm32l0xx_it.c
Normal file
@ -0,0 +1,175 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32l0xx_it.c
|
||||
* @brief Interrupt Service Routines.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2023 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "main.h"
|
||||
#include "stm32l0xx_it.h"
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Includes */
|
||||
/* USER CODE END Includes */
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN TD */
|
||||
|
||||
/* USER CODE END TD */
|
||||
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PD */
|
||||
|
||||
/* USER CODE END PD */
|
||||
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PM */
|
||||
|
||||
/* USER CODE END PM */
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PV */
|
||||
|
||||
/* USER CODE END PV */
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* USER CODE BEGIN PFP */
|
||||
|
||||
/* USER CODE END PFP */
|
||||
|
||||
/* Private user code ---------------------------------------------------------*/
|
||||
/* USER CODE BEGIN 0 */
|
||||
|
||||
/* USER CODE END 0 */
|
||||
|
||||
/* External variables --------------------------------------------------------*/
|
||||
extern TIM_HandleTypeDef htim2;
|
||||
/* USER CODE BEGIN EV */
|
||||
|
||||
/* USER CODE END EV */
|
||||
|
||||
/******************************************************************************/
|
||||
/* Cortex-M0+ Processor Interruption and Exception Handlers */
|
||||
/******************************************************************************/
|
||||
/**
|
||||
* @brief This function handles Non maskable interrupt.
|
||||
*/
|
||||
void NMI_Handler(void)
|
||||
{
|
||||
/* USER CODE BEGIN NonMaskableInt_IRQn 0 */
|
||||
|
||||
/* USER CODE END NonMaskableInt_IRQn 0 */
|
||||
/* USER CODE BEGIN NonMaskableInt_IRQn 1 */
|
||||
while (1)
|
||||
{
|
||||
}
|
||||
/* USER CODE END NonMaskableInt_IRQn 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles Hard fault interrupt.
|
||||
*/
|
||||
void HardFault_Handler(void)
|
||||
{
|
||||
/* USER CODE BEGIN HardFault_IRQn 0 */
|
||||
|
||||
/* USER CODE END HardFault_IRQn 0 */
|
||||
while (1)
|
||||
{
|
||||
/* USER CODE BEGIN W1_HardFault_IRQn 0 */
|
||||
/* USER CODE END W1_HardFault_IRQn 0 */
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles System service call via SWI instruction.
|
||||
*/
|
||||
void SVC_Handler(void)
|
||||
{
|
||||
/* USER CODE BEGIN SVC_IRQn 0 */
|
||||
|
||||
/* USER CODE END SVC_IRQn 0 */
|
||||
/* USER CODE BEGIN SVC_IRQn 1 */
|
||||
|
||||
/* USER CODE END SVC_IRQn 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles Pendable request for system service.
|
||||
*/
|
||||
void PendSV_Handler(void)
|
||||
{
|
||||
/* USER CODE BEGIN PendSV_IRQn 0 */
|
||||
|
||||
/* USER CODE END PendSV_IRQn 0 */
|
||||
/* USER CODE BEGIN PendSV_IRQn 1 */
|
||||
|
||||
/* USER CODE END PendSV_IRQn 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles System tick timer.
|
||||
*/
|
||||
void SysTick_Handler(void)
|
||||
{
|
||||
/* USER CODE BEGIN SysTick_IRQn 0 */
|
||||
|
||||
/* USER CODE END SysTick_IRQn 0 */
|
||||
HAL_IncTick();
|
||||
/* USER CODE BEGIN SysTick_IRQn 1 */
|
||||
|
||||
/* USER CODE END SysTick_IRQn 1 */
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* STM32L0xx Peripheral Interrupt Handlers */
|
||||
/* Add here the Interrupt Handlers for the used peripherals. */
|
||||
/* For the available peripheral interrupt handler names, */
|
||||
/* please refer to the startup file (startup_stm32l0xx.s). */
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief This function handles EXTI line 4 to 15 interrupts.
|
||||
*/
|
||||
void EXTI4_15_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN EXTI4_15_IRQn 0 */
|
||||
|
||||
/* USER CODE END EXTI4_15_IRQn 0 */
|
||||
HAL_GPIO_EXTI_IRQHandler(DIO1_Pin);
|
||||
HAL_GPIO_EXTI_IRQHandler(DIO2_Pin);
|
||||
HAL_GPIO_EXTI_IRQHandler(DIO0_Pin);
|
||||
/* USER CODE BEGIN EXTI4_15_IRQn 1 */
|
||||
|
||||
/* USER CODE END EXTI4_15_IRQn 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles TIM2 global interrupt.
|
||||
*/
|
||||
void TIM2_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN TIM2_IRQn 0 */
|
||||
|
||||
/* USER CODE END TIM2_IRQn 0 */
|
||||
HAL_TIM_IRQHandler(&htim2);
|
||||
/* USER CODE BEGIN TIM2_IRQn 1 */
|
||||
|
||||
/* USER CODE END TIM2_IRQn 1 */
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN 1 */
|
||||
|
||||
/* USER CODE END 1 */
|
273
src/system_stm32l0xx.c
Normal file
273
src/system_stm32l0xx.c
Normal file
@ -0,0 +1,273 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file system_stm32l0xx.c
|
||||
* @author MCD Application Team
|
||||
* @brief CMSIS Cortex-M0+ Device Peripheral Access Layer System Source File.
|
||||
*
|
||||
* This file provides two functions and one global variable to be called from
|
||||
* user application:
|
||||
* - SystemInit(): This function is called at startup just after reset and
|
||||
* before branch to main program. This call is made inside
|
||||
* the "startup_stm32l0xx.s" file.
|
||||
*
|
||||
* - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
|
||||
* by the user application to setup the SysTick
|
||||
* timer or configure other parameters.
|
||||
*
|
||||
* - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
|
||||
* be called whenever the core clock is changed
|
||||
* during program execution.
|
||||
*
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2016 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/** @addtogroup CMSIS
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup stm32l0xx_system
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32L0xx_System_Private_Includes
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "stm32l0xx.h"
|
||||
|
||||
#if !defined (HSE_VALUE)
|
||||
#define HSE_VALUE ((uint32_t)8000000U) /*!< Value of the External oscillator in Hz */
|
||||
#endif /* HSE_VALUE */
|
||||
|
||||
#if !defined (MSI_VALUE)
|
||||
#define MSI_VALUE ((uint32_t)2097152U) /*!< Value of the Internal oscillator in Hz*/
|
||||
#endif /* MSI_VALUE */
|
||||
|
||||
#if !defined (HSI_VALUE)
|
||||
#define HSI_VALUE ((uint32_t)16000000U) /*!< Value of the Internal oscillator in Hz*/
|
||||
#endif /* HSI_VALUE */
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32L0xx_System_Private_TypesDefinitions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32L0xx_System_Private_Defines
|
||||
* @{
|
||||
*/
|
||||
/************************* Miscellaneous Configuration ************************/
|
||||
|
||||
/* Note: Following vector table addresses must be defined in line with linker
|
||||
configuration. */
|
||||
/*!< Uncomment the following line if you need to relocate the vector table
|
||||
anywhere in Flash or Sram, else the vector table is kept at the automatic
|
||||
remap of boot address selected */
|
||||
/* #define USER_VECT_TAB_ADDRESS */
|
||||
|
||||
#if defined(USER_VECT_TAB_ADDRESS)
|
||||
/*!< Uncomment the following line if you need to relocate your vector Table
|
||||
in Sram else user remap will be done in Flash. */
|
||||
/* #define VECT_TAB_SRAM */
|
||||
#if defined(VECT_TAB_SRAM)
|
||||
#define VECT_TAB_BASE_ADDRESS SRAM_BASE /*!< Vector Table base address field.
|
||||
This value must be a multiple of 0x200. */
|
||||
#define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field.
|
||||
This value must be a multiple of 0x200. */
|
||||
#else
|
||||
#define VECT_TAB_BASE_ADDRESS FLASH_BASE /*!< Vector Table base address field.
|
||||
This value must be a multiple of 0x200. */
|
||||
#define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field.
|
||||
This value must be a multiple of 0x200. */
|
||||
#endif /* VECT_TAB_SRAM */
|
||||
#endif /* USER_VECT_TAB_ADDRESS */
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32L0xx_System_Private_Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32L0xx_System_Private_Variables
|
||||
* @{
|
||||
*/
|
||||
/* This variable is updated in three ways:
|
||||
1) by calling CMSIS function SystemCoreClockUpdate()
|
||||
2) by calling HAL API function HAL_RCC_GetHCLKFreq()
|
||||
3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
|
||||
Note: If you use this function to configure the system clock; then there
|
||||
is no need to call the 2 first functions listed above, since SystemCoreClock
|
||||
variable is updated automatically.
|
||||
*/
|
||||
uint32_t SystemCoreClock = 2097152U; /* 32.768 kHz * 2^6 */
|
||||
const uint8_t AHBPrescTable[16] = {0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U, 6U, 7U, 8U, 9U};
|
||||
const uint8_t APBPrescTable[8] = {0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U};
|
||||
const uint8_t PLLMulTable[9] = {3U, 4U, 6U, 8U, 12U, 16U, 24U, 32U, 48U};
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32L0xx_System_Private_FunctionPrototypes
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32L0xx_System_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Setup the microcontroller system.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void SystemInit (void)
|
||||
{
|
||||
/* Configure the Vector Table location add offset address ------------------*/
|
||||
#if defined (USER_VECT_TAB_ADDRESS)
|
||||
SCB->VTOR = VECT_TAB_BASE_ADDRESS | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
|
||||
#endif /* USER_VECT_TAB_ADDRESS */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Update SystemCoreClock variable according to Clock Register Values.
|
||||
* The SystemCoreClock variable contains the core clock (HCLK), it can
|
||||
* be used by the user application to setup the SysTick timer or configure
|
||||
* other parameters.
|
||||
*
|
||||
* @note Each time the core clock (HCLK) changes, this function must be called
|
||||
* to update SystemCoreClock variable value. Otherwise, any configuration
|
||||
* based on this variable will be incorrect.
|
||||
*
|
||||
* @note - The system frequency computed by this function is not the real
|
||||
* frequency in the chip. It is calculated based on the predefined
|
||||
* constant and the selected clock source:
|
||||
*
|
||||
* - If SYSCLK source is MSI, SystemCoreClock will contain the MSI
|
||||
* value as defined by the MSI range.
|
||||
*
|
||||
* - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*)
|
||||
*
|
||||
* - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**)
|
||||
*
|
||||
* - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**)
|
||||
* or HSI_VALUE(*) multiplied/divided by the PLL factors.
|
||||
*
|
||||
* (*) HSI_VALUE is a constant defined in stm32l0xx_hal.h file (default value
|
||||
* 16 MHz) but the real value may vary depending on the variations
|
||||
* in voltage and temperature.
|
||||
*
|
||||
* (**) HSE_VALUE is a constant defined in stm32l0xx_hal.h file (default value
|
||||
* 8 MHz), user has to ensure that HSE_VALUE is same as the real
|
||||
* frequency of the crystal used. Otherwise, this function may
|
||||
* have wrong result.
|
||||
*
|
||||
* - The result of this function could be not correct when using fractional
|
||||
* value for HSE crystal.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void SystemCoreClockUpdate (void)
|
||||
{
|
||||
uint32_t tmp = 0U, pllmul = 0U, plldiv = 0U, pllsource = 0U, msirange = 0U;
|
||||
|
||||
/* Get SYSCLK source -------------------------------------------------------*/
|
||||
tmp = RCC->CFGR & RCC_CFGR_SWS;
|
||||
|
||||
switch (tmp)
|
||||
{
|
||||
case 0x00U: /* MSI used as system clock */
|
||||
msirange = (RCC->ICSCR & RCC_ICSCR_MSIRANGE) >> RCC_ICSCR_MSIRANGE_Pos;
|
||||
SystemCoreClock = (32768U * (1U << (msirange + 1U)));
|
||||
break;
|
||||
case 0x04U: /* HSI used as system clock */
|
||||
if ((RCC->CR & RCC_CR_HSIDIVF) != 0U)
|
||||
{
|
||||
SystemCoreClock = HSI_VALUE / 4U;
|
||||
}
|
||||
else
|
||||
{
|
||||
SystemCoreClock = HSI_VALUE;
|
||||
}
|
||||
break;
|
||||
case 0x08U: /* HSE used as system clock */
|
||||
SystemCoreClock = HSE_VALUE;
|
||||
break;
|
||||
default: /* PLL used as system clock */
|
||||
/* Get PLL clock source and multiplication factor ----------------------*/
|
||||
pllmul = RCC->CFGR & RCC_CFGR_PLLMUL;
|
||||
plldiv = RCC->CFGR & RCC_CFGR_PLLDIV;
|
||||
pllmul = PLLMulTable[(pllmul >> RCC_CFGR_PLLMUL_Pos)];
|
||||
plldiv = (plldiv >> RCC_CFGR_PLLDIV_Pos) + 1U;
|
||||
|
||||
pllsource = RCC->CFGR & RCC_CFGR_PLLSRC;
|
||||
|
||||
if (pllsource == 0x00U)
|
||||
{
|
||||
/* HSI oscillator clock selected as PLL clock entry */
|
||||
if ((RCC->CR & RCC_CR_HSIDIVF) != 0U)
|
||||
{
|
||||
SystemCoreClock = (((HSI_VALUE / 4U) * pllmul) / plldiv);
|
||||
}
|
||||
else
|
||||
{
|
||||
SystemCoreClock = (((HSI_VALUE) * pllmul) / plldiv);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* HSE selected as PLL clock entry */
|
||||
SystemCoreClock = (((HSE_VALUE) * pllmul) / plldiv);
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* Compute HCLK clock frequency --------------------------------------------*/
|
||||
/* Get HCLK prescaler */
|
||||
tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> RCC_CFGR_HPRE_Pos)];
|
||||
/* HCLK clock frequency */
|
||||
SystemCoreClock >>= tmp;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
272
startup_stm32l051xx.s
Normal file
272
startup_stm32l051xx.s
Normal file
@ -0,0 +1,272 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file startup_stm32l051xx.s
|
||||
* @author MCD Application Team
|
||||
* @brief STM32L051xx Devices vector table for GCC toolchain.
|
||||
* This module performs:
|
||||
* - Set the initial SP
|
||||
* - Set the initial PC == Reset_Handler,
|
||||
* - Set the vector table entries with the exceptions ISR address
|
||||
* - Branches to main in the C library (which eventually
|
||||
* calls main()).
|
||||
* After Reset the Cortex-M0+ processor is in Thread mode,
|
||||
* priority is Privileged, and the Stack is set to Main.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2016 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
.syntax unified
|
||||
.cpu cortex-m0plus
|
||||
.fpu softvfp
|
||||
.thumb
|
||||
|
||||
.global g_pfnVectors
|
||||
.global Default_Handler
|
||||
|
||||
/* start address for the initialization values of the .data section.
|
||||
defined in linker script */
|
||||
.word _sidata
|
||||
/* start address for the .data section. defined in linker script */
|
||||
.word _sdata
|
||||
/* end address for the .data section. defined in linker script */
|
||||
.word _edata
|
||||
/* start address for the .bss section. defined in linker script */
|
||||
.word _sbss
|
||||
/* end address for the .bss section. defined in linker script */
|
||||
.word _ebss
|
||||
|
||||
.section .text.Reset_Handler
|
||||
.weak Reset_Handler
|
||||
.type Reset_Handler, %function
|
||||
Reset_Handler:
|
||||
ldr r0, =_estack
|
||||
mov sp, r0 /* set stack pointer */
|
||||
|
||||
/* Call the clock system initialization function.*/
|
||||
bl SystemInit
|
||||
|
||||
/* Copy the data segment initializers from flash to SRAM */
|
||||
ldr r0, =_sdata
|
||||
ldr r1, =_edata
|
||||
ldr r2, =_sidata
|
||||
movs r3, #0
|
||||
b LoopCopyDataInit
|
||||
|
||||
CopyDataInit:
|
||||
ldr r4, [r2, r3]
|
||||
str r4, [r0, r3]
|
||||
adds r3, r3, #4
|
||||
|
||||
LoopCopyDataInit:
|
||||
adds r4, r0, r3
|
||||
cmp r4, r1
|
||||
bcc CopyDataInit
|
||||
|
||||
/* Zero fill the bss segment. */
|
||||
ldr r2, =_sbss
|
||||
ldr r4, =_ebss
|
||||
movs r3, #0
|
||||
b LoopFillZerobss
|
||||
|
||||
FillZerobss:
|
||||
str r3, [r2]
|
||||
adds r2, r2, #4
|
||||
|
||||
LoopFillZerobss:
|
||||
cmp r2, r4
|
||||
bcc FillZerobss
|
||||
|
||||
/* Call static constructors */
|
||||
bl __libc_init_array
|
||||
/* Call the application's entry point.*/
|
||||
bl main
|
||||
|
||||
LoopForever:
|
||||
b LoopForever
|
||||
|
||||
|
||||
.size Reset_Handler, .-Reset_Handler
|
||||
|
||||
/**
|
||||
* @brief This is the code that gets called when the processor receives an
|
||||
* unexpected interrupt. This simply enters an infinite loop, preserving
|
||||
* the system state for examination by a debugger.
|
||||
*
|
||||
* @param None
|
||||
* @retval : None
|
||||
*/
|
||||
.section .text.Default_Handler,"ax",%progbits
|
||||
Default_Handler:
|
||||
Infinite_Loop:
|
||||
b Infinite_Loop
|
||||
.size Default_Handler, .-Default_Handler
|
||||
/******************************************************************************
|
||||
*
|
||||
* The minimal vector table for a Cortex M0. Note that the proper constructs
|
||||
* must be placed on this to ensure that it ends up at physical address
|
||||
* 0x0000.0000.
|
||||
*
|
||||
******************************************************************************/
|
||||
.section .isr_vector,"a",%progbits
|
||||
.type g_pfnVectors, %object
|
||||
.size g_pfnVectors, .-g_pfnVectors
|
||||
|
||||
|
||||
g_pfnVectors:
|
||||
.word _estack
|
||||
.word Reset_Handler
|
||||
.word NMI_Handler
|
||||
.word HardFault_Handler
|
||||
.word 0
|
||||
.word 0
|
||||
.word 0
|
||||
.word 0
|
||||
.word 0
|
||||
.word 0
|
||||
.word 0
|
||||
.word SVC_Handler
|
||||
.word 0
|
||||
.word 0
|
||||
.word PendSV_Handler
|
||||
.word SysTick_Handler
|
||||
.word WWDG_IRQHandler /* Window WatchDog */
|
||||
.word PVD_IRQHandler /* PVD through EXTI Line detection */
|
||||
.word RTC_IRQHandler /* RTC through the EXTI line */
|
||||
.word FLASH_IRQHandler /* FLASH */
|
||||
.word RCC_IRQHandler /* RCC */
|
||||
.word EXTI0_1_IRQHandler /* EXTI Line 0 and 1 */
|
||||
.word EXTI2_3_IRQHandler /* EXTI Line 2 and 3 */
|
||||
.word EXTI4_15_IRQHandler /* EXTI Line 4 to 15 */
|
||||
.word 0 /* Reserved */
|
||||
.word DMA1_Channel1_IRQHandler /* DMA1 Channel 1 */
|
||||
.word DMA1_Channel2_3_IRQHandler /* DMA1 Channel 2 and Channel 3 */
|
||||
.word DMA1_Channel4_5_6_7_IRQHandler /* DMA1 Channel 4, Channel 5, Channel 6 and Channel 7*/
|
||||
.word ADC1_COMP_IRQHandler /* ADC1, COMP1 and COMP2 */
|
||||
.word LPTIM1_IRQHandler /* LPTIM1 */
|
||||
.word 0 /* Reserved */
|
||||
.word TIM2_IRQHandler /* TIM2 */
|
||||
.word 0 /* Reserved */
|
||||
.word TIM6_IRQHandler /* TIM6 */
|
||||
.word 0 /* Reserved */
|
||||
.word 0 /* Reserved */
|
||||
.word TIM21_IRQHandler /* TIM21 */
|
||||
.word 0 /* Reserved */
|
||||
.word TIM22_IRQHandler /* TIM22 */
|
||||
.word I2C1_IRQHandler /* I2C1 */
|
||||
.word I2C2_IRQHandler /* I2C2 */
|
||||
.word SPI1_IRQHandler /* SPI1 */
|
||||
.word SPI2_IRQHandler /* SPI2 */
|
||||
.word USART1_IRQHandler /* USART1 */
|
||||
.word USART2_IRQHandler /* USART2 */
|
||||
.word LPUART1_IRQHandler /* LPUART1 */
|
||||
.word 0 /* Reserved */
|
||||
.word 0 /* Reserved */
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Provide weak aliases for each Exception handler to the Default_Handler.
|
||||
* As they are weak aliases, any function with the same name will override
|
||||
* this definition.
|
||||
*
|
||||
*******************************************************************************/
|
||||
|
||||
.weak NMI_Handler
|
||||
.thumb_set NMI_Handler,Default_Handler
|
||||
|
||||
.weak HardFault_Handler
|
||||
.thumb_set HardFault_Handler,Default_Handler
|
||||
|
||||
.weak SVC_Handler
|
||||
.thumb_set SVC_Handler,Default_Handler
|
||||
|
||||
.weak PendSV_Handler
|
||||
.thumb_set PendSV_Handler,Default_Handler
|
||||
|
||||
.weak SysTick_Handler
|
||||
.thumb_set SysTick_Handler,Default_Handler
|
||||
|
||||
.weak WWDG_IRQHandler
|
||||
.thumb_set WWDG_IRQHandler,Default_Handler
|
||||
|
||||
.weak PVD_IRQHandler
|
||||
.thumb_set PVD_IRQHandler,Default_Handler
|
||||
|
||||
.weak RTC_IRQHandler
|
||||
.thumb_set RTC_IRQHandler,Default_Handler
|
||||
|
||||
.weak FLASH_IRQHandler
|
||||
.thumb_set FLASH_IRQHandler,Default_Handler
|
||||
|
||||
.weak RCC_IRQHandler
|
||||
.thumb_set RCC_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI0_1_IRQHandler
|
||||
.thumb_set EXTI0_1_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI2_3_IRQHandler
|
||||
.thumb_set EXTI2_3_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI4_15_IRQHandler
|
||||
.thumb_set EXTI4_15_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA1_Channel1_IRQHandler
|
||||
.thumb_set DMA1_Channel1_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA1_Channel2_3_IRQHandler
|
||||
.thumb_set DMA1_Channel2_3_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA1_Channel4_5_6_7_IRQHandler
|
||||
.thumb_set DMA1_Channel4_5_6_7_IRQHandler,Default_Handler
|
||||
|
||||
.weak ADC1_COMP_IRQHandler
|
||||
.thumb_set ADC1_COMP_IRQHandler,Default_Handler
|
||||
|
||||
.weak LPTIM1_IRQHandler
|
||||
.thumb_set LPTIM1_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM2_IRQHandler
|
||||
.thumb_set TIM2_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM6_IRQHandler
|
||||
.thumb_set TIM6_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM21_IRQHandler
|
||||
.thumb_set TIM21_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM22_IRQHandler
|
||||
.thumb_set TIM22_IRQHandler,Default_Handler
|
||||
|
||||
.weak I2C1_IRQHandler
|
||||
.thumb_set I2C1_IRQHandler,Default_Handler
|
||||
|
||||
.weak I2C2_IRQHandler
|
||||
.thumb_set I2C2_IRQHandler,Default_Handler
|
||||
|
||||
.weak SPI1_IRQHandler
|
||||
.thumb_set SPI1_IRQHandler,Default_Handler
|
||||
|
||||
.weak SPI2_IRQHandler
|
||||
.thumb_set SPI2_IRQHandler,Default_Handler
|
||||
|
||||
.weak USART1_IRQHandler
|
||||
.thumb_set USART1_IRQHandler,Default_Handler
|
||||
|
||||
.weak USART2_IRQHandler
|
||||
.thumb_set USART2_IRQHandler,Default_Handler
|
||||
|
||||
.weak LPUART1_IRQHandler
|
||||
.thumb_set LPUART1_IRQHandler,Default_Handler
|
||||
|
||||
|
||||
|
||||
|
||||
|
11
test/README
Executable file
11
test/README
Executable file
@ -0,0 +1,11 @@
|
||||
|
||||
This directory is intended for PlatformIO Test Runner and project tests.
|
||||
|
||||
Unit Testing is a software testing method by which individual units of
|
||||
source code, sets of one or more MCU program modules together with associated
|
||||
control data, usage procedures, and operating procedures, are tested to
|
||||
determine whether they are fit for use. Unit testing finds problems early
|
||||
in the development cycle.
|
||||
|
||||
More information about PlatformIO Unit Testing:
|
||||
- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html
|
Loading…
Reference in New Issue
Block a user