parent
018b69cdc8
commit
11ccc7496e
@ -0,0 +1,208 @@ |
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> |
||||
<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns="http://www.w3.org/TR/REC-html40"><head> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> |
||||
|
||||
|
||||
<link rel="File-List" href="Library_files/filelist.xml"> |
||||
|
||||
|
||||
<link rel="Edit-Time-Data" href="Library_files/editdata.mso"><!--[if !mso]> <style> v\:* {behavior:url(#default#VML);} o\:* {behavior:url(#default#VML);} w\:* {behavior:url(#default#VML);} .shape {behavior:url(#default#VML);} </style> <![endif]--><title>Release Notes for SX1272 component</title><!--[if gte mso 9]><xml> <o:DocumentProperties> <o:Author>STMicroelectronics</o:Author> <o:LastAuthor>STMicroelectronics</o:LastAuthor> <o:Revision>37</o:Revision> <o:TotalTime>136</o:TotalTime> <o:Created>2009-02-27T19:26:00Z</o:Created> <o:LastSaved>2009-03-01T17:56:00Z</o:LastSaved> <o:Pages>1</o:Pages> <o:Words>522</o:Words> <o:Characters>2977</o:Characters> <o:Company>STMicroelectronics</o:Company> <o:Lines>24</o:Lines> <o:Paragraphs>6</o:Paragraphs> <o:CharactersWithSpaces>3493</o:CharactersWithSpaces> <o:Version>11.6568</o:Version> </o:DocumentProperties> </xml><![endif]--><!--[if gte mso 9]><xml> <w:WordDocument> <w:Zoom>110</w:Zoom> <w:ValidateAgainstSchemas/> <w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid> <w:IgnoreMixedContent>false</w:IgnoreMixedContent> <w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText> <w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel> </w:WordDocument> </xml><![endif]--><!--[if gte mso 9]><xml> <w:LatentStyles DefLockedState="false" LatentStyleCount="156"> </w:LatentStyles> </xml><![endif]--> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<style> |
||||
<!-- |
||||
/* Style Definitions */ |
||||
p.MsoNormal, li.MsoNormal, div.MsoNormal |
||||
{mso-style-parent:""; |
||||
margin:0in; |
||||
margin-bottom:.0001pt; |
||||
mso-pagination:widow-orphan; |
||||
font-size:12.0pt; |
||||
font-family:"Times New Roman"; |
||||
mso-fareast-font-family:"Times New Roman";} |
||||
h2 |
||||
{mso-style-next:Normal; |
||||
margin-top:12.0pt; |
||||
margin-right:0in; |
||||
margin-bottom:3.0pt; |
||||
margin-left:0in; |
||||
mso-pagination:widow-orphan; |
||||
page-break-after:avoid; |
||||
mso-outline-level:2; |
||||
font-size:14.0pt; |
||||
font-family:Arial; |
||||
font-weight:bold; |
||||
font-style:italic;} |
||||
a:link, span.MsoHyperlink |
||||
{color:blue; |
||||
text-decoration:underline; |
||||
text-underline:single;} |
||||
a:visited, span.MsoHyperlinkFollowed |
||||
{color:blue; |
||||
text-decoration:underline; |
||||
text-underline:single;} |
||||
p |
||||
{mso-margin-top-alt:auto; |
||||
margin-right:0in; |
||||
mso-margin-bottom-alt:auto; |
||||
margin-left:0in; |
||||
mso-pagination:widow-orphan; |
||||
font-size:12.0pt; |
||||
font-family:"Times New Roman"; |
||||
mso-fareast-font-family:"Times New Roman";} |
||||
@page Section1 |
||||
{size:8.5in 11.0in; |
||||
margin:1.0in 1.25in 1.0in 1.25in; |
||||
mso-header-margin:.5in; |
||||
mso-footer-margin:.5in; |
||||
mso-paper-source:0;} |
||||
div.Section1 |
||||
{page:Section1;} |
||||
--> |
||||
</style><!--[if gte mso 10]> <style> /* Style Definitions */ table.MsoNormalTable {mso-style-name:"Table Normal"; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; mso-style-noshow:yes; mso-style-parent:""; mso-padding-alt:0in 5.4pt 0in 5.4pt; mso-para-margin:0in; mso-para-margin-bottom:.0001pt; mso-pagination:widow-orphan; font-size:10.0pt; font-family:"Times New Roman"; mso-ansi-language:#0400; mso-fareast-language:#0400; mso-bidi-language:#0400;} </style> <![endif]--><!--[if gte mso 9]><xml> <o:shapedefaults v:ext="edit" spidmax="5122"/> </xml><![endif]--><!--[if gte mso 9]><xml> <o:shapelayout v:ext="edit"> <o:idmap v:ext="edit" data="1"/> </o:shapelayout></xml><![endif]--> |
||||
<meta content="MCD Application Team" name="author"></head> |
||||
<body link="blue" vlink="blue"> |
||||
<div class="Section1"> |
||||
<p class="MsoNormal"><span style="font-family: Arial;"><o:p><br> |
||||
</o:p></span></p> |
||||
<div align="center"> |
||||
<table class="MsoNormalTable" style="width: 675pt;" border="0" cellpadding="0" cellspacing="0" width="900"> |
||||
<tbody> |
||||
<tr> |
||||
<td style="padding: 0cm;" valign="top"> |
||||
<table class="MsoNormalTable" style="width: 675pt;" border="0" cellpadding="0" cellspacing="0" width="900"> |
||||
<tbody> |
||||
<tr style=""> |
||||
<td style="padding: 1.5pt;"> |
||||
<h1 style="margin-bottom: 18pt; text-align: center;" align="center"><span style="font-size: 20pt; font-family: Verdana; color: rgb(51, 102, 255);">Release |
||||
Notes for SX1272 component</span><span style="font-size: 20pt; font-family: Verdana;"><o:p></o:p></span></h1> |
||||
<p class="MsoNormal" style="text-align: center;" align="center"><span style="font-size: 10pt; font-family: Arial; color: black;">Copyright |
||||
2017 STMicroelectronics</span><span style="color: black;"><u1:p></u1:p><o:p></o:p></span></p> |
||||
<p class="MsoNormal" style="text-align: center;" align="center"><span style="font-size: 10pt; font-family: Arial; color: black;"><img alt="" id="_x0000_i1025" src="../../../../_htmresc/st_logo.png" style="border: 0px solid ; width: 86px; height: 65px;"></span><span style="font-size: 10pt;"><o:p></o:p></span></p> |
||||
</td> |
||||
</tr> |
||||
</tbody> |
||||
</table> |
||||
<p class="MsoNormal"><span style="font-family: Arial; display: none;"><o:p> </o:p></span></p> |
||||
<table class="MsoNormalTable" style="width: 675pt;" border="0" cellpadding="0" width="900"> |
||||
<tbody> |
||||
<tr style=""> |
||||
|
||||
<span style="font-family: "Times New Roman";"></span> |
||||
<h3 style="background: rgb(51, 102, 255) none repeat scroll 0% 50%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; margin-right: 500pt; width: 200px;"> |
||||
<span style="font-size: 10pt; font-family: Arial; color: white;">V1.0.1 / 08-September-2017</span> |
||||
</h3> |
||||
<p class="MsoNormal" style="margin: 4.5pt 0cm 4.5pt 18pt;"> |
||||
<b style=""> |
||||
<u> |
||||
<span style="font-size: 10pt; font-family: Verdana; color: black;">Main Changes<o:p></o:p> |
||||
</span> |
||||
</u> |
||||
</b> |
||||
</p> |
||||
|
||||
<ul style="margin-top: 0cm;" type="square"> |
||||
<li class="MsoNormal"> |
||||
<span style="font-size: 10pt; font-family: Verdana;">Retrieve Public Network handling in the radio driver |
||||
<span style="font-weight: bold; font-style: italic;"> |
||||
</span> |
||||
</span> |
||||
</li> |
||||
<li class="MsoNormal"> |
||||
<span style="font-size: 10pt; font-family: Verdana;">Carrier Sense update |
||||
<span style="font-weight: bold; font-style: italic;"> |
||||
</span> |
||||
</span> |
||||
</li> |
||||
<li class="MsoNormal"> |
||||
<span style="font-size: 10pt; font-family: Verdana;">Modem selection update |
||||
<span style="font-weight: bold; font-style: italic;"> |
||||
</span> |
||||
</span> |
||||
</li> |
||||
</ul> |
||||
|
||||
<span style="font-family: "Times New Roman";"></span> |
||||
<h3 style="background: rgb(51, 102, 255) none repeat scroll 0% 50%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; margin-right: 500pt; width: 200px;"> |
||||
<span style="font-size: 10pt; font-family: Arial; color: white;">V1.0.0 / 01-June-2017</span> |
||||
</h3> |
||||
<p class="MsoNormal" style="margin: 4.5pt 0cm 4.5pt 18pt;"> |
||||
<b style=""> |
||||
<u> |
||||
<span style="font-size: 10pt; font-family: Verdana; color: black;">Main Changes<o:p></o:p> |
||||
</span> |
||||
</u> |
||||
</b> |
||||
</p> |
||||
|
||||
<ul style="margin-top: 0cm;" type="square"> |
||||
<li class="MsoNormal"> |
||||
<span style="font-size: 10pt; font-family: Verdana;">First Release |
||||
<span style="font-weight: bold; font-style: italic;"> |
||||
</span> |
||||
</span> |
||||
</li> |
||||
</ul> |
||||
<span style="font-size: 10pt; font-family: Verdana;"> </span> |
||||
<h2 style="background: rgb(51, 102, 255) none repeat scroll 0% 50%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> |
||||
<a name="License"></a> |
||||
<span style="font-size: 12pt; color: white;">License<o:p></o:p> |
||||
</span> |
||||
</h2> |
||||
<div style="text-align: justify;"> |
||||
<div style="text-align: justify;"><font size="-1"> |
||||
<span style="font-family: "Verdana","sans-serif";"> |
||||
Redistribution and use in source and binary forms, with or without |
||||
modification, are permitted provided that the following conditions are |
||||
met: |
||||
</span> |
||||
<br> |
||||
</font> |
||||
<ol><li><font size="-1"><span style="font-family: "Verdana","sans-serif";">Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.</span><span style="font-family: "Verdana","sans-serif";"></span></font></li><li><font size="-1"><span style="font-family: "Verdana","sans-serif";">Redistributions |
||||
in binary form must reproduce the above copyright notice, this list of |
||||
conditions and the following disclaimer in </span><span style="font-family: "Verdana","sans-serif";">the documentation and/or other materials provided with the distribution.</span><span style="font-family: "Verdana","sans-serif";"></span></font></li><li><font size="-1"><span style="font-family: "Verdana","sans-serif";">Neither the name of STMicroelectronics nor the names of its contributors may be used to endorse or promote products derived |
||||
</span><span style="font-family: "Verdana","sans-serif";">from this software without specific prior written permission.</span><br> |
||||
</font> |
||||
</li></ol> |
||||
<font size="-1"> |
||||
|
||||
<span style="font-family: "Verdana","sans-serif";">THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED</span><span style="font-family: "Verdana","sans-serif";"> WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A </span><span style="font-family: "Verdana","sans-serif";">PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY </span><span style="font-family: "Verdana","sans-serif";">DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, </span><span style="font-family: "Verdana","sans-serif";">PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER</span><span style="font-family: "Verdana","sans-serif";"> CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR </span><span style="font-family: "Verdana","sans-serif";">OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.</span></font> |
||||
|
||||
</div> |
||||
<span style="font-family: "Verdana","sans-serif";"></span></div> |
||||
<span style="font-size: 10pt; font-family: "Verdana","sans-serif"; color: black;"></span> <b><span style="font-size: 10pt; font-family: Verdana; color: black;"></span></b> |
||||
|
||||
<div class="MsoNormal" style="text-align: center;" align="center"><span style="color: black;"> |
||||
<hr align="center" size="2" width="100%"></span></div> |
||||
<p class="MsoNormal" style="margin: 4.5pt 0cm 4.5pt 18pt; text-align: center;" align="center"><span style="font-size: 10pt; font-family: Verdana; color: black;">For |
||||
complete documentation on </span><span style="font-size: 10pt; font-family: Verdana;">STM32<span style="color: black;"> Microcontrollers |
||||
visit </span><u><span style="color: blue;"><a href="http://www.st.com/internet/mcu/class/1734.jsp" target="_blank">www.st.com/STM32</a></span></u></span><span style="font-size: 10pt; font-family: Verdana;"><a target="_blank" href="http://www.st.com/internet/mcu/family/141.jsp"><u><span style="color: blue;"></span></u></a></span><span style="font-size: 10pt; font-family: Verdana;"><u><span style="color: blue;"></span></u></span><span style="color: black;"><o:p></o:p></span></p> |
||||
</td> |
||||
</tr> |
||||
</tbody> |
||||
</table> |
||||
<p class="MsoNormal"><span style="font-size: 10pt;"><o:p></o:p></span></p> |
||||
</td> |
||||
</tr> |
||||
</tbody> |
||||
</table> |
||||
</div> |
||||
<p class="MsoNormal"><o:p> </o:p></p> |
||||
</div> |
||||
|
||||
</body></html> |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,523 @@ |
||||
/*
|
||||
/ _____) _ | | |
||||
( (____ _____ ____ _| |_ _____ ____| |__ |
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | | |
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_| |
||||
(C)2013 Semtech |
||||
|
||||
Description: Generic SX1272 driver implementation |
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project |
||||
|
||||
Maintainer: Miguel Luis and Gregory Cristian |
||||
*/ |
||||
/*******************************************************************************
|
||||
* @file sx1272.h |
||||
* @author MCD Application Team |
||||
* @version V1.0.1 |
||||
* @date 08-September-2017 |
||||
* @brief Header for driver sx1272.c |
||||
****************************************************************************** |
||||
* @attention |
||||
* |
||||
* <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2> |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without modification, |
||||
* are permitted provided that the following conditions are met: |
||||
* 1. Redistributions of source code must retain the above copyright notice, |
||||
* this list of conditions and the following disclaimer. |
||||
* 2. 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. |
||||
* 3. Neither the name of STMicroelectronics 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 __SX1272_H__ |
||||
#define __SX1272_H__ |
||||
|
||||
#include "sx1272Regs-Fsk.h" |
||||
#include "sx1272Regs-LoRa.h" |
||||
|
||||
/*!
|
||||
* Radio wake-up time from sleep |
||||
*/ |
||||
#define RADIO_WAKEUP_TIME 2 // [ms]
|
||||
|
||||
/*!
|
||||
* Sync word for Private LoRa networks |
||||
*/ |
||||
#define LORA_MAC_PRIVATE_SYNCWORD 0x12 |
||||
|
||||
/*!
|
||||
* Sync word for Public LoRa networks |
||||
*/ |
||||
#define LORA_MAC_PUBLIC_SYNCWORD 0x34 |
||||
|
||||
/*!
|
||||
* Radio FSK modem parameters |
||||
*/ |
||||
typedef struct |
||||
{ |
||||
int8_t Power; |
||||
uint32_t Fdev; |
||||
uint32_t Bandwidth; |
||||
uint32_t BandwidthAfc; |
||||
uint32_t Datarate; |
||||
uint16_t PreambleLen; |
||||
bool FixLen; |
||||
uint8_t PayloadLen; |
||||
bool CrcOn; |
||||
bool IqInverted; |
||||
bool RxContinuous; |
||||
uint32_t TxTimeout; |
||||
uint32_t RxSingleTimeout; |
||||
}RadioFskSettings_t; |
||||
|
||||
/*!
|
||||
* Radio FSK packet handler state |
||||
*/ |
||||
typedef struct |
||||
{ |
||||
uint8_t PreambleDetected; |
||||
uint8_t SyncWordDetected; |
||||
int8_t RssiValue; |
||||
int32_t AfcValue; |
||||
uint8_t RxGain; |
||||
uint16_t Size; |
||||
uint16_t NbBytes; |
||||
uint8_t FifoThresh; |
||||
uint8_t ChunkSize; |
||||
}RadioFskPacketHandler_t; |
||||
|
||||
/*!
|
||||
* Radio LoRa modem parameters |
||||
*/ |
||||
typedef struct |
||||
{ |
||||
int8_t Power; |
||||
uint32_t Bandwidth; |
||||
uint32_t Datarate; |
||||
bool LowDatarateOptimize; |
||||
uint8_t Coderate; |
||||
uint16_t PreambleLen; |
||||
bool FixLen; |
||||
uint8_t PayloadLen; |
||||
bool CrcOn; |
||||
bool FreqHopOn; |
||||
uint8_t HopPeriod; |
||||
bool IqInverted; |
||||
bool RxContinuous; |
||||
uint32_t TxTimeout; |
||||
bool PublicNetwork; |
||||
}RadioLoRaSettings_t; |
||||
|
||||
/*!
|
||||
* Radio LoRa packet handler state |
||||
*/ |
||||
typedef struct |
||||
{ |
||||
int8_t SnrValue; |
||||
int16_t RssiValue; |
||||
uint8_t Size; |
||||
}RadioLoRaPacketHandler_t; |
||||
|
||||
/*!
|
||||
* Radio Settings |
||||
*/ |
||||
typedef struct |
||||
{ |
||||
RadioState_t State; |
||||
RadioModems_t Modem; |
||||
uint32_t Channel; |
||||
RadioFskSettings_t Fsk; |
||||
RadioFskPacketHandler_t FskPacketHandler; |
||||
RadioLoRaSettings_t LoRa; |
||||
RadioLoRaPacketHandler_t LoRaPacketHandler; |
||||
}RadioSettings_t; |
||||
|
||||
/*!
|
||||
* Radio hardware and global parameters |
||||
*/ |
||||
typedef struct SX1272_s |
||||
{ |
||||
uint8_t RxTx; |
||||
RadioSettings_t Settings; |
||||
}SX1272_t; |
||||
|
||||
extern SX1272_t SX1272; |
||||
/*!
|
||||
* Hardware IO IRQ callback function definition |
||||
*/ |
||||
typedef void ( DioIrqHandler )( void ); |
||||
|
||||
/*!
|
||||
* SX1272 definitions |
||||
*/ |
||||
#define XTAL_FREQ 32000000 |
||||
#define FREQ_STEP 61.03515625 |
||||
#define FREQ_STEP_8 15625 /* FREQ_STEP<<8 */ |
||||
|
||||
/*!
|
||||
* \brief Radio hardware registers initialization definition |
||||
* |
||||
* \remark Can be automatically generated by the SX1272 GUI (not yet implemented) |
||||
*/ |
||||
#define RADIO_INIT_REGISTERS_VALUE \ |
||||
{ \
|
||||
{ MODEM_FSK , REG_LNA , 0x23 },\
|
||||
{ MODEM_FSK , REG_RXCONFIG , 0x1E },\
|
||||
{ MODEM_FSK , REG_RSSICONFIG , 0xD2 },\
|
||||
{ MODEM_FSK , REG_AFCFEI , 0x01 },\
|
||||
{ MODEM_FSK , REG_PREAMBLEDETECT , 0xAA },\
|
||||
{ MODEM_FSK , REG_OSC , 0x07 },\
|
||||
{ MODEM_FSK , REG_SYNCCONFIG , 0x12 },\
|
||||
{ MODEM_FSK , REG_SYNCVALUE1 , 0xC1 },\
|
||||
{ MODEM_FSK , REG_SYNCVALUE2 , 0x94 },\
|
||||
{ MODEM_FSK , REG_SYNCVALUE3 , 0xC1 },\
|
||||
{ MODEM_FSK , REG_PACKETCONFIG1 , 0xD8 },\
|
||||
{ MODEM_FSK , REG_FIFOTHRESH , 0x8F },\
|
||||
{ MODEM_FSK , REG_IMAGECAL , 0x02 },\
|
||||
{ MODEM_FSK , REG_DIOMAPPING1 , 0x00 },\
|
||||
{ MODEM_FSK , REG_DIOMAPPING2 , 0x30 },\
|
||||
{ MODEM_LORA, REG_LR_DETECTOPTIMIZE , 0x43 },\
|
||||
{ MODEM_LORA, REG_LR_PAYLOADMAXLENGTH, 0x40 },\
|
||||
} \
|
||||
|
||||
/* Freq = channel * FREQ_STEP */ |
||||
#define SX_CHANNEL_TO_FREQ( channel, freq ) \ |
||||
do \
|
||||
{ \
|
||||
uint32_t initialChanInt, initialChanFrac; \
|
||||
initialChanInt = channel >> 8; \
|
||||
initialChanFrac = channel - ( initialChanInt << 8 ); \
|
||||
freq = initialChanInt * FREQ_STEP_8 + ( ( initialChanFrac * FREQ_STEP_8 + ( 128 ) ) >> 8 ); \
|
||||
}while( 0 ) |
||||
|
||||
/* channel = Freq / FREQ_STEP */ |
||||
#define SX_FREQ_TO_CHANNEL( channel, freq ) \ |
||||
do \
|
||||
{ \
|
||||
uint32_t initialFreqInt, initialFreqFrac; \
|
||||
initialFreqInt = freq / FREQ_STEP_8; \
|
||||
initialFreqFrac = freq - ( initialFreqInt * FREQ_STEP_8 ); \
|
||||
channel = ( initialFreqInt << 8 ) + ( ( ( initialFreqFrac << 8 ) + ( FREQ_STEP_8 / 2 ) ) / FREQ_STEP_8 ); \
|
||||
}while( 0 ) |
||||
|
||||
#define RX_BUFFER_SIZE 256 |
||||
|
||||
typedef struct sBoardCallback |
||||
{ |
||||
/*!
|
||||
* \brief Set XO state on the board |
||||
*/ |
||||
void ( *SX1272BoardSetXO )( uint8_t state ); |
||||
/*!
|
||||
* \brief Get Board Wake Up time |
||||
*/ |
||||
uint32_t ( *SX1272BoardGetWakeTime )( void ); |
||||
/*!
|
||||
* \brief Initializes the radio I/Os Irq |
||||
*/ |
||||
void ( *SX1272BoardIoIrqInit )( DioIrqHandler **irqHandlers ); |
||||
/*!
|
||||
* \brief Sets the radio output power. |
||||
* |
||||
* \param [IN] power Sets the RF output power |
||||
*/ |
||||
void ( *SX1272BoardSetRfTxPower )( int8_t power ); |
||||
/*!
|
||||
* \brief Set the RF Switch I/Os pins in Low Power mode |
||||
* |
||||
* \param [IN] status enable or disable |
||||
*/ |
||||
void ( *SX1272BoardSetAntSwLowPower )( bool status ); |
||||
/*!
|
||||
* \brief Controls the antena switch if necessary. |
||||
* |
||||
* \remark see errata note |
||||
* |
||||
* \param [IN] opMode Current radio operating mode |
||||
*/ |
||||
void ( *SX1272BoardSetAntSw )( uint8_t opMode ); |
||||
}LoRaBoardCallback_t; |
||||
|
||||
/*!
|
||||
* ============================================================================ |
||||
* Public functions prototypes |
||||
* ============================================================================ |
||||
*/ |
||||
void SX1272BoardInit( LoRaBoardCallback_t *callbacks ); |
||||
/*!
|
||||
* \brief Initializes the radio |
||||
* |
||||
* \param [IN] events Structure containing the driver callback functions |
||||
* \param [OUT] returns the wake up time of the radio and associated board |
||||
*/ |
||||
uint32_t SX1272Init( RadioEvents_t *events ); |
||||
|
||||
/*!
|
||||
* Return current radio status |
||||
* |
||||
* \param status Radio status.[RF_IDLE, RF_RX_RUNNING, RF_TX_RUNNING] |
||||
*/ |
||||
RadioState_t SX1272GetStatus( void ); |
||||
|
||||
/*!
|
||||
* \brief Configures the radio with the given modem |
||||
* |
||||
* \param [IN] modem Modem to be used [0: FSK, 1: LoRa] |
||||
*/ |
||||
void SX1272SetModem( RadioModems_t modem ); |
||||
|
||||
/*!
|
||||
* \brief Sets the channel configuration |
||||
* |
||||
* \param [IN] freq Channel RF frequency |
||||
*/ |
||||
void SX1272SetChannel( uint32_t freq ); |
||||
|
||||
/*!
|
||||
* \brief Checks if the channel is free for the given time |
||||
* |
||||
* \param [IN] modem Radio modem to be used [0: FSK, 1: LoRa] |
||||
* \param [IN] freq Channel RF frequency |
||||
* \param [IN] rssiThresh RSSI threshold |
||||
* \param [IN] maxCarrierSenseTime Max time while the RSSI is measured |
||||
* |
||||
* \retval isFree [true: Channel is free, false: Channel is not free] |
||||
*/ |
||||
bool SX1272IsChannelFree( RadioModems_t modem, uint32_t freq, int16_t rssiThresh, uint32_t maxCarrierSenseTime ); |
||||
|
||||
/*!
|
||||
* \brief Generates a 32 bits random value based on the RSSI readings |
||||
* |
||||
* \remark This function sets the radio in LoRa modem mode and disables |
||||
* all interrupts. |
||||
* After calling this function either SX1272SetRxConfig or |
||||
* SX1272SetTxConfig functions must be called. |
||||
* |
||||
* \retval randomValue 32 bits random value |
||||
*/ |
||||
uint32_t SX1272Random( void ); |
||||
|
||||
/*!
|
||||
* \brief Sets the reception parameters |
||||
* |
||||
* \param [IN] modem Radio modem to be used [0: FSK, 1: LoRa] |
||||
* \param [IN] bandwidth Sets the bandwidth |
||||
* FSK : >= 2600 and <= 250000 Hz |
||||
* LoRa: [0: 125 kHz, 1: 250 kHz, |
||||
* 2: 500 kHz, 3: Reserved] |
||||
* \param [IN] datarate Sets the Datarate |
||||
* FSK : 600..300000 bits/s |
||||
* LoRa: [6: 64, 7: 128, 8: 256, 9: 512, |
||||
* 10: 1024, 11: 2048, 12: 4096 chips] |
||||
* \param [IN] coderate Sets the coding rate (LoRa only) |
||||
* FSK : N/A ( set to 0 ) |
||||
* LoRa: [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8] |
||||
* \param [IN] bandwidthAfc Sets the AFC Bandwidth (FSK only) |
||||
* FSK : >= 2600 and <= 250000 Hz |
||||
* LoRa: N/A ( set to 0 ) |
||||
* \param [IN] preambleLen Sets the Preamble length |
||||
* FSK : Number of bytes |
||||
* LoRa: Length in symbols (the hardware adds 4 more symbols) |
||||
* \param [IN] symbTimeout Sets the RxSingle timeout value |
||||
* FSK : timeout number of bytes |
||||
* LoRa: timeout in symbols |
||||
* \param [IN] fixLen Fixed length packets [0: variable, 1: fixed] |
||||
* \param [IN] payloadLen Sets payload length when fixed length is used |
||||
* \param [IN] crcOn Enables/Disables the CRC [0: OFF, 1: ON] |
||||
* \param [IN] freqHopOn Enables disables the intra-packet frequency hopping |
||||
* FSK : N/A ( set to 0 ) |
||||
* LoRa: [0: OFF, 1: ON] |
||||
* \param [IN] hopPeriod Number of symbols between each hop |
||||
* FSK : N/A ( set to 0 ) |
||||
* LoRa: Number of symbols |
||||
* \param [IN] iqInverted Inverts IQ signals (LoRa only) |
||||
* FSK : N/A ( set to 0 ) |
||||
* LoRa: [0: not inverted, 1: inverted] |
||||
* \param [IN] rxContinuous Sets the reception in continuous mode |
||||
* [false: single mode, true: continuous mode] |
||||
*/ |
||||
void SX1272SetRxConfig( RadioModems_t modem, uint32_t bandwidth, |
||||
uint32_t datarate, uint8_t coderate, |
||||
uint32_t bandwidthAfc, uint16_t preambleLen, |
||||
uint16_t symbTimeout, bool fixLen, |
||||
uint8_t payloadLen, |
||||
bool crcOn, bool freqHopOn, uint8_t hopPeriod, |
||||
bool iqInverted, bool rxContinuous ); |
||||
|
||||
/*!
|
||||
* \brief Sets the transmission parameters |
||||
* |
||||
* \param [IN] modem Radio modem to be used [0: FSK, 1: LoRa] |
||||
* \param [IN] power Sets the output power [dBm] |
||||
* \param [IN] fdev Sets the frequency deviation (FSK only) |
||||
* FSK : [Hz] |
||||
* LoRa: 0 |
||||
* \param [IN] bandwidth Sets the bandwidth (LoRa only) |
||||
* FSK : 0 |
||||
* LoRa: [0: 125 kHz, 1: 250 kHz, |
||||
* 2: 500 kHz, 3: Reserved] |
||||
* \param [IN] datarate Sets the Datarate |
||||
* FSK : 600..300000 bits/s |
||||
* LoRa: [6: 64, 7: 128, 8: 256, 9: 512, |
||||
* 10: 1024, 11: 2048, 12: 4096 chips] |
||||
* \param [IN] coderate Sets the coding rate (LoRa only) |
||||
* FSK : N/A ( set to 0 ) |
||||
* LoRa: [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8] |
||||
* \param [IN] preambleLen Sets the preamble length |
||||
* FSK : Number of bytes |
||||
* LoRa: Length in symbols (the hardware adds 4 more symbols) |
||||
* \param [IN] fixLen Fixed length packets [0: variable, 1: fixed] |
||||
* \param [IN] crcOn Enables disables the CRC [0: OFF, 1: ON] |
||||
* \param [IN] freqHopOn Enables disables the intra-packet frequency hopping |
||||
* FSK : N/A ( set to 0 ) |
||||
* LoRa: [0: OFF, 1: ON] |
||||
* \param [IN] hopPeriod Number of symbols between each hop |
||||
* FSK : N/A ( set to 0 ) |
||||
* LoRa: Number of symbols |
||||
* \param [IN] iqInverted Inverts IQ signals (LoRa only) |
||||
* FSK : N/A ( set to 0 ) |
||||
* LoRa: [0: not inverted, 1: inverted] |
||||
* \param [IN] timeout Transmission timeout [ms] |
||||
*/ |
||||
void SX1272SetTxConfig( RadioModems_t modem, int8_t power, uint32_t fdev, |
||||
uint32_t bandwidth, uint32_t datarate, |
||||
uint8_t coderate, uint16_t preambleLen, |
||||
bool fixLen, bool crcOn, bool freqHopOn, |
||||
uint8_t hopPeriod, bool iqInverted, uint32_t timeout ); |
||||
|
||||
/*!
|
||||
* \brief Computes the packet time on air in ms for the given payload |
||||
* |
||||
* \Remark Can only be called once SetRxConfig or SetTxConfig have been called |
||||
* |
||||
* \param [IN] modem Radio modem to be used [0: FSK, 1: LoRa] |
||||
* \param [IN] pktLen Packet payload length |
||||
* |
||||
* \retval airTime Computed airTime (ms) for the given packet payload length |
||||
*/ |
||||
uint32_t SX1272GetTimeOnAir( RadioModems_t modem, uint8_t pktLen ); |
||||
|
||||
/*!
|
||||
* \brief Sends the buffer of size. Prepares the packet to be sent and sets |
||||
* the radio in transmission |
||||
* |
||||
* \param [IN]: buffer Buffer pointer |
||||
* \param [IN]: size Buffer size |
||||
*/ |
||||
void SX1272Send( uint8_t *buffer, uint8_t size ); |
||||
|
||||
/*!
|
||||
* \brief Sets the radio in sleep mode |
||||
*/ |
||||
void SX1272SetSleep( void ); |
||||
|
||||
/*!
|
||||
* \brief Sets the radio in standby mode |
||||
*/ |
||||
void SX1272SetStby( void ); |
||||
|
||||
/*!
|
||||
* \brief Sets the radio in reception mode for the given time |
||||
* \param [IN] timeout Reception timeout [ms] [0: continuous, others timeout] |
||||
*/ |
||||
void SX1272SetRx( uint32_t timeout ); |
||||
|
||||
/*!
|
||||
* \brief Start a Channel Activity Detection |
||||
*/ |
||||
void SX1272StartCad( void ); |
||||
|
||||
/*!
|
||||
* \brief Sets the radio in continuous wave transmission mode |
||||
* |
||||
* \param [IN]: freq Channel RF frequency |
||||
* \param [IN]: power Sets the output power [dBm] |
||||
* \param [IN]: time Transmission mode timeout [s] |
||||
*/ |
||||
void SX1272SetTxContinuousWave( uint32_t freq, int8_t power, uint16_t time ); |
||||
|
||||
/*!
|
||||
* \brief Reads the current RSSI value |
||||
* |
||||
* \retval rssiValue Current RSSI value in [dBm] |
||||
*/ |
||||
int16_t SX1272ReadRssi( RadioModems_t modem ); |
||||
|
||||
/*!
|
||||
* \brief Writes the radio register at the specified address |
||||
* |
||||
* \param [IN]: addr Register address |
||||
* \param [IN]: data New register value |
||||
*/ |
||||
void SX1272Write( uint8_t addr, uint8_t data ); |
||||
|
||||
/*!
|
||||
* \brief Reads the radio register at the specified address |
||||
* |
||||
* \param [IN]: addr Register address |
||||
* \retval data Register value |
||||
*/ |
||||
uint8_t SX1272Read( uint8_t addr ); |
||||
|
||||
/*!
|
||||
* \brief Writes multiple radio registers starting at address |
||||
* |
||||
* \param [IN] addr First Radio register address |
||||
* \param [IN] buffer Buffer containing the new register's values |
||||
* \param [IN] size Number of registers to be written |
||||
*/ |
||||
void SX1272WriteBuffer( uint8_t addr, uint8_t *buffer, uint8_t size ); |
||||
|
||||
/*!
|
||||
* \brief Reads multiple radio registers starting at address |
||||
* |
||||
* \param [IN] addr First Radio register address |
||||
* \param [OUT] buffer Buffer where to copy the registers data |
||||
* \param [IN] size Number of registers to be read |
||||
*/ |
||||
void SX1272ReadBuffer( uint8_t addr, uint8_t *buffer, uint8_t size ); |
||||
|
||||
/*!
|
||||
* \brief Sets the maximum payload length. |
||||
* |
||||
* \param [IN] modem Radio modem to be used [0: FSK, 1: LoRa] |
||||
* \param [IN] max Maximum payload length in bytes |
||||
*/ |
||||
void SX1272SetMaxPayloadLength( RadioModems_t modem, uint8_t max ); |
||||
|
||||
/*!
|
||||
* \brief Sets the network to public or private. Updates the sync byte. |
||||
* |
||||
* \remark Applies to LoRa modem only |
||||
* |
||||
* \param [IN] enable if true, it enables a public network |
||||
*/ |
||||
void SX1272SetPublicNetwork( bool enable ); |
||||
|
||||
/*!
|
||||
* \brief Service to get the radio wake-up time. |
||||
* |
||||
* \retval Value of the radio wake-up time. |
||||
*/ |
||||
uint32_t SX1272GetRadioWakeUpTime( void ); |
||||
|
||||
#endif /* __SX1272_H__ */ |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,545 @@ |
||||
/*
|
||||
/ _____) _ | | |
||||
( (____ _____ ____ _| |_ _____ ____| |__ |
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | | |
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_| |
||||
(C)2013 Semtech |
||||
|
||||
Description: SX1272 LoRa modem registers and bits definitions |
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project |
||||
|
||||
Maintainer: Miguel Luis and Gregory Cristian |
||||
*/ |
||||
#ifndef __SX1272_REGS_LORA_H__ |
||||
#define __SX1272_REGS_LORA_H__ |
||||
|
||||
/*!
|
||||
* ============================================================================ |
||||
* SX1272 Internal registers Address |
||||
* ============================================================================ |
||||
*/ |
||||
#define REG_LR_FIFO 0x00 |
||||
// Common settings
|
||||
#define REG_LR_OPMODE 0x01 |
||||
#define REG_LR_FRFMSB 0x06 |
||||
#define REG_LR_FRFMID 0x07 |
||||
#define REG_LR_FRFLSB 0x08 |
||||
// Tx settings
|
||||
#define REG_LR_PACONFIG 0x09 |
||||
#define REG_LR_PARAMP 0x0A |
||||
#define REG_LR_OCP 0x0B |
||||
// Rx settings
|
||||
#define REG_LR_LNA 0x0C |
||||
// LoRa registers
|
||||
#define REG_LR_FIFOADDRPTR 0x0D |
||||
#define REG_LR_FIFOTXBASEADDR 0x0E |
||||
#define REG_LR_FIFORXBASEADDR 0x0F |
||||
#define REG_LR_FIFORXCURRENTADDR 0x10 |
||||
#define REG_LR_IRQFLAGSMASK 0x11 |
||||
#define REG_LR_IRQFLAGS 0x12 |
||||
#define REG_LR_RXNBBYTES 0x13 |
||||
#define REG_LR_RXHEADERCNTVALUEMSB 0x14 |
||||
#define REG_LR_RXHEADERCNTVALUELSB 0x15 |
||||
#define REG_LR_RXPACKETCNTVALUEMSB 0x16 |
||||
#define REG_LR_RXPACKETCNTVALUELSB 0x17 |
||||
#define REG_LR_MODEMSTAT 0x18 |
||||
#define REG_LR_PKTSNRVALUE 0x19 |
||||
#define REG_LR_PKTRSSIVALUE 0x1A |
||||
#define REG_LR_RSSIVALUE 0x1B |
||||
#define REG_LR_HOPCHANNEL 0x1C |
||||
#define REG_LR_MODEMCONFIG1 0x1D |
||||
#define REG_LR_MODEMCONFIG2 0x1E |
||||
#define REG_LR_SYMBTIMEOUTLSB 0x1F |
||||
#define REG_LR_PREAMBLEMSB 0x20 |
||||
#define REG_LR_PREAMBLELSB 0x21 |
||||
#define REG_LR_PAYLOADLENGTH 0x22 |
||||
#define REG_LR_PAYLOADMAXLENGTH 0x23 |
||||
#define REG_LR_HOPPERIOD 0x24 |
||||
#define REG_LR_FIFORXBYTEADDR 0x25 |
||||
#define REG_LR_FEIMSB 0x28 |
||||
#define REG_LR_FEIMID 0x29 |
||||
#define REG_LR_FEILSB 0x2A |
||||
#define REG_LR_RSSIWIDEBAND 0x2C |
||||
#define REG_LR_DETECTOPTIMIZE 0x31 |
||||
#define REG_LR_INVERTIQ 0x33 |
||||
#define REG_LR_DETECTIONTHRESHOLD 0x37 |
||||
#define REG_LR_SYNCWORD 0x39 |
||||
#define REG_LR_INVERTIQ2 0x3B |
||||
|
||||
// end of documented register in datasheet
|
||||
// I/O settings
|
||||
#define REG_LR_DIOMAPPING1 0x40 |
||||
#define REG_LR_DIOMAPPING2 0x41 |
||||
// Version
|
||||
#define REG_LR_VERSION 0x42 |
||||
// Additional settings
|
||||
#define REG_LR_AGCREF 0x43 |
||||
#define REG_LR_AGCTHRESH1 0x44 |
||||
#define REG_LR_AGCTHRESH2 0x45 |
||||
#define REG_LR_AGCTHRESH3 0x46 |
||||
#define REG_LR_PLLHOP 0x4B |
||||
#define REG_LR_TCXO 0x58 |
||||
#define REG_LR_PADAC 0x5A |
||||
#define REG_LR_PLL 0x5C |
||||
#define REG_LR_PLLLOWPN 0x5E |
||||
#define REG_LR_FORMERTEMP 0x6C |
||||
|
||||
/*!
|
||||
* ============================================================================ |
||||
* SX1272 LoRa bits control definition |
||||
* ============================================================================ |
||||
*/ |
||||
|
||||
/*!
|
||||
* RegFifo |
||||
*/ |
||||
|
||||
/*!
|
||||
* RegOpMode |
||||
*/ |
||||
#define RFLR_OPMODE_LONGRANGEMODE_MASK 0x7F |
||||
#define RFLR_OPMODE_LONGRANGEMODE_OFF 0x00 // Default
|
||||
#define RFLR_OPMODE_LONGRANGEMODE_ON 0x80 |
||||
|
||||
#define RFLR_OPMODE_ACCESSSHAREDREG_MASK 0xBF |
||||
#define RFLR_OPMODE_ACCESSSHAREDREG_ENABLE 0x40 |
||||
#define RFLR_OPMODE_ACCESSSHAREDREG_DISABLE 0x00 // Default
|
||||
|
||||
#define RFLR_OPMODE_MASK 0xF8 |
||||
#define RFLR_OPMODE_SLEEP 0x00 |
||||
#define RFLR_OPMODE_STANDBY 0x01 // Default
|
||||
#define RFLR_OPMODE_SYNTHESIZER_TX 0x02 |
||||
#define RFLR_OPMODE_TRANSMITTER 0x03 |
||||
#define RFLR_OPMODE_SYNTHESIZER_RX 0x04 |
||||
#define RFLR_OPMODE_RECEIVER 0x05 |
||||
// LoRa specific modes
|
||||
#define RFLR_OPMODE_RECEIVER_SINGLE 0x06 |
||||
#define RFLR_OPMODE_CAD 0x07 |
||||
|
||||
/*!
|
||||
* RegFrf (MHz) |
||||
*/ |
||||
#define RFLR_FRFMSB_915_MHZ 0xE4 // Default
|
||||
#define RFLR_FRFMID_915_MHZ 0xC0 // Default
|
||||
#define RFLR_FRFLSB_915_MHZ 0x00 // Default
|
||||
|
||||
/*!
|
||||
* RegPaConfig |
||||
*/ |
||||
#define RFLR_PACONFIG_PASELECT_MASK 0x7F |
||||
#define RFLR_PACONFIG_PASELECT_PABOOST 0x80 |
||||
#define RFLR_PACONFIG_PASELECT_RFO 0x00 // Default
|
||||
|
||||
#define RFLR_PACONFIG_OUTPUTPOWER_MASK 0xF0 |
||||
|
||||
/*!
|
||||
* RegPaRamp |
||||
*/ |
||||
#define RFLR_PARAMP_LOWPNTXPLL_MASK 0xE0 |
||||
#define RFLR_PARAMP_LOWPNTXPLL_OFF 0x10 // Default
|
||||
#define RFLR_PARAMP_LOWPNTXPLL_ON 0x00 |
||||
|
||||
#define RFLR_PARAMP_MASK 0xF0 |
||||
#define RFLR_PARAMP_3400_US 0x00 |
||||
#define RFLR_PARAMP_2000_US 0x01 |
||||
#define RFLR_PARAMP_1000_US 0x02 |
||||
#define RFLR_PARAMP_0500_US 0x03 |
||||
#define RFLR_PARAMP_0250_US 0x04 |
||||
#define RFLR_PARAMP_0125_US 0x05 |
||||
#define RFLR_PARAMP_0100_US 0x06 |
||||
#define RFLR_PARAMP_0062_US 0x07 |
||||
#define RFLR_PARAMP_0050_US 0x08 |
||||
#define RFLR_PARAMP_0040_US 0x09 // Default
|
||||
#define RFLR_PARAMP_0031_US 0x0A |
||||
#define RFLR_PARAMP_0025_US 0x0B |
||||
#define RFLR_PARAMP_0020_US 0x0C |
||||
#define RFLR_PARAMP_0015_US 0x0D |
||||
#define RFLR_PARAMP_0012_US 0x0E |
||||
#define RFLR_PARAMP_0010_US 0x0F |
||||
|
||||
/*!
|
||||
* RegOcp |
||||
*/ |
||||
#define RFLR_OCP_MASK 0xDF |
||||
#define RFLR_OCP_ON 0x20 // Default
|
||||
#define RFLR_OCP_OFF 0x00 |
||||
|
||||
#define RFLR_OCP_TRIM_MASK 0xE0 |
||||
#define RFLR_OCP_TRIM_045_MA 0x00 |
||||
#define RFLR_OCP_TRIM_050_MA 0x01 |
||||
#define RFLR_OCP_TRIM_055_MA 0x02 |
||||
#define RFLR_OCP_TRIM_060_MA 0x03 |
||||
#define RFLR_OCP_TRIM_065_MA 0x04 |
||||
#define RFLR_OCP_TRIM_070_MA 0x05 |
||||
#define RFLR_OCP_TRIM_075_MA 0x06 |
||||
#define RFLR_OCP_TRIM_080_MA 0x07 |
||||
#define RFLR_OCP_TRIM_085_MA 0x08 |
||||
#define RFLR_OCP_TRIM_090_MA 0x09 |
||||
#define RFLR_OCP_TRIM_095_MA 0x0A |
||||
#define RFLR_OCP_TRIM_100_MA 0x0B // Default
|
||||
#define RFLR_OCP_TRIM_105_MA 0x0C |
||||
#define RFLR_OCP_TRIM_110_MA 0x0D |
||||
#define RFLR_OCP_TRIM_115_MA 0x0E |
||||
#define RFLR_OCP_TRIM_120_MA 0x0F |
||||
#define RFLR_OCP_TRIM_130_MA 0x10 |
||||
#define RFLR_OCP_TRIM_140_MA 0x11 |
||||
#define RFLR_OCP_TRIM_150_MA 0x12 |
||||
#define RFLR_OCP_TRIM_160_MA 0x13 |
||||
#define RFLR_OCP_TRIM_170_MA 0x14 |
||||
#define RFLR_OCP_TRIM_180_MA 0x15 |
||||
#define RFLR_OCP_TRIM_190_MA 0x16 |
||||
#define RFLR_OCP_TRIM_200_MA 0x17 |
||||
#define RFLR_OCP_TRIM_210_MA 0x18 |
||||
#define RFLR_OCP_TRIM_220_MA 0x19 |
||||
#define RFLR_OCP_TRIM_230_MA 0x1A |
||||
#define RFLR_OCP_TRIM_240_MA 0x1B |
||||
|
||||
/*!
|
||||
* RegLna |
||||
*/ |
||||
#define RFLR_LNA_GAIN_MASK 0x1F |
||||
#define RFLR_LNA_GAIN_G1 0x20 // Default
|
||||
#define RFLR_LNA_GAIN_G2 0x40 |
||||
#define RFLR_LNA_GAIN_G3 0x60 |
||||
#define RFLR_LNA_GAIN_G4 0x80 |
||||
#define RFLR_LNA_GAIN_G5 0xA0 |
||||
#define RFLR_LNA_GAIN_G6 0xC0 |
||||
|
||||
#define RFLR_LNA_BOOST_MASK 0xFC |
||||
#define RFLR_LNA_BOOST_OFF 0x00 // Default
|
||||
#define RFLR_LNA_BOOST_ON 0x03 |
||||
|
||||
/*!
|
||||
* RegFifoAddrPtr |
||||
*/ |
||||
#define RFLR_FIFOADDRPTR 0x00 // Default
|
||||
|
||||
/*!
|
||||
* RegFifoTxBaseAddr |
||||
*/ |
||||
#define RFLR_FIFOTXBASEADDR 0x80 // Default
|
||||
|
||||
/*!
|
||||
* RegFifoTxBaseAddr |
||||
*/ |
||||
#define RFLR_FIFORXBASEADDR 0x00 // Default
|
||||
|
||||
/*!
|
||||
* RegFifoRxCurrentAddr (Read Only) |
||||
*/ |
||||
|
||||
/*!
|
||||
* RegIrqFlagsMask |
||||
*/ |
||||
#define RFLR_IRQFLAGS_RXTIMEOUT_MASK 0x80 |
||||
#define RFLR_IRQFLAGS_RXDONE_MASK 0x40 |
||||
#define RFLR_IRQFLAGS_PAYLOADCRCERROR_MASK 0x20 |
||||
#define RFLR_IRQFLAGS_VALIDHEADER_MASK 0x10 |
||||
#define RFLR_IRQFLAGS_TXDONE_MASK 0x08 |
||||
#define RFLR_IRQFLAGS_CADDONE_MASK 0x04 |
||||
#define RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL_MASK 0x02 |
||||
#define RFLR_IRQFLAGS_CADDETECTED_MASK 0x01 |
||||
|
||||
/*!
|
||||
* RegIrqFlags |
||||
*/ |
||||
#define RFLR_IRQFLAGS_RXTIMEOUT 0x80 |
||||
#define RFLR_IRQFLAGS_RXDONE 0x40 |
||||
#define RFLR_IRQFLAGS_PAYLOADCRCERROR 0x20 |
||||
#define RFLR_IRQFLAGS_VALIDHEADER 0x10 |
||||
#define RFLR_IRQFLAGS_TXDONE 0x08 |
||||
#define RFLR_IRQFLAGS_CADDONE 0x04 |
||||
#define RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL 0x02 |
||||
#define RFLR_IRQFLAGS_CADDETECTED 0x01 |
||||
|
||||
/*!
|
||||
* RegFifoRxNbBytes (Read Only) |
||||
*/ |
||||
|
||||
/*!
|
||||
* RegRxHeaderCntValueMsb (Read Only) |
||||
*/ |
||||
|
||||
/*!
|
||||
* RegRxHeaderCntValueLsb (Read Only) |
||||
*/ |
||||
|
||||
/*!
|
||||
* RegRxPacketCntValueMsb (Read Only) |
||||
*/ |
||||
|
||||
/*!
|
||||
* RegRxPacketCntValueLsb (Read Only) |
||||
*/ |
||||
|
||||
/*!
|
||||
* RegModemStat (Read Only) |
||||
*/ |
||||
#define RFLR_MODEMSTAT_RX_CR_MASK 0x1F |
||||
#define RFLR_MODEMSTAT_MODEM_STATUS_MASK 0xE0 |
||||
|
||||
/*!
|
||||
* RegPktSnrValue (Read Only) |
||||
*/ |
||||
|
||||
/*!
|
||||
* RegPktRssiValue (Read Only) |
||||
*/ |
||||
|
||||
/*!
|
||||
* RegRssiValue (Read Only) |
||||
*/ |
||||
|
||||
/*!
|
||||
* RegHopChannel (Read Only) |
||||
*/ |
||||
#define RFLR_HOPCHANNEL_PLL_LOCK_TIMEOUT_MASK 0x7F |
||||
#define RFLR_HOPCHANNEL_PLL_LOCK_FAIL 0x80 |
||||
#define RFLR_HOPCHANNEL_PLL_LOCK_SUCCEED 0x00 // Default
|
||||
|
||||
#define RFLR_HOPCHANNEL_CRCONPAYLOAD_MASK 0xBF |
||||
#define RFLR_HOPCHANNEL_CRCONPAYLOAD_ON 0x40 |
||||
#define RFLR_HOPCHANNEL_CRCONPAYLOAD_OFF 0x00 // Default
|
||||
|
||||
#define RFLR_HOPCHANNEL_CHANNEL_MASK 0x3F |
||||
|
||||
/*!
|
||||
* RegModemConfig1 |
||||
*/ |
||||
#define RFLR_MODEMCONFIG1_BW_MASK 0x3F |
||||
#define RFLR_MODEMCONFIG1_BW_125_KHZ 0x00 // Default
|
||||
#define RFLR_MODEMCONFIG1_BW_250_KHZ 0x40 |
||||
#define RFLR_MODEMCONFIG1_BW_500_KHZ 0x80 |
||||
|
||||
#define RFLR_MODEMCONFIG1_CODINGRATE_MASK 0xC7 |
||||
#define RFLR_MODEMCONFIG1_CODINGRATE_4_5 0x08 |
||||
#define RFLR_MODEMCONFIG1_CODINGRATE_4_6 0x10 // Default
|
||||
#define RFLR_MODEMCONFIG1_CODINGRATE_4_7 0x18 |
||||
#define RFLR_MODEMCONFIG1_CODINGRATE_4_8 0x20 |
||||
|
||||
#define RFLR_MODEMCONFIG1_IMPLICITHEADER_MASK 0xFB |
||||
#define RFLR_MODEMCONFIG1_IMPLICITHEADER_ON 0x04 |
||||
#define RFLR_MODEMCONFIG1_IMPLICITHEADER_OFF 0x00 // Default
|
||||
|
||||
#define RFLR_MODEMCONFIG1_RXPAYLOADCRC_MASK 0xFD |
||||
#define RFLR_MODEMCONFIG1_RXPAYLOADCRC_ON 0x02 |
||||
#define RFLR_MODEMCONFIG1_RXPAYLOADCRC_OFF 0x00 // Default
|
||||
|
||||
#define RFLR_MODEMCONFIG1_LOWDATARATEOPTIMIZE_MASK 0xFE |
||||
#define RFLR_MODEMCONFIG1_LOWDATARATEOPTIMIZE_ON 0x01 |
||||
#define RFLR_MODEMCONFIG1_LOWDATARATEOPTIMIZE_OFF 0x00 // Default
|
||||
|
||||
/*!
|
||||
* RegModemConfig2 |
||||
*/ |
||||
#define RFLR_MODEMCONFIG2_SF_MASK 0x0F |
||||
#define RFLR_MODEMCONFIG2_SF_6 0x60 |
||||
#define RFLR_MODEMCONFIG2_SF_7 0x70 // Default
|
||||
#define RFLR_MODEMCONFIG2_SF_8 0x80 |
||||
#define RFLR_MODEMCONFIG2_SF_9 0x90 |
||||
#define RFLR_MODEMCONFIG2_SF_10 0xA0 |
||||
#define RFLR_MODEMCONFIG2_SF_11 0xB0 |
||||
#define RFLR_MODEMCONFIG2_SF_12 0xC0 |
||||
|
||||
#define RFLR_MODEMCONFIG2_TXCONTINUOUSMODE_MASK 0xF7 |
||||
#define RFLR_MODEMCONFIG2_TXCONTINUOUSMODE_ON 0x08 |
||||
#define RFLR_MODEMCONFIG2_TXCONTINUOUSMODE_OFF 0x00 |
||||
|
||||
#define RFLR_MODEMCONFIG2_AGCAUTO_MASK 0xFB |
||||
#define RFLR_MODEMCONFIG2_AGCAUTO_ON 0x04 // Default
|
||||
#define RFLR_MODEMCONFIG2_AGCAUTO_OFF 0x00 |
||||
|
||||
#define RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB_MASK 0xFC |
||||
#define RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB 0x00 // Default
|
||||
|
||||
/*!
|
||||
* RegSymbTimeoutLsb |
||||
*/ |
||||
#define RFLR_SYMBTIMEOUTLSB_SYMBTIMEOUT 0x64 // Default
|
||||
|
||||
/*!
|
||||
* RegPreambleLengthMsb |
||||
*/ |
||||
#define RFLR_PREAMBLELENGTHMSB 0x00 // Default
|
||||
|
||||
/*!
|
||||
* RegPreambleLengthLsb |
||||
*/ |
||||
#define RFLR_PREAMBLELENGTHLSB 0x08 // Default
|
||||
|
||||
/*!
|
||||
* RegPayloadLength |
||||
*/ |
||||
#define RFLR_PAYLOADLENGTH 0x0E // Default
|
||||
|
||||
/*!
|
||||
* RegPayloadMaxLength |
||||
*/ |
||||
#define RFLR_PAYLOADMAXLENGTH 0xFF // Default
|
||||
|
||||
/*!
|
||||
* RegHopPeriod |
||||
*/ |
||||
#define RFLR_HOPPERIOD_FREQFOPPINGPERIOD 0x00 // Default
|
||||
|
||||
/*!
|
||||
* RegFifoRxByteAddr (Read Only) |
||||
*/ |
||||
|
||||
/*!
|
||||
* RegFeiMsb (Read Only) |
||||
*/ |
||||
|
||||
/*!
|
||||
* RegFeiMid (Read Only) |
||||
*/ |
||||
|
||||
/*!
|
||||
* RegFeiLsb (Read Only) |
||||
*/ |
||||
|
||||
/*!
|
||||
* RegRssiWideband (Read Only) |
||||
*/ |
||||
|
||||
/*!
|
||||
* RegDetectOptimize |
||||
*/ |
||||
#define RFLR_DETECTIONOPTIMIZE_MASK 0xF8 |
||||
#define RFLR_DETECTIONOPTIMIZE_SF7_TO_SF12 0x03 // Default
|
||||
#define RFLR_DETECTIONOPTIMIZE_SF6 0x05 |
||||
|
||||
/*!
|
||||
* RegInvertIQ |
||||
*/ |
||||
#define RFLR_INVERTIQ_RX_MASK 0xBF |
||||
#define RFLR_INVERTIQ_RX_OFF 0x00 |
||||
#define RFLR_INVERTIQ_RX_ON 0x40 |
||||
#define RFLR_INVERTIQ_TX_MASK 0xFE |
||||
#define RFLR_INVERTIQ_TX_OFF 0x01 |
||||
#define RFLR_INVERTIQ_TX_ON 0x00 |
||||
|
||||
/*!
|
||||
* RegDetectionThreshold |
||||
*/ |
||||
#define RFLR_DETECTIONTHRESH_SF7_TO_SF12 0x0A // Default
|
||||
#define RFLR_DETECTIONTHRESH_SF6 0x0C |
||||
|
||||
/*!
|
||||
* RegInvertIQ2 |
||||
*/ |
||||
#define RFLR_INVERTIQ2_ON 0x19 |
||||
#define RFLR_INVERTIQ2_OFF 0x1D |
||||
|
||||
/*!
|
||||
* RegDioMapping1 |
||||
*/ |
||||
#define RFLR_DIOMAPPING1_DIO0_MASK 0x3F |
||||
#define RFLR_DIOMAPPING1_DIO0_00 0x00 // Default
|
||||
#define RFLR_DIOMAPPING1_DIO0_01 0x40 |
||||
#define RFLR_DIOMAPPING1_DIO0_10 0x80 |
||||
#define RFLR_DIOMAPPING1_DIO0_11 0xC0 |
||||
|
||||
#define RFLR_DIOMAPPING1_DIO1_MASK 0xCF |
||||
#define RFLR_DIOMAPPING1_DIO1_00 0x00 // Default
|
||||
#define RFLR_DIOMAPPING1_DIO1_01 0x10 |
||||
#define RFLR_DIOMAPPING1_DIO1_10 0x20 |
||||
#define RFLR_DIOMAPPING1_DIO1_11 0x30 |
||||
|
||||
#define RFLR_DIOMAPPING1_DIO2_MASK 0xF3 |
||||
#define RFLR_DIOMAPPING1_DIO2_00 0x00 // Default
|
||||
#define RFLR_DIOMAPPING1_DIO2_01 0x04 |
||||
#define RFLR_DIOMAPPING1_DIO2_10 0x08 |
||||
#define RFLR_DIOMAPPING1_DIO2_11 0x0C |
||||
|
||||
#define RFLR_DIOMAPPING1_DIO3_MASK 0xFC |
||||
#define RFLR_DIOMAPPING1_DIO3_00 0x00 // Default
|
||||
#define RFLR_DIOMAPPING1_DIO3_01 0x01 |
||||
#define RFLR_DIOMAPPING1_DIO3_10 0x02 |
||||
#define RFLR_DIOMAPPING1_DIO3_11 0x03 |
||||
|
||||
/*!
|
||||
* RegDioMapping2 |
||||
*/ |
||||
#define RFLR_DIOMAPPING2_DIO4_MASK 0x3F |
||||
#define RFLR_DIOMAPPING2_DIO4_00 0x00 // Default
|
||||
#define RFLR_DIOMAPPING2_DIO4_01 0x40 |
||||
#define RFLR_DIOMAPPING2_DIO4_10 0x80 |
||||
#define RFLR_DIOMAPPING2_DIO4_11 0xC0 |
||||
|
||||
#define RFLR_DIOMAPPING2_DIO5_MASK 0xCF |
||||
#define RFLR_DIOMAPPING2_DIO5_00 0x00 // Default
|
||||
#define RFLR_DIOMAPPING2_DIO5_01 0x10 |
||||
#define RFLR_DIOMAPPING2_DIO5_10 0x20 |
||||
#define RFLR_DIOMAPPING2_DIO5_11 0x30 |
||||
|
||||
#define RFLR_DIOMAPPING2_MAP_MASK 0xFE |
||||
#define RFLR_DIOMAPPING2_MAP_PREAMBLEDETECT 0x01 |
||||
#define RFLR_DIOMAPPING2_MAP_RSSI 0x00 // Default
|
||||
|
||||
/*!
|
||||
* RegVersion (Read Only) |
||||
*/ |
||||
|
||||
/*!
|
||||
* RegAgcRef |
||||
*/ |
||||
|
||||
/*!
|
||||
* RegAgcThresh1 |
||||
*/ |
||||
|
||||
/*!
|
||||
* RegAgcThresh2 |
||||
*/ |
||||
|
||||
/*!
|
||||
* RegAgcThresh3 |
||||
*/ |
||||
|
||||
/*!
|
||||
* RegPllHop |
||||
*/ |
||||
#define RFLR_PLLHOP_FASTHOP_MASK 0x7F |
||||
#define RFLR_PLLHOP_FASTHOP_ON 0x80 |
||||
#define RFLR_PLLHOP_FASTHOP_OFF 0x00 // Default
|
||||
|
||||
/*!
|
||||
* RegTcxo |
||||
*/ |
||||
#define RFLR_TCXO_TCXOINPUT_MASK 0xEF |
||||
#define RFLR_TCXO_TCXOINPUT_ON 0x10 |
||||
#define RFLR_TCXO_TCXOINPUT_OFF 0x00 // Default
|
||||
|
||||
/*!
|
||||
* RegPaDac |
||||
*/ |
||||
#define RFLR_PADAC_20DBM_MASK 0xF8 |
||||
#define RFLR_PADAC_20DBM_ON 0x07 |
||||
#define RFLR_PADAC_20DBM_OFF 0x04 // Default
|
||||
|
||||
/*!
|
||||
* RegPll |
||||
*/ |
||||
#define RFLR_PLL_BANDWIDTH_MASK 0x3F |
||||
#define RFLR_PLL_BANDWIDTH_75 0x00 |
||||
#define RFLR_PLL_BANDWIDTH_150 0x40 |
||||
#define RFLR_PLL_BANDWIDTH_225 0x80 |
||||
#define RFLR_PLL_BANDWIDTH_300 0xC0 // Default
|
||||
|
||||
/*!
|
||||
* RegPllLowPn |
||||
*/ |
||||
#define RFLR_PLLLOWPN_BANDWIDTH_MASK 0x3F |
||||
#define RFLR_PLLLOWPN_BANDWIDTH_75 0x00 |
||||
#define RFLR_PLLLOWPN_BANDWIDTH_150 0x40 |
||||
#define RFLR_PLLLOWPN_BANDWIDTH_225 0x80 |
||||
#define RFLR_PLLLOWPN_BANDWIDTH_300 0xC0 // Default
|
||||
|
||||
/*!
|
||||
* RegFormerTemp |
||||
*/ |
||||
|
||||
#endif // __SX1272_REGS_LORA_H__
|
@ -0,0 +1,269 @@ |
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> |
||||
<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns="http://www.w3.org/TR/REC-html40"><head> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> |
||||
|
||||
|
||||
<link rel="File-List" href="Library_files/filelist.xml"> |
||||
|
||||
|
||||
<link rel="Edit-Time-Data" href="Library_files/editdata.mso"><!--[if !mso]> <style> v\:* {behavior:url(#default#VML);} o\:* {behavior:url(#default#VML);} w\:* {behavior:url(#default#VML);} .shape {behavior:url(#default#VML);} </style> <![endif]--><title>Release Notes for sx1272mb2das Board Drivers</title><!--[if gte mso 9]><xml> <o:DocumentProperties> <o:Author>STMicroelectronics</o:Author> <o:LastAuthor>STMicroelectronics</o:LastAuthor> <o:Revision>37</o:Revision> <o:TotalTime>136</o:TotalTime> <o:Created>2009-02-27T19:26:00Z</o:Created> <o:LastSaved>2009-03-01T17:56:00Z</o:LastSaved> <o:Pages>1</o:Pages> <o:Words>522</o:Words> <o:Characters>2977</o:Characters> <o:Company>STMicroelectronics</o:Company> <o:Lines>24</o:Lines> <o:Paragraphs>6</o:Paragraphs> <o:CharactersWithSpaces>3493</o:CharactersWithSpaces> <o:Version>11.6568</o:Version> </o:DocumentProperties> </xml><![endif]--><!--[if gte mso 9]><xml> <w:WordDocument> <w:Zoom>110</w:Zoom> <w:ValidateAgainstSchemas/> <w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid> <w:IgnoreMixedContent>false</w:IgnoreMixedContent> <w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText> <w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel> </w:WordDocument> </xml><![endif]--><!--[if gte mso 9]><xml> <w:LatentStyles DefLockedState="false" LatentStyleCount="156"> </w:LatentStyles> </xml><![endif]--> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<style> |
||||
<!-- |
||||
/* Style Definitions */ |
||||
p.MsoNormal, li.MsoNormal, div.MsoNormal |
||||
{mso-style-parent:""; |
||||
margin:0in; |
||||
margin-bottom:.0001pt; |
||||
mso-pagination:widow-orphan; |
||||
font-size:12.0pt; |
||||
font-family:"Times New Roman"; |
||||
mso-fareast-font-family:"Times New Roman";} |
||||
h2 |
||||
{mso-style-next:Normal; |
||||
margin-top:12.0pt; |
||||
margin-right:0in; |
||||
margin-bottom:3.0pt; |
||||
margin-left:0in; |
||||
mso-pagination:widow-orphan; |
||||
page-break-after:avoid; |
||||
mso-outline-level:2; |
||||
font-size:14.0pt; |
||||
font-family:Arial; |
||||
font-weight:bold; |
||||
font-style:italic;} |
||||
a:link, span.MsoHyperlink |
||||
{color:blue; |
||||
text-decoration:underline; |
||||
text-underline:single;} |
||||
a:visited, span.MsoHyperlinkFollowed |
||||
{color:blue; |
||||
text-decoration:underline; |
||||
text-underline:single;} |
||||
p |
||||
{mso-margin-top-alt:auto; |
||||
margin-right:0in; |
||||
mso-margin-bottom-alt:auto; |
||||
margin-left:0in; |
||||
mso-pagination:widow-orphan; |
||||
font-size:12.0pt; |
||||
font-family:"Times New Roman"; |
||||
mso-fareast-font-family:"Times New Roman";} |
||||
@page Section1 |
||||
{size:8.5in 11.0in; |
||||
margin:1.0in 1.25in 1.0in 1.25in; |
||||
mso-header-margin:.5in; |
||||
mso-footer-margin:.5in; |
||||
mso-paper-source:0;} |
||||
div.Section1 |
||||
{page:Section1;} |
||||
--> |
||||
</style><!--[if gte mso 10]> <style> /* Style Definitions */ table.MsoNormalTable {mso-style-name:"Table Normal"; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; mso-style-noshow:yes; mso-style-parent:""; mso-padding-alt:0in 5.4pt 0in 5.4pt; mso-para-margin:0in; mso-para-margin-bottom:.0001pt; mso-pagination:widow-orphan; font-size:10.0pt; font-family:"Times New Roman"; mso-ansi-language:#0400; mso-fareast-language:#0400; mso-bidi-language:#0400;} </style> <![endif]--><!--[if gte mso 9]><xml> <o:shapedefaults v:ext="edit" spidmax="5122"/> </xml><![endif]--><!--[if gte mso 9]><xml> <o:shapelayout v:ext="edit"> <o:idmap v:ext="edit" data="1"/> </o:shapelayout></xml><![endif]--> |
||||
<meta content="MCD Application Team" name="author"></head> |
||||
<body link="blue" vlink="blue"> |
||||
<div class="Section1"> |
||||
<p class="MsoNormal"><span style="font-family: Arial;"><o:p><br> |
||||
</o:p></span></p> |
||||
<div align="center"> |
||||
<table class="MsoNormalTable" style="width: 675pt;" border="0" cellpadding="0" cellspacing="0" width="900"> |
||||
<tbody> |
||||
<tr> |
||||
<td style="padding: 0cm;" valign="top"> |
||||
<table class="MsoNormalTable" style="width: 675pt;" border="0" cellpadding="0" cellspacing="0" width="900"> |
||||
<tbody> |
||||
<tr style=""> |
||||
<td style="padding: 1.5pt;"> |
||||
<h1 style="margin-bottom: 18pt; text-align: center;" align="center"><span style="font-size: 20pt; font-family: Verdana; color: rgb(51, 102, 255);">Release |
||||
Notes for sx1272mb2das Board Drivers</span><span style="font-size: 20pt; font-family: Verdana;"><o:p></o:p></span></h1> |
||||
<p class="MsoNormal" style="text-align: center;" align="center"><span style="font-size: 10pt; font-family: Arial; color: black;">Copyright |
||||
2017 STMicroelectronics</span><span style="color: black;"><u1:p></u1:p><o:p></o:p></span></p> |
||||
<p class="MsoNormal" style="text-align: center;" align="center"><span style="font-size: 10pt; font-family: Arial; color: black;"><img alt="" id="_x0000_i1025" src="../../../_htmresc/st_logo.png" style="border: 0px solid ; width: 86px; height: 65px;"></span><span style="font-size: 10pt;"><o:p></o:p></span></p> |
||||
</td> |
||||
</tr> |
||||
</tbody> |
||||
</table> |
||||
<p class="MsoNormal"><span style="font-family: Arial; display: none;"><o:p> </o:p></span></p> |
||||
<table class="MsoNormalTable" style="width: 675pt;" border="0" cellpadding="0" width="900"> |
||||
<tbody> |
||||
<tr style=""> |
||||
<td style="padding: 0cm;" valign="top"> |
||||
<span style="font-family: "Times New Roman";"> |
||||
</span> |
||||
<h3 style="background: rgb(51, 102, 255) none repeat scroll 0% 50%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; margin-right: 500pt; width: 200px;"> |
||||
<span style="font-size: 10pt; font-family: Arial; color: white;">V1.0.4 / 08-September-2017 |
||||
</span> |
||||
</h3> |
||||
<p class="MsoNormal" style="margin: 4.5pt 0cm 4.5pt 18pt;"> |
||||
<b style=""> |
||||
<u> |
||||
<span style="font-size: 10pt; font-family: Verdana; color: black;">Main Changes<o:p></o:p> |
||||
</span> |
||||
</u> |
||||
</b> |
||||
</p> |
||||
|
||||
<ul style="margin-top: 0cm;" type="square"> |
||||
<li class="MsoNormal"> |
||||
<span style="font-size: 10pt; font-family: Verdana;">Retrieve Public Network handling in the radio driver |
||||
<span style="font-weight: bold; font-style: italic;"> |
||||
</span> |
||||
</span> |
||||
</li> |
||||
</ul> |
||||
<span style="font-family: "Times New Roman";"> |
||||
</span> |
||||
<h3 style="background: rgb(51, 102, 255) none repeat scroll 0% 50%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; margin-right: 500pt; width: 200px;"> |
||||
<span style="font-size: 10pt; font-family: Arial; color: white;">V1.0.3 / 01-June-2017 |
||||
</span> |
||||
</h3> |
||||
<p class="MsoNormal" style="margin: 4.5pt 0cm 4.5pt 18pt;"> |
||||
<b style=""> |
||||
<u> |
||||
<span style="font-size: 10pt; font-family: Verdana; color: black;">Main Changes<o:p></o:p> |
||||
</span> |
||||
</u> |
||||
</b> |
||||
</p> |
||||
|
||||
<ul style="margin-top: 0cm;" type="square"> |
||||
<li class="MsoNormal"> |
||||
<span style="font-size: 10pt; font-family: Verdana;">SX1272 radio driver externalized as component |
||||
<span style="font-weight: bold; font-style: italic;"> |
||||
</span> |
||||
</span> |
||||
</li> |
||||
</ul> |
||||
<span style="font-family: "Times New Roman";"> |
||||
</span> |
||||
<h3 style="background: rgb(51, 102, 255) none repeat scroll 0% 50%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; margin-right: 500pt; width: 200px;"> |
||||
<span style="font-size: 10pt; font-family: Arial; color: white;">V1.0.2 / 27-February-2017 |
||||
</span> |
||||
</h3> |
||||
<p class="MsoNormal" style="margin: 4.5pt 0cm 4.5pt 18pt;"> |
||||
<b style=""> |
||||
<u> |
||||
<span style="font-size: 10pt; font-family: Verdana; color: black;">Main Changes<o:p></o:p> |
||||
</span> |
||||
</u> |
||||
</b> |
||||
</p> |
||||
|
||||
<ul style="margin-top: 0cm;" type="square"> |
||||
<li class="MsoNormal"> |
||||
<span style="font-size: 10pt; font-family: Verdana;">Power settings now board dependent |
||||
<span style="font-weight: bold; font-style: italic;"> |
||||
</span> |
||||
</span> |
||||
</li> |
||||
</ul> |
||||
<span style="font-family: "Times New Roman";"> |
||||
</span> |
||||
<h3 style="background: rgb(51, 102, 255) none repeat scroll 0% 50%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; margin-right: 500pt; width: 200px;"> |
||||
<span style="font-size: 10pt; font-family: Arial; color: white;">V1.0.1 / 15-September-2016 |
||||
</span> |
||||
</h3> |
||||
<p class="MsoNormal" style="margin: 4.5pt 0cm 4.5pt 18pt;"> |
||||
<b style=""> |
||||
<u> |
||||
<span style="font-size: 10pt; font-family: Verdana; color: black;">Main Changes<o:p></o:p> |
||||
</span> |
||||
</u> |
||||
</b> |
||||
</p> |
||||
|
||||
<ul style="margin-top: 0cm;" type="square"> |
||||
<li class="MsoNormal"> |
||||
<span style="font-size: 10pt; font-family: Verdana;">Interrupt handling |
||||
<span style="font-weight: bold; font-style: italic;"> |
||||
</span> |
||||
</span> |
||||
</li> |
||||
</ul> |
||||
<span style="font-family: "Times New Roman";"> |
||||
</span> |
||||
<h3 style="background: rgb(51, 102, 255) none repeat scroll 0% 50%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; margin-right: 500pt; width: 200px;"> |
||||
<span style="font-size: 10pt; font-family: Arial; color: white;">V1.0.0 / 01-July-2016 |
||||
</span> |
||||
</h3> |
||||
<p class="MsoNormal" style="margin: 4.5pt 0cm 4.5pt 18pt;"> |
||||
<b style=""> |
||||
<u> |
||||
<span style="font-size: 10pt; font-family: Verdana; color: black;">Main Changes<o:p></o:p> |
||||
</span> |
||||
</u> |
||||
</b> |
||||
</p> |
||||
|
||||
<ul style="margin-top: 0cm;" type="square"> |
||||
<li class="MsoNormal"> |
||||
<span style="font-size: 10pt; font-family: Verdana;">First Release |
||||
<span style="font-weight: bold; font-style: italic;"> |
||||
</span> |
||||
</span> |
||||
</li> |
||||
</ul> |
||||
<span style="font-size: 10pt; font-family: Verdana;"> |
||||
</span> |
||||
<h2 style="background: rgb(51, 102, 255) none repeat scroll 0% 50%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> |
||||
<a name="License"></a> |
||||
<span style="font-size: 12pt; color: white;">License<o:p></o:p> |
||||
</span> |
||||
</h2> |
||||
<div style="text-align: justify;"> |
||||
<div style="text-align: justify;"><font size="-1"> |
||||
<span style="font-family: "Verdana","sans-serif";"> |
||||
Redistribution and use in source and binary forms, with or without |
||||
modification, are permitted provided that the following conditions are |
||||
met: |
||||
</span> |
||||
<br> |
||||
</font> |
||||
<ol><li><font size="-1"><span style="font-family: "Verdana","sans-serif";">Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.</span><span style="font-family: "Verdana","sans-serif";"></span></font></li><li><font size="-1"><span style="font-family: "Verdana","sans-serif";">Redistributions |
||||
in binary form must reproduce the above copyright notice, this list of |
||||
conditions and the following disclaimer in </span><span style="font-family: "Verdana","sans-serif";">the documentation and/or other materials provided with the distribution.</span><span style="font-family: "Verdana","sans-serif";"></span></font></li><li><font size="-1"><span style="font-family: "Verdana","sans-serif";">Neither the name of STMicroelectronics nor the names of its contributors may be used to endorse or promote products derived |
||||
</span><span style="font-family: "Verdana","sans-serif";">from this software without specific prior written permission.</span><br> |
||||
</font> |
||||
</li></ol> |
||||
<font size="-1"> |
||||
|
||||
<span style="font-family: "Verdana","sans-serif";">THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED</span><span style="font-family: "Verdana","sans-serif";"> WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A </span><span style="font-family: "Verdana","sans-serif";">PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY </span><span style="font-family: "Verdana","sans-serif";">DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, </span><span style="font-family: "Verdana","sans-serif";">PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER</span><span style="font-family: "Verdana","sans-serif";"> CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR </span><span style="font-family: "Verdana","sans-serif";">OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.</span></font> |
||||
|
||||
</div> |
||||
<span style="font-family: "Verdana","sans-serif";"></span></div> |
||||
<span style="font-size: 10pt; font-family: "Verdana","sans-serif"; color: black;"></span> <b><span style="font-size: 10pt; font-family: Verdana; color: black;"></span></b> |
||||
|
||||
<div class="MsoNormal" style="text-align: center;" align="center"><span style="color: black;"> |
||||
<hr align="center" size="2" width="100%"></span></div> |
||||
<p class="MsoNormal" style="margin: 4.5pt 0cm 4.5pt 18pt; text-align: center;" align="center"><span style="font-size: 10pt; font-family: Verdana; color: black;">For |
||||
complete documentation on </span><span style="font-size: 10pt; font-family: Verdana;">STM32<span style="color: black;"> Microcontrollers |
||||
visit </span><u><span style="color: blue;"><a href="http://www.st.com/internet/mcu/class/1734.jsp" target="_blank">www.st.com/STM32</a></span></u></span><span style="font-size: 10pt; font-family: Verdana;"><a target="_blank" href="http://www.st.com/internet/mcu/family/141.jsp"><u><span style="color: blue;"></span></u></a></span><span style="font-size: 10pt; font-family: Verdana;"><u><span style="color: blue;"></span></u></span><span style="color: black;"><o:p></o:p></span></p> |
||||
</td> |
||||
</tr> |
||||
</tbody> |
||||
</table> |
||||
<p class="MsoNormal"><span style="font-size: 10pt;"><o:p></o:p></span></p> |
||||
</td> |
||||
</tr> |
||||
</tbody> |
||||
</table> |
||||
</div> |
||||
<p class="MsoNormal"><o:p> </o:p></p> |
||||
</div> |
||||
|
||||
</body></html> |
@ -0,0 +1,262 @@ |
||||
/*
|
||||
/ _____) _ | | |
||||
( (____ _____ ____ _| |_ _____ ____| |__ |
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | | |
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_| |
||||
(C)2013 Semtech |
||||
|
||||
Description: SX1272 driver specific target board functions implementation |
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project |
||||
|
||||
Maintainer: Miguel Luis and Gregory Cristian |
||||
*/ |
||||
/*******************************************************************************
|
||||
* @file sx1272mb2das.c |
||||
* @author MCD Application Team |
||||
* @version V1.0.4 |
||||
* @date 08-September-2017 |
||||
* @brief driver sx1272mb2das board
|
||||
****************************************************************************** |
||||
* @attention |
||||
* |
||||
* <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2> |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without modification, |
||||
* are permitted provided that the following conditions are met: |
||||
* 1. Redistributions of source code must retain the above copyright notice, |
||||
* this list of conditions and the following disclaimer. |
||||
* 2. 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. |
||||
* 3. Neither the name of STMicroelectronics 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. |
||||
* |
||||
****************************************************************************** |
||||
*/ |
||||
|
||||
/* Includes ------------------------------------------------------------------*/ |
||||
#include "hw.h" |
||||
#include "radio.h" |
||||
#include "sx1272.h" |
||||
#include "sx1272mb2das.h" |
||||
|
||||
|
||||
#define IRQ_HIGH_PRIORITY 0 |
||||
|
||||
/*!
|
||||
* Flag used to set the RF switch control pins in low power mode when the radio is not active. |
||||
*/ |
||||
|
||||
|
||||
void SX1272SetXO( uint8_t state ); |
||||
|
||||
uint32_t SX1272GetWakeTime( void ); |
||||
|
||||
void SX1272IoIrqInit( DioIrqHandler **irqHandlers ); |
||||
|
||||
uint8_t SX1272GetPaSelect( uint32_t channel ); |
||||
|
||||
void SX1272SetAntSwLowPower( bool status ); |
||||
|
||||
void SX1272SetRfTxPower( int8_t power ); |
||||
|
||||
void SX1272SetAntSw( uint8_t opMode ); |
||||
/*!
|
||||
* \brief Controls the antena switch if necessary. |
||||
* |
||||
* \remark see errata note |
||||
* |
||||
* \param [IN] opMode Current radio operating mode |
||||
*/ |
||||
static LoRaBoardCallback_t BoardCallbacks = { SX1272SetXO, |
||||
SX1272GetWakeTime, |
||||
SX1272IoIrqInit, |
||||
SX1272SetRfTxPower, |
||||
SX1272SetAntSwLowPower, |
||||
SX1272SetAntSw}; |
||||
|
||||
/*!
|
||||
* Radio driver structure initialization |
||||
*/ |
||||
const struct Radio_s Radio = |
||||
{ |
||||
SX1272IoInit, |
||||
SX1272IoDeInit, |
||||
SX1272Init, |
||||
SX1272GetStatus, |
||||
SX1272SetModem, |
||||
SX1272SetChannel, |
||||
SX1272IsChannelFree, |
||||
SX1272Random, |
||||
SX1272SetRxConfig, |
||||
SX1272SetTxConfig, |
||||
SX1272CheckRfFrequency, |
||||
SX1272GetTimeOnAir, |
||||
SX1272Send, |
||||
SX1272SetSleep, |
||||
SX1272SetStby, |
||||
SX1272SetRx, |
||||
SX1272StartCad, |
||||
SX1272SetTxContinuousWave, |
||||
SX1272ReadRssi, |
||||
SX1272Write, |
||||
SX1272Read, |
||||
SX1272WriteBuffer, |
||||
SX1272ReadBuffer, |
||||
SX1272SetMaxPayloadLength, |
||||
SX1272SetPublicNetwork, |
||||
SX1272GetRadioWakeUpTime |
||||
}; |
||||
|
||||
uint32_t SX1272GetWakeTime( void ) |
||||
{ |
||||
return BOARD_WAKEUP_TIME; |
||||
} |
||||
|
||||
void SX1272SetXO( uint8_t state ) |
||||
{ |
||||
} |
||||
void SX1272IoInit( void ) |
||||
{ |
||||
GPIO_InitTypeDef initStruct={0}; |
||||
|
||||
SX1272BoardInit( &BoardCallbacks ); |
||||
|
||||
initStruct.Mode = GPIO_MODE_IT_RISING; |
||||
initStruct.Pull = GPIO_PULLDOWN; |
||||
initStruct.Speed = GPIO_SPEED_HIGH; |
||||
|
||||
HW_GPIO_Init( RADIO_DIO_0_PORT, RADIO_DIO_0_PIN, &initStruct ); |
||||
HW_GPIO_Init( RADIO_DIO_1_PORT, RADIO_DIO_1_PIN, &initStruct ); |
||||
HW_GPIO_Init( RADIO_DIO_2_PORT, RADIO_DIO_2_PIN, &initStruct ); |
||||
HW_GPIO_Init( RADIO_DIO_3_PORT, RADIO_DIO_3_PIN, &initStruct ); |
||||
} |
||||
|
||||
void SX1272IoIrqInit( DioIrqHandler **irqHandlers ) |
||||
{ |
||||
HW_GPIO_SetIrq( RADIO_DIO_0_PORT, RADIO_DIO_0_PIN, IRQ_HIGH_PRIORITY, irqHandlers[0] ); |
||||
HW_GPIO_SetIrq( RADIO_DIO_1_PORT, RADIO_DIO_1_PIN, IRQ_HIGH_PRIORITY, irqHandlers[1] ); |
||||
HW_GPIO_SetIrq( RADIO_DIO_2_PORT, RADIO_DIO_2_PIN, IRQ_HIGH_PRIORITY, irqHandlers[2] ); |
||||
HW_GPIO_SetIrq( RADIO_DIO_3_PORT, RADIO_DIO_3_PIN, IRQ_HIGH_PRIORITY, irqHandlers[3] ); |
||||
} |
||||
|
||||
void SX1272IoDeInit( void ) |
||||
{ |
||||
GPIO_InitTypeDef initStruct={0}; |
||||
|
||||
initStruct.Mode = GPIO_MODE_IT_RISING ;//GPIO_MODE_ANALOG;
|
||||
initStruct.Pull = GPIO_PULLDOWN; |
||||
|
||||
HW_GPIO_Init( RADIO_DIO_0_PORT, RADIO_DIO_0_PIN, &initStruct ); |
||||
HW_GPIO_Init( RADIO_DIO_1_PORT, RADIO_DIO_1_PIN, &initStruct ); |
||||
HW_GPIO_Init( RADIO_DIO_2_PORT, RADIO_DIO_2_PIN, &initStruct ); |
||||
HW_GPIO_Init( RADIO_DIO_3_PORT, RADIO_DIO_3_PIN, &initStruct ); |
||||
} |
||||
|
||||
void SX1272SetRfTxPower( int8_t power ) |
||||
{ |
||||
uint8_t paConfig = 0; |
||||
uint8_t paDac = 0; |
||||
|
||||
paConfig = SX1272Read( REG_PACONFIG ); |
||||
paDac = SX1272Read( REG_PADAC ); |
||||
|
||||
paConfig = ( paConfig & RF_PACONFIG_PASELECT_MASK ) | SX1272GetPaSelect( SX1272.Settings.Channel ); |
||||
|
||||
if( ( paConfig & RF_PACONFIG_PASELECT_PABOOST ) == RF_PACONFIG_PASELECT_PABOOST ) |
||||
{ |
||||
if( power > 17 ) |
||||
{ |
||||
paDac = ( paDac & RF_PADAC_20DBM_MASK ) | RF_PADAC_20DBM_ON; |
||||
} |
||||
else |
||||
{ |
||||
paDac = ( paDac & RF_PADAC_20DBM_MASK ) | RF_PADAC_20DBM_OFF; |
||||
} |
||||
if( ( paDac & RF_PADAC_20DBM_ON ) == RF_PADAC_20DBM_ON ) |
||||
{ |
||||
if( power < 5 ) |
||||
{ |
||||
power = 5; |
||||
} |
||||
if( power > 20 ) |
||||
{ |
||||
power = 20; |
||||
} |
||||
paConfig = ( paConfig & RFLR_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power - 5 ) & 0x0F ); |
||||
} |
||||
else |
||||
{ |
||||
if( power < 2 ) |
||||
{ |
||||
power = 2; |
||||
} |
||||
if( power > 17 ) |
||||
{ |
||||
power = 17; |
||||
} |
||||
paConfig = ( paConfig & RFLR_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power - 2 ) & 0x0F ); |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
if( power < -1 ) |
||||
{ |
||||
power = -1; |
||||
} |
||||
if( power > 14 ) |
||||
{ |
||||
power = 14; |
||||
} |
||||
paConfig = ( paConfig & RFLR_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power + 1 ) & 0x0F ); |
||||
} |
||||
SX1272Write( REG_PACONFIG, paConfig ); |
||||
SX1272Write( REG_PADAC, paDac ); |
||||
} |
||||
|
||||
uint8_t SX1272GetPaSelect( uint32_t channel ) |
||||
{ |
||||
return RF_PACONFIG_PASELECT_RFO; |
||||
} |
||||
|
||||
void SX1272SetAntSwLowPower( bool status ) |
||||
{ |
||||
//Ant Switch Controlled by SX1272 IC
|
||||
} |
||||
|
||||
void SX1272SetAntSw( uint8_t opMode ) |
||||
{ |
||||
switch( opMode ) |
||||
{ |
||||
case RFLR_OPMODE_TRANSMITTER: |
||||
SX1272.RxTx = 1; |
||||
break; |
||||
case RFLR_OPMODE_RECEIVER: |
||||
case RFLR_OPMODE_RECEIVER_SINGLE: |
||||
case RFLR_OPMODE_CAD: |
||||
default: |
||||
SX1272.RxTx = 0; |
||||
break; |
||||
} |
||||
} |
||||
|
||||
bool SX1272CheckRfFrequency( uint32_t frequency ) |
||||
{ |
||||
// Implement check. Currently all frequencies are supported
|
||||
return true; |
||||
} |
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
@ -0,0 +1,98 @@ |
||||
/*
|
||||
/ _____) _ | | |
||||
( (____ _____ ____ _| |_ _____ ____| |__ |
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | | |
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_| |
||||
(C)2013 Semtech |
||||
|
||||
Description: SX1272 driver specific target board functions implementation |
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project |
||||
|
||||
Maintainer: Miguel Luis and Gregory Cristian |
||||
*/ |
||||
/*******************************************************************************
|
||||
* @file sx1272mb2das.c |
||||
* @author MCD Application Team |
||||
* @version V1.0.4 |
||||
* @date 08-September-2017 |
||||
* @brief driver sx1272 board ( sx1272mb2das ) |
||||
****************************************************************************** |
||||
* @attention |
||||
* |
||||
* <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2> |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without modification, |
||||
* are permitted provided that the following conditions are met: |
||||
* 1. Redistributions of source code must retain the above copyright notice, |
||||
* this list of conditions and the following disclaimer. |
||||
* 2. 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. |
||||
* 3. Neither the name of STMicroelectronics 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. |
||||
* |
||||
****************************************************************************** |
||||
*/ |
||||
/* Define to prevent recursive inclusion -------------------------------------*/ |
||||
#ifndef __SX1272MB2DAS__ |
||||
#define __SX1272MB2DAS__ |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
/* Includes ------------------------------------------------------------------*/ |
||||
/* Exported types ------------------------------------------------------------*/ |
||||
/* Exported constants --------------------------------------------------------*/ |
||||
|
||||
#define BOARD_WAKEUP_TIME 0 // no TCXO
|
||||
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
|
||||
/*!
|
||||
* \brief Initializes the radio I/Os pins interface |
||||
*/ |
||||
void SX1272IoInit( void ); |
||||
|
||||
|
||||
/*!
|
||||
* \brief De-initializes the radio I/Os pins interface. |
||||
* |
||||
* \remark Useful when going in MCU low power modes |
||||
*/ |
||||
void SX1272IoDeInit( void ); |
||||
|
||||
/*!
|
||||
* \brief Checks if the given RF frequency is supported by the hardware |
||||
* |
||||
* \param [IN] frequency RF frequency to be checked |
||||
* \retval isSupported [true: supported, false: unsupported] |
||||
*/ |
||||
bool SX1272CheckRfFrequency( uint32_t frequency ); |
||||
|
||||
/*!
|
||||
* Radio hardware and global parameters |
||||
*/ |
||||
extern SX1272_t SX1272; |
||||
|
||||
#ifdef __cplusplus |
||||
} |
||||
#endif |
||||
|
||||
#endif /* __SX1272MB2DAS__ */ |
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
@ -0,0 +1,147 @@ |
||||
/*
|
||||
/ _____) _ | | |
||||
( (____ _____ ____ _| |_ _____ ____| |__ |
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | | |
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_| |
||||
(C)2015 Semtech |
||||
|
||||
Description: End device commissioning parameters |
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project |
||||
|
||||
Maintainer: Miguel Luis and Gregory Cristian |
||||
*/ |
||||
/******************************************************************************
|
||||
* @file commissioning.h |
||||
* @author MCD Application Team |
||||
* @version V1.1.2 |
||||
* @date 08-September-2017 |
||||
* @brief End device commissioning parameters |
||||
****************************************************************************** |
||||
* @attention |
||||
* |
||||
* <h2><center>© Copyright (c) 2017 STMicroelectronics International N.V.
|
||||
* All rights reserved.</center></h2> |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted, provided that the following conditions are met: |
||||
* |
||||
* 1. Redistribution of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer. |
||||
* 2. 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. |
||||
* 3. Neither the name of STMicroelectronics nor the names of other
|
||||
* contributors to this software may be used to endorse or promote products
|
||||
* derived from this software without specific written permission. |
||||
* 4. This software, including modifications and/or derivative works of this
|
||||
* software, must execute solely and exclusively on microcontroller or |
||||
* microprocessor devices manufactured by or for STMicroelectronics. |
||||
* 5. Redistribution and use of this software other than as permitted under
|
||||
* this license is void and will automatically terminate your rights under
|
||||
* this license.
|
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
* PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY |
||||
* RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT
|
||||
* SHALL STMICROELECTRONICS OR CONTRIBUTORS 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. |
||||
* |
||||
****************************************************************************** |
||||
*/ |
||||
/* Define to prevent recursive inclusion -------------------------------------*/ |
||||
#ifndef __LORA_COMMISSIONING_H__ |
||||
#define __LORA_COMMISSIONING_H__ |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
/* Exported types ------------------------------------------------------------*/ |
||||
/* Exported constants --------------------------------------------------------*/ |
||||
/* External variables --------------------------------------------------------*/ |
||||
/* Exported macros -----------------------------------------------------------*/ |
||||
/* Exported functions ------------------------------------------------------- */
|
||||
/*!
|
||||
* When set to 1 the application uses the Over-the-Air activation procedure |
||||
* When set to 0 the application uses the Personalization activation procedure |
||||
*/ |
||||
#define OVER_THE_AIR_ACTIVATION 1 |
||||
|
||||
/*!
|
||||
* Indicates if the end-device is to be connected to a private or public network |
||||
*/ |
||||
#define LORAWAN_PUBLIC_NETWORK true |
||||
|
||||
/*!
|
||||
* When set to 1 DevEui is LORAWAN_DEVICE_EUI |
||||
* When set to 0 DevEui is automatically generated by calling |
||||
* BoardGetUniqueId function |
||||
*/ |
||||
#define STATIC_DEVICE_EUI 0 |
||||
|
||||
/*!
|
||||
* Mote device IEEE EUI (big endian) |
||||
* |
||||
* \remark see STATIC_DEVICE_EUI comments |
||||
*/ |
||||
#define LORAWAN_DEVICE_EUI { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 } |
||||
|
||||
|
||||
/*!
|
||||
* Application IEEE EUI (big endian) |
||||
*/ |
||||
#define LORAWAN_APPLICATION_EUI { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 } |
||||
|
||||
/*!
|
||||
* AES encryption/decryption cipher application key |
||||
*/ |
||||
#define LORAWAN_APPLICATION_KEY { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C } |
||||
|
||||
#if( OVER_THE_AIR_ACTIVATION == 0 ) |
||||
|
||||
/*!
|
||||
* Current network ID |
||||
*/ |
||||
#define LORAWAN_NETWORK_ID ( uint32_t )0 |
||||
|
||||
/*!
|
||||
* When set to 1 DevAdd is LORAWAN_DEVICE_ADDRESS |
||||
* When set to 0 DevAdd is automatically generated using |
||||
* a pseudo random generator seeded with a value derived from |
||||
* BoardUniqueId value |
||||
*/ |
||||
#define STATIC_DEVICE_ADDRESS 0 |
||||
/*!
|
||||
* Device address on the network (big endian) |
||||
* |
||||
* \remark see STATIC_DEVICE_ADDRESS comments |
||||
*/ |
||||
#define LORAWAN_DEVICE_ADDRESS ( uint32_t )0x0100000a |
||||
|
||||
/*!
|
||||
* AES encryption/decryption cipher network session key |
||||
*/ |
||||
#define LORAWAN_NWKSKEY { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C } |
||||
|
||||
/*!
|
||||
* AES encryption/decryption cipher application session key |
||||
*/ |
||||
#define LORAWAN_APPSKEY { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C } |
||||
|
||||
#endif /* OVER_THE_AIR_ACTIVATION == 0 */ |
||||
|
||||
|
||||
#ifdef __cplusplus |
||||
} |
||||
#endif |
||||
|
||||
#endif /* __LORA_COMMISSIONING_H__ */ |
@ -0,0 +1,154 @@ |
||||
/*
|
||||
/ _____) _ | | |
||||
( (____ _____ ____ _| |_ _____ ____| |__ |
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | | |
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_| |
||||
(C)2013 Semtech |
||||
|
||||
Description: Bleeper board GPIO driver implementation |
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project |
||||
|
||||
Maintainer: Miguel Luis and Gregory Cristian |
||||
*/ |
||||
/******************************************************************************
|
||||
* @file hw_gpio.h |
||||
* @author MCD Application Team |
||||
* @version V1.1.2 |
||||
* @date 08-September-2017 |
||||
* @brief Header for driver hw_rtc.c module |
||||
****************************************************************************** |
||||
* @attention |
||||
* |
||||
* <h2><center>© Copyright (c) 2017 STMicroelectronics International N.V.
|
||||
* All rights reserved.</center></h2> |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted, provided that the following conditions are met: |
||||
* |
||||
* 1. Redistribution of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer. |
||||
* 2. 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. |
||||
* 3. Neither the name of STMicroelectronics nor the names of other
|
||||
* contributors to this software may be used to endorse or promote products
|
||||
* derived from this software without specific written permission. |
||||
* 4. This software, including modifications and/or derivative works of this
|
||||
* software, must execute solely and exclusively on microcontroller or |
||||
* microprocessor devices manufactured by or for STMicroelectronics. |
||||
* 5. Redistribution and use of this software other than as permitted under
|
||||
* this license is void and will automatically terminate your rights under
|
||||
* this license.
|
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
* PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY |
||||
* RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT
|
||||
* SHALL STMICROELECTRONICS OR CONTRIBUTORS 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. |
||||
* |
||||
****************************************************************************** |
||||
*/ |
||||
#if 0 |
||||
/* Define to prevent recursive inclusion -------------------------------------*/ |
||||
#ifndef __HW_GPIO_H__ |
||||
#define __HW_GPIO_H__ |
||||
|
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/ |
||||
|
||||
typedef void( GpioIrqHandler )( void ); |
||||
|
||||
/* Exported constants --------------------------------------------------------*/ |
||||
/* External variables --------------------------------------------------------*/ |
||||
/* Exported macros -----------------------------------------------------------*/ |
||||
/* Exported functions ------------------------------------------------------- */
|
||||
|
||||
|
||||
/*!
|
||||
* GPIO IRQ handler function prototype |
||||
*/ |
||||
|
||||
|
||||
IRQn_Type MSP_GetIRQn( uint16_t gpioPin); |
||||
|
||||
|
||||
/*!
|
||||
* @brief Initializes the given GPIO object |
||||
* |
||||
* @param GPIOx: where x can be (A..E and H) |
||||
* @param GPIO_Pin: specifies the port bit to be written. |
||||
* This parameter can be one of GPIO_PIN_x where x can be (0..15). |
||||
* All port bits are not necessarily available on all GPIOs. |
||||
* @param [IN] initStruct GPIO_InitTypeDef intit structure |
||||
* @retval none |
||||
*/ |
||||
void HW_GPIO_Init( GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_InitTypeDef* initStruct); |
||||
|
||||
/*!
|
||||
* @brief Records the interrupt handler for the GPIO object |
||||
* |
||||
* @param GPIOx: where x can be (A..E and H)
|
||||
* @param GPIO_Pin: specifies the port bit to be written. |
||||
* This parameter can be one of GPIO_PIN_x where x can be (0..15). |
||||
* All port bits are not necessarily available on all GPIOs. |
||||
* @param [IN] prio NVIC priority (0 is highest) |
||||
* @param [IN] irqHandler points to the function to execute |
||||
* @retval none |
||||
*/ |
||||
void HW_GPIO_SetIrq( GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, uint32_t prio, GpioIrqHandler *irqHandler ); |
||||
|
||||
/*!
|
||||
* @brief Execute the interrupt from the object |
||||
* |
||||
* @param GPIOx: where x can be (A..E and H)
|
||||
* @param GPIO_Pin: specifies the port bit to be written. |
||||
* This parameter can be one of GPIO_PIN_x where x can be (0..15). |
||||
* All port bits are not necessarily available on all GPIOs. |
||||
* @retval none |
||||
*/ |
||||
void HW_GPIO_IrqHandler( uint16_t GPIO_Pin ); |
||||
|
||||
/*!
|
||||
* @brief Writes the given value to the GPIO output |
||||
* |
||||
* @param GPIO_Pin: specifies the port bit to be written. |
||||
* This parameter can be one of GPIO_PIN_x where x can be (0..15). |
||||
* All port bits are not necessarily available on all GPIOs. |
||||
* @param [IN] value New GPIO output value |
||||
* @retval none |
||||
*/ |
||||
void HW_GPIO_Write( GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, uint32_t value ); |
||||
|
||||
/*!
|
||||
* @brief Reads the current GPIO input value |
||||
* |
||||
* @param GPIOx: where x can be (A..E and H)
|
||||
* @param GPIO_Pin: specifies the port bit to be written. |
||||
* This parameter can be one of GPIO_PIN_x where x can be (0..15). |
||||
* All port bits are not necessarily available on all GPIOs. |
||||
* @retval value Current GPIO input value |
||||
*/ |
||||
uint32_t HW_GPIO_Read( GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin ); |
||||
|
||||
#ifdef __cplusplus |
||||
} |
||||
#endif |
||||
|
||||
#endif /* __HW_GPIO_H__ */ |
||||
#endif |
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
||||
|
@ -0,0 +1,181 @@ |
||||
/*
|
||||
/ _____) _ | | |
||||
( (____ _____ ____ _| |_ _____ ____| |__ |
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | | |
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_| |
||||
(C)2013 Semtech |
||||
|
||||
Description: Bleeper board GPIO driver implementation |
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project |
||||
|
||||
Maintainer: Miguel Luis and Gregory Cristian |
||||
*/ |
||||
/******************************************************************************
|
||||
* @file hw_rtc.h |
||||
* @author MCD Application Team |
||||
* @version V1.1.2 |
||||
* @date 08-September-2017 |
||||
* @brief Header for driver hw_rtc.c module |
||||
****************************************************************************** |
||||
* @attention |
||||
* |
||||
* <h2><center>© Copyright (c) 2017 STMicroelectronics International N.V.
|
||||
* All rights reserved.</center></h2> |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted, provided that the following conditions are met: |
||||
* |
||||
* 1. Redistribution of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer. |
||||
* 2. 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. |
||||
* 3. Neither the name of STMicroelectronics nor the names of other
|
||||
* contributors to this software may be used to endorse or promote products
|
||||
* derived from this software without specific written permission. |
||||
* 4. This software, including modifications and/or derivative works of this
|
||||
* software, must execute solely and exclusively on microcontroller or |
||||
* microprocessor devices manufactured by or for STMicroelectronics. |
||||
* 5. Redistribution and use of this software other than as permitted under
|
||||
* this license is void and will automatically terminate your rights under
|
||||
* this license.
|
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
* PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY |
||||
* RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT
|
||||
* SHALL STMICROELECTRONICS OR CONTRIBUTORS 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. |
||||
* |
||||
****************************************************************************** |
||||
*/ |
||||
#if 0 |
||||
|
||||
#ifndef __HW_RTC_H__ |
||||
#define __HW_RTC_H__ |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
/* Includes ------------------------------------------------------------------*/ |
||||
#include "utilities.h" |
||||
|
||||
/* Exported types ------------------------------------------------------------*/ |
||||
/* Exported constants --------------------------------------------------------*/ |
||||
/* External variables --------------------------------------------------------*/ |
||||
/* Exported macros -----------------------------------------------------------*/ |
||||
/* Exported functions ------------------------------------------------------- */
|
||||
|
||||
/*!
|
||||
* @brief Initializes the RTC timer |
||||
* @note The timer is based on the RTC |
||||
* @param none |
||||
* @retval none |
||||
*/ |
||||
void HW_RTC_Init( void ); |
||||
|
||||
/*!
|
||||
* @brief Stop the Alarm |
||||
* @param none |
||||
* @retval none |
||||
*/ |
||||
void HW_RTC_StopAlarm( void ); |
||||
|
||||
/*!
|
||||
* @brief Return the minimum timeout the RTC is able to handle |
||||
* @param none |
||||
* @retval minimum value for a timeout |
||||
*/ |
||||
uint32_t HW_RTC_GetMinimumTimeout( void ); |
||||
|
||||
/*!
|
||||
* @brief Set the alarm |
||||
* @note The alarm is set at Reference + timeout |
||||
* @param timeout Duration of the Timer in ticks |
||||
*/ |
||||
void HW_RTC_SetAlarm( uint32_t timeout ); |
||||
|
||||
/*!
|
||||
* @brief Get the RTC timer elapsed time since the last Reference was set |
||||
* @retval RTC Elapsed time in ticks |
||||
*/ |
||||
uint32_t HW_RTC_GetTimerElapsedTime( void ); |
||||
|
||||
/*!
|
||||
* @brief Get the RTC timer value |
||||
* @retval none |
||||
*/ |
||||
uint32_t HW_RTC_GetTimerValue( void ); |
||||
|
||||
/*!
|
||||
* @brief Set the RTC timer Reference |
||||
* @retval Timer Reference Value in Ticks |
||||
*/ |
||||
uint32_t HW_RTC_SetTimerContext( void ); |
||||
|
||||
/*!
|
||||
* @brief Get the RTC timer Reference |
||||
* @retval Timer Value in Ticks |
||||
*/ |
||||
uint32_t HW_RTC_GetTimerContext( void ); |
||||
/*!
|
||||
* @brief RTC IRQ Handler on the RTC Alarm |
||||
* @param none |
||||
* @retval none |
||||
*/ |
||||
void HW_RTC_IrqHandler ( void ); |
||||
|
||||
/*!
|
||||
* @brief a delay of delay ms by polling RTC |
||||
* @param delay in ms |
||||
* @param none |
||||
* @retval none |
||||
*/ |
||||
void HW_RTC_DelayMs( uint32_t delay ); |
||||
|
||||
/*!
|
||||
* @brief calculates the wake up time between wake up and mcu start |
||||
* @note resolution in RTC_ALARM_TIME_BASE |
||||
* @param none |
||||
* @retval none |
||||
*/ |
||||
void HW_RTC_setMcuWakeUpTime( void ); |
||||
|
||||
/*!
|
||||
* @brief returns the wake up time in us |
||||
* @param none |
||||
* @retval wake up time in ticks |
||||
*/ |
||||
int16_t HW_RTC_getMcuWakeUpTime( void ); |
||||
|
||||
/*!
|
||||
* @brief converts time in ms to time in ticks |
||||
* @param [IN] time in milliseconds |
||||
* @retval returns time in timer ticks |
||||
*/ |
||||
uint32_t HW_RTC_ms2Tick( TimerTime_t timeMicroSec ); |
||||
|
||||
/*!
|
||||
* @brief converts time in ticks to time in ms |
||||
* @param [IN] time in timer ticks |
||||
* @retval returns time in timer milliseconds |
||||
*/ |
||||
TimerTime_t HW_RTC_Tick2ms( uint32_t tick ); |
||||
|
||||
#ifdef __cplusplus |
||||
} |
||||
#endif |
||||
|
||||
#endif /* __HW_RTC_H__ */ |
||||
|
||||
#endif |
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
@ -0,0 +1,128 @@ |
||||
/*
|
||||
/ _____) _ | | |
||||
( (____ _____ ____ _| |_ _____ ____| |__ |
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | | |
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_| |
||||
(C)2013 Semtech |
||||
|
||||
Description: Header for driver hw spi module |
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project |
||||
|
||||
Maintainer: Miguel Luis and Gregory Cristian |
||||
*/ |
||||
/******************************************************************************
|
||||
* @file hw_spi.h |
||||
* @author MCD Application Team |
||||
* @version V1.1.2 |
||||
* @date 08-September-2017 |
||||
* @brief Header for driver hw_spi.c module |
||||
****************************************************************************** |
||||
* @attention |
||||
* |
||||
* <h2><center>© Copyright (c) 2017 STMicroelectronics International N.V.
|
||||
* All rights reserved.</center></h2> |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted, provided that the following conditions are met: |
||||
* |
||||
* 1. Redistribution of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer. |
||||
* 2. 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. |
||||
* 3. Neither the name of STMicroelectronics nor the names of other
|
||||
* contributors to this software may be used to endorse or promote products
|
||||
* derived from this software without specific written permission. |
||||
* 4. This software, including modifications and/or derivative works of this
|
||||
* software, must execute solely and exclusively on microcontroller or |
||||
* microprocessor devices manufactured by or for STMicroelectronics. |
||||
* 5. Redistribution and use of this software other than as permitted under
|
||||
* this license is void and will automatically terminate your rights under
|
||||
* this license.
|
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
* PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY |
||||
* RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT
|
||||
* SHALL STMICROELECTRONICS OR CONTRIBUTORS 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. |
||||
* |
||||
****************************************************************************** |
||||
*/ |
||||
|
||||
#if 0 |
||||
/* Define to prevent recursive inclusion -------------------------------------*/ |
||||
#ifndef __HW_SPI_H__ |
||||
#define __HW_SPI_H__ |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
/* Exported types ------------------------------------------------------------*/ |
||||
/* Exported constants --------------------------------------------------------*/ |
||||
/* External variables --------------------------------------------------------*/ |
||||
/* Exported macros -----------------------------------------------------------*/ |
||||
/* Exported functions ------------------------------------------------------- */
|
||||
|
||||
/*!
|
||||
* @brief Initializes the SPI object and MCU peripheral |
||||
* |
||||
* @param [IN] none |
||||
*/ |
||||
void HW_SPI_Init( void ); |
||||
|
||||
/*!
|
||||
* @brief De-initializes the SPI object and MCU peripheral |
||||
* |
||||
* @param [IN] none |
||||
*/ |
||||
void HW_SPI_DeInit( void ); |
||||
|
||||
/*!
|
||||
* @brief Initializes the SPI IOs |
||||
* |
||||
* @param [IN] none |
||||
*/ |
||||
void HW_SPI_IoInit( void ); |
||||
|
||||
/*!
|
||||
* @brief De-initializes the SPI IOs |
||||
* |
||||
* @param [IN] none |
||||
*/ |
||||
void HW_SPI_IoDeInit( void ); |
||||
|
||||
/*!
|
||||
* @brief Sends outData and receives inData |
||||
* |
||||
* @param [IN] outData Byte to be sent |
||||
* @retval inData Received byte. |
||||
*/ |
||||
uint16_t HW_SPI_InOut( uint16_t outData ); |
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus |
||||
} |
||||
#endif |
||||
|
||||
#endif /* __HW_SPI_H__ */ |
||||
#endif |
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -0,0 +1,87 @@ |
||||
/*
|
||||
/ _____) _ | | |
||||
( (____ _____ ____ _| |_ _____ ____| |__ |
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | | |
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_| |
||||
(C)2013 Semtech |
||||
|
||||
Description: contains all hardware driver |
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project |
||||
|
||||
Maintainer: Miguel Luis and Gregory Cristian |
||||
*/ |
||||
/******************************************************************************
|
||||
* @file hw.h |
||||
* @author MCD Application Team |
||||
* @version V1.1.2 |
||||
* @date 08-September-2017 |
||||
* @brief contains all hardware driver |
||||
****************************************************************************** |
||||
* @attention |
||||
* |
||||
* <h2><center>© Copyright (c) 2017 STMicroelectronics International N.V.
|
||||
* All rights reserved.</center></h2> |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted, provided that the following conditions are met: |
||||
* |
||||
* 1. Redistribution of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer. |
||||
* 2. 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. |
||||
* 3. Neither the name of STMicroelectronics nor the names of other
|
||||
* contributors to this software may be used to endorse or promote products
|
||||
* derived from this software without specific written permission. |
||||
* 4. This software, including modifications and/or derivative works of this
|
||||
* software, must execute solely and exclusively on microcontroller or |
||||
* microprocessor devices manufactured by or for STMicroelectronics. |
||||
* 5. Redistribution and use of this software other than as permitted under
|
||||
* this license is void and will automatically terminate your rights under
|
||||
* this license.
|
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
* PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY |
||||
* RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT
|
||||
* SHALL STMICROELECTRONICS OR CONTRIBUTORS 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. |
||||
* |
||||
****************************************************************************** |
||||
*/ |
||||
#if 0 |
||||
/* Define to prevent recursive inclusion -------------------------------------*/ |
||||
#ifndef __HW_H__ |
||||
#define __HW_H__ |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
/* Includes ------------------------------------------------------------------*/ |
||||
#include <math.h> |
||||
#include <stdbool.h> |
||||
#include <stdint.h> |
||||
#include "hw_conf.h" |
||||
#include "hw_gpio.h" |
||||
#include "hw_spi.h" |
||||
#include "hw_rtc.h" |
||||
#include "hw_msp.h" |
||||
#include "debug.h" |
||||
|
||||
#ifdef __cplusplus |
||||
} |
||||
#endif |
||||
|
||||
#endif /* __HW_H__ */ |
||||
|
||||
#endif |
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
||||
|
@ -0,0 +1,192 @@ |
||||
/*
|
||||
/ _____) _ | | |
||||
( (____ _____ ____ _| |_ _____ ____| |__ |
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | | |
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_| |
||||
(C)2013 Semtech |
||||
|
||||
Description: Bleeper board GPIO driver implementation |
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project |
||||
|
||||
Maintainer: Miguel Luis and Gregory Cristian |
||||
*/ |
||||
/******************************************************************************
|
||||
* @file hw_gpio.c |
||||
* @author MCD Application Team |
||||
* @version V1.1.2 |
||||
* @date 08-September-2017 |
||||
* @brief driver for GPIO |
||||
****************************************************************************** |
||||
* @attention |
||||
* |
||||
* <h2><center>© Copyright (c) 2017 STMicroelectronics International N.V.
|
||||
* All rights reserved.</center></h2> |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted, provided that the following conditions are met: |
||||
* |
||||
* 1. Redistribution of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer. |
||||
* 2. 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. |
||||
* 3. Neither the name of STMicroelectronics nor the names of other
|
||||
* contributors to this software may be used to endorse or promote products
|
||||
* derived from this software without specific written permission. |
||||
* 4. This software, including modifications and/or derivative works of this
|
||||
* software, must execute solely and exclusively on microcontroller or |
||||
* microprocessor devices manufactured by or for STMicroelectronics. |
||||
* 5. Redistribution and use of this software other than as permitted under
|
||||
* this license is void and will automatically terminate your rights under
|
||||
* this license.
|
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
* PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY |
||||
* RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT
|
||||
* SHALL STMICROELECTRONICS OR CONTRIBUTORS 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. |
||||
* |
||||
****************************************************************************** |
||||
*/ |
||||
#if 0 |
||||
/* Includes ------------------------------------------------------------------*/ |
||||
#include "hw.h" |
||||
|
||||
/* Private typedef -----------------------------------------------------------*/ |
||||
/* Private define ------------------------------------------------------------*/ |
||||
/* Private macro -------------------------------------------------------------*/ |
||||
/* Private variables ---------------------------------------------------------*/ |
||||
static GpioIrqHandler *GpioIrq[16] = { NULL }; |
||||
|
||||
/* Private function prototypes -----------------------------------------------*/ |
||||
|
||||
static uint8_t HW_GPIO_GetBitPos(uint16_t GPIO_Pin); |
||||
|
||||
/* Exported functions ---------------------------------------------------------*/ |
||||
/*!
|
||||
* @brief Initializes the given GPIO object |
||||
* |
||||
* @param GPIOx: where x can be (A..E and H) |
||||
* @param GPIO_Pin: specifies the port bit to be written. |
||||
* This parameter can be one of GPIO_PIN_x where x can be (0..15). |
||||
* All port bits are not necessarily available on all GPIOs. |
||||
* @param [IN] initStruct GPIO_InitTypeDef intit structure |
||||
* @retval none |
||||
*/ |
||||
void HW_GPIO_Init( GPIO_TypeDef* port, uint16_t GPIO_Pin, GPIO_InitTypeDef* initStruct) |
||||
{ |
||||
|
||||
RCC_GPIO_CLK_ENABLE( (uint32_t) port); |
||||
|
||||
initStruct->Pin = GPIO_Pin ; |
||||
|
||||
HAL_GPIO_Init( port, initStruct ); |
||||
} |
||||
|
||||
/*!
|
||||
* @brief Records the interrupt handler for the GPIO object |
||||
* |
||||
* @param GPIOx: where x can be (A..E and H)
|
||||
* @param GPIO_Pin: specifies the port bit to be written. |
||||
* This parameter can be one of GPIO_PIN_x where x can be (0..15). |
||||
* All port bits are not necessarily available on all GPIOs. |
||||
* @param [IN] prio NVIC priority (0 is highest) |
||||
* @param [IN] irqHandler points to the function to execute |
||||
* @retval none |
||||
*/ |
||||
void HW_GPIO_SetIrq( GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, uint32_t prio, GpioIrqHandler *irqHandler ) |
||||
{ |
||||
IRQn_Type IRQnb; |
||||
|
||||
uint32_t BitPos = HW_GPIO_GetBitPos( GPIO_Pin ) ; |
||||
|
||||
if ( irqHandler != NULL) |
||||
{ |
||||
GpioIrq[ BitPos ] = irqHandler; |
||||
|
||||
IRQnb = MSP_GetIRQn( GPIO_Pin ); |
||||
|
||||
HAL_NVIC_SetPriority( IRQnb , prio, 0); |
||||
|
||||
HAL_NVIC_EnableIRQ( IRQnb ); |
||||
} |
||||
} |
||||
|
||||
/*!
|
||||
* @brief Execute the interrupt from the object |
||||
* |
||||
* @param GPIO_Pin: specifies the port bit to be written. |
||||
* This parameter can be one of GPIO_PIN_x where x can be (0..15). |
||||
* All port bits are not necessarily available on all GPIOs. |
||||
* @retval none |
||||
*/ |
||||
void HW_GPIO_IrqHandler( uint16_t GPIO_Pin ) |
||||
{ |
||||
uint32_t BitPos = HW_GPIO_GetBitPos( GPIO_Pin ); |
||||
|
||||
if ( GpioIrq[ BitPos ] != NULL) |
||||
{ |
||||
GpioIrq[ BitPos ] ( ); |
||||
} |
||||
} |
||||
|
||||
/*!
|
||||
* @brief Writes the given value to the GPIO output |
||||
* |
||||
* @param GPIO_Pin: specifies the port bit to be written. |
||||
* This parameter can be one of GPIO_PIN_x where x can be (0..15). |
||||
* All port bits are not necessarily available on all GPIOs. |
||||
* @param [IN] value New GPIO output value |
||||
* @retval none |
||||
*/ |
||||
void HW_GPIO_Write( GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, uint32_t value ) |
||||
{ |
||||
HAL_GPIO_WritePin( GPIOx, GPIO_Pin , (GPIO_PinState) value ); |
||||
} |
||||
|
||||
/*!
|
||||
* @brief Reads the current GPIO input value |
||||
* |
||||
* @param GPIOx: where x can be (A..E and H)
|
||||
* @param GPIO_Pin: specifies the port bit to be written. |
||||
* This parameter can be one of GPIO_PIN_x where x can be (0..15). |
||||
* All port bits are not necessarily available on all GPIOs. |
||||
* @retval value Current GPIO input value |
||||
*/ |
||||
uint32_t HW_GPIO_Read( GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin ) |
||||
{ |
||||
return HAL_GPIO_ReadPin( GPIOx, GPIO_Pin); |
||||
} |
||||
|
||||
/* Private functions ---------------------------------------------------------*/ |
||||
|
||||
/*!
|
||||
* @brief Get the position of the bit set in the GPIO_Pin |
||||
* @param GPIO_Pin: specifies the port bit to be written. |
||||
* This parameter can be one of GPIO_PIN_x where x can be (0..15). |
||||
* All port bits are not necessarily available on all GPIOs. |
||||
* @retval the position of the bit |
||||
*/ |
||||
static uint8_t HW_GPIO_GetBitPos(uint16_t GPIO_Pin) |
||||
{ |
||||
uint8_t PinPos=0; |
||||
|
||||
if ( ( GPIO_Pin & 0xFF00 ) != 0) { PinPos |= 0x8; } |
||||
if ( ( GPIO_Pin & 0xF0F0 ) != 0) { PinPos |= 0x4; } |
||||
if ( ( GPIO_Pin & 0xCCCC ) != 0) { PinPos |= 0x2; } |
||||
if ( ( GPIO_Pin & 0xAAAA ) != 0) { PinPos |= 0x1; } |
||||
|
||||
return PinPos; |
||||
} |
||||
|
||||
#endif |
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
@ -0,0 +1,632 @@ |
||||
/*
|
||||
/ _____) _ | | |
||||
( (____ _____ ____ _| |_ _____ ____| |__ |
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | | |
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_| |
||||
(C)2013 Semtech |
||||
|
||||
Description: MCU RTC timer |
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project |
||||
|
||||
Maintainer: Miguel Luis and Gregory Cristian |
||||
*/ |
||||
/*******************************************************************************
|
||||
* @file hw_rtc.c |
||||
* @author MCD Application Team |
||||
* @version V1.1.2 |
||||
* @date 08-September-2017 |
||||
* @brief driver for RTC |
||||
****************************************************************************** |
||||
* @attention |
||||
* |
||||
* <h2><center>© Copyright (c) 2017 STMicroelectronics International N.V.
|
||||
* All rights reserved.</center></h2> |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted, provided that the following conditions are met: |
||||
* |
||||
* 1. Redistribution of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer. |
||||
* 2. 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. |
||||
* 3. Neither the name of STMicroelectronics nor the names of other
|
||||
* contributors to this software may be used to endorse or promote products
|
||||
* derived from this software without specific written permission. |
||||
* 4. This software, including modifications and/or derivative works of this
|
||||
* software, must execute solely and exclusively on microcontroller or |
||||
* microprocessor devices manufactured by or for STMicroelectronics. |
||||
* 5. Redistribution and use of this software other than as permitted under
|
||||
* this license is void and will automatically terminate your rights under
|
||||
* this license.
|
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
* PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY |
||||
* RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT
|
||||
* SHALL STMICROELECTRONICS OR CONTRIBUTORS 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. |
||||
* |
||||
****************************************************************************** |
||||
*/ |
||||
#if 0 |
||||
/* Includes ------------------------------------------------------------------*/ |
||||
#include "hw.h" |
||||
#include "low_power.h" |
||||
|
||||
/* Private typedef -----------------------------------------------------------*/ |
||||
typedef struct |
||||
{ |
||||
TimerTime_t Rtc_Time; /* Reference time */ |
||||
|
||||
RTC_TimeTypeDef RTC_Calndr_Time; /* Reference time in calendar format */ |
||||
|
||||
RTC_DateTypeDef RTC_Calndr_Date; /* Reference date in calendar format */ |
||||
|
||||
} RtcTimerContext_t; |
||||
|
||||
/* Private define ------------------------------------------------------------*/ |
||||
|
||||
/* MCU Wake Up Time */ |
||||
#define MIN_ALARM_DELAY 3 /* in ticks */ |
||||
|
||||
/* subsecond number of bits */ |
||||
#define N_PREDIV_S 10 |
||||
|
||||
/* Synchonuous prediv */ |
||||
#define PREDIV_S ((1<<N_PREDIV_S)-1) |
||||
|
||||
/* Asynchonuous prediv */ |
||||
#define PREDIV_A (1<<(15-N_PREDIV_S))-1 |
||||
|
||||
/* Sub-second mask definition */ |
||||
#if (N_PREDIV_S == 10) |
||||
#define HW_RTC_ALARMSUBSECONDMASK RTC_ALARMSUBSECONDMASK_SS14_10 |
||||
#else |
||||
#error "Please define HW_RTC_ALARMSUBSECONDMASK" |
||||
#endif |
||||
|
||||
/* RTC Time base in us */ |
||||
#define USEC_NUMBER 1000000 |
||||
#define MSEC_NUMBER (USEC_NUMBER/1000) |
||||
#define RTC_ALARM_TIME_BASE (USEC_NUMBER>>N_PREDIV_S) |
||||
|
||||
#define COMMON_FACTOR 3 |
||||
#define CONV_NUMER (MSEC_NUMBER>>COMMON_FACTOR) |
||||
#define CONV_DENOM (1<<(N_PREDIV_S-COMMON_FACTOR)) |
||||
|
||||
#define DAYS_IN_LEAP_YEAR (uint32_t) 366 |
||||
|
||||
#define DAYS_IN_YEAR (uint32_t) 365 |
||||
|
||||
#define SECONDS_IN_1DAY (uint32_t) 86400 |
||||
|
||||
#define SECONDS_IN_1HOUR (uint32_t) 3600 |
||||
|
||||
#define SECONDS_IN_1MINUTE (uint32_t) 60 |
||||
|
||||
#define MINUTES_IN_1HOUR (uint32_t) 60 |
||||
|
||||
#define HOURS_IN_1DAY (uint32_t) 24 |
||||
|
||||
#define DAYS_IN_MONTH_CORRECTION_NORM ((uint32_t) 0x99AAA0 ) |
||||
#define DAYS_IN_MONTH_CORRECTION_LEAP ((uint32_t) 0x445550 ) |
||||
|
||||
|
||||
/* Calculates ceiling(X/N) */ |
||||
#define DIVC(X,N) ( ( (X) + (N) -1 ) / (N) ) |
||||
|
||||
|
||||
/* Private macro -------------------------------------------------------------*/ |
||||
/* Private variables ---------------------------------------------------------*/ |
||||
/*!
|
||||
* \brief Indicates if the RTC is already Initalized or not |
||||
*/ |
||||
static bool HW_RTC_Initalized = false; |
||||
|
||||
/*!
|
||||
* \brief compensates MCU wakeup time |
||||
*/ |
||||
|
||||
static bool McuWakeUpTimeInitialized = false; |
||||
|
||||
/*!
|
||||
* \brief compensates MCU wakeup time |
||||
*/ |
||||
|
||||
static int16_t McuWakeUpTimeCal = 0; |
||||
|
||||
/*!
|
||||
* Number of days in each month on a normal year |
||||
*/ |
||||
static const uint8_t DaysInMonth[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; |
||||
|
||||
/*!
|
||||
* Number of days in each month on a leap year |
||||
*/ |
||||
static const uint8_t DaysInMonthLeapYear[] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; |
||||
|
||||
static RTC_HandleTypeDef RtcHandle={0}; |
||||
|
||||
static RTC_AlarmTypeDef RTC_AlarmStructure; |
||||
|
||||
/*!
|
||||
* Keep the value of the RTC timer when the RTC alarm is set |
||||
* Set with the HW_RTC_SetTimerContext function |
||||
* Value is kept as a Reference to calculate alarm |
||||
*/ |
||||
static RtcTimerContext_t RtcTimerContext; |
||||
|
||||
/* Private function prototypes -----------------------------------------------*/ |
||||
|
||||
static void HW_RTC_SetConfig( void ); |
||||
|
||||
static void HW_RTC_SetAlarmConfig( void ); |
||||
|
||||
static void HW_RTC_StartWakeUpAlarm( uint32_t timeoutValue ); |
||||
|
||||
static TimerTime_t HW_RTC_GetCalendarValue( RTC_DateTypeDef* RTC_DateStruct, RTC_TimeTypeDef* RTC_TimeStruct ); |
||||
|
||||
/* Exported functions ---------------------------------------------------------*/ |
||||
|
||||
/*!
|
||||
* @brief Initializes the RTC timer |
||||
* @note The timer is based on the RTC |
||||
* @param none |
||||
* @retval none |
||||
*/ |
||||
void HW_RTC_Init( void ) |
||||
{ |
||||
if( HW_RTC_Initalized == false ) |
||||
{ |
||||
HW_RTC_SetConfig( ); |
||||
HW_RTC_SetAlarmConfig( ); |
||||
HW_RTC_SetTimerContext( ); |
||||
HW_RTC_Initalized = true; |
||||
} |
||||
} |
||||
|
||||
/*!
|
||||
* @brief Configures the RTC timer |
||||
* @note The timer is based on the RTC |
||||
* @param none |
||||
* @retval none |
||||
*/ |
||||
static void HW_RTC_SetConfig( void ) |
||||
{ |
||||
RTC_TimeTypeDef RTC_TimeStruct; |
||||
RTC_DateTypeDef RTC_DateStruct; |
||||
|
||||
RtcHandle.Instance = RTC; |
||||
|
||||
RtcHandle.Init.HourFormat = RTC_HOURFORMAT_24; |
||||
RtcHandle.Init.AsynchPrediv = PREDIV_A; /* RTC_ASYNCH_PREDIV; */ |
||||
RtcHandle.Init.SynchPrediv = PREDIV_S; /* RTC_SYNCH_PREDIV; */ |
||||
RtcHandle.Init.OutPut = RTC_OUTPUT; |
||||
RtcHandle.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH; |
||||
RtcHandle.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN; |
||||
|
||||
HAL_RTC_Init( &RtcHandle ); |
||||
|
||||
/*Monday 1st January 2016*/ |
||||
RTC_DateStruct.Year = 0; |
||||
RTC_DateStruct.Month = RTC_MONTH_JANUARY; |
||||
RTC_DateStruct.Date = 1; |
||||
RTC_DateStruct.WeekDay = RTC_WEEKDAY_MONDAY; |
||||
HAL_RTC_SetDate(&RtcHandle , &RTC_DateStruct, RTC_FORMAT_BIN); |
||||
|
||||
/*at 0:0:0*/ |
||||
RTC_TimeStruct.Hours = 0; |
||||
RTC_TimeStruct.Minutes = 0; |
||||
|
||||
RTC_TimeStruct.Seconds = 0; |
||||
RTC_TimeStruct.TimeFormat = 0; |
||||
RTC_TimeStruct.SubSeconds = 0; |
||||
RTC_TimeStruct.StoreOperation = RTC_DAYLIGHTSAVING_NONE; |
||||
RTC_TimeStruct.DayLightSaving = RTC_STOREOPERATION_RESET; |
||||
|
||||
HAL_RTC_SetTime(&RtcHandle , &RTC_TimeStruct, RTC_FORMAT_BIN); |
||||
|
||||
/*Enable Direct Read of the calendar registers (not through Shadow) */ |
||||
HAL_RTCEx_EnableBypassShadow(&RtcHandle); |
||||
} |
||||
|
||||
/*!
|
||||
* @brief calculates the wake up time between wake up and mcu start |
||||
* @note resulotion in RTC_ALARM_TIME_BASE in timer ticks |
||||
* @param none |
||||
* @retval none |
||||
*/ |
||||
void HW_RTC_setMcuWakeUpTime( void ) |
||||
{ |
||||
RTC_TimeTypeDef RTC_TimeStruct; |
||||
RTC_DateTypeDef RTC_DateStruct; |
||||
|
||||
TimerTime_t now, hit; |
||||
int16_t McuWakeUpTime; |
||||
|
||||
if ((McuWakeUpTimeInitialized == false) && |
||||
( HAL_NVIC_GetPendingIRQ( RTC_Alarm_IRQn ) == 1)) |
||||
{ /* warning: works ok if now is below 30 days
|
||||
it is ok since it's done once at first alarm wake-up*/ |
||||
McuWakeUpTimeInitialized = true; |
||||
now = HW_RTC_GetCalendarValue( &RTC_DateStruct, &RTC_TimeStruct ); |
||||
|
||||
DBG_GPIO_SET(GPIOB, GPIO_PIN_13); |
||||
DBG_GPIO_RST(GPIOB, GPIO_PIN_13); |
||||
HAL_RTC_GetAlarm(&RtcHandle, &RTC_AlarmStructure, RTC_ALARM_A, RTC_FORMAT_BIN ); |
||||
hit = RTC_AlarmStructure.AlarmTime.Seconds+ |
||||
60*(RTC_AlarmStructure.AlarmTime.Minutes+ |
||||
60*(RTC_AlarmStructure.AlarmTime.Hours+ |
||||
24*(RTC_AlarmStructure.AlarmDateWeekDay))); |
||||
hit = ( hit << N_PREDIV_S ) + (PREDIV_S - RTC_AlarmStructure.AlarmTime.SubSeconds); |
||||
|
||||
McuWakeUpTime = (int16_t) ((now-hit)); |
||||
McuWakeUpTimeCal += McuWakeUpTime; |
||||
DBG_PRINTF("Cal=%d, %d\n\r",McuWakeUpTimeCal, McuWakeUpTime); |
||||
} |
||||
} |
||||
|
||||
int16_t HW_RTC_getMcuWakeUpTime( void ) |
||||
{ |
||||
return McuWakeUpTimeCal; |
||||
} |
||||
|
||||
/*!
|
||||
* @brief returns the wake up time in ticks |
||||
* @param none |
||||
* @retval wake up time in ticks |
||||
*/ |
||||
uint32_t HW_RTC_GetMinimumTimeout( void ) |
||||
{ |
||||
return( MIN_ALARM_DELAY ); |
||||
} |
||||
|
||||
/*!
|
||||
* @brief converts time in ms to time in ticks |
||||
* @param [IN] time in milliseconds |
||||
* @retval returns time in timer ticks |
||||
*/ |
||||
uint32_t HW_RTC_ms2Tick( TimerTime_t timeMicroSec ) |
||||
{ |
||||
/*return( ( timeMicroSec / RTC_ALARM_TIME_BASE ) ); */ |
||||
return ( uint32_t) ( ( ((uint64_t)timeMicroSec) * CONV_DENOM ) / CONV_NUMER ); |
||||
} |
||||
|
||||
/*!
|
||||
* @brief converts time in ticks to time in ms |
||||
* @param [IN] time in timer ticks |
||||
* @retval returns time in milliseconds |
||||
*/ |
||||
TimerTime_t HW_RTC_Tick2ms( uint32_t tick ) |
||||
{ |
||||
/*return( ( timeMicroSec * RTC_ALARM_TIME_BASE ) ); */ |
||||
return ( ( (uint64_t)( tick )* CONV_NUMER ) / CONV_DENOM ); |
||||
} |
||||
|
||||
/*!
|
||||
* @brief Set the alarm |
||||
* @note The alarm is set at now (read in this funtion) + timeout |
||||
* @param timeout Duration of the Timer ticks |
||||
*/ |
||||
void HW_RTC_SetAlarm( uint32_t timeout ) |
||||
{ |
||||
/* we don't go in Low Power mode for timeout below MIN_ALARM_DELAY */ |
||||
if ( (MIN_ALARM_DELAY + McuWakeUpTimeCal ) < ((timeout - HW_RTC_GetTimerElapsedTime( ) )) ) |
||||
{ |
||||
LowPower_Enable( e_LOW_POWER_RTC ); |
||||
} |
||||
else |
||||
{ |
||||
LowPower_Disable( e_LOW_POWER_RTC ); |
||||
} |
||||
|
||||
if( LowPower_GetState() == 0 ) |
||||
{ |
||||
LowPower_Enable( e_LOW_POWER_RTC ); |
||||
timeout = timeout - McuWakeUpTimeCal; |
||||
} |
||||
|
||||
HW_RTC_StartWakeUpAlarm( timeout ); |
||||
} |
||||
|
||||
/*!
|
||||
* @brief Get the RTC timer elapsed time since the last Alarm was set |
||||
* @param none |
||||
* @retval RTC Elapsed time in ticks |
||||
*/ |
||||
uint32_t HW_RTC_GetTimerElapsedTime( void ) |
||||
{ |
||||
RTC_TimeTypeDef RTC_TimeStruct; |
||||
RTC_DateTypeDef RTC_DateStruct; |
||||
|
||||
TimerTime_t CalendarValue = HW_RTC_GetCalendarValue(&RTC_DateStruct, &RTC_TimeStruct ); |
||||
|
||||
return( ( uint32_t )( CalendarValue - RtcTimerContext.Rtc_Time )); |
||||
} |
||||
|
||||
/*!
|
||||
* @brief Get the RTC timer value |
||||
* @param none |
||||
* @retval RTC Timer value in ticks |
||||
*/ |
||||
uint32_t HW_RTC_GetTimerValue( void ) |
||||
{ |
||||
RTC_TimeTypeDef RTC_TimeStruct; |
||||
RTC_DateTypeDef RTC_DateStruct; |
||||
|
||||
uint32_t CalendarValue = (uint32_t) HW_RTC_GetCalendarValue(&RTC_DateStruct, &RTC_TimeStruct ); |
||||
|
||||
return( CalendarValue ); |
||||
} |
||||
|
||||
/*!
|
||||
* @brief Stop the Alarm |
||||
* @param none |
||||
* @retval none |
||||
*/ |
||||
void HW_RTC_StopAlarm( void ) |
||||
{ |
||||
|
||||
/* Clear RTC Alarm Flag */ |
||||
__HAL_RTC_ALARM_CLEAR_FLAG( &RtcHandle, RTC_FLAG_ALRAF); |
||||
|
||||
/* Disable the Alarm A interrupt */ |
||||
|
||||
HAL_RTC_DeactivateAlarm(&RtcHandle, RTC_ALARM_A ); |
||||
} |
||||
|
||||
/*!
|
||||
* @brief RTC IRQ Handler on the RTC Alarm |
||||
* @param none |
||||
* @retval none |
||||
*/ |
||||
void HW_RTC_IrqHandler ( void ) |
||||
{ |
||||
RTC_HandleTypeDef* hrtc=&RtcHandle; |
||||
/* enable low power at irq*/ |
||||
LowPower_Enable( e_LOW_POWER_RTC ); |
||||
|
||||
/* Get the AlarmA interrupt source enable status */ |
||||
if(__HAL_RTC_ALARM_GET_IT_SOURCE(hrtc, RTC_IT_ALRA) != RESET) |
||||
{ |
||||
/* Get the pending status of the AlarmA Interrupt */ |
||||
if(__HAL_RTC_ALARM_GET_FLAG(hrtc, RTC_FLAG_ALRAF) != RESET) |
||||
{ |
||||
/* Clear the AlarmA interrupt pending bit */ |
||||
__HAL_RTC_ALARM_CLEAR_FLAG(hrtc, RTC_FLAG_ALRAF);
|
||||
/* Clear the EXTI's line Flag for RTC Alarm */ |
||||
__HAL_RTC_ALARM_EXTI_CLEAR_FLAG(); |
||||
/* AlarmA callback */ |
||||
HAL_RTC_AlarmAEventCallback(hrtc); |
||||
} |
||||
} |
||||
} |
||||
|
||||
|
||||
/*!
|
||||
* @brief a delay of delay ms by polling RTC |
||||
* @param delay in ms |
||||
* @retval none |
||||
*/ |
||||
void HW_RTC_DelayMs( uint32_t delay ) |
||||
{ |
||||
TimerTime_t delayValue = 0; |
||||
TimerTime_t timeout = 0; |
||||
|
||||
delayValue = HW_RTC_ms2Tick( delay ); |
||||
|
||||
/* Wait delay ms */ |
||||
timeout = HW_RTC_GetTimerValue( ); |
||||
while( ( ( HW_RTC_GetTimerValue( ) - timeout ) ) < delayValue ) |
||||
{ |
||||
__NOP( ); |
||||
} |
||||
} |
||||
|
||||
/*!
|
||||
* @brief set Time Reference set also the RTC_DateStruct and RTC_TimeStruct |
||||
* @param none |
||||
* @retval Timer Value |
||||
*/ |
||||
uint32_t HW_RTC_SetTimerContext( void ) |
||||
{ |
||||
RtcTimerContext.Rtc_Time = HW_RTC_GetCalendarValue( &RtcTimerContext.RTC_Calndr_Date, &RtcTimerContext.RTC_Calndr_Time ); |
||||
return ( uint32_t ) RtcTimerContext.Rtc_Time; |
||||
} |
||||
|
||||
/*!
|
||||
* @brief Get the RTC timer Reference |
||||
* @param none |
||||
* @retval Timer Value in Ticks |
||||
*/ |
||||
uint32_t HW_RTC_GetTimerContext( void ) |
||||
{ |
||||
return (uint32_t) RtcTimerContext.Rtc_Time; |
||||
} |
||||
/* Private functions ---------------------------------------------------------*/ |
||||
|
||||
/*!
|
||||
* @brief configure alarm at init |
||||
* @param none |
||||
* @retval none |
||||
*/ |
||||
static void HW_RTC_SetAlarmConfig( void ) |
||||
{ |
||||
HAL_RTC_DeactivateAlarm(&RtcHandle, RTC_ALARM_A); |
||||
} |
||||
|
||||
/*!
|
||||
* @brief start wake up alarm |
||||
* @note alarm in RtcTimerContext.Rtc_Time + timeoutValue |
||||
* @param timeoutValue in ticks |
||||
* @retval none |
||||
*/ |
||||
static void HW_RTC_StartWakeUpAlarm( uint32_t timeoutValue ) |
||||
{ |
||||
uint16_t rtcAlarmSubSeconds = 0; |
||||
uint16_t rtcAlarmSeconds = 0; |
||||
uint16_t rtcAlarmMinutes = 0; |
||||
uint16_t rtcAlarmHours = 0; |
||||
uint16_t rtcAlarmDays = 0; |
||||
RTC_TimeTypeDef RTC_TimeStruct = RtcTimerContext.RTC_Calndr_Time; |
||||
RTC_DateTypeDef RTC_DateStruct = RtcTimerContext.RTC_Calndr_Date; |
||||
|
||||
HW_RTC_StopAlarm( ); |
||||
DBG_GPIO_SET(GPIOB, GPIO_PIN_13); |
||||
|
||||
/*reverse counter */ |
||||
rtcAlarmSubSeconds = PREDIV_S - RTC_TimeStruct.SubSeconds; |
||||
rtcAlarmSubSeconds += ( timeoutValue & PREDIV_S); |
||||
/* convert timeout to seconds */ |
||||
timeoutValue >>= N_PREDIV_S; /* convert timeout in seconds */ |
||||
|
||||
/*convert microsecs to RTC format and add to 'Now' */ |
||||
rtcAlarmDays = RTC_DateStruct.Date; |
||||
while (timeoutValue >= SECONDS_IN_1DAY) |
||||
{ |
||||
timeoutValue -= SECONDS_IN_1DAY; |
||||
rtcAlarmDays++; |
||||
} |
||||
|
||||
/* calc hours */ |
||||
rtcAlarmHours = RTC_TimeStruct.Hours; |
||||
while (timeoutValue >= SECONDS_IN_1HOUR) |
||||
{ |
||||
timeoutValue -= SECONDS_IN_1HOUR; |
||||
rtcAlarmHours++; |
||||
} |
||||
|
||||
/* calc minutes */ |
||||
rtcAlarmMinutes = RTC_TimeStruct.Minutes; |
||||
while (timeoutValue >= SECONDS_IN_1MINUTE) |
||||
{ |
||||
timeoutValue -= SECONDS_IN_1MINUTE; |
||||
rtcAlarmMinutes++; |
||||
} |
||||
|
||||
/* calc seconds */ |
||||
rtcAlarmSeconds = RTC_TimeStruct.Seconds + timeoutValue; |
||||
|
||||
/***** correct for modulo********/ |
||||
while (rtcAlarmSubSeconds >= (PREDIV_S+1)) |
||||
{ |
||||
rtcAlarmSubSeconds -= (PREDIV_S+1); |
||||
rtcAlarmSeconds++; |
||||
} |
||||
|
||||
while (rtcAlarmSeconds >= SECONDS_IN_1MINUTE) |
||||
{
|
||||
rtcAlarmSeconds -= SECONDS_IN_1MINUTE; |
||||
rtcAlarmMinutes++; |
||||
} |
||||
|
||||
while (rtcAlarmMinutes >= MINUTES_IN_1HOUR) |
||||
{ |
||||
rtcAlarmMinutes -= MINUTES_IN_1HOUR; |
||||
rtcAlarmHours++; |
||||
} |
||||
|
||||
while (rtcAlarmHours >= HOURS_IN_1DAY) |
||||
{ |
||||
rtcAlarmHours -= HOURS_IN_1DAY; |
||||
rtcAlarmDays++; |
||||
} |
||||
|
||||
if( RTC_DateStruct.Year % 4 == 0 )
|
||||
{ |
||||
if( rtcAlarmDays > DaysInMonthLeapYear[ RTC_DateStruct.Month - 1 ] )
|
||||
{ |
||||
rtcAlarmDays = rtcAlarmDays % DaysInMonthLeapYear[ RTC_DateStruct.Month - 1 ]; |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
if( rtcAlarmDays > DaysInMonth[ RTC_DateStruct.Month - 1 ] )
|
||||
{
|
||||
rtcAlarmDays = rtcAlarmDays % DaysInMonth[ RTC_DateStruct.Month - 1 ]; |
||||
} |
||||
} |
||||
|
||||
/* Set RTC_AlarmStructure with calculated values*/ |
||||
RTC_AlarmStructure.AlarmTime.SubSeconds = PREDIV_S-rtcAlarmSubSeconds; |
||||
RTC_AlarmStructure.AlarmSubSecondMask = HW_RTC_ALARMSUBSECONDMASK;
|
||||
RTC_AlarmStructure.AlarmTime.Seconds = rtcAlarmSeconds; |
||||
RTC_AlarmStructure.AlarmTime.Minutes = rtcAlarmMinutes; |
||||
RTC_AlarmStructure.AlarmTime.Hours = rtcAlarmHours; |
||||
RTC_AlarmStructure.AlarmDateWeekDay = ( uint8_t )rtcAlarmDays; |
||||
RTC_AlarmStructure.AlarmTime.TimeFormat = RTC_TimeStruct.TimeFormat; |
||||
RTC_AlarmStructure.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE;
|
||||
RTC_AlarmStructure.AlarmMask = RTC_ALARMMASK_NONE; |
||||
RTC_AlarmStructure.Alarm = RTC_ALARM_A; |
||||
RTC_AlarmStructure.AlarmTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE; |
||||
RTC_AlarmStructure.AlarmTime.StoreOperation = RTC_STOREOPERATION_RESET; |
||||
|
||||
/* Set RTC_Alarm */ |
||||
HAL_RTC_SetAlarm_IT( &RtcHandle, &RTC_AlarmStructure, RTC_FORMAT_BIN ); |
||||
|
||||
/* Debug Printf*/ |
||||
DBG( HW_RTC_GetCalendarValue( &RTC_DateStruct, &RTC_TimeStruct ); ); |
||||
DBG_PRINTF("it's %d:%d:%d:%d ", RTC_TimeStruct.Hours, RTC_TimeStruct.Minutes, RTC_TimeStruct.Seconds, ((PREDIV_S - RTC_TimeStruct.SubSeconds)*1000)>>N_PREDIV_S); |
||||
DBG_PRINTF("WU@ %d:%d:%d:%d\n\r", rtcAlarmHours, rtcAlarmMinutes, rtcAlarmSeconds, (rtcAlarmSubSeconds*1000)>>N_PREDIV_S ); |
||||
|
||||
DBG_GPIO_RST(GPIOB, GPIO_PIN_13); |
||||
} |
||||
|
||||
|
||||
/*!
|
||||
* @brief get current time from calendar in ticks |
||||
* @param pointer to RTC_DateStruct |
||||
* @param pointer to RTC_TimeStruct |
||||
* @retval time in ticks |
||||
*/ |
||||
static TimerTime_t HW_RTC_GetCalendarValue( RTC_DateTypeDef* RTC_DateStruct, RTC_TimeTypeDef* RTC_TimeStruct ) |
||||
{ |
||||
TimerTime_t calendarValue = 0; |
||||
uint32_t first_read; |
||||
uint32_t correction; |
||||
|
||||
/* Get Time and Date*/ |
||||
HAL_RTC_GetTime( &RtcHandle, RTC_TimeStruct, RTC_FORMAT_BIN ); |
||||
|
||||
/* make sure it is correct due to asynchronus nature of RTC*/ |
||||
do { |
||||
first_read = RTC_TimeStruct->SubSeconds; |
||||
HAL_RTC_GetDate( &RtcHandle, RTC_DateStruct, RTC_FORMAT_BIN ); |
||||
HAL_RTC_GetTime( &RtcHandle, RTC_TimeStruct, RTC_FORMAT_BIN ); |
||||
} while (first_read != RTC_TimeStruct->SubSeconds); |
||||
|
||||
/* calculte amount of elapsed days since 01/01/2000 */ |
||||
calendarValue= DIVC( (DAYS_IN_YEAR*3 + DAYS_IN_LEAP_YEAR)* RTC_DateStruct->Year , 4); |
||||
|
||||
correction = ( (RTC_DateStruct->Year % 4) == 0 ) ? DAYS_IN_MONTH_CORRECTION_LEAP : DAYS_IN_MONTH_CORRECTION_NORM ; |
||||
|
||||
calendarValue +=( DIVC( (RTC_DateStruct->Month-1)*(30+31) ,2 ) - (((correction>> ((RTC_DateStruct->Month-1)*2) )&0x3))); |
||||
|
||||
calendarValue += (RTC_DateStruct->Date -1); |
||||
|
||||
/* convert from days to seconds */ |
||||
calendarValue *= SECONDS_IN_1DAY;
|
||||
|
||||
calendarValue += ( ( uint32_t )RTC_TimeStruct->Seconds +
|
||||
( ( uint32_t )RTC_TimeStruct->Minutes * SECONDS_IN_1MINUTE ) + |
||||
( ( uint32_t )RTC_TimeStruct->Hours * SECONDS_IN_1HOUR ) ) ; |
||||
|
||||
|
||||
|
||||
calendarValue = (calendarValue<<N_PREDIV_S) + ( PREDIV_S - RTC_TimeStruct->SubSeconds); |
||||
|
||||
return( calendarValue ); |
||||
} |
||||
|
||||
#endif |
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
||||
|
@ -0,0 +1,224 @@ |
||||
/*
|
||||
/ _____) _ | | |
||||
( (____ _____ ____ _| |_ _____ ____| |__ |
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | | |
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_| |
||||
(C)2013 Semtech |
||||
|
||||
Description: Bleeper board SPI driver implementation |
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project |
||||
|
||||
Maintainer: Miguel Luis and Gregory Cristian |
||||
*/ |
||||
/*******************************************************************************
|
||||
* @file hw_spi.c |
||||
* @author MCD Application Team |
||||
* @version V1.1.2 |
||||
* @date 08-September-2017 |
||||
* @brief manages the SPI interface |
||||
****************************************************************************** |
||||
* @attention |
||||
* |
||||
* <h2><center>© Copyright (c) 2017 STMicroelectronics International N.V.
|
||||
* All rights reserved.</center></h2> |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted, provided that the following conditions are met: |
||||
* |
||||
* 1. Redistribution of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer. |
||||
* 2. 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. |
||||
* 3. Neither the name of STMicroelectronics nor the names of other
|
||||
* contributors to this software may be used to endorse or promote products
|
||||
* derived from this software without specific written permission. |
||||
* 4. This software, including modifications and/or derivative works of this
|
||||
* software, must execute solely and exclusively on microcontroller or |
||||
* microprocessor devices manufactured by or for STMicroelectronics. |
||||
* 5. Redistribution and use of this software other than as permitted under
|
||||
* this license is void and will automatically terminate your rights under
|
||||
* this license.
|
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
* PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY |
||||
* RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT
|
||||
* SHALL STMICROELECTRONICS OR CONTRIBUTORS 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. |
||||
* |
||||
****************************************************************************** |
||||
*/ |
||||
#if 0 |
||||
/* Includes ------------------------------------------------------------------*/ |
||||
#include "hw.h" |
||||
#include "utilities.h" |
||||
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/ |
||||
/* Private define ------------------------------------------------------------*/ |
||||
/* Private macro -------------------------------------------------------------*/ |
||||
/* Private variables ---------------------------------------------------------*/ |
||||
static SPI_HandleTypeDef hspi; |
||||
/* Private function prototypes -----------------------------------------------*/ |
||||
|
||||
/*!
|
||||
* @brief Calculates Spi Divisor based on Spi Frequency and Mcu Frequency |
||||
* |
||||
* @param [IN] Spi Frequency |
||||
* @retval Spi divisor |
||||
*/ |
||||
static uint32_t SpiFrequency( uint32_t hz ); |
||||
|
||||
/* Exported functions ---------------------------------------------------------*/ |
||||
|
||||
/*!
|
||||
* @brief Initializes the SPI object and MCU peripheral |
||||
* |
||||
* @param [IN] none |
||||
*/ |
||||
void HW_SPI_Init( void ) |
||||
{ |
||||
|
||||
/*##-1- Configure the SPI peripheral */ |
||||
/* Set the SPI parameters */ |
||||
|
||||
hspi.Instance = SPI1; |
||||
|
||||
hspi.Init.BaudRatePrescaler = SpiFrequency( 10000000 ); |
||||
hspi.Init.Direction = SPI_DIRECTION_2LINES; |
||||
hspi.Init.Mode = SPI_MODE_MASTER; |
||||
hspi.Init.CLKPolarity = SPI_POLARITY_LOW; |
||||
hspi.Init.CLKPhase = SPI_PHASE_1EDGE; |
||||
hspi.Init.DataSize = SPI_DATASIZE_8BIT; |
||||
hspi.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
|
||||
hspi.Init.FirstBit = SPI_FIRSTBIT_MSB; |
||||
hspi.Init.NSS = SPI_NSS_SOFT; |
||||
hspi.Init.TIMode = SPI_TIMODE_DISABLE; |
||||
|
||||
|
||||
SPI_CLK_ENABLE();
|
||||
|
||||
|
||||
if(HAL_SPI_Init( &hspi) != HAL_OK) |
||||
{ |
||||
/* Initialization Error */ |
||||
Error_Handler(); |
||||
} |
||||
|
||||
/*##-2- Configure the SPI GPIOs */ |
||||
HW_SPI_IoInit( ); |
||||
} |
||||
|
||||
/*!
|
||||
* @brief De-initializes the SPI object and MCU peripheral |
||||
* |
||||
* @param [IN] none |
||||
*/ |
||||
void HW_SPI_DeInit( void ) |
||||
{ |
||||
|
||||
HAL_SPI_DeInit( &hspi); |
||||
|
||||
/*##-1- Reset peripherals ####*/ |
||||
__HAL_RCC_SPI1_FORCE_RESET(); |
||||
__HAL_RCC_SPI1_RELEASE_RESET(); |
||||
/*##-2- Configure the SPI GPIOs */ |
||||
HW_SPI_IoDeInit( ); |
||||
} |
||||
|
||||
void HW_SPI_IoInit( void ) |
||||
{ |
||||
GPIO_InitTypeDef initStruct={0}; |
||||
|
||||
|
||||
initStruct.Mode =GPIO_MODE_AF_PP; |
||||
initStruct.Pull = GPIO_PULLDOWN; |
||||
initStruct.Speed = GPIO_SPEED_HIGH; |
||||
initStruct.Alternate= SPI1_AF ; |
||||
|
||||
HW_GPIO_Init( RADIO_SCLK_PORT, RADIO_SCLK_PIN, &initStruct); |
||||
HW_GPIO_Init( RADIO_MISO_PORT, RADIO_MISO_PIN, &initStruct); |
||||
HW_GPIO_Init( RADIO_MOSI_PORT, RADIO_MOSI_PIN, &initStruct); |
||||
|
||||
initStruct.Mode = GPIO_MODE_OUTPUT_PP; |
||||
initStruct.Pull = GPIO_PULLUP; |
||||
|
||||
HW_GPIO_Init( RADIO_NSS_PORT, RADIO_NSS_PIN, &initStruct ); |
||||
|
||||
HW_GPIO_Write ( RADIO_NSS_PORT, RADIO_NSS_PIN, 1 ); |
||||
} |
||||
|
||||
void HW_SPI_IoDeInit( void ) |
||||
{ |
||||
GPIO_InitTypeDef initStruct={0}; |
||||
|
||||
initStruct.Mode =GPIO_MODE_OUTPUT_PP; |
||||
|
||||
initStruct.Pull =GPIO_PULLDOWN ; |
||||
HW_GPIO_Init ( RADIO_MOSI_PORT, RADIO_MOSI_PIN, &initStruct );
|
||||
HW_GPIO_Write( RADIO_MOSI_PORT, RADIO_MOSI_PIN, 0 ); |
||||
|
||||
initStruct.Pull =GPIO_PULLDOWN;
|
||||
HW_GPIO_Init ( RADIO_MISO_PORT, RADIO_MISO_PIN, &initStruct );
|
||||
HW_GPIO_Write( RADIO_MISO_PORT, RADIO_MISO_PIN, 0 ); |
||||
|
||||
initStruct.Pull =GPIO_PULLDOWN ;
|
||||
HW_GPIO_Init ( RADIO_SCLK_PORT, RADIO_SCLK_PIN, &initStruct );
|
||||
HW_GPIO_Write( RADIO_SCLK_PORT, RADIO_SCLK_PIN, 0 ); |
||||
|
||||
initStruct.Pull = GPIO_PULLUP; |
||||
HW_GPIO_Init ( RADIO_NSS_PORT, RADIO_NSS_PIN , &initStruct );
|
||||
HW_GPIO_Write( RADIO_NSS_PORT, RADIO_NSS_PIN , 1 ); |
||||
} |
||||
|
||||
/*!
|
||||
* @brief Sends outData and receives inData |
||||
* |
||||
* @param [IN] outData Byte to be sent |
||||
* @retval inData Received byte. |
||||
*/ |
||||
uint16_t HW_SPI_InOut( uint16_t txData ) |
||||
{ |
||||
uint16_t rxData ; |
||||
|
||||
HAL_SPI_TransmitReceive( &hspi, ( uint8_t * ) &txData, ( uint8_t* ) &rxData, 1, HAL_MAX_DELAY);
|
||||
|
||||
return rxData; |
||||
} |
||||
|
||||
/* Private functions ---------------------------------------------------------*/ |
||||
|
||||
static uint32_t SpiFrequency( uint32_t hz ) |
||||
{ |
||||
uint32_t divisor = 0; |
||||
uint32_t SysClkTmp = SystemCoreClock; |
||||
uint32_t baudRate; |
||||
|
||||
while( SysClkTmp > hz) |
||||
{ |
||||
divisor++; |
||||
SysClkTmp= ( SysClkTmp >> 1); |
||||
|
||||
if (divisor >= 7) |
||||
break; |
||||
} |
||||
|
||||
baudRate =((( divisor & 0x4 ) == 0 )? 0x0 : SPI_CR1_BR_2 )|
|
||||
((( divisor & 0x2 ) == 0 )? 0x0 : SPI_CR1_BR_1 )|
|
||||
((( divisor & 0x1 ) == 0 )? 0x0 : SPI_CR1_BR_0 ); |
||||
|
||||
return baudRate; |
||||
} |
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
||||
|
||||
#endif |
@ -0,0 +1,773 @@ |
||||
/*
|
||||
/ _____) _ | | |
||||
( (____ _____ ____ _| |_ _____ ____| |__ |
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | | |
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_| |
||||
(C)2013 Semtech |
||||
|
||||
Description: LoRaMac classA device implementation |
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project |
||||
|
||||
Maintainer: Miguel Luis, Gregory Cristian and Wael Guibene |
||||
*/ |
||||
/******************************************************************************
|
||||
* @file lora.c |
||||
* @author MCD Application Team |
||||
* @version V1.1.2 |
||||
* @date 08-September-2017 |
||||
* @brief lora API to drive the lora state Machine |
||||
****************************************************************************** |
||||
* @attention |
||||
* |
||||
* <h2><center>© Copyright (c) 2017 STMicroelectronics International N.V.
|
||||
* All rights reserved.</center></h2> |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted, provided that the following conditions are met: |
||||
* |
||||
* 1. Redistribution of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer. |
||||
* 2. 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. |
||||
* 3. Neither the name of STMicroelectronics nor the names of other
|
||||
* contributors to this software may be used to endorse or promote products
|
||||
* derived from this software without specific written permission. |
||||
* 4. This software, including modifications and/or derivative works of this
|
||||
* software, must execute solely and exclusively on microcontroller or |
||||
* microprocessor devices manufactured by or for STMicroelectronics. |
||||
* 5. Redistribution and use of this software other than as permitted under
|
||||
* this license is void and will automatically terminate your rights under
|
||||
* this license.
|
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
* PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY |
||||
* RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT
|
||||
* SHALL STMICROELECTRONICS OR CONTRIBUTORS 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. |
||||
* |
||||
****************************************************************************** |
||||
*/ |
||||
|
||||
/* Includes ------------------------------------------------------------------*/ |
||||
#include "hw.h" |
||||
#include "timeServer.h" |
||||
#include "LoRaMac.h" |
||||
#include "lora.h" |
||||
|
||||
/*!
|
||||
* Join requests trials duty cycle. |
||||
*/ |
||||
#define OVER_THE_AIR_ACTIVATION_DUTYCYCLE 10000 // 10 [s] value in ms
|
||||
|
||||
#if defined( REGION_EU868 ) |
||||
|
||||
#include "LoRaMacTest.h" |
||||
|
||||
/*!
|
||||
* LoRaWAN ETSI duty cycle control enable/disable |
||||
* |
||||
* \remark Please note that ETSI mandates duty cycled transmissions. Use only for test purposes |
||||
*/ |
||||
#define LORAWAN_DUTYCYCLE_ON true |
||||
|
||||
#define USE_SEMTECH_DEFAULT_CHANNEL_LINEUP 0 |
||||
|
||||
#if( USE_SEMTECH_DEFAULT_CHANNEL_LINEUP == 1 ) |
||||
|
||||
#define LC4 { 867100000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 } |
||||
#define LC5 { 867300000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 } |
||||
#define LC6 { 867500000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 } |
||||
#define LC7 { 867700000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 } |
||||
#define LC8 { 867900000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 } |
||||
#define LC9 { 868800000, 0, { ( ( DR_7 << 4 ) | DR_7 ) }, 2 } |
||||
#define LC10 { 868300000, 0, { ( ( DR_6 << 4 ) | DR_6 ) }, 1 } |
||||
|
||||
#endif |
||||
|
||||
#endif |
||||
|
||||
static uint8_t DevEui[] = LORAWAN_DEVICE_EUI; |
||||
static uint8_t AppEui[] = LORAWAN_APPLICATION_EUI; |
||||
static uint8_t AppKey[] = LORAWAN_APPLICATION_KEY; |
||||
|
||||
#if( OVER_THE_AIR_ACTIVATION == 0 ) |
||||
|
||||
static uint8_t NwkSKey[] = LORAWAN_NWKSKEY; |
||||
static uint8_t AppSKey[] = LORAWAN_APPSKEY; |
||||
|
||||
/*!
|
||||
* Device address |
||||
*/ |
||||
static uint32_t DevAddr = LORAWAN_DEVICE_ADDRESS; |
||||
|
||||
#endif |
||||
|
||||
/*!
|
||||
* User application data buffer size |
||||
*/ |
||||
#define LORAWAN_APP_DATA_BUFF_SIZE 64 |
||||
|
||||
/*!
|
||||
* User application data |
||||
*/ |
||||
static uint8_t AppDataBuff[LORAWAN_APP_DATA_BUFF_SIZE]; |
||||
|
||||
/*!
|
||||
* User application data structure |
||||
*/ |
||||
static lora_AppData_t AppData={ AppDataBuff, 0 ,0 }; |
||||
|
||||
/*!
|
||||
* Indicates if the node is sending confirmed or unconfirmed messages |
||||
*/ |
||||
static FunctionalState IsTxConfirmed ; |
||||
|
||||
/*!
|
||||
* Defines the LoRa parameters at Init |
||||
*/ |
||||
static LoRaParam_t* LoRaParamInit; |
||||
/*!
|
||||
* Timer to handle the application data transmission duty cycle |
||||
*/ |
||||
static TimerEvent_t TxNextPacketTimer; |
||||
|
||||
static DeviceState_t DeviceState = DEVICE_STATE_INIT ; |
||||
|
||||
/*!
|
||||
* Timer to handle the state of LED1 |
||||
*/ |
||||
|
||||
static LoRaMacPrimitives_t LoRaMacPrimitives; |
||||
static LoRaMacCallback_t LoRaMacCallbacks; |
||||
static MibRequestConfirm_t mibReq; |
||||
|
||||
static LoRaMainCallback_t *LoRaMainCallbacks; |
||||
|
||||
|
||||
/*!
|
||||
* Indicates if a new packet can be sent |
||||
*/ |
||||
static bool NextTx = true; |
||||
|
||||
/*!
|
||||
* LoRaWAN compliance tests support data |
||||
*/ |
||||
struct ComplianceTest_s |
||||
{ |
||||
bool Running; |
||||
uint8_t State; |
||||
FunctionalState IsTxConfirmed; |
||||
uint8_t AppPort; |
||||
uint8_t AppDataSize; |
||||
uint8_t *AppDataBuffer; |
||||
uint16_t DownLinkCounter; |
||||
bool LinkCheck; |
||||
uint8_t DemodMargin; |
||||
uint8_t NbGateways; |
||||
}ComplianceTest; |
||||
|
||||
/*!
|
||||
* \brief Prepares the payload of the frame |
||||
*/ |
||||
static void PrepareTxFrame( ) |
||||
{ |
||||
if( ComplianceTest.Running == true ) |
||||
{ |
||||
if( ComplianceTest.LinkCheck == true ) |
||||
{ |
||||
ComplianceTest.LinkCheck = false; |
||||
AppData.BuffSize = 3; |
||||
AppData.Buff[0] = 5; |
||||
AppData.Buff[1] = ComplianceTest.DemodMargin; |
||||
AppData.Buff[2] = ComplianceTest.NbGateways; |
||||
ComplianceTest.State = 1; |
||||
} |
||||
else |
||||
{ |
||||
switch( ComplianceTest.State ) |
||||
{ |
||||
case 4: |
||||
ComplianceTest.State = 1; |
||||
break; |
||||
case 1: |
||||
AppData.BuffSize = 2; |
||||
AppData.Buff[0] = ComplianceTest.DownLinkCounter >> 8; |
||||
AppData.Buff[1] = ComplianceTest.DownLinkCounter; |
||||
break; |
||||
} |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
LoRaMainCallbacks->LoraTxData(&AppData, &IsTxConfirmed); |
||||
} |
||||
} |
||||
|
||||
/*!
|
||||
* \brief Prepares the payload of the frame |
||||
* |
||||
* \retval [0: frame could be send, 1: error] |
||||
*/ |
||||
static bool SendFrame( void ) |
||||
{ |
||||
McpsReq_t mcpsReq; |
||||
LoRaMacTxInfo_t txInfo; |
||||
|
||||
if( LoRaMacQueryTxPossible( AppData.BuffSize, &txInfo ) != LORAMAC_STATUS_OK ) |
||||
{ |
||||
// Send empty frame in order to flush MAC commands
|
||||
mcpsReq.Type = MCPS_UNCONFIRMED; |
||||
mcpsReq.Req.Unconfirmed.fBuffer = NULL; |
||||
mcpsReq.Req.Unconfirmed.fBufferSize = 0; |
||||
mcpsReq.Req.Unconfirmed.Datarate = LoRaParamInit->TxDatarate; |
||||
} |
||||
else |
||||
{ |
||||
if( IsTxConfirmed == DISABLE ) |
||||
{ |
||||
mcpsReq.Type = MCPS_UNCONFIRMED; |
||||
mcpsReq.Req.Unconfirmed.fPort = AppData.Port; |
||||
mcpsReq.Req.Unconfirmed.fBuffer = AppData.Buff; |
||||
mcpsReq.Req.Unconfirmed.fBufferSize = AppData.BuffSize; |
||||
mcpsReq.Req.Unconfirmed.Datarate = LoRaParamInit->TxDatarate; |
||||
} |
||||
else |
||||
{ |
||||
mcpsReq.Type = MCPS_CONFIRMED; |
||||
mcpsReq.Req.Confirmed.fPort = AppData.Port; |
||||
mcpsReq.Req.Confirmed.fBuffer = AppData.Buff; |
||||
mcpsReq.Req.Confirmed.fBufferSize = AppData.BuffSize; |
||||
mcpsReq.Req.Confirmed.NbTrials = 8; |
||||
mcpsReq.Req.Confirmed.Datarate = LoRaParamInit->TxDatarate; |
||||
} |
||||
} |
||||
if( LoRaMacMcpsRequest( &mcpsReq ) == LORAMAC_STATUS_OK ) |
||||
{ |
||||
return false; |
||||
} |
||||
return true; |
||||
} |
||||
|
||||
void OnSendEvent( void ) |
||||
{ |
||||
MibRequestConfirm_t mibReq; |
||||
LoRaMacStatus_t status; |
||||
|
||||
mibReq.Type = MIB_NETWORK_JOINED; |
||||
status = LoRaMacMibGetRequestConfirm( &mibReq ); |
||||
|
||||
if( status == LORAMAC_STATUS_OK ) |
||||
{ |
||||
if( mibReq.Param.IsNetworkJoined == true ) |
||||
{ |
||||
DeviceState = DEVICE_STATE_SEND; |
||||
NextTx = true; |
||||
} |
||||
else |
||||
{ |
||||
DeviceState = DEVICE_STATE_JOIN; |
||||
} |
||||
} |
||||
} |
||||
/*!
|
||||
* \brief Function executed on TxNextPacket Timeout event |
||||
*/ |
||||
static void OnTxNextPacketTimerEvent( void ) |
||||
{ |
||||
TimerStop( &TxNextPacketTimer ); |
||||
OnSendEvent(); |
||||
} |
||||
|
||||
/*!
|
||||
* \brief MCPS-Confirm event function |
||||
* |
||||
* \param [IN] McpsConfirm - Pointer to the confirm structure, |
||||
* containing confirm attributes. |
||||
*/ |
||||
static void McpsConfirm( McpsConfirm_t *mcpsConfirm ) |
||||
{ |
||||
if( mcpsConfirm->Status == LORAMAC_EVENT_INFO_STATUS_OK ) |
||||
{ |
||||
switch( mcpsConfirm->McpsRequest ) |
||||
{ |
||||
case MCPS_UNCONFIRMED: |
||||
{ |
||||
// Check Datarate
|
||||
// Check TxPower
|
||||
break; |
||||
} |
||||
case MCPS_CONFIRMED: |
||||
{ |
||||
// Check Datarate
|
||||
// Check TxPower
|
||||
// Check AckReceived
|
||||
// Check NbTrials
|
||||
break; |
||||
} |
||||
case MCPS_PROPRIETARY: |
||||
{ |
||||
break; |
||||
} |
||||
default: |
||||
break; |
||||
} |
||||
} |
||||
NextTx = true; |
||||
} |
||||
|
||||
/*!
|
||||
* \brief MCPS-Indication event function |
||||
* |
||||
* \param [IN] mcpsIndication - Pointer to the indication structure, |
||||
* containing indication attributes. |
||||
*/ |
||||
static void McpsIndication( McpsIndication_t *mcpsIndication ) |
||||
{ |
||||
if( mcpsIndication->Status != LORAMAC_EVENT_INFO_STATUS_OK ) |
||||
{ |
||||
return; |
||||
} |
||||
|
||||
switch( mcpsIndication->McpsIndication ) |
||||
{ |
||||
case MCPS_UNCONFIRMED: |
||||
{ |
||||
break; |
||||
} |
||||
case MCPS_CONFIRMED: |
||||
{ |
||||
break; |
||||
} |
||||
case MCPS_PROPRIETARY: |
||||
{ |
||||
break; |
||||
} |
||||
case MCPS_MULTICAST: |
||||
{ |
||||
break; |
||||
} |
||||
default: |
||||
break; |
||||
} |
||||
|
||||
// Check Multicast
|
||||
// Check Port
|
||||
// Check Datarate
|
||||
// Check FramePending
|
||||
// Check Buffer
|
||||
// Check BufferSize
|
||||
// Check Rssi
|
||||
// Check Snr
|
||||
// Check RxSlot
|
||||
|
||||
if( ComplianceTest.Running == true ) |
||||
{ |
||||
ComplianceTest.DownLinkCounter++; |
||||
} |
||||
|
||||
if( mcpsIndication->RxData == true ) |
||||
{ |
||||
switch( mcpsIndication->Port ) |
||||
{ |
||||
case 224: |
||||
if( ComplianceTest.Running == false ) |
||||
{ |
||||
// Check compliance test enable command (i)
|
||||
if( ( mcpsIndication->BufferSize == 4 ) && |
||||
( mcpsIndication->Buffer[0] == 0x01 ) && |
||||
( mcpsIndication->Buffer[1] == 0x01 ) && |
||||
( mcpsIndication->Buffer[2] == 0x01 ) && |
||||
( mcpsIndication->Buffer[3] == 0x01 ) ) |
||||
{ |
||||
IsTxConfirmed = DISABLE; |
||||
AppData.Port = 224; |
||||
AppData.BuffSize = 2; |
||||
ComplianceTest.DownLinkCounter = 0; |
||||
ComplianceTest.LinkCheck = false; |
||||
ComplianceTest.DemodMargin = 0; |
||||
ComplianceTest.NbGateways = 0; |
||||
ComplianceTest.Running = true; |
||||
ComplianceTest.State = 1; |
||||
|
||||
MibRequestConfirm_t mibReq; |
||||
mibReq.Type = MIB_ADR; |
||||
mibReq.Param.AdrEnable = true; |
||||
LoRaMacMibSetRequestConfirm( &mibReq ); |
||||
|
||||
#if defined( REGION_EU868 ) |
||||
LoRaMacTestSetDutyCycleOn( false ); |
||||
#endif |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
ComplianceTest.State = mcpsIndication->Buffer[0]; |
||||
switch( ComplianceTest.State ) |
||||
{ |
||||
case 0: // Check compliance test disable command (ii)
|
||||
ComplianceTest.DownLinkCounter = 0; |
||||
ComplianceTest.Running = false; |
||||
|
||||
MibRequestConfirm_t mibReq; |
||||
mibReq.Type = MIB_ADR; |
||||
mibReq.Param.AdrEnable = LoRaParamInit->AdrEnable; |
||||
LoRaMacMibSetRequestConfirm( &mibReq ); |
||||
#if defined( REGION_EU868 ) |
||||
LoRaMacTestSetDutyCycleOn( LORAWAN_DUTYCYCLE_ON ); |
||||
#endif |
||||
break; |
||||
case 1: // (iii, iv)
|
||||
AppData.BuffSize = 2; |
||||
break; |
||||
case 2: // Enable confirmed messages (v)
|
||||
IsTxConfirmed = ENABLE; |
||||
ComplianceTest.State = 1; |
||||
break; |
||||
case 3: // Disable confirmed messages (vi)
|
||||
IsTxConfirmed = DISABLE; |
||||
ComplianceTest.State = 1; |
||||
break; |
||||
case 4: // (vii)
|
||||
AppData.BuffSize = mcpsIndication->BufferSize; |
||||
|
||||
AppData.Buff[0] = 4; |
||||
for( uint8_t i = 1; i < AppData.BuffSize; i++ ) |
||||
{ |
||||
AppData.Buff[i] = mcpsIndication->Buffer[i] + 1; |
||||
} |
||||
break; |
||||
case 5: // (viii)
|
||||
{ |
||||
MlmeReq_t mlmeReq; |
||||
mlmeReq.Type = MLME_LINK_CHECK; |
||||
LoRaMacMlmeRequest( &mlmeReq ); |
||||
} |
||||
break; |
||||
case 6: // (ix)
|
||||
{ |
||||
MlmeReq_t mlmeReq; |
||||
|
||||
// Disable TestMode and revert back to normal operation
|
||||
|
||||
ComplianceTest.DownLinkCounter = 0; |
||||
ComplianceTest.Running = false; |
||||
|
||||
MibRequestConfirm_t mibReq; |
||||
mibReq.Type = MIB_ADR; |
||||
mibReq.Param.AdrEnable = LoRaParamInit->AdrEnable; |
||||
LoRaMacMibSetRequestConfirm( &mibReq ); |
||||
|
||||
mlmeReq.Type = MLME_JOIN; |
||||
|
||||
mlmeReq.Req.Join.DevEui = DevEui; |
||||
mlmeReq.Req.Join.AppEui = AppEui; |
||||
mlmeReq.Req.Join.AppKey = AppKey; |
||||
mlmeReq.Req.Join.NbTrials = 3; |
||||
|
||||
LoRaMacMlmeRequest( &mlmeReq ); |
||||
DeviceState = DEVICE_STATE_SLEEP; |
||||
} |
||||
break; |
||||
case 7: // (x)
|
||||
{ |
||||
if( mcpsIndication->BufferSize == 3 ) |
||||
{ |
||||
MlmeReq_t mlmeReq; |
||||
mlmeReq.Type = MLME_TXCW; |
||||
mlmeReq.Req.TxCw.Timeout = ( uint16_t )( ( mcpsIndication->Buffer[1] << 8 ) | mcpsIndication->Buffer[2] ); |
||||
LoRaMacMlmeRequest( &mlmeReq ); |
||||
} |
||||
else if( mcpsIndication->BufferSize == 7 ) |
||||
{ |
||||
MlmeReq_t mlmeReq; |
||||
mlmeReq.Type = MLME_TXCW_1; |
||||
mlmeReq.Req.TxCw.Timeout = ( uint16_t )( ( mcpsIndication->Buffer[1] << 8 ) | mcpsIndication->Buffer[2] ); |
||||
mlmeReq.Req.TxCw.Frequency = ( uint32_t )( ( mcpsIndication->Buffer[3] << 16 ) | ( mcpsIndication->Buffer[4] << 8 ) | mcpsIndication->Buffer[5] ) * 100; |
||||
mlmeReq.Req.TxCw.Power = mcpsIndication->Buffer[6]; |
||||
LoRaMacMlmeRequest( &mlmeReq ); |
||||
} |
||||
ComplianceTest.State = 1; |
||||
} |
||||
break; |
||||
default:
|
||||
break; |
||||
} |
||||
} |
||||
break; |
||||
default: |
||||
|
||||
AppData.Port = mcpsIndication->Port; |
||||
AppData.BuffSize = mcpsIndication->BufferSize; |
||||
memcpy1( AppData.Buff, mcpsIndication->Buffer, AppData.BuffSize ); |
||||
|
||||
LoRaMainCallbacks->LoraRxData( &AppData ); |
||||
break; |
||||
} |
||||
} |
||||
} |
||||
|
||||
/*!
|
||||
* \brief MLME-Confirm event function |
||||
* |
||||
* \param [IN] MlmeConfirm - Pointer to the confirm structure, |
||||
* containing confirm attributes. |
||||
*/ |
||||
static void MlmeConfirm( MlmeConfirm_t *mlmeConfirm ) |
||||
{ |
||||
switch( mlmeConfirm->MlmeRequest ) |
||||
{ |
||||
case MLME_JOIN: |
||||
{ |
||||
if( mlmeConfirm->Status == LORAMAC_EVENT_INFO_STATUS_OK ) |
||||
{ |
||||
// Status is OK, node has joined the network
|
||||
DeviceState = DEVICE_STATE_JOINED; |
||||
} |
||||
else |
||||
{ |
||||
// Join was not successful. Try to join again
|
||||
DeviceState = DEVICE_STATE_JOIN; |
||||
} |
||||
break; |
||||
} |
||||
case MLME_LINK_CHECK: |
||||
{ |
||||
if( mlmeConfirm->Status == LORAMAC_EVENT_INFO_STATUS_OK ) |
||||
{ |
||||
// Check DemodMargin
|
||||
// Check NbGateways
|
||||
if( ComplianceTest.Running == true ) |
||||
{ |
||||
ComplianceTest.LinkCheck = true; |
||||
ComplianceTest.DemodMargin = mlmeConfirm->DemodMargin; |
||||
ComplianceTest.NbGateways = mlmeConfirm->NbGateways; |
||||
} |
||||
} |
||||
break; |
||||
} |
||||
default: |
||||
break; |
||||
} |
||||
NextTx = true; |
||||
} |
||||
/**
|
||||
* lora Init |
||||
*/ |
||||
void lora_Init (LoRaMainCallback_t *callbacks, LoRaParam_t* LoRaParam ) |
||||
{ |
||||
/* init the DeviceState*/ |
||||
DeviceState= DEVICE_STATE_INIT; |
||||
|
||||
/* init the Tx Duty Cycle*/ |
||||
LoRaParamInit = LoRaParam; |
||||
|
||||
/* init the main call backs*/ |
||||
LoRaMainCallbacks = callbacks; |
||||
|
||||
#if (STATIC_DEVICE_EUI != 1) |
||||
LoRaMainCallbacks->BoardGetUniqueId( DevEui );
|
||||
#endif |
||||
|
||||
#if( OVER_THE_AIR_ACTIVATION != 0 ) |
||||
|
||||
PRINTF("OTAA\n\r");
|
||||
PRINTF("DevEui= %02X", DevEui[0]) ;for(int i=1; i<8 ; i++) {PRINTF("-%02X", DevEui[i]); }; PRINTF("\n\r"); |
||||
PRINTF("AppEui= %02X", AppEui[0]) ;for(int i=1; i<8 ; i++) {PRINTF("-%02X", AppEui[i]); }; PRINTF("\n\r"); |
||||
PRINTF("AppKey= %02X", AppKey[0]) ;for(int i=1; i<16; i++) {PRINTF(" %02X", AppKey[i]); }; PRINTF("\n\n\r"); |
||||
#else |
||||
|
||||
#if (STATIC_DEVICE_ADDRESS != 1) |
||||
// Random seed initialization
|
||||
srand1( LoRaMainCallbacks->BoardGetRandomSeed( ) ); |
||||
// Choose a random device address
|
||||
DevAddr = randr( 0, 0x01FFFFFF ); |
||||
#endif |
||||
PRINTF("ABP\n\r");
|
||||
PRINTF("DevEui= %02X", DevEui[0]) ;for(int i=1; i<8 ; i++) {PRINTF("-%02X", DevEui[i]); }; PRINTF("\n\r"); |
||||
PRINTF("DevAdd= %08X\n\r", DevAddr) ; |
||||
PRINTF("NwkSKey= %02X", NwkSKey[0]) ;for(int i=1; i<16 ; i++) {PRINTF(" %02X", NwkSKey[i]); }; PRINTF("\n\r"); |
||||
PRINTF("AppSKey= %02X", AppSKey[0]) ;for(int i=1; i<16 ; i++) {PRINTF(" %02X", AppSKey[i]); }; PRINTF("\n\r"); |
||||
#endif |
||||
|
||||
} |
||||
|
||||
/**
|
||||
* lora class A state machine |
||||
*/ |
||||
|
||||
void lora_fsm( void) |
||||
{ |
||||
switch( DeviceState ) |
||||
{ |
||||
case DEVICE_STATE_INIT: |
||||
{ |
||||
LoRaMacPrimitives.MacMcpsConfirm = McpsConfirm; |
||||
LoRaMacPrimitives.MacMcpsIndication = McpsIndication; |
||||
LoRaMacPrimitives.MacMlmeConfirm = MlmeConfirm; |
||||
LoRaMacCallbacks.GetBatteryLevel = LoRaMainCallbacks->BoardGetBatteryLevel; |
||||
#if defined( REGION_AS923 ) |
||||
LoRaMacInitialization( &LoRaMacPrimitives, &LoRaMacCallbacks, LORAMAC_REGION_AS923 ); |
||||
#elif defined( REGION_AU915 ) |
||||
LoRaMacInitialization( &LoRaMacPrimitives, &LoRaMacCallbacks, LORAMAC_REGION_AU915 ); |
||||
#elif defined( REGION_CN470 ) |
||||
LoRaMacInitialization( &LoRaMacPrimitives, &LoRaMacCallbacks, LORAMAC_REGION_CN470 ); |
||||
#elif defined( REGION_CN779 ) |
||||
LoRaMacInitialization( &LoRaMacPrimitives, &LoRaMacCallbacks, LORAMAC_REGION_CN779 ); |
||||
#elif defined( REGION_EU433 ) |
||||
LoRaMacInitialization( &LoRaMacPrimitives, &LoRaMacCallbacks, LORAMAC_REGION_EU433 ); |
||||
#elif defined( REGION_IN865 ) |
||||
LoRaMacInitialization( &LoRaMacPrimitives, &LoRaMacCallbacks, LORAMAC_REGION_IN865 ); |
||||
#elif defined( REGION_EU868 ) |
||||
LoRaMacInitialization( &LoRaMacPrimitives, &LoRaMacCallbacks, LORAMAC_REGION_EU868 ); |
||||
#elif defined( REGION_KR920 ) |
||||
LoRaMacInitialization( &LoRaMacPrimitives, &LoRaMacCallbacks, LORAMAC_REGION_KR920 ); |
||||
#elif defined( REGION_US915 ) |
||||
LoRaMacInitialization( &LoRaMacPrimitives, &LoRaMacCallbacks, LORAMAC_REGION_US915 ); |
||||
#elif defined( REGION_US915_HYBRID ) |
||||
LoRaMacInitialization( &LoRaMacPrimitives, &LoRaMacCallbacks, LORAMAC_REGION_US915_HYBRID ); |
||||
#else |
||||
#error "Please define a region in the compiler options." |
||||
#endif |
||||
|
||||
TimerInit( &TxNextPacketTimer, OnTxNextPacketTimerEvent ); |
||||
|
||||
mibReq.Type = MIB_ADR; |
||||
mibReq.Param.AdrEnable = LoRaParamInit->AdrEnable; |
||||
LoRaMacMibSetRequestConfirm( &mibReq ); |
||||
|
||||
mibReq.Type = MIB_PUBLIC_NETWORK; |
||||
mibReq.Param.EnablePublicNetwork = LoRaParamInit->EnablePublicNetwork; |
||||
LoRaMacMibSetRequestConfirm( &mibReq ); |
||||
|
||||
mibReq.Type = MIB_DEVICE_CLASS; |
||||
mibReq.Param.Class= LoRaParamInit->Class; |
||||
LoRaMacMibSetRequestConfirm( &mibReq ); |
||||
|
||||
#if defined( REGION_EU868 ) |
||||
LoRaMacTestSetDutyCycleOn( LORAWAN_DUTYCYCLE_ON ); |
||||
|
||||
#if( USE_SEMTECH_DEFAULT_CHANNEL_LINEUP == 1 ) |
||||
LoRaMacChannelAdd( 3, ( ChannelParams_t )LC4 ); |
||||
LoRaMacChannelAdd( 4, ( ChannelParams_t )LC5 ); |
||||
LoRaMacChannelAdd( 5, ( ChannelParams_t )LC6 ); |
||||
LoRaMacChannelAdd( 6, ( ChannelParams_t )LC7 ); |
||||
LoRaMacChannelAdd( 7, ( ChannelParams_t )LC8 ); |
||||
LoRaMacChannelAdd( 8, ( ChannelParams_t )LC9 ); |
||||
LoRaMacChannelAdd( 9, ( ChannelParams_t )LC10 ); |
||||
|
||||
mibReq.Type = MIB_RX2_DEFAULT_CHANNEL; |
||||
mibReq.Param.Rx2DefaultChannel = ( Rx2ChannelParams_t ){ 869525000, DR_3 }; |
||||
LoRaMacMibSetRequestConfirm( &mibReq ); |
||||
|
||||
mibReq.Type = MIB_RX2_CHANNEL; |
||||
mibReq.Param.Rx2Channel = ( Rx2ChannelParams_t ){ 869525000, DR_3 }; |
||||
LoRaMacMibSetRequestConfirm( &mibReq ); |
||||
#endif |
||||
|
||||
#endif |
||||
DeviceState = DEVICE_STATE_JOIN; |
||||
break; |
||||
} |
||||
case DEVICE_STATE_JOIN: |
||||
{ |
||||
#if( OVER_THE_AIR_ACTIVATION != 0 ) |
||||
MlmeReq_t mlmeReq; |
||||
|
||||
mlmeReq.Type = MLME_JOIN; |
||||
mlmeReq.Req.Join.DevEui = DevEui; |
||||
mlmeReq.Req.Join.AppEui = AppEui; |
||||
mlmeReq.Req.Join.AppKey = AppKey; |
||||
mlmeReq.Req.Join.NbTrials = LoRaParamInit->NbTrials; |
||||
|
||||
if( NextTx == true ) |
||||
{ |
||||
LoRaMacMlmeRequest( &mlmeReq ); |
||||
} |
||||
|
||||
DeviceState = DEVICE_STATE_SLEEP; |
||||
#else |
||||
mibReq.Type = MIB_NET_ID; |
||||
mibReq.Param.NetID = LORAWAN_NETWORK_ID; |
||||
LoRaMacMibSetRequestConfirm( &mibReq ); |
||||
|
||||
mibReq.Type = MIB_DEV_ADDR; |
||||
mibReq.Param.DevAddr = DevAddr; |
||||
LoRaMacMibSetRequestConfirm( &mibReq ); |
||||
|
||||
mibReq.Type = MIB_NWK_SKEY; |
||||
mibReq.Param.NwkSKey = NwkSKey; |
||||
LoRaMacMibSetRequestConfirm( &mibReq ); |
||||
|
||||
mibReq.Type = MIB_APP_SKEY; |
||||
mibReq.Param.AppSKey = AppSKey; |
||||
LoRaMacMibSetRequestConfirm( &mibReq ); |
||||
|
||||
mibReq.Type = MIB_NETWORK_JOINED; |
||||
mibReq.Param.IsNetworkJoined = true; |
||||
LoRaMacMibSetRequestConfirm( &mibReq ); |
||||
|
||||
DeviceState = DEVICE_STATE_SEND; |
||||
#endif |
||||
break; |
||||
} |
||||
case DEVICE_STATE_JOINED: |
||||
{ |
||||
PRINTF("JOINED\n\r"); |
||||
DeviceState = DEVICE_STATE_SEND; |
||||
break; |
||||
} |
||||
case DEVICE_STATE_SEND: |
||||
{ |
||||
if( NextTx == true ) |
||||
{ |
||||
PrepareTxFrame( ); |
||||
|
||||
NextTx = SendFrame( ); |
||||
} |
||||
if( ComplianceTest.Running == true ) |
||||
{ |
||||
// Schedule next packet transmission as soon as possible
|
||||
TimerSetValue( &TxNextPacketTimer, 5000); /* 5s */ |
||||
TimerStart( &TxNextPacketTimer ); |
||||
} |
||||
else if (LoRaParamInit->TxEvent == TX_ON_TIMER ) |
||||
{ |
||||
// Schedule next packet transmission
|
||||
TimerSetValue( &TxNextPacketTimer, LoRaParamInit->TxDutyCycleTime ); |
||||
TimerStart( &TxNextPacketTimer ); |
||||
} |
||||
|
||||
DeviceState = DEVICE_STATE_SLEEP; |
||||
break; |
||||
} |
||||
case DEVICE_STATE_SLEEP: |
||||
{ |
||||
// Wake up through events
|
||||
break; |
||||
} |
||||
default: |
||||
{ |
||||
DeviceState = DEVICE_STATE_INIT; |
||||
break; |
||||
} |
||||
} |
||||
} |
||||
|
||||
|
||||
DeviceState_t lora_getDeviceState( void ) |
||||
{ |
||||
return DeviceState; |
||||
} |
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
||||
|
@ -0,0 +1,251 @@ |
||||
/*
|
||||
/ _____) _ | | |
||||
( (____ _____ ____ _| |_ _____ ____| |__ |
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | | |
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_| |
||||
(C)2013 Semtech |
||||
|
||||
Description: LoRaMac classA device implementation |
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project |
||||
|
||||
Maintainer: Miguel Luis, Gregory Cristian and Wael Guibene |
||||
*/ |
||||
/******************************************************************************
|
||||
* @file lora.h |
||||
* @author MCD Application Team |
||||
* @version V1.1.2 |
||||
* @date 08-September-2017 |
||||
* @brief lora API to drive the lora state Machine |
||||
****************************************************************************** |
||||
* @attention |
||||
* |
||||
* <h2><center>© Copyright (c) 2017 STMicroelectronics International N.V.
|
||||
* All rights reserved.</center></h2> |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted, provided that the following conditions are met: |
||||
* |
||||
* 1. Redistribution of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer. |
||||
* 2. 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. |
||||
* 3. Neither the name of STMicroelectronics nor the names of other
|
||||
* contributors to this software may be used to endorse or promote products
|
||||
* derived from this software without specific written permission. |
||||
* 4. This software, including modifications and/or derivative works of this
|
||||
* software, must execute solely and exclusively on microcontroller or |
||||
* microprocessor devices manufactured by or for STMicroelectronics. |
||||
* 5. Redistribution and use of this software other than as permitted under
|
||||
* this license is void and will automatically terminate your rights under
|
||||
* this license.
|
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
* PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY |
||||
* RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT
|
||||
* SHALL STMICROELECTRONICS OR CONTRIBUTORS 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. |
||||
* |
||||
****************************************************************************** |
||||
*/ |
||||
/* Define to prevent recursive inclusion -------------------------------------*/ |
||||
|
||||
#ifndef __LORA_MAIN_H__ |
||||
#define __LORA_MAIN_H__ |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
/* Includes ------------------------------------------------------------------*/ |
||||
#include "Commissioning.h" |
||||
#include "LoRaMac.h" |
||||
#include "region/Region.h" |
||||
|
||||
/* Exported constants --------------------------------------------------------*/ |
||||
/* Exported types ------------------------------------------------------------*/ |
||||
|
||||
/*!
|
||||
* Application Data structure |
||||
*/ |
||||
typedef struct |
||||
{ |
||||
/*point to the LoRa App data buffer*/ |
||||
uint8_t* Buff; |
||||
/*LoRa App data buffer size*/ |
||||
uint8_t BuffSize; |
||||
/*Port on which the LoRa App is data is sent/ received*/ |
||||
uint8_t Port; |
||||
|
||||
} lora_AppData_t; |
||||
|
||||
/*!
|
||||
* LoRa State Machine states
|
||||
*/ |
||||
typedef enum eDevicState |
||||
{ |
||||
DEVICE_STATE_INIT, |
||||
DEVICE_STATE_JOIN, |
||||
DEVICE_STATE_JOINED, |
||||
DEVICE_STATE_SEND, |
||||
DEVICE_STATE_CYCLE, |
||||
DEVICE_STATE_SLEEP |
||||
} DeviceState_t; |
||||
|
||||
/*!
|
||||
* LoRa State Machine states
|
||||
*/ |
||||
typedef enum eTxEventType |
||||
{ |
||||
/*!
|
||||
* @brief AppdataTransmition issue based on timer every TxDutyCycleTime |
||||
*/ |
||||
TX_ON_TIMER, |
||||
/*!
|
||||
* @brief AppdataTransmition external event plugged on OnSendEvent( ) |
||||
*/ |
||||
TX_ON_EVENT |
||||
} TxEventType_t; |
||||
|
||||
|
||||
/*!
|
||||
* LoRa State Machine states
|
||||
*/ |
||||
typedef struct sLoRaParam |
||||
{ |
||||
/*!
|
||||
* @brief Event type |
||||
* |
||||
* @retval value battery level ( 0: very low, 254: fully charged ) |
||||
*/ |
||||
TxEventType_t TxEvent; |
||||
/*!
|
||||
* @brief Application data transmission duty cycle in ms |
||||
* |
||||
* @note when TX_ON_TIMER Event type is selected |
||||
*/ |
||||
uint32_t TxDutyCycleTime; |
||||
/*!
|
||||
* @brief LoRaWAN device class |
||||
*/ |
||||
DeviceClass_t Class; |
||||
/*!
|
||||
* @brief Activation state of adaptativeDatarate |
||||
*/ |
||||
bool AdrEnable; |
||||
/*!
|
||||
* @brief Uplink datarate, if AdrEnable is off |
||||
*/ |
||||
int8_t TxDatarate; |
||||
/*!
|
||||
* @brief Enable or disable a public network |
||||
* |
||||
*/ |
||||
bool EnablePublicNetwork; |
||||
/*!
|
||||
* @brief Number of trials for the join request. |
||||
*/ |
||||
uint8_t NbTrials; |
||||
|
||||
} LoRaParam_t; |
||||
|
||||
/* Lora Main callbacks*/ |
||||
typedef struct sLoRaMainCallback |
||||
{ |
||||
/*!
|
||||
* @brief Get the current battery level |
||||
* |
||||
* @retval value battery level ( 0: very low, 254: fully charged ) |
||||
*/ |
||||
uint8_t ( *BoardGetBatteryLevel )( void ); |
||||
|
||||
/*!
|
||||
* @brief Gets the board 64 bits unique ID
|
||||
* |
||||
* @param [IN] id Pointer to an array that will contain the Unique ID |
||||
*/ |
||||
void ( *BoardGetUniqueId ) ( uint8_t *id); |
||||
/*!
|
||||
* Returns a pseudo random seed generated using the MCU Unique ID |
||||
* |
||||
* @retval seed Generated pseudo random seed |
||||
*/ |
||||
uint32_t ( *BoardGetRandomSeed ) (void); |
||||
/*!
|
||||
* @brief Prepares Tx Data to be sent on Lora network
|
||||
* |
||||
* @param [IN] AppData is a buffer to fill |
||||
* |
||||
* @param [IN] port is a Application port on wicth Appdata will be sent |
||||
* |
||||
* @param [IN] length of the AppDataBuffer to send |
||||
* |
||||
* @param [IN] requests a confirmed Frame from the Network |
||||
*/ |
||||
void ( *LoraTxData ) ( lora_AppData_t *AppData, FunctionalState* IsTxConfirmed); |
||||
/*!
|
||||
* @brief Process Rx Data received from Lora network
|
||||
* |
||||
* @param [IN] AppData is a buffer to process |
||||
* |
||||
* @param [IN] port is a Application port on wicth Appdata will be sent |
||||
* |
||||
* @param [IN] length is the number of recieved bytes |
||||
*/ |
||||
void ( *LoraRxData ) ( lora_AppData_t *AppData); |
||||
|
||||
} LoRaMainCallback_t; |
||||
|
||||
|
||||
|
||||
/* External variables --------------------------------------------------------*/ |
||||
/* Exported macros -----------------------------------------------------------*/ |
||||
/* Exported functions ------------------------------------------------------- */
|
||||
/**
|
||||
* @brief Lora Initialisation |
||||
* @param [IN] LoRaMainCallback_t |
||||
* @param [IN] application parmaters |
||||
* @retval none |
||||
*/ |
||||
void lora_Init (LoRaMainCallback_t *callbacks, LoRaParam_t* LoRaParam ); |
||||
|
||||
/**
|
||||
* @brief run Lora classA state Machine
|
||||
* @param [IN] none |
||||
* @retval none |
||||
*/ |
||||
void lora_fsm( void ); |
||||
|
||||
/**
|
||||
* @brief functionl requesting loRa state machine to send data
|
||||
* @note function to link in mode TX_ON_EVENT
|
||||
* @param none |
||||
* @retval none |
||||
*/ |
||||
void OnSendEvent( void ); |
||||
|
||||
|
||||
/**
|
||||
* @brief API returns the state of the lora state machine |
||||
* @note return @DeviceState_t state |
||||
* @param [IN] none |
||||
* @retval return @FlagStatus |
||||
*/ |
||||
DeviceState_t lora_getDeviceState( void ); |
||||
|
||||
#ifdef __cplusplus |
||||
} |
||||
#endif |
||||
|
||||
#endif /*__LORA_MAIN_H__*/ |
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
@ -0,0 +1,88 @@ |
||||
/*
|
||||
/ _____) _ | | |
||||
( (____ _____ ____ _| |_ _____ ____| |__ |
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | | |
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_| |
||||
(C)2013 Semtech |
||||
|
||||
Description: LoRaMac classA device implementation |
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project |
||||
|
||||
Maintainer: Miguel Luis, Gregory Cristian and Wael Guibene |
||||
*/ |
||||
/******************************************************************************
|
||||
* @file lora_mac_version.h |
||||
* @author MCD Application Team |
||||
* @version V1.1.2 |
||||
* @date 08-September-2017 |
||||
* @brief defines the lora mac version |
||||
****************************************************************************** |
||||
* @attention |
||||
* |
||||
* <h2><center>© Copyright (c) 2017 STMicroelectronics International N.V.
|
||||
* All rights reserved.</center></h2> |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted, provided that the following conditions are met: |
||||
* |
||||
* 1. Redistribution of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer. |
||||
* 2. 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. |
||||
* 3. Neither the name of STMicroelectronics nor the names of other
|
||||
* contributors to this software may be used to endorse or promote products
|
||||
* derived from this software without specific written permission. |
||||
* 4. This software, including modifications and/or derivative works of this
|
||||
* software, must execute solely and exclusively on microcontroller or |
||||
* microprocessor devices manufactured by or for STMicroelectronics. |
||||
* 5. Redistribution and use of this software other than as permitted under
|
||||
* this license is void and will automatically terminate your rights under
|
||||
* this license.
|
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
* PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY |
||||
* RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT
|
||||
* SHALL STMICROELECTRONICS OR CONTRIBUTORS 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. |
||||
* |
||||
****************************************************************************** |
||||
*/ |
||||
/* Define to prevent recursive inclusion -------------------------------------*/ |
||||
|
||||
#ifndef __LORA_MAC_VERSION_H__ |
||||
#define __LORA_MAC_VERSION_H__ |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
/* Includes ------------------------------------------------------------------*/ |
||||
/* Exported constants --------------------------------------------------------*/ |
||||
|
||||
/*the 3 MSBs define the version based on Github version */ |
||||
/*https://github.com/Lora-net/LoRaMac-node/wiki/LoRaMAC-node-Wiki*/ |
||||
/* version 4.4.0 from develop branch */ |
||||
#define LORA_MAC_VERSION (uint32_t) 0x44030000 |
||||
|
||||
/* Exported types ------------------------------------------------------------*/ |
||||
/* External variables --------------------------------------------------------*/ |
||||
/* Exported macros -----------------------------------------------------------*/ |
||||
/* Exported functions ------------------------------------------------------- */
|
||||
|
||||
#ifdef __cplusplus |
||||
} |
||||
#endif |
||||
|
||||
#endif /*__LORA_MAC_VERSION_H__*/ |
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
@ -0,0 +1,936 @@ |
||||
/*
|
||||
--------------------------------------------------------------------------- |
||||
Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved. |
||||
|
||||
LICENSE TERMS |
||||
|
||||
The redistribution and use of this software (with or without changes) |
||||
is allowed without the payment of fees or royalties provided that: |
||||
|
||||
1. source code distributions include the above copyright notice, this |
||||
list of conditions and the following disclaimer; |
||||
|
||||
2. binary distributions include the above copyright notice, this list |
||||
of conditions and the following disclaimer in their documentation; |
||||
|
||||
3. the name of the copyright holder is not used to endorse products |
||||
built using this software without specific written permission. |
||||
|
||||
DISCLAIMER |
||||
|
||||
This software is provided 'as is' with no explicit or implied warranties |
||||
in respect of its properties, including, but not limited to, correctness |
||||
and/or fitness for purpose. |
||||
--------------------------------------------------------------------------- |
||||
Issue 09/09/2006 |
||||
|
||||
This is an AES implementation that uses only 8-bit byte operations on the |
||||
cipher state (there are options to use 32-bit types if available). |
||||
|
||||
The combination of mix columns and byte substitution used here is based on |
||||
that developed by Karl Malbrain. His contribution is acknowledged. |
||||
*/ |
||||
|
||||
/* define if you have a fast memcpy function on your system */ |
||||
#if 0 |
||||
# define HAVE_MEMCPY |
||||
# include <string.h> |
||||
# if defined( _MSC_VER ) |
||||
# include <intrin.h> |
||||
# pragma intrinsic( memcpy ) |
||||
# endif |
||||
#endif |
||||
|
||||
|
||||
#include <stdlib.h> |
||||
#include <stdint.h> |
||||
|
||||
/* define if you have fast 32-bit types on your system */ |
||||
#if 0 |
||||
# define HAVE_UINT_32T |
||||
#endif |
||||
|
||||
/* define if you don't want any tables */ |
||||
#if 1 |
||||
# define USE_TABLES |
||||
#endif |
||||
|
||||
/* On Intel Core 2 duo VERSION_1 is faster */ |
||||
|
||||
/* alternative versions (test for performance on your system) */ |
||||
#if 1 |
||||
# define VERSION_1 |
||||
#endif |
||||
|
||||
#include "aes.h" |
||||
|
||||
//#if defined( HAVE_UINT_32T )
|
||||
// typedef unsigned long uint32_t;
|
||||
//#endif
|
||||
|
||||
/* functions for finite field multiplication in the AES Galois field */ |
||||
|
||||
#define WPOLY 0x011b |
||||
#define BPOLY 0x1b |
||||
#define DPOLY 0x008d |
||||
|
||||
#define f1(x) (x) |
||||
#define f2(x) ((x << 1) ^ (((x >> 7) & 1) * WPOLY)) |
||||
#define f4(x) ((x << 2) ^ (((x >> 6) & 1) * WPOLY) ^ (((x >> 6) & 2) * WPOLY)) |
||||
#define f8(x) ((x << 3) ^ (((x >> 5) & 1) * WPOLY) ^ (((x >> 5) & 2) * WPOLY) \ |
||||
^ (((x >> 5) & 4) * WPOLY)) |
||||
#define d2(x) (((x) >> 1) ^ ((x) & 1 ? DPOLY : 0)) |
||||
|
||||
#define f3(x) (f2(x) ^ x) |
||||
#define f9(x) (f8(x) ^ x) |
||||
#define fb(x) (f8(x) ^ f2(x) ^ x) |
||||
#define fd(x) (f8(x) ^ f4(x) ^ x) |
||||
#define fe(x) (f8(x) ^ f4(x) ^ f2(x)) |
||||
|
||||
#if defined( USE_TABLES ) |
||||
|
||||
#define sb_data(w) { /* S Box data values */ \ |
||||
w(0x63), w(0x7c), w(0x77), w(0x7b), w(0xf2), w(0x6b), w(0x6f), w(0xc5),\
|
||||
w(0x30), w(0x01), w(0x67), w(0x2b), w(0xfe), w(0xd7), w(0xab), w(0x76),\
|
||||
w(0xca), w(0x82), w(0xc9), w(0x7d), w(0xfa), w(0x59), w(0x47), w(0xf0),\
|
||||
w(0xad), w(0xd4), w(0xa2), w(0xaf), w(0x9c), w(0xa4), w(0x72), w(0xc0),\
|
||||
w(0xb7), w(0xfd), w(0x93), w(0x26), w(0x36), w(0x3f), w(0xf7), w(0xcc),\
|
||||
w(0x34), w(0xa5), w(0xe5), w(0xf1), w(0x71), w(0xd8), w(0x31), w(0x15),\
|
||||
w(0x04), w(0xc7), w(0x23), w(0xc3), w(0x18), w(0x96), w(0x05), w(0x9a),\
|
||||
w(0x07), w(0x12), w(0x80), w(0xe2), w(0xeb), w(0x27), w(0xb2), w(0x75),\
|
||||
w(0x09), w(0x83), w(0x2c), w(0x1a), w(0x1b), w(0x6e), w(0x5a), w(0xa0),\
|
||||
w(0x52), w(0x3b), w(0xd6), w(0xb3), w(0x29), w(0xe3), w(0x2f), w(0x84),\
|
||||
w(0x53), w(0xd1), w(0x00), w(0xed), w(0x20), w(0xfc), w(0xb1), w(0x5b),\
|
||||
w(0x6a), w(0xcb), w(0xbe), w(0x39), w(0x4a), w(0x4c), w(0x58), w(0xcf),\
|
||||
w(0xd0), w(0xef), w(0xaa), w(0xfb), w(0x43), w(0x4d), w(0x33), w(0x85),\
|
||||
w(0x45), w(0xf9), w(0x02), w(0x7f), w(0x50), w(0x3c), w(0x9f), w(0xa8),\
|
||||
w(0x51), w(0xa3), w(0x40), w(0x8f), w(0x92), w(0x9d), w(0x38), w(0xf5),\
|
||||
w(0xbc), w(0xb6), w(0xda), w(0x21), w(0x10), w(0xff), w(0xf3), w(0xd2),\
|
||||
w(0xcd), w(0x0c), w(0x13), w(0xec), w(0x5f), w(0x97), w(0x44), w(0x17),\
|
||||
w(0xc4), w(0xa7), w(0x7e), w(0x3d), w(0x64), w(0x5d), w(0x19), w(0x73),\
|
||||
w(0x60), w(0x81), w(0x4f), w(0xdc), w(0x22), w(0x2a), w(0x90), w(0x88),\
|
||||
w(0x46), w(0xee), w(0xb8), w(0x14), w(0xde), w(0x5e), w(0x0b), w(0xdb),\
|
||||
w(0xe0), w(0x32), w(0x3a), w(0x0a), w(0x49), w(0x06), w(0x24), w(0x5c),\
|
||||
w(0xc2), w(0xd3), w(0xac), w(0x62), w(0x91), w(0x95), w(0xe4), w(0x79),\
|
||||
w(0xe7), w(0xc8), w(0x37), w(0x6d), w(0x8d), w(0xd5), w(0x4e), w(0xa9),\
|
||||
w(0x6c), w(0x56), w(0xf4), w(0xea), w(0x65), w(0x7a), w(0xae), w(0x08),\
|
||||
w(0xba), w(0x78), w(0x25), w(0x2e), w(0x1c), w(0xa6), w(0xb4), w(0xc6),\
|
||||
w(0xe8), w(0xdd), w(0x74), w(0x1f), w(0x4b), w(0xbd), w(0x8b), w(0x8a),\
|
||||
w(0x70), w(0x3e), w(0xb5), w(0x66), w(0x48), w(0x03), w(0xf6), w(0x0e),\
|
||||
w(0x61), w(0x35), w(0x57), w(0xb9), w(0x86), w(0xc1), w(0x1d), w(0x9e),\
|
||||
w(0xe1), w(0xf8), w(0x98), w(0x11), w(0x69), w(0xd9), w(0x8e), w(0x94),\
|
||||
w(0x9b), w(0x1e), w(0x87), w(0xe9), w(0xce), w(0x55), w(0x28), w(0xdf),\
|
||||
w(0x8c), w(0xa1), w(0x89), w(0x0d), w(0xbf), w(0xe6), w(0x42), w(0x68),\
|
||||
w(0x41), w(0x99), w(0x2d), w(0x0f), w(0xb0), w(0x54), w(0xbb), w(0x16) } |
||||
|
||||
#define isb_data(w) { /* inverse S Box data values */ \ |
||||
w(0x52), w(0x09), w(0x6a), w(0xd5), w(0x30), w(0x36), w(0xa5), w(0x38),\
|
||||
w(0xbf), w(0x40), w(0xa3), w(0x9e), w(0x81), w(0xf3), w(0xd7), w(0xfb),\
|
||||
w(0x7c), w(0xe3), w(0x39), w(0x82), w(0x9b), w(0x2f), w(0xff), w(0x87),\
|
||||
w(0x34), w(0x8e), w(0x43), w(0x44), w(0xc4), w(0xde), w(0xe9), w(0xcb),\
|
||||
w(0x54), w(0x7b), w(0x94), w(0x32), w(0xa6), w(0xc2), w(0x23), w(0x3d),\
|
||||
w(0xee), w(0x4c), w(0x95), w(0x0b), w(0x42), w(0xfa), w(0xc3), w(0x4e),\
|
||||
w(0x08), w(0x2e), w(0xa1), w(0x66), w(0x28), w(0xd9), w(0x24), w(0xb2),\
|
||||
w(0x76), w(0x5b), w(0xa2), w(0x49), w(0x6d), w(0x8b), w(0xd1), w(0x25),\
|
||||
w(0x72), w(0xf8), w(0xf6), w(0x64), w(0x86), w(0x68), w(0x98), w(0x16),\
|
||||
w(0xd4), w(0xa4), w(0x5c), w(0xcc), w(0x5d), w(0x65), w(0xb6), w(0x92),\
|
||||
w(0x6c), w(0x70), w(0x48), w(0x50), w(0xfd), w(0xed), w(0xb9), w(0xda),\
|
||||
w(0x5e), w(0x15), w(0x46), w(0x57), w(0xa7), w(0x8d), w(0x9d), w(0x84),\
|
||||
w(0x90), w(0xd8), w(0xab), w(0x00), w(0x8c), w(0xbc), w(0xd3), w(0x0a),\
|
||||
w(0xf7), w(0xe4), w(0x58), w(0x05), w(0xb8), w(0xb3), w(0x45), w(0x06),\
|
||||
w(0xd0), w(0x2c), w(0x1e), w(0x8f), w(0xca), w(0x3f), w(0x0f), w(0x02),\
|
||||
w(0xc1), w(0xaf), w(0xbd), w(0x03), w(0x01), w(0x13), w(0x8a), w(0x6b),\
|
||||
w(0x3a), w(0x91), w(0x11), w(0x41), w(0x4f), w(0x67), w(0xdc), w(0xea),\
|
||||
w(0x97), w(0xf2), w(0xcf), w(0xce), w(0xf0), w(0xb4), w(0xe6), w(0x73),\
|
||||
w(0x96), w(0xac), w(0x74), w(0x22), w(0xe7), w(0xad), w(0x35), w(0x85),\
|
||||
w(0xe2), w(0xf9), w(0x37), w(0xe8), w(0x1c), w(0x75), w(0xdf), w(0x6e),\
|
||||
w(0x47), w(0xf1), w(0x1a), w(0x71), w(0x1d), w(0x29), w(0xc5), w(0x89),\
|
||||
w(0x6f), w(0xb7), w(0x62), w(0x0e), w(0xaa), w(0x18), w(0xbe), w(0x1b),\
|
||||
w(0xfc), w(0x56), w(0x3e), w(0x4b), w(0xc6), w(0xd2), w(0x79), w(0x20),\
|
||||
w(0x9a), w(0xdb), w(0xc0), w(0xfe), w(0x78), w(0xcd), w(0x5a), w(0xf4),\
|
||||
w(0x1f), w(0xdd), w(0xa8), w(0x33), w(0x88), w(0x07), w(0xc7), w(0x31),\
|
||||
w(0xb1), w(0x12), w(0x10), w(0x59), w(0x27), w(0x80), w(0xec), w(0x5f),\
|
||||
w(0x60), w(0x51), w(0x7f), w(0xa9), w(0x19), w(0xb5), w(0x4a), w(0x0d),\
|
||||
w(0x2d), w(0xe5), w(0x7a), w(0x9f), w(0x93), w(0xc9), w(0x9c), w(0xef),\
|
||||
w(0xa0), w(0xe0), w(0x3b), w(0x4d), w(0xae), w(0x2a), w(0xf5), w(0xb0),\
|
||||
w(0xc8), w(0xeb), w(0xbb), w(0x3c), w(0x83), w(0x53), w(0x99), w(0x61),\
|
||||
w(0x17), w(0x2b), w(0x04), w(0x7e), w(0xba), w(0x77), w(0xd6), w(0x26),\
|
||||
w(0xe1), w(0x69), w(0x14), w(0x63), w(0x55), w(0x21), w(0x0c), w(0x7d) } |
||||
|
||||
#define mm_data(w) { /* basic data for forming finite field tables */ \ |
||||
w(0x00), w(0x01), w(0x02), w(0x03), w(0x04), w(0x05), w(0x06), w(0x07),\
|
||||
w(0x08), w(0x09), w(0x0a), w(0x0b), w(0x0c), w(0x0d), w(0x0e), w(0x0f),\
|
||||
w(0x10), w(0x11), w(0x12), w(0x13), w(0x14), w(0x15), w(0x16), w(0x17),\
|
||||
w(0x18), w(0x19), w(0x1a), w(0x1b), w(0x1c), w(0x1d), w(0x1e), w(0x1f),\
|
||||
w(0x20), w(0x21), w(0x22), w(0x23), w(0x24), w(0x25), w(0x26), w(0x27),\
|
||||
w(0x28), w(0x29), w(0x2a), w(0x2b), w(0x2c), w(0x2d), w(0x2e), w(0x2f),\
|
||||
w(0x30), w(0x31), w(0x32), w(0x33), w(0x34), w(0x35), w(0x36), w(0x37),\
|
||||
w(0x38), w(0x39), w(0x3a), w(0x3b), w(0x3c), w(0x3d), w(0x3e), w(0x3f),\
|
||||
w(0x40), w(0x41), w(0x42), w(0x43), w(0x44), w(0x45), w(0x46), w(0x47),\
|
||||
w(0x48), w(0x49), w(0x4a), w(0x4b), w(0x4c), w(0x4d), w(0x4e), w(0x4f),\
|
||||
w(0x50), w(0x51), w(0x52), w(0x53), w(0x54), w(0x55), w(0x56), w(0x57),\
|
||||
w(0x58), w(0x59), w(0x5a), w(0x5b), w(0x5c), w(0x5d), w(0x5e), w(0x5f),\
|
||||
w(0x60), w(0x61), w(0x62), w(0x63), w(0x64), w(0x65), w(0x66), w(0x67),\
|
||||
w(0x68), w(0x69), w(0x6a), w(0x6b), w(0x6c), w(0x6d), w(0x6e), w(0x6f),\
|
||||
w(0x70), w(0x71), w(0x72), w(0x73), w(0x74), w(0x75), w(0x76), w(0x77),\
|
||||
w(0x78), w(0x79), w(0x7a), w(0x7b), w(0x7c), w(0x7d), w(0x7e), w(0x7f),\
|
||||
w(0x80), w(0x81), w(0x82), w(0x83), w(0x84), w(0x85), w(0x86), w(0x87),\
|
||||
w(0x88), w(0x89), w(0x8a), w(0x8b), w(0x8c), w(0x8d), w(0x8e), w(0x8f),\
|
||||
w(0x90), w(0x91), w(0x92), w(0x93), w(0x94), w(0x95), w(0x96), w(0x97),\
|
||||
w(0x98), w(0x99), w(0x9a), w(0x9b), w(0x9c), w(0x9d), w(0x9e), w(0x9f),\
|
||||
w(0xa0), w(0xa1), w(0xa2), w(0xa3), w(0xa4), w(0xa5), w(0xa6), w(0xa7),\
|
||||
w(0xa8), w(0xa9), w(0xaa), w(0xab), w(0xac), w(0xad), w(0xae), w(0xaf),\
|
||||
w(0xb0), w(0xb1), w(0xb2), w(0xb3), w(0xb4), w(0xb5), w(0xb6), w(0xb7),\
|
||||
w(0xb8), w(0xb9), w(0xba), w(0xbb), w(0xbc), w(0xbd), w(0xbe), w(0xbf),\
|
||||
w(0xc0), w(0xc1), w(0xc2), w(0xc3), w(0xc4), w(0xc5), w(0xc6), w(0xc7),\
|
||||
w(0xc8), w(0xc9), w(0xca), w(0xcb), w(0xcc), w(0xcd), w(0xce), w(0xcf),\
|
||||
w(0xd0), w(0xd1), w(0xd2), w(0xd3), w(0xd4), w(0xd5), w(0xd6), w(0xd7),\
|
||||
w(0xd8), w(0xd9), w(0xda), w(0xdb), w(0xdc), w(0xdd), w(0xde), w(0xdf),\
|
||||
w(0xe0), w(0xe1), w(0xe2), w(0xe3), w(0xe4), w(0xe5), w(0xe6), w(0xe7),\
|
||||
w(0xe8), w(0xe9), w(0xea), w(0xeb), w(0xec), w(0xed), w(0xee), w(0xef),\
|
||||
w(0xf0), w(0xf1), w(0xf2), w(0xf3), w(0xf4), w(0xf5), w(0xf6), w(0xf7),\
|
||||
w(0xf8), w(0xf9), w(0xfa), w(0xfb), w(0xfc), w(0xfd), w(0xfe), w(0xff) } |
||||
|
||||
static const uint8_t sbox[256] = sb_data(f1); |
||||
|
||||
#if defined( AES_DEC_PREKEYED ) |
||||
static const uint8_t isbox[256] = isb_data(f1); |
||||
#endif |
||||
|
||||
static const uint8_t gfm2_sbox[256] = sb_data(f2); |
||||
static const uint8_t gfm3_sbox[256] = sb_data(f3); |
||||
|
||||
#if defined( AES_DEC_PREKEYED ) |
||||
static const uint8_t gfmul_9[256] = mm_data(f9); |
||||
static const uint8_t gfmul_b[256] = mm_data(fb); |
||||
static const uint8_t gfmul_d[256] = mm_data(fd); |
||||
static const uint8_t gfmul_e[256] = mm_data(fe); |
||||
#endif |
||||
|
||||
#define s_box(x) sbox[(x)] |
||||
#if defined( AES_DEC_PREKEYED ) |
||||
#define is_box(x) isbox[(x)] |
||||
#endif |
||||
#define gfm2_sb(x) gfm2_sbox[(x)] |
||||
#define gfm3_sb(x) gfm3_sbox[(x)] |
||||
#if defined( AES_DEC_PREKEYED ) |
||||
#define gfm_9(x) gfmul_9[(x)] |
||||
#define gfm_b(x) gfmul_b[(x)] |
||||
#define gfm_d(x) gfmul_d[(x)] |
||||
#define gfm_e(x) gfmul_e[(x)] |
||||
#endif |
||||
#else |
||||
|
||||
/* this is the high bit of x right shifted by 1 */ |
||||
/* position. Since the starting polynomial has */ |
||||
/* 9 bits (0x11b), this right shift keeps the */ |
||||
/* values of all top bits within a byte */ |
||||
|
||||
static uint8_t hibit(const uint8_t x) |
||||
{ uint8_t r = (uint8_t)((x >> 1) | (x >> 2)); |
||||
|
||||
r |= (r >> 2); |
||||
r |= (r >> 4); |
||||
return (r + 1) >> 1; |
||||
} |
||||
|
||||
/* return the inverse of the finite field element x */ |
||||
|
||||
static uint8_t gf_inv(const uint8_t x) |
||||
{ uint8_t p1 = x, p2 = BPOLY, n1 = hibit(x), n2 = 0x80, v1 = 1, v2 = 0; |
||||
|
||||
if(x < 2) |
||||
return x; |
||||
|
||||
for( ; ; ) |
||||
{ |
||||
if(n1) |
||||
while(n2 >= n1) /* divide polynomial p2 by p1 */ |
||||
{ |
||||
n2 /= n1; /* shift smaller polynomial left */ |
||||
p2 ^= (p1 * n2) & 0xff; /* and remove from larger one */ |
||||
v2 ^= (v1 * n2); /* shift accumulated value and */ |
||||
n2 = hibit(p2); /* add into result */ |
||||
} |
||||
else |
||||
return v1; |
||||
|
||||
if(n2) /* repeat with values swapped */ |
||||
while(n1 >= n2) |
||||
{ |
||||
n1 /= n2; |
||||
p1 ^= p2 * n1; |
||||
v1 ^= v2 * n1; |
||||
n1 = hibit(p1); |
||||
} |
||||
else |
||||
return v2; |
||||
} |
||||
} |
||||
|
||||
/* The forward and inverse affine transformations used in the S-box */ |
||||
uint8_t fwd_affine(const uint8_t x) |
||||
{ |
||||
#if defined( HAVE_UINT_32T ) |
||||
uint32_t w = x; |
||||
w ^= (w << 1) ^ (w << 2) ^ (w << 3) ^ (w << 4); |
||||
return 0x63 ^ ((w ^ (w >> 8)) & 0xff); |
||||
#else |
||||
return 0x63 ^ x ^ (x << 1) ^ (x << 2) ^ (x << 3) ^ (x << 4) |
||||
^ (x >> 7) ^ (x >> 6) ^ (x >> 5) ^ (x >> 4); |
||||
#endif |
||||
} |
||||
|
||||
uint8_t inv_affine(const uint8_t x) |
||||
{ |
||||
#if defined( HAVE_UINT_32T ) |
||||
uint32_t w = x; |
||||
w = (w << 1) ^ (w << 3) ^ (w << 6); |
||||
return 0x05 ^ ((w ^ (w >> 8)) & 0xff); |
||||
#else |
||||
return 0x05 ^ (x << 1) ^ (x << 3) ^ (x << 6) |
||||
^ (x >> 7) ^ (x >> 5) ^ (x >> 2); |
||||
#endif |
||||
} |
||||
|
||||
#define s_box(x) fwd_affine(gf_inv(x)) |
||||
#define is_box(x) gf_inv(inv_affine(x)) |
||||
#define gfm2_sb(x) f2(s_box(x)) |
||||
#define gfm3_sb(x) f3(s_box(x)) |
||||
#define gfm_9(x) f9(x) |
||||
#define gfm_b(x) fb(x) |
||||
#define gfm_d(x) fd(x) |
||||
#define gfm_e(x) fe(x) |
||||
|
||||
#endif |
||||
|
||||
#if defined( HAVE_MEMCPY ) |
||||
# define block_copy_nn(d, s, l) memcpy(d, s, l) |
||||
# define block_copy(d, s) memcpy(d, s, N_BLOCK) |
||||
#else |
||||
# define block_copy_nn(d, s, l) copy_block_nn(d, s, l) |
||||
# define block_copy(d, s) copy_block(d, s) |
||||
#endif |
||||
|
||||
static void copy_block( void *d, const void *s ) |
||||
{ |
||||
#if defined( HAVE_UINT_32T ) |
||||
((uint32_t*)d)[ 0] = ((uint32_t*)s)[ 0]; |
||||
((uint32_t*)d)[ 1] = ((uint32_t*)s)[ 1]; |
||||
((uint32_t*)d)[ 2] = ((uint32_t*)s)[ 2]; |
||||
((uint32_t*)d)[ 3] = ((uint32_t*)s)[ 3]; |
||||
#else |
||||
((uint8_t*)d)[ 0] = ((uint8_t*)s)[ 0]; |
||||
((uint8_t*)d)[ 1] = ((uint8_t*)s)[ 1]; |
||||
((uint8_t*)d)[ 2] = ((uint8_t*)s)[ 2]; |
||||
((uint8_t*)d)[ 3] = ((uint8_t*)s)[ 3]; |
||||
((uint8_t*)d)[ 4] = ((uint8_t*)s)[ 4]; |
||||
((uint8_t*)d)[ 5] = ((uint8_t*)s)[ 5]; |
||||
((uint8_t*)d)[ 6] = ((uint8_t*)s)[ 6]; |
||||
((uint8_t*)d)[ 7] = ((uint8_t*)s)[ 7]; |
||||
((uint8_t*)d)[ 8] = ((uint8_t*)s)[ 8]; |
||||
((uint8_t*)d)[ 9] = ((uint8_t*)s)[ 9]; |
||||
((uint8_t*)d)[10] = ((uint8_t*)s)[10]; |
||||
((uint8_t*)d)[11] = ((uint8_t*)s)[11]; |
||||
((uint8_t*)d)[12] = ((uint8_t*)s)[12]; |
||||
((uint8_t*)d)[13] = ((uint8_t*)s)[13]; |
||||
((uint8_t*)d)[14] = ((uint8_t*)s)[14]; |
||||
((uint8_t*)d)[15] = ((uint8_t*)s)[15]; |
||||
#endif |
||||
} |
||||
|
||||
static void copy_block_nn( uint8_t * d, const uint8_t *s, uint8_t nn ) |
||||
{ |
||||
while( nn-- ) |
||||
//*((uint8_t*)d)++ = *((uint8_t*)s)++;
|
||||
*d++ = *s++; |
||||
} |
||||
|
||||
static void xor_block( void *d, const void *s ) |
||||
{ |
||||
#if defined( HAVE_UINT_32T ) |
||||
((uint32_t*)d)[ 0] ^= ((uint32_t*)s)[ 0]; |
||||
((uint32_t*)d)[ 1] ^= ((uint32_t*)s)[ 1]; |
||||
((uint32_t*)d)[ 2] ^= ((uint32_t*)s)[ 2]; |
||||
((uint32_t*)d)[ 3] ^= ((uint32_t*)s)[ 3]; |
||||
#else |
||||
((uint8_t*)d)[ 0] ^= ((uint8_t*)s)[ 0]; |
||||
((uint8_t*)d)[ 1] ^= ((uint8_t*)s)[ 1]; |
||||
((uint8_t*)d)[ 2] ^= ((uint8_t*)s)[ 2]; |
||||
((uint8_t*)d)[ 3] ^= ((uint8_t*)s)[ 3]; |
||||
((uint8_t*)d)[ 4] ^= ((uint8_t*)s)[ 4]; |
||||
((uint8_t*)d)[ 5] ^= ((uint8_t*)s)[ 5]; |
||||
((uint8_t*)d)[ 6] ^= ((uint8_t*)s)[ 6]; |
||||
((uint8_t*)d)[ 7] ^= ((uint8_t*)s)[ 7]; |
||||
((uint8_t*)d)[ 8] ^= ((uint8_t*)s)[ 8]; |
||||
((uint8_t*)d)[ 9] ^= ((uint8_t*)s)[ 9]; |
||||
((uint8_t*)d)[10] ^= ((uint8_t*)s)[10]; |
||||
((uint8_t*)d)[11] ^= ((uint8_t*)s)[11]; |
||||
((uint8_t*)d)[12] ^= ((uint8_t*)s)[12]; |
||||
((uint8_t*)d)[13] ^= ((uint8_t*)s)[13]; |
||||
((uint8_t*)d)[14] ^= ((uint8_t*)s)[14]; |
||||
((uint8_t*)d)[15] ^= ((uint8_t*)s)[15]; |
||||
#endif |
||||
} |
||||
|
||||
static void copy_and_key( void *d, const void *s, const void *k ) |
||||
{ |
||||
#if defined( HAVE_UINT_32T ) |
||||
((uint32_t*)d)[ 0] = ((uint32_t*)s)[ 0] ^ ((uint32_t*)k)[ 0]; |
||||
((uint32_t*)d)[ 1] = ((uint32_t*)s)[ 1] ^ ((uint32_t*)k)[ 1]; |
||||
((uint32_t*)d)[ 2] = ((uint32_t*)s)[ 2] ^ ((uint32_t*)k)[ 2]; |
||||
((uint32_t*)d)[ 3] = ((uint32_t*)s)[ 3] ^ ((uint32_t*)k)[ 3]; |
||||
#elif 1 |
||||
((uint8_t*)d)[ 0] = ((uint8_t*)s)[ 0] ^ ((uint8_t*)k)[ 0]; |
||||
((uint8_t*)d)[ 1] = ((uint8_t*)s)[ 1] ^ ((uint8_t*)k)[ 1]; |
||||
((uint8_t*)d)[ 2] = ((uint8_t*)s)[ 2] ^ ((uint8_t*)k)[ 2]; |
||||
((uint8_t*)d)[ 3] = ((uint8_t*)s)[ 3] ^ ((uint8_t*)k)[ 3]; |
||||
((uint8_t*)d)[ 4] = ((uint8_t*)s)[ 4] ^ ((uint8_t*)k)[ 4]; |
||||
((uint8_t*)d)[ 5] = ((uint8_t*)s)[ 5] ^ ((uint8_t*)k)[ 5]; |
||||
((uint8_t*)d)[ 6] = ((uint8_t*)s)[ 6] ^ ((uint8_t*)k)[ 6]; |
||||
((uint8_t*)d)[ 7] = ((uint8_t*)s)[ 7] ^ ((uint8_t*)k)[ 7]; |
||||
((uint8_t*)d)[ 8] = ((uint8_t*)s)[ 8] ^ ((uint8_t*)k)[ 8]; |
||||
((uint8_t*)d)[ 9] = ((uint8_t*)s)[ 9] ^ ((uint8_t*)k)[ 9]; |
||||
((uint8_t*)d)[10] = ((uint8_t*)s)[10] ^ ((uint8_t*)k)[10]; |
||||
((uint8_t*)d)[11] = ((uint8_t*)s)[11] ^ ((uint8_t*)k)[11]; |
||||
((uint8_t*)d)[12] = ((uint8_t*)s)[12] ^ ((uint8_t*)k)[12]; |
||||
((uint8_t*)d)[13] = ((uint8_t*)s)[13] ^ ((uint8_t*)k)[13]; |
||||
((uint8_t*)d)[14] = ((uint8_t*)s)[14] ^ ((uint8_t*)k)[14]; |
||||
((uint8_t*)d)[15] = ((uint8_t*)s)[15] ^ ((uint8_t*)k)[15]; |
||||
#else |
||||
block_copy(d, s); |
||||
xor_block(d, k); |
||||
#endif |
||||
} |
||||
|
||||
static void add_round_key( uint8_t d[N_BLOCK], const uint8_t k[N_BLOCK] ) |
||||
{ |
||||
xor_block(d, k); |
||||
} |
||||
|
||||
static void shift_sub_rows( uint8_t st[N_BLOCK] ) |
||||
{ uint8_t tt; |
||||
|
||||
st[ 0] = s_box(st[ 0]); st[ 4] = s_box(st[ 4]); |
||||
st[ 8] = s_box(st[ 8]); st[12] = s_box(st[12]); |
||||
|
||||
tt = st[1]; st[ 1] = s_box(st[ 5]); st[ 5] = s_box(st[ 9]); |
||||
st[ 9] = s_box(st[13]); st[13] = s_box( tt ); |
||||
|
||||
tt = st[2]; st[ 2] = s_box(st[10]); st[10] = s_box( tt ); |
||||
tt = st[6]; st[ 6] = s_box(st[14]); st[14] = s_box( tt ); |
||||
|
||||
tt = st[15]; st[15] = s_box(st[11]); st[11] = s_box(st[ 7]); |
||||
st[ 7] = s_box(st[ 3]); st[ 3] = s_box( tt ); |
||||
} |
||||
|
||||
#if defined( AES_DEC_PREKEYED ) |
||||
|
||||
static void inv_shift_sub_rows( uint8_t st[N_BLOCK] ) |
||||
{ uint8_t tt; |
||||
|
||||
st[ 0] = is_box(st[ 0]); st[ 4] = is_box(st[ 4]); |
||||
st[ 8] = is_box(st[ 8]); st[12] = is_box(st[12]); |
||||
|
||||
tt = st[13]; st[13] = is_box(st[9]); st[ 9] = is_box(st[5]); |
||||
st[ 5] = is_box(st[1]); st[ 1] = is_box( tt ); |
||||
|
||||
tt = st[2]; st[ 2] = is_box(st[10]); st[10] = is_box( tt ); |
||||
tt = st[6]; st[ 6] = is_box(st[14]); st[14] = is_box( tt ); |
||||
|
||||
tt = st[3]; st[ 3] = is_box(st[ 7]); st[ 7] = is_box(st[11]); |
||||
st[11] = is_box(st[15]); st[15] = is_box( tt ); |
||||
} |
||||
|
||||
#endif |
||||
|
||||
#if defined( VERSION_1 ) |
||||
static void mix_sub_columns( uint8_t dt[N_BLOCK] ) |
||||
{ uint8_t st[N_BLOCK]; |
||||
block_copy(st, dt); |
||||
#else |
||||
static void mix_sub_columns( uint8_t dt[N_BLOCK], uint8_t st[N_BLOCK] ) |
||||
{ |
||||
#endif |
||||
dt[ 0] = gfm2_sb(st[0]) ^ gfm3_sb(st[5]) ^ s_box(st[10]) ^ s_box(st[15]); |
||||
dt[ 1] = s_box(st[0]) ^ gfm2_sb(st[5]) ^ gfm3_sb(st[10]) ^ s_box(st[15]); |
||||
dt[ 2] = s_box(st[0]) ^ s_box(st[5]) ^ gfm2_sb(st[10]) ^ gfm3_sb(st[15]); |
||||
dt[ 3] = gfm3_sb(st[0]) ^ s_box(st[5]) ^ s_box(st[10]) ^ gfm2_sb(st[15]); |
||||
|
||||
dt[ 4] = gfm2_sb(st[4]) ^ gfm3_sb(st[9]) ^ s_box(st[14]) ^ s_box(st[3]); |
||||
dt[ 5] = s_box(st[4]) ^ gfm2_sb(st[9]) ^ gfm3_sb(st[14]) ^ s_box(st[3]); |
||||
dt[ 6] = s_box(st[4]) ^ s_box(st[9]) ^ gfm2_sb(st[14]) ^ gfm3_sb(st[3]); |
||||
dt[ 7] = gfm3_sb(st[4]) ^ s_box(st[9]) ^ s_box(st[14]) ^ gfm2_sb(st[3]); |
||||
|
||||
dt[ 8] = gfm2_sb(st[8]) ^ gfm3_sb(st[13]) ^ s_box(st[2]) ^ s_box(st[7]); |
||||
dt[ 9] = s_box(st[8]) ^ gfm2_sb(st[13]) ^ gfm3_sb(st[2]) ^ s_box(st[7]); |
||||
dt[10] = s_box(st[8]) ^ s_box(st[13]) ^ gfm2_sb(st[2]) ^ gfm3_sb(st[7]); |
||||
dt[11] = gfm3_sb(st[8]) ^ s_box(st[13]) ^ s_box(st[2]) ^ gfm2_sb(st[7]); |
||||
|
||||
dt[12] = gfm2_sb(st[12]) ^ gfm3_sb(st[1]) ^ s_box(st[6]) ^ s_box(st[11]); |
||||
dt[13] = s_box(st[12]) ^ gfm2_sb(st[1]) ^ gfm3_sb(st[6]) ^ s_box(st[11]); |
||||
dt[14] = s_box(st[12]) ^ s_box(st[1]) ^ gfm2_sb(st[6]) ^ gfm3_sb(st[11]); |
||||
dt[15] = gfm3_sb(st[12]) ^ s_box(st[1]) ^ s_box(st[6]) ^ gfm2_sb(st[11]); |
||||
} |
||||
|
||||
#if defined( AES_DEC_PREKEYED ) |
||||
|
||||
#if defined( VERSION_1 ) |
||||
static void inv_mix_sub_columns( uint8_t dt[N_BLOCK] ) |
||||
{ uint8_t st[N_BLOCK]; |
||||
block_copy(st, dt); |
||||
#else |
||||
static void inv_mix_sub_columns( uint8_t dt[N_BLOCK], uint8_t st[N_BLOCK] ) |
||||
{ |
||||
#endif |
||||
dt[ 0] = is_box(gfm_e(st[ 0]) ^ gfm_b(st[ 1]) ^ gfm_d(st[ 2]) ^ gfm_9(st[ 3])); |
||||
dt[ 5] = is_box(gfm_9(st[ 0]) ^ gfm_e(st[ 1]) ^ gfm_b(st[ 2]) ^ gfm_d(st[ 3])); |
||||
dt[10] = is_box(gfm_d(st[ 0]) ^ gfm_9(st[ 1]) ^ gfm_e(st[ 2]) ^ gfm_b(st[ 3])); |
||||
dt[15] = is_box(gfm_b(st[ 0]) ^ gfm_d(st[ 1]) ^ gfm_9(st[ 2]) ^ gfm_e(st[ 3])); |
||||
|
||||
dt[ 4] = is_box(gfm_e(st[ 4]) ^ gfm_b(st[ 5]) ^ gfm_d(st[ 6]) ^ gfm_9(st[ 7])); |
||||
dt[ 9] = is_box(gfm_9(st[ 4]) ^ gfm_e(st[ 5]) ^ gfm_b(st[ 6]) ^ gfm_d(st[ 7])); |
||||
dt[14] = is_box(gfm_d(st[ 4]) ^ gfm_9(st[ 5]) ^ gfm_e(st[ 6]) ^ gfm_b(st[ 7])); |
||||
dt[ 3] = is_box(gfm_b(st[ 4]) ^ gfm_d(st[ 5]) ^ gfm_9(st[ 6]) ^ gfm_e(st[ 7])); |
||||
|
||||
dt[ 8] = is_box(gfm_e(st[ 8]) ^ gfm_b(st[ 9]) ^ gfm_d(st[10]) ^ gfm_9(st[11])); |
||||
dt[13] = is_box(gfm_9(st[ 8]) ^ gfm_e(st[ 9]) ^ gfm_b(st[10]) ^ gfm_d(st[11])); |
||||
dt[ 2] = is_box(gfm_d(st[ 8]) ^ gfm_9(st[ 9]) ^ gfm_e(st[10]) ^ gfm_b(st[11])); |
||||
dt[ 7] = is_box(gfm_b(st[ 8]) ^ gfm_d(st[ 9]) ^ gfm_9(st[10]) ^ gfm_e(st[11])); |
||||
|
||||
dt[12] = is_box(gfm_e(st[12]) ^ gfm_b(st[13]) ^ gfm_d(st[14]) ^ gfm_9(st[15])); |
||||
dt[ 1] = is_box(gfm_9(st[12]) ^ gfm_e(st[13]) ^ gfm_b(st[14]) ^ gfm_d(st[15])); |
||||
dt[ 6] = is_box(gfm_d(st[12]) ^ gfm_9(st[13]) ^ gfm_e(st[14]) ^ gfm_b(st[15])); |
||||
dt[11] = is_box(gfm_b(st[12]) ^ gfm_d(st[13]) ^ gfm_9(st[14]) ^ gfm_e(st[15])); |
||||
} |
||||
|
||||
#endif |
||||
|
||||
#if defined( AES_ENC_PREKEYED ) || defined( AES_DEC_PREKEYED ) |
||||
|
||||
/* Set the cipher key for the pre-keyed version */ |
||||
|
||||
return_type aes_set_key( const uint8_t key[], length_type keylen, aes_context ctx[1] ) |
||||
{ |
||||
uint8_t cc, rc, hi; |
||||
|
||||
switch( keylen ) |
||||
{ |
||||
case 16: |
||||
case 24: |
||||
case 32: |
||||
break; |
||||
default: |
||||
ctx->rnd = 0; |
||||
return ( uint8_t )-1; |
||||
} |
||||
block_copy_nn(ctx->ksch, key, keylen); |
||||
hi = (keylen + 28) << 2; |
||||
ctx->rnd = (hi >> 4) - 1; |
||||
for( cc = keylen, rc = 1; cc < hi; cc += 4 ) |
||||
{ uint8_t tt, t0, t1, t2, t3; |
||||
|
||||
t0 = ctx->ksch[cc - 4]; |
||||
t1 = ctx->ksch[cc - 3]; |
||||
t2 = ctx->ksch[cc - 2]; |
||||
t3 = ctx->ksch[cc - 1]; |
||||
if( cc % keylen == 0 ) |
||||
{ |
||||
tt = t0; |
||||
t0 = s_box(t1) ^ rc; |
||||
t1 = s_box(t2); |
||||
t2 = s_box(t3); |
||||
t3 = s_box(tt); |
||||
rc = f2(rc); |
||||
} |
||||
else if( keylen > 24 && cc % keylen == 16 ) |
||||
{ |
||||
t0 = s_box(t0); |
||||
t1 = s_box(t1); |
||||
t2 = s_box(t2); |
||||
t3 = s_box(t3); |
||||
} |
||||
tt = cc - keylen; |
||||
ctx->ksch[cc + 0] = ctx->ksch[tt + 0] ^ t0; |
||||
ctx->ksch[cc + 1] = ctx->ksch[tt + 1] ^ t1; |
||||
ctx->ksch[cc + 2] = ctx->ksch[tt + 2] ^ t2; |
||||
ctx->ksch[cc + 3] = ctx->ksch[tt + 3] ^ t3; |
||||
} |
||||
return 0; |
||||
} |
||||
|
||||
#endif |
||||
|
||||
#if defined( AES_ENC_PREKEYED ) |
||||
|
||||
/* Encrypt a single block of 16 bytes */ |
||||
|
||||
return_type aes_encrypt( const uint8_t in[N_BLOCK], uint8_t out[N_BLOCK], const aes_context ctx[1] ) |
||||
{ |
||||
if( ctx->rnd ) |
||||
{ |
||||
uint8_t s1[N_BLOCK], r; |
||||
copy_and_key( s1, in, ctx->ksch ); |
||||
|
||||
for( r = 1 ; r < ctx->rnd ; ++r ) |
||||
#if defined( VERSION_1 ) |
||||
{ |
||||
mix_sub_columns( s1 ); |
||||
add_round_key( s1, ctx->ksch + r * N_BLOCK); |
||||
} |
||||
#else |
||||
{ uint8_t s2[N_BLOCK]; |
||||
mix_sub_columns( s2, s1 ); |
||||
copy_and_key( s1, s2, ctx->ksch + r * N_BLOCK); |
||||
} |
||||
#endif |
||||
shift_sub_rows( s1 ); |
||||
copy_and_key( out, s1, ctx->ksch + r * N_BLOCK ); |
||||
} |
||||
else |
||||
return ( uint8_t )-1; |
||||
return 0; |
||||
} |
||||
|
||||
/* CBC encrypt a number of blocks (input and return an IV) */ |
||||
|
||||
return_type aes_cbc_encrypt( const uint8_t *in, uint8_t *out, |
||||
int32_t n_block, uint8_t iv[N_BLOCK], const aes_context ctx[1] ) |
||||
{ |
||||
|
||||
while(n_block--) |
||||
{ |
||||
xor_block(iv, in); |
||||
if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS) |
||||
return EXIT_FAILURE; |
||||
//memcpy(out, iv, N_BLOCK);
|
||||
block_copy(out, iv); |
||||
in += N_BLOCK; |
||||
out += N_BLOCK; |
||||
} |
||||
return EXIT_SUCCESS; |
||||
} |
||||
|
||||
#endif |
||||
|
||||
#if defined( AES_DEC_PREKEYED ) |
||||
|
||||
/* Decrypt a single block of 16 bytes */ |
||||
|
||||
return_type aes_decrypt( const uint8_t in[N_BLOCK], uint8_t out[N_BLOCK], const aes_context ctx[1] ) |
||||
{ |
||||
if( ctx->rnd ) |
||||
{ |
||||
uint8_t s1[N_BLOCK], r; |
||||
copy_and_key( s1, in, ctx->ksch + ctx->rnd * N_BLOCK ); |
||||
inv_shift_sub_rows( s1 ); |
||||
|
||||
for( r = ctx->rnd ; --r ; ) |
||||
#if defined( VERSION_1 ) |
||||
{ |
||||
add_round_key( s1, ctx->ksch + r * N_BLOCK ); |
||||
inv_mix_sub_columns( s1 ); |
||||
} |
||||
#else |
||||
{ uint8_t s2[N_BLOCK]; |
||||
copy_and_key( s2, s1, ctx->ksch + r * N_BLOCK ); |
||||
inv_mix_sub_columns( s1, s2 ); |
||||
} |
||||
#endif |
||||
copy_and_key( out, s1, ctx->ksch ); |
||||
} |
||||
else |
||||
return -1; |
||||
return 0; |
||||
} |
||||
|
||||
/* CBC decrypt a number of blocks (input and return an IV) */ |
||||
|
||||
return_type aes_cbc_decrypt( const uint8_t *in, uint8_t *out, |
||||
int32_t n_block, uint8_t iv[N_BLOCK], const aes_context ctx[1] ) |
||||
{ |
||||
while(n_block--) |
||||
{ uint8_t tmp[N_BLOCK]; |
||||
|
||||
//memcpy(tmp, in, N_BLOCK);
|
||||
block_copy(tmp, in); |
||||
if(aes_decrypt(in, out, ctx) != EXIT_SUCCESS) |
||||
return EXIT_FAILURE; |
||||
xor_block(out, iv); |
||||
//memcpy(iv, tmp, N_BLOCK);
|
||||
block_copy(iv, tmp); |
||||
in += N_BLOCK; |
||||
out += N_BLOCK; |
||||
} |
||||
return EXIT_SUCCESS; |
||||
} |
||||
|
||||
#endif |
||||
|
||||
#if defined( AES_ENC_128_OTFK ) |
||||
|
||||
/* The 'on the fly' encryption key update for for 128 bit keys */ |
||||
|
||||
static void update_encrypt_key_128( uint8_t k[N_BLOCK], uint8_t *rc ) |
||||
{ uint8_t cc; |
||||
|
||||
k[0] ^= s_box(k[13]) ^ *rc; |
||||
k[1] ^= s_box(k[14]); |
||||
k[2] ^= s_box(k[15]); |
||||
k[3] ^= s_box(k[12]); |
||||
*rc = f2( *rc ); |
||||
|
||||
for(cc = 4; cc < 16; cc += 4 ) |
||||
{ |
||||
k[cc + 0] ^= k[cc - 4]; |
||||
k[cc + 1] ^= k[cc - 3]; |
||||
k[cc + 2] ^= k[cc - 2]; |
||||
k[cc + 3] ^= k[cc - 1]; |
||||
} |
||||
} |
||||
|
||||
/* Encrypt a single block of 16 bytes with 'on the fly' 128 bit keying */ |
||||
|
||||
void aes_encrypt_128( const uint8_t in[N_BLOCK], uint8_t out[N_BLOCK], |
||||
const uint8_t key[N_BLOCK], uint8_t o_key[N_BLOCK] ) |
||||
{ uint8_t s1[N_BLOCK], r, rc = 1; |
||||
|
||||
if(o_key != key) |
||||
block_copy( o_key, key ); |
||||
copy_and_key( s1, in, o_key ); |
||||
|
||||
for( r = 1 ; r < 10 ; ++r ) |
||||
#if defined( VERSION_1 ) |
||||
{ |
||||
mix_sub_columns( s1 ); |
||||
update_encrypt_key_128( o_key, &rc ); |
||||
add_round_key( s1, o_key ); |
||||
} |
||||
#else |
||||
{ uint8_t s2[N_BLOCK]; |
||||
mix_sub_columns( s2, s1 ); |
||||
update_encrypt_key_128( o_key, &rc ); |
||||
copy_and_key( s1, s2, o_key ); |
||||
} |
||||
#endif |
||||
|
||||
shift_sub_rows( s1 ); |
||||
update_encrypt_key_128( o_key, &rc ); |
||||
copy_and_key( out, s1, o_key ); |
||||
} |
||||
|
||||
#endif |
||||
|
||||
#if defined( AES_DEC_128_OTFK ) |
||||
|
||||
/* The 'on the fly' decryption key update for for 128 bit keys */ |
||||
|
||||
static void update_decrypt_key_128( uint8_t k[N_BLOCK], uint8_t *rc ) |
||||
{ uint8_t cc; |
||||
|
||||
for( cc = 12; cc > 0; cc -= 4 ) |
||||
{ |
||||
k[cc + 0] ^= k[cc - 4]; |
||||
k[cc + 1] ^= k[cc - 3]; |
||||
k[cc + 2] ^= k[cc - 2]; |
||||
k[cc + 3] ^= k[cc - 1]; |
||||
} |
||||
*rc = d2(*rc); |
||||
k[0] ^= s_box(k[13]) ^ *rc; |
||||
k[1] ^= s_box(k[14]); |
||||
k[2] ^= s_box(k[15]); |
||||
k[3] ^= s_box(k[12]); |
||||
} |
||||
|
||||
/* Decrypt a single block of 16 bytes with 'on the fly' 128 bit keying */ |
||||
|
||||
void aes_decrypt_128( const uint8_t in[N_BLOCK], uint8_t out[N_BLOCK], |
||||
const uint8_t key[N_BLOCK], uint8_t o_key[N_BLOCK] ) |
||||
{ |
||||
uint8_t s1[N_BLOCK], r, rc = 0x6c; |
||||
if(o_key != key) |
||||
block_copy( o_key, key ); |
||||
|
||||
copy_and_key( s1, in, o_key ); |
||||
inv_shift_sub_rows( s1 ); |
||||
|
||||
for( r = 10 ; --r ; ) |
||||
#if defined( VERSION_1 ) |
||||
{ |
||||
update_decrypt_key_128( o_key, &rc ); |
||||
add_round_key( s1, o_key ); |
||||
inv_mix_sub_columns( s1 ); |
||||
} |
||||
#else |
||||
{ uint8_t s2[N_BLOCK]; |
||||
update_decrypt_key_128( o_key, &rc ); |
||||
copy_and_key( s2, s1, o_key ); |
||||
inv_mix_sub_columns( s1, s2 ); |
||||
} |
||||
#endif |
||||
update_decrypt_key_128( o_key, &rc ); |
||||
copy_and_key( out, s1, o_key ); |
||||
} |
||||
|
||||
#endif |
||||
|
||||
#if defined( AES_ENC_256_OTFK ) |
||||
|
||||
/* The 'on the fly' encryption key update for for 256 bit keys */ |
||||
|
||||
static void update_encrypt_key_256( uint8_t k[2 * N_BLOCK], uint8_t *rc ) |
||||
{ uint8_t cc; |
||||
|
||||
k[0] ^= s_box(k[29]) ^ *rc; |
||||
k[1] ^= s_box(k[30]); |
||||
k[2] ^= s_box(k[31]); |
||||
k[3] ^= s_box(k[28]); |
||||
*rc = f2( *rc ); |
||||
|
||||
for(cc = 4; cc < 16; cc += 4) |
||||
{ |
||||
k[cc + 0] ^= k[cc - 4]; |
||||
k[cc + 1] ^= k[cc - 3]; |
||||
k[cc + 2] ^= k[cc - 2]; |
||||
k[cc + 3] ^= k[cc - 1]; |
||||
} |
||||
|
||||
k[16] ^= s_box(k[12]); |
||||
k[17] ^= s_box(k[13]); |
||||
k[18] ^= s_box(k[14]); |
||||
k[19] ^= s_box(k[15]); |
||||
|
||||
for( cc = 20; cc < 32; cc += 4 ) |
||||
{ |
||||
k[cc + 0] ^= k[cc - 4]; |
||||
k[cc + 1] ^= k[cc - 3]; |
||||
k[cc + 2] ^= k[cc - 2]; |
||||
k[cc + 3] ^= k[cc - 1]; |
||||
} |
||||
} |
||||
|
||||
/* Encrypt a single block of 16 bytes with 'on the fly' 256 bit keying */ |
||||
|
||||
void aes_encrypt_256( const uint8_t in[N_BLOCK], uint8_t out[N_BLOCK], |
||||
const uint8_t key[2 * N_BLOCK], uint8_t o_key[2 * N_BLOCK] ) |
||||
{ |
||||
uint8_t s1[N_BLOCK], r, rc = 1; |
||||
if(o_key != key) |
||||
{ |
||||
block_copy( o_key, key ); |
||||
block_copy( o_key + 16, key + 16 ); |
||||
} |
||||
copy_and_key( s1, in, o_key ); |
||||
|
||||
for( r = 1 ; r < 14 ; ++r ) |
||||
#if defined( VERSION_1 ) |
||||
{ |
||||
mix_sub_columns(s1); |
||||
if( r & 1 ) |
||||
add_round_key( s1, o_key + 16 ); |
||||
else |
||||
{ |
||||
update_encrypt_key_256( o_key, &rc ); |
||||
add_round_key( s1, o_key ); |
||||
} |
||||
} |
||||
#else |
||||
{ uint8_t s2[N_BLOCK]; |
||||
mix_sub_columns( s2, s1 ); |
||||
if( r & 1 ) |
||||
copy_and_key( s1, s2, o_key + 16 ); |
||||
else |
||||
{ |
||||
update_encrypt_key_256( o_key, &rc ); |
||||
copy_and_key( s1, s2, o_key ); |
||||
} |
||||
} |
||||
#endif |
||||
|
||||
shift_sub_rows( s1 ); |
||||
update_encrypt_key_256( o_key, &rc ); |
||||
copy_and_key( out, s1, o_key ); |
||||
} |
||||
|
||||
#endif |
||||
|
||||
#if defined( AES_DEC_256_OTFK ) |
||||
|
||||
/* The 'on the fly' encryption key update for for 256 bit keys */ |
||||
|
||||
static void update_decrypt_key_256( uint8_t k[2 * N_BLOCK], uint8_t *rc ) |
||||
{ uint8_t cc; |
||||
|
||||
for(cc = 28; cc > 16; cc -= 4) |
||||
{ |
||||
k[cc + 0] ^= k[cc - 4]; |
||||
k[cc + 1] ^= k[cc - 3]; |
||||
k[cc + 2] ^= k[cc - 2]; |
||||
k[cc + 3] ^= k[cc - 1]; |
||||
} |
||||
|
||||
k[16] ^= s_box(k[12]); |
||||
k[17] ^= s_box(k[13]); |
||||
k[18] ^= s_box(k[14]); |
||||
k[19] ^= s_box(k[15]); |
||||
|
||||
for(cc = 12; cc > 0; cc -= 4) |
||||
{ |
||||
k[cc + 0] ^= k[cc - 4]; |
||||
k[cc + 1] ^= k[cc - 3]; |
||||
k[cc + 2] ^= k[cc - 2]; |
||||
k[cc + 3] ^= k[cc - 1]; |
||||
} |
||||
|
||||
*rc = d2(*rc); |
||||
k[0] ^= s_box(k[29]) ^ *rc; |
||||
k[1] ^= s_box(k[30]); |
||||
k[2] ^= s_box(k[31]); |
||||
k[3] ^= s_box(k[28]); |
||||
} |
||||
|
||||
/* Decrypt a single block of 16 bytes with 'on the fly'
|
||||
256 bit keying |
||||
*/ |
||||
void aes_decrypt_256( const uint8_t in[N_BLOCK], uint8_t out[N_BLOCK], |
||||
const uint8_t key[2 * N_BLOCK], uint8_t o_key[2 * N_BLOCK] ) |
||||
{ |
||||
uint8_t s1[N_BLOCK], r, rc = 0x80; |
||||
|
||||
if(o_key != key) |
||||
{ |
||||
block_copy( o_key, key ); |
||||
block_copy( o_key + 16, key + 16 ); |
||||
} |
||||
|
||||
copy_and_key( s1, in, o_key ); |
||||
inv_shift_sub_rows( s1 ); |
||||
|
||||
for( r = 14 ; --r ; ) |
||||
#if defined( VERSION_1 ) |
||||
{ |
||||
if( ( r & 1 ) ) |
||||
{ |
||||
update_decrypt_key_256( o_key, &rc ); |
||||
add_round_key( s1, o_key + 16 ); |
||||
} |
||||
else |
||||
add_round_key( s1, o_key ); |
||||
inv_mix_sub_columns( s1 ); |
||||
} |
||||
#else |
||||
{ uint8_t s2[N_BLOCK]; |
||||
if( ( r & 1 ) ) |
||||
{ |
||||
update_decrypt_key_256( o_key, &rc ); |
||||
copy_and_key( s2, s1, o_key + 16 ); |
||||
} |
||||
else |
||||
copy_and_key( s2, s1, o_key ); |
||||
inv_mix_sub_columns( s1, s2 ); |
||||
} |
||||
#endif |
||||
copy_and_key( out, s1, o_key ); |
||||
} |
||||
|
||||
#endif |
@ -0,0 +1,160 @@ |
||||
/*
|
||||
--------------------------------------------------------------------------- |
||||
Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved. |
||||
|
||||
LICENSE TERMS |
||||
|
||||
The redistribution and use of this software (with or without changes) |
||||
is allowed without the payment of fees or royalties provided that: |
||||
|
||||
1. source code distributions include the above copyright notice, this |
||||
list of conditions and the following disclaimer; |
||||
|
||||
2. binary distributions include the above copyright notice, this list |
||||
of conditions and the following disclaimer in their documentation; |
||||
|
||||
3. the name of the copyright holder is not used to endorse products |
||||
built using this software without specific written permission. |
||||
|
||||
DISCLAIMER |
||||
|
||||
This software is provided 'as is' with no explicit or implied warranties |
||||
in respect of its properties, including, but not limited to, correctness |
||||
and/or fitness for purpose. |
||||
--------------------------------------------------------------------------- |
||||
Issue 09/09/2006 |
||||
|
||||
This is an AES implementation that uses only 8-bit byte operations on the |
||||
cipher state. |
||||
*/ |
||||
|
||||
#ifndef AES_H |
||||
#define AES_H |
||||
|
||||
#if 1 |
||||
# define AES_ENC_PREKEYED /* AES encryption with a precomputed key schedule */ |
||||
#endif |
||||
#if 0 |
||||
# define AES_DEC_PREKEYED /* AES decryption with a precomputed key schedule */ |
||||
#endif |
||||
#if 0 |
||||
# define AES_ENC_128_OTFK /* AES encryption with 'on the fly' 128 bit keying */ |
||||
#endif |
||||
#if 0 |
||||
# define AES_DEC_128_OTFK /* AES decryption with 'on the fly' 128 bit keying */ |
||||
#endif |
||||
#if 0 |
||||
# define AES_ENC_256_OTFK /* AES encryption with 'on the fly' 256 bit keying */ |
||||
#endif |
||||
#if 0 |
||||
# define AES_DEC_256_OTFK /* AES decryption with 'on the fly' 256 bit keying */ |
||||
#endif |
||||
|
||||
#define N_ROW 4 |
||||
#define N_COL 4 |
||||
#define N_BLOCK (N_ROW * N_COL) |
||||
#define N_MAX_ROUNDS 14 |
||||
|
||||
typedef uint8_t return_type; |
||||
|
||||
/* Warning: The key length for 256 bit keys overflows a byte
|
||||
(see comment below) |
||||
*/ |
||||
|
||||
typedef uint8_t length_type; |
||||
|
||||
typedef struct |
||||
{ uint8_t ksch[(N_MAX_ROUNDS + 1) * N_BLOCK]; |
||||
uint8_t rnd; |
||||
} aes_context; |
||||
|
||||
/* The following calls are for a precomputed key schedule
|
||||
|
||||
NOTE: If the length_type used for the key length is an |
||||
unsigned 8-bit character, a key length of 256 bits must |
||||
be entered as a length in bytes (valid inputs are hence |
||||
128, 192, 16, 24 and 32). |
||||
*/ |
||||
|
||||
#if defined( AES_ENC_PREKEYED ) || defined( AES_DEC_PREKEYED ) |
||||
|
||||
return_type aes_set_key( const uint8_t key[], |
||||
length_type keylen, |
||||
aes_context ctx[1] ); |
||||
#endif |
||||
|
||||
#if defined( AES_ENC_PREKEYED ) |
||||
|
||||
return_type aes_encrypt( const uint8_t in[N_BLOCK], |
||||
uint8_t out[N_BLOCK], |
||||
const aes_context ctx[1] ); |
||||
|
||||
return_type aes_cbc_encrypt( const uint8_t *in, |
||||
uint8_t *out, |
||||
int32_t n_block, |
||||
uint8_t iv[N_BLOCK], |
||||
const aes_context ctx[1] ); |
||||
#endif |
||||
|
||||
#if defined( AES_DEC_PREKEYED ) |
||||
|
||||
return_type aes_decrypt( const uint8_t in[N_BLOCK], |
||||
uint8_t out[N_BLOCK], |
||||
const aes_context ctx[1] ); |
||||
|
||||
return_type aes_cbc_decrypt( const uint8_t *in, |
||||
uint8_t *out, |
||||
int32_t n_block, |
||||
uint8_t iv[N_BLOCK], |
||||
const aes_context ctx[1] ); |
||||
#endif |
||||
|
||||
/* The following calls are for 'on the fly' keying. In this case the
|
||||
encryption and decryption keys are different. |
||||
|
||||
The encryption subroutines take a key in an array of bytes in |
||||
key[L] where L is 16, 24 or 32 bytes for key lengths of 128, |
||||
192, and 256 bits respectively. They then encrypts the input |
||||
data, in[] with this key and put the reult in the output array |
||||
out[]. In addition, the second key array, o_key[L], is used |
||||
to output the key that is needed by the decryption subroutine |
||||
to reverse the encryption operation. The two key arrays can |
||||
be the same array but in this case the original key will be |
||||
overwritten. |
||||
|
||||
In the same way, the decryption subroutines output keys that |
||||
can be used to reverse their effect when used for encryption. |
||||
|
||||
Only 128 and 256 bit keys are supported in these 'on the fly' |
||||
modes. |
||||
*/ |
||||
|
||||
#if defined( AES_ENC_128_OTFK ) |
||||
void aes_encrypt_128( const uint8_t in[N_BLOCK], |
||||
uint8_t out[N_BLOCK], |
||||
const uint8_t key[N_BLOCK], |
||||
uint8_t o_key[N_BLOCK] ); |
||||
#endif |
||||
|
||||
#if defined( AES_DEC_128_OTFK ) |
||||
void aes_decrypt_128( const uint8_t in[N_BLOCK], |
||||
uint8_t out[N_BLOCK], |
||||
const uint8_t key[N_BLOCK], |
||||
uint8_t o_key[N_BLOCK] ); |
||||
#endif |
||||
|
||||
#if defined( AES_ENC_256_OTFK ) |
||||
void aes_encrypt_256( const uint8_t in[N_BLOCK], |
||||
uint8_t out[N_BLOCK], |
||||
const uint8_t key[2 * N_BLOCK], |
||||
uint8_t o_key[2 * N_BLOCK] ); |
||||
#endif |
||||
|
||||
#if defined( AES_DEC_256_OTFK ) |
||||
void aes_decrypt_256( const uint8_t in[N_BLOCK], |
||||
uint8_t out[N_BLOCK], |
||||
const uint8_t key[2 * N_BLOCK], |
||||
uint8_t o_key[2 * N_BLOCK] ); |
||||
#endif |
||||
|
||||
#endif |
@ -0,0 +1,153 @@ |
||||
/**************************************************************************
|
||||
Copyright (C) 2009 Lander Casado, Philippas Tsigas |
||||
|
||||
All rights reserved. |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining |
||||
a copy of this software and associated documentation files
|
||||
(the "Software"), to deal with the Software without restriction, including |
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to |
||||
permit persons to whom the Software is furnished to do so, subject to |
||||
the following conditions:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimers. Redistributions in |
||||
binary form must reproduce the above copyright notice, this list of |
||||
conditions and the following disclaimers in the documentation and/or
|
||||
other materials provided with the distribution. |
||||
|
||||
In no event shall the authors or copyright holders be liable for any special, |
||||
incidental, indirect or consequential damages of any kind, or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether or not
|
||||
advised of the possibility of damage, and on any theory of liability,
|
||||
arising out of or in connection with the use or performance of this software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS WITH THE SOFTWARE |
||||
|
||||
*****************************************************************************/ |
||||
//#include <sys/param.h>
|
||||
//#include <sys/systm.h>
|
||||
#include <stdint.h> |
||||
#include "aes.h" |
||||
#include "cmac.h" |
||||
#include "utilities.h" |
||||
|
||||
#define LSHIFT(v, r) do { \ |
||||
int32_t i; \
|
||||
for (i = 0; i < 15; i++) \
|
||||
(r)[i] = (v)[i] << 1 | (v)[i + 1] >> 7; \
|
||||
(r)[15] = (v)[15] << 1; \
|
||||
} while (0) |
||||
|
||||
#define XOR(v, r) do { \ |
||||
int32_t i; \
|
||||
for (i = 0; i < 16; i++) \
|
||||
{ \
|
||||
(r)[i] = (r)[i] ^ (v)[i]; \
|
||||
} \
|
||||
} while (0) \
|
||||
|
||||
|
||||
void AES_CMAC_Init(AES_CMAC_CTX *ctx) |
||||
{ |
||||
memset1(ctx->X, 0, sizeof ctx->X); |
||||
ctx->M_n = 0; |
||||
memset1(ctx->rijndael.ksch, '\0', 240); |
||||
} |
||||
|
||||
void AES_CMAC_SetKey(AES_CMAC_CTX *ctx, const uint8_t key[AES_CMAC_KEY_LENGTH]) |
||||
{ |
||||
//rijndael_set_key_enc_only(&ctx->rijndael, key, 128);
|
||||
aes_set_key( key, AES_CMAC_KEY_LENGTH, &ctx->rijndael); |
||||
} |
||||
|
||||
void AES_CMAC_Update(AES_CMAC_CTX *ctx, const uint8_t *data, uint32_t len) |
||||
{ |
||||
uint32_t mlen; |
||||
uint8_t in[16]; |
||||
|
||||
if (ctx->M_n > 0) { |
||||
mlen = MIN(16 - ctx->M_n, len); |
||||
memcpy1(ctx->M_last + ctx->M_n, data, mlen); |
||||
ctx->M_n += mlen; |
||||
if (ctx->M_n < 16 || len == mlen) |
||||
return; |
||||
XOR(ctx->M_last, ctx->X); |
||||
//rijndael_encrypt(&ctx->rijndael, ctx->X, ctx->X);
|
||||
aes_encrypt( ctx->X, ctx->X, &ctx->rijndael); |
||||
data += mlen; |
||||
len -= mlen; |
||||
} |
||||
while (len > 16) { /* not last block */ |
||||
|
||||
XOR(data, ctx->X); |
||||
//rijndael_encrypt(&ctx->rijndael, ctx->X, ctx->X);
|
||||
|
||||
memcpy1(in, &ctx->X[0], 16); //Bestela ez du ondo iten
|
||||
aes_encrypt( in, in, &ctx->rijndael); |
||||
memcpy1(&ctx->X[0], in, 16); |
||||
|
||||
data += 16; |
||||
len -= 16; |
||||
} |
||||
/* potential last block, save it */ |
||||
memcpy1(ctx->M_last, data, len); |
||||
ctx->M_n = len; |
||||
} |
||||
|
||||
void AES_CMAC_Final(uint8_t digest[AES_CMAC_DIGEST_LENGTH], AES_CMAC_CTX *ctx) |
||||
{ |
||||
uint8_t K[16]; |
||||
uint8_t in[16]; |
||||
/* generate subkey K1 */ |
||||
memset1(K, '\0', 16); |
||||
|
||||
//rijndael_encrypt(&ctx->rijndael, K, K);
|
||||
|
||||
aes_encrypt( K, K, &ctx->rijndael); |
||||
|
||||
if (K[0] & 0x80) { |
||||
LSHIFT(K, K); |
||||
K[15] ^= 0x87; |
||||
} else |
||||
LSHIFT(K, K); |
||||
|
||||
|
||||
if (ctx->M_n == 16) { |
||||
/* last block was a complete block */ |
||||
XOR(K, ctx->M_last); |
||||
|
||||
} else { |
||||
/* generate subkey K2 */ |
||||
if (K[0] & 0x80) { |
||||
LSHIFT(K, K); |
||||
K[15] ^= 0x87; |
||||
} else |
||||
LSHIFT(K, K); |
||||
|
||||
/* padding(M_last) */ |
||||
ctx->M_last[ctx->M_n] = 0x80; |
||||
while (++ctx->M_n < 16) |
||||
ctx->M_last[ctx->M_n] = 0; |
||||
|
||||
XOR(K, ctx->M_last); |
||||
|
||||
|
||||
} |
||||
XOR(ctx->M_last, ctx->X); |
||||
|
||||
//rijndael_encrypt(&ctx->rijndael, ctx->X, digest);
|
||||
|
||||
memcpy1(in, &ctx->X[0], 16); //Bestela ez du ondo iten
|
||||
aes_encrypt(in, digest, &ctx->rijndael); |
||||
memset1(K, 0, sizeof K); |
||||
|
||||
} |
||||
|
@ -0,0 +1,63 @@ |
||||
/**************************************************************************
|
||||
Copyright (C) 2009 Lander Casado, Philippas Tsigas |
||||
|
||||
All rights reserved. |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining |
||||
a copy of this software and associated documentation files
|
||||
(the "Software"), to deal with the Software without restriction, including |
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to |
||||
permit persons to whom the Software is furnished to do so, subject to |
||||
the following conditions:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimers. Redistributions in |
||||
binary form must reproduce the above copyright notice, this list of |
||||
conditions and the following disclaimers in the documentation and/or
|
||||
other materials provided with the distribution. |
||||
|
||||
In no event shall the authors or copyright holders be liable for any special, |
||||
incidental, indirect or consequential damages of any kind, or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether or not
|
||||
advised of the possibility of damage, and on any theory of liability,
|
||||
arising out of or in connection with the use or performance of this software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS WITH THE SOFTWARE |
||||
|
||||
*****************************************************************************/ |
||||
|
||||
#ifndef _CMAC_H_ |
||||
#define _CMAC_H_ |
||||
|
||||
#include "aes.h" |
||||
|
||||
#define AES_CMAC_KEY_LENGTH 16 |
||||
#define AES_CMAC_DIGEST_LENGTH 16 |
||||
|
||||
typedef struct _AES_CMAC_CTX { |
||||
aes_context rijndael; |
||||
uint8_t X[16]; |
||||
uint8_t M_last[16]; |
||||
uint32_t M_n; |
||||
} AES_CMAC_CTX; |
||||
|
||||
//#include <sys/cdefs.h>
|
||||
|
||||
//__BEGIN_DECLS
|
||||
void AES_CMAC_Init(AES_CMAC_CTX * ctx); |
||||
void AES_CMAC_SetKey(AES_CMAC_CTX * ctx, const uint8_t key[AES_CMAC_KEY_LENGTH]); |
||||
void AES_CMAC_Update(AES_CMAC_CTX * ctx, const uint8_t * data, uint32_t len); |
||||
// __attribute__((__bounded__(__string__,2,3)));
|
||||
void AES_CMAC_Final(uint8_t digest[AES_CMAC_DIGEST_LENGTH], AES_CMAC_CTX * ctx); |
||||
// __attribute__((__bounded__(__minbytes__,1,AES_CMAC_DIGEST_LENGTH)));
|
||||
//__END_DECLS
|
||||
|
||||
#endif /* _CMAC_H_ */ |
||||
|
@ -0,0 +1,25 @@ |
||||
--- Revised BSD License --- |
||||
Copyright (c) 2013, SEMTECH S.A. |
||||
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 Semtech corporation 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 SEMTECH S.A. 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 diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,202 @@ |
||||
/*
|
||||
/ _____) _ | | |
||||
( (____ _____ ____ _| |_ _____ ____| |__ |
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | | |
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_| |
||||
(C)2013 Semtech |
||||
___ _____ _ ___ _ _____ ___ ___ ___ ___ |
||||
/ __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| |
||||
\__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| |
||||
|___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| |
||||
embedded.connectivity.solutions=============== |
||||
|
||||
Description: LoRa MAC layer implementation |
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project |
||||
|
||||
Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jaeckle ( STACKFORCE ) |
||||
*/ |
||||
#include <stdlib.h> |
||||
#include <stdint.h> |
||||
#include "utilities.h" |
||||
|
||||
#include "aes.h" |
||||
#include "cmac.h" |
||||
|
||||
#include "LoRaMacCrypto.h" |
||||
|
||||
/*!
|
||||
* CMAC/AES Message Integrity Code (MIC) Block B0 size |
||||
*/ |
||||
#define LORAMAC_MIC_BLOCK_B0_SIZE 16 |
||||
|
||||
/*!
|
||||
* MIC field computation initial data |
||||
*/ |
||||
static uint8_t MicBlockB0[] = { 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 |
||||
}; |
||||
|
||||
/*!
|
||||
* Contains the computed MIC field. |
||||
* |
||||
* \remark Only the 4 first bytes are used |
||||
*/ |
||||
static uint8_t Mic[16]; |
||||
|
||||
/*!
|
||||
* Encryption aBlock and sBlock |
||||
*/ |
||||
static uint8_t aBlock[] = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 |
||||
}; |
||||
static uint8_t sBlock[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 |
||||
}; |
||||
|
||||
/*!
|
||||
* AES computation context variable |
||||
*/ |
||||
static aes_context AesContext; |
||||
|
||||
/*!
|
||||
* CMAC computation context variable |
||||
*/ |
||||
static AES_CMAC_CTX AesCmacCtx[1]; |
||||
|
||||
/*!
|
||||
* \brief Computes the LoRaMAC frame MIC field
|
||||
* |
||||
* \param [IN] buffer Data buffer |
||||
* \param [IN] size Data buffer size |
||||
* \param [IN] key AES key to be used |
||||
* \param [IN] address Frame address |
||||
* \param [IN] dir Frame direction [0: uplink, 1: downlink] |
||||
* \param [IN] sequenceCounter Frame sequence counter |
||||
* \param [OUT] mic Computed MIC field |
||||
*/ |
||||
void LoRaMacComputeMic( const uint8_t *buffer, uint16_t size, const uint8_t *key, uint32_t address, uint8_t dir, uint32_t sequenceCounter, uint32_t *mic ) |
||||
{ |
||||
MicBlockB0[5] = dir; |
||||
|
||||
MicBlockB0[6] = ( address ) & 0xFF; |
||||
MicBlockB0[7] = ( address >> 8 ) & 0xFF; |
||||
MicBlockB0[8] = ( address >> 16 ) & 0xFF; |
||||
MicBlockB0[9] = ( address >> 24 ) & 0xFF; |
||||
|
||||
MicBlockB0[10] = ( sequenceCounter ) & 0xFF; |
||||
MicBlockB0[11] = ( sequenceCounter >> 8 ) & 0xFF; |
||||
MicBlockB0[12] = ( sequenceCounter >> 16 ) & 0xFF; |
||||
MicBlockB0[13] = ( sequenceCounter >> 24 ) & 0xFF; |
||||
|
||||
MicBlockB0[15] = size & 0xFF; |
||||
|
||||
AES_CMAC_Init( AesCmacCtx ); |
||||
|
||||
AES_CMAC_SetKey( AesCmacCtx, key ); |
||||
|
||||
AES_CMAC_Update( AesCmacCtx, MicBlockB0, LORAMAC_MIC_BLOCK_B0_SIZE ); |
||||
|
||||
AES_CMAC_Update( AesCmacCtx, buffer, size & 0xFF ); |
||||
|
||||
AES_CMAC_Final( Mic, AesCmacCtx ); |
||||
|
||||
*mic = ( uint32_t )( ( uint32_t )Mic[3] << 24 | ( uint32_t )Mic[2] << 16 | ( uint32_t )Mic[1] << 8 | ( uint32_t )Mic[0] ); |
||||
} |
||||
|
||||
void LoRaMacPayloadEncrypt( const uint8_t *buffer, uint16_t size, const uint8_t *key, uint32_t address, uint8_t dir, uint32_t sequenceCounter, uint8_t *encBuffer ) |
||||
{ |
||||
uint16_t i; |
||||
uint8_t bufferIndex = 0; |
||||
uint16_t ctr = 1; |
||||
|
||||
memset1( AesContext.ksch, '\0', 240 ); |
||||
aes_set_key( key, 16, &AesContext ); |
||||
|
||||
aBlock[5] = dir; |
||||
|
||||
aBlock[6] = ( address ) & 0xFF; |
||||
aBlock[7] = ( address >> 8 ) & 0xFF; |
||||
aBlock[8] = ( address >> 16 ) & 0xFF; |
||||
aBlock[9] = ( address >> 24 ) & 0xFF; |
||||
|
||||
aBlock[10] = ( sequenceCounter ) & 0xFF; |
||||
aBlock[11] = ( sequenceCounter >> 8 ) & 0xFF; |
||||
aBlock[12] = ( sequenceCounter >> 16 ) & 0xFF; |
||||
aBlock[13] = ( sequenceCounter >> 24 ) & 0xFF; |
||||
|
||||
while( size >= 16 ) |
||||
{ |
||||
aBlock[15] = ( ( ctr ) & 0xFF ); |
||||
ctr++; |
||||
aes_encrypt( aBlock, sBlock, &AesContext ); |
||||
for( i = 0; i < 16; i++ ) |
||||
{ |
||||
encBuffer[bufferIndex + i] = buffer[bufferIndex + i] ^ sBlock[i]; |
||||
} |
||||
size -= 16; |
||||
bufferIndex += 16; |
||||
} |
||||
|
||||
if( size > 0 ) |
||||
{ |
||||
aBlock[15] = ( ( ctr ) & 0xFF ); |
||||
aes_encrypt( aBlock, sBlock, &AesContext ); |
||||
for( i = 0; i < size; i++ ) |
||||
{ |
||||
encBuffer[bufferIndex + i] = buffer[bufferIndex + i] ^ sBlock[i]; |
||||
} |
||||
} |
||||
} |
||||
|
||||
void LoRaMacPayloadDecrypt( const uint8_t *buffer, uint16_t size, const uint8_t *key, uint32_t address, uint8_t dir, uint32_t sequenceCounter, uint8_t *decBuffer ) |
||||
{ |
||||
LoRaMacPayloadEncrypt( buffer, size, key, address, dir, sequenceCounter, decBuffer ); |
||||
} |
||||
|
||||
void LoRaMacJoinComputeMic( const uint8_t *buffer, uint16_t size, const uint8_t *key, uint32_t *mic ) |
||||
{ |
||||
AES_CMAC_Init( AesCmacCtx ); |
||||
|
||||
AES_CMAC_SetKey( AesCmacCtx, key ); |
||||
|
||||
AES_CMAC_Update( AesCmacCtx, buffer, size & 0xFF ); |
||||
|
||||
AES_CMAC_Final( Mic, AesCmacCtx ); |
||||
|
||||
*mic = ( uint32_t )( ( uint32_t )Mic[3] << 24 | ( uint32_t )Mic[2] << 16 | ( uint32_t )Mic[1] << 8 | ( uint32_t )Mic[0] ); |
||||
} |
||||
|
||||
void LoRaMacJoinDecrypt( const uint8_t *buffer, uint16_t size, const uint8_t *key, uint8_t *decBuffer ) |
||||
{ |
||||
memset1( AesContext.ksch, '\0', 240 ); |
||||
aes_set_key( key, 16, &AesContext ); |
||||
aes_encrypt( buffer, decBuffer, &AesContext ); |
||||
// Check if optional CFList is included
|
||||
if( size >= 16 ) |
||||
{ |
||||
aes_encrypt( buffer + 16, decBuffer + 16, &AesContext ); |
||||
} |
||||
} |
||||
|
||||
void LoRaMacJoinComputeSKeys( const uint8_t *key, const uint8_t *appNonce, uint16_t devNonce, uint8_t *nwkSKey, uint8_t *appSKey ) |
||||
{ |
||||
uint8_t nonce[16]; |
||||
uint8_t *pDevNonce = ( uint8_t * )&devNonce; |
||||
|
||||
memset1( AesContext.ksch, '\0', 240 ); |
||||
aes_set_key( key, 16, &AesContext ); |
||||
|
||||
memset1( nonce, 0, sizeof( nonce ) ); |
||||
nonce[0] = 0x01; |
||||
memcpy1( nonce + 1, appNonce, 6 ); |
||||
memcpy1( nonce + 7, pDevNonce, 2 ); |
||||
aes_encrypt( nonce, nwkSKey, &AesContext ); |
||||
|
||||
memset1( nonce, 0, sizeof( nonce ) ); |
||||
nonce[0] = 0x02; |
||||
memcpy1( nonce + 1, appNonce, 6 ); |
||||
memcpy1( nonce + 7, pDevNonce, 2 ); |
||||
aes_encrypt( nonce, appSKey, &AesContext ); |
||||
} |
@ -0,0 +1,111 @@ |
||||
/*!
|
||||
* \file LoRaMacCrypto.h |
||||
* |
||||
* \brief LoRa MAC layer cryptography implementation |
||||
* |
||||
* \copyright Revised BSD License, see section \ref LICENSE. |
||||
* |
||||
* \code |
||||
* ______ _ |
||||
* / _____) _ | | |
||||
* ( (____ _____ ____ _| |_ _____ ____| |__ |
||||
* \____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
* _____) ) ____| | | || |_| ____( (___| | | | |
||||
* (______/|_____)_|_|_| \__)_____)\____)_| |_| |
||||
* (C)2013 Semtech |
||||
* |
||||
* ___ _____ _ ___ _ _____ ___ ___ ___ ___ |
||||
* / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| |
||||
* \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| |
||||
* |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| |
||||
* embedded.connectivity.solutions=============== |
||||
* |
||||
* \endcode |
||||
* |
||||
* \author Miguel Luis ( Semtech ) |
||||
* |
||||
* \author Gregory Cristian ( Semtech ) |
||||
* |
||||
* \author Daniel Jaeckle ( STACKFORCE ) |
||||
* |
||||
* \defgroup LORAMAC_CRYPTO LoRa MAC layer cryptography implementation |
||||
* This module covers the implementation of cryptographic functions |
||||
* of the LoRaMAC layer. |
||||
* \{ |
||||
*/ |
||||
#ifndef __LORAMAC_CRYPTO_H__ |
||||
#define __LORAMAC_CRYPTO_H__ |
||||
|
||||
/*!
|
||||
* Computes the LoRaMAC frame MIC field |
||||
* |
||||
* \param [IN] buffer - Data buffer |
||||
* \param [IN] size - Data buffer size |
||||
* \param [IN] key - AES key to be used |
||||
* \param [IN] address - Frame address |
||||
* \param [IN] dir - Frame direction [0: uplink, 1: downlink] |
||||
* \param [IN] sequenceCounter - Frame sequence counter |
||||
* \param [OUT] mic - Computed MIC field |
||||
*/ |
||||
void LoRaMacComputeMic( const uint8_t *buffer, uint16_t size, const uint8_t *key, uint32_t address, uint8_t dir, uint32_t sequenceCounter, uint32_t *mic ); |
||||
|
||||
/*!
|
||||
* Computes the LoRaMAC payload encryption |
||||
* |
||||
* \param [IN] buffer - Data buffer |
||||
* \param [IN] size - Data buffer size |
||||
* \param [IN] key - AES key to be used |
||||
* \param [IN] address - Frame address |
||||
* \param [IN] dir - Frame direction [0: uplink, 1: downlink] |
||||
* \param [IN] sequenceCounter - Frame sequence counter |
||||
* \param [OUT] encBuffer - Encrypted buffer |
||||
*/ |
||||
void LoRaMacPayloadEncrypt( const uint8_t *buffer, uint16_t size, const uint8_t *key, uint32_t address, uint8_t dir, uint32_t sequenceCounter, uint8_t *encBuffer ); |
||||
|
||||
/*!
|
||||
* Computes the LoRaMAC payload decryption |
||||
* |
||||
* \param [IN] buffer - Data buffer |
||||
* \param [IN] size - Data buffer size |
||||
* \param [IN] key - AES key to be used |
||||
* \param [IN] address - Frame address |
||||
* \param [IN] dir - Frame direction [0: uplink, 1: downlink] |
||||
* \param [IN] sequenceCounter - Frame sequence counter |
||||
* \param [OUT] decBuffer - Decrypted buffer |
||||
*/ |
||||
void LoRaMacPayloadDecrypt( const uint8_t *buffer, uint16_t size, const uint8_t *key, uint32_t address, uint8_t dir, uint32_t sequenceCounter, uint8_t *decBuffer ); |
||||
|
||||
/*!
|
||||
* Computes the LoRaMAC Join Request frame MIC field |
||||
* |
||||
* \param [IN] buffer - Data buffer |
||||
* \param [IN] size - Data buffer size |
||||
* \param [IN] key - AES key to be used |
||||
* \param [OUT] mic - Computed MIC field |
||||
*/ |
||||
void LoRaMacJoinComputeMic( const uint8_t *buffer, uint16_t size, const uint8_t *key, uint32_t *mic ); |
||||
|
||||
/*!
|
||||
* Computes the LoRaMAC join frame decryption |
||||
* |
||||
* \param [IN] buffer - Data buffer |
||||
* \param [IN] size - Data buffer size |
||||
* \param [IN] key - AES key to be used |
||||
* \param [OUT] decBuffer - Decrypted buffer |
||||
*/ |
||||
void LoRaMacJoinDecrypt( const uint8_t *buffer, uint16_t size, const uint8_t *key, uint8_t *decBuffer ); |
||||
|
||||
/*!
|
||||
* Computes the LoRaMAC join frame decryption |
||||
* |
||||
* \param [IN] key - AES key to be used |
||||
* \param [IN] appNonce - Application nonce |
||||
* \param [IN] devNonce - Device nonce |
||||
* \param [OUT] nwkSKey - Network session key |
||||
* \param [OUT] appSKey - Application session key |
||||
*/ |
||||
void LoRaMacJoinComputeSKeys( const uint8_t *key, const uint8_t *appNonce, uint16_t devNonce, uint8_t *nwkSKey, uint8_t *appSKey ); |
||||
|
||||
/*! \} defgroup LORAMAC */ |
||||
|
||||
#endif // __LORAMAC_CRYPTO_H__
|
@ -0,0 +1,81 @@ |
||||
/*!
|
||||
* \file LoRaMacTest.h |
||||
* |
||||
* \brief LoRa MAC layer test function implementation |
||||
* |
||||
* \copyright Revised BSD License, see section \ref LICENSE. |
||||
* |
||||
* \code |
||||
* ______ _ |
||||
* / _____) _ | | |
||||
* ( (____ _____ ____ _| |_ _____ ____| |__ |
||||
* \____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
* _____) ) ____| | | || |_| ____( (___| | | | |
||||
* (______/|_____)_|_|_| \__)_____)\____)_| |_| |
||||
* (C)2013 Semtech |
||||
* |
||||
* ___ _____ _ ___ _ _____ ___ ___ ___ ___ |
||||
* / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| |
||||
* \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| |
||||
* |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| |
||||
* embedded.connectivity.solutions=============== |
||||
* |
||||
* \endcode |
||||
* |
||||
* \author Miguel Luis ( Semtech ) |
||||
* |
||||
* \author Gregory Cristian ( Semtech ) |
||||
* |
||||
* \author Daniel Jaeckle ( STACKFORCE ) |
||||
* |
||||
* \defgroup LORAMACTEST LoRa MAC layer test function implementation |
||||
* This module specifies the API implementation of test function of the LoRaMAC layer. |
||||
* The functions in this file are only for testing purposes only. |
||||
* \{ |
||||
*/ |
||||
#ifndef __LORAMACTEST_H__ |
||||
#define __LORAMACTEST_H__ |
||||
|
||||
/*!
|
||||
* \brief Enabled or disables the reception windows |
||||
* |
||||
* \details This is a test function. It shall be used for testing purposes only. |
||||
* Changing this attribute may lead to a non-conformance LoRaMac operation. |
||||
* |
||||
* \param [IN] enable - Enabled or disables the reception windows |
||||
*/ |
||||
void LoRaMacTestRxWindowsOn( bool enable ); |
||||
|
||||
/*!
|
||||
* \brief Enables the MIC field test |
||||
* |
||||
* \details This is a test function. It shall be used for testing purposes only. |
||||
* Changing this attribute may lead to a non-conformance LoRaMac operation. |
||||
* |
||||
* \param [IN] txPacketCounter - Fixed Tx packet counter value |
||||
*/ |
||||
void LoRaMacTestSetMic( uint16_t txPacketCounter ); |
||||
|
||||
/*!
|
||||
* \brief Enabled or disables the duty cycle |
||||
* |
||||
* \details This is a test function. It shall be used for testing purposes only. |
||||
* Changing this attribute may lead to a non-conformance LoRaMac operation. |
||||
* |
||||
* \param [IN] enable - Enabled or disables the duty cycle |
||||
*/ |
||||
void LoRaMacTestSetDutyCycleOn( bool enable ); |
||||
|
||||
/*!
|
||||
* \brief Sets the channel index |
||||
* |
||||
* \details This is a test function. It shall be used for testing purposes only. |
||||
* Changing this attribute may lead to a non-conformance LoRaMac operation. |
||||
* |
||||
* \param [IN] channel - Channel index |
||||
*/ |
||||
void LoRaMacTestSetChannel( uint8_t channel ); |
||||
|
||||
/*! \} defgroup LORAMACTEST */ |
||||
|
||||
#endif // __LORAMACTEST_H__
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,503 @@ |
||||
/*!
|
||||
* \file RegionAS923.h |
||||
* |
||||
* \brief Region definition for AS923 |
||||
* |
||||
* \copyright Revised BSD License, see section \ref LICENSE. |
||||
* |
||||
* \code |
||||
* ______ _ |
||||
* / _____) _ | | |
||||
* ( (____ _____ ____ _| |_ _____ ____| |__ |
||||
* \____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
* _____) ) ____| | | || |_| ____( (___| | | | |
||||
* (______/|_____)_|_|_| \__)_____)\____)_| |_| |
||||
* (C)2013 Semtech |
||||
* |
||||
* ___ _____ _ ___ _ _____ ___ ___ ___ ___ |
||||
* / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| |
||||
* \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| |
||||
* |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| |
||||
* embedded.connectivity.solutions=============== |
||||
* |
||||
* \endcode |
||||
* |
||||
* \author Miguel Luis ( Semtech ) |
||||
* |
||||
* \author Gregory Cristian ( Semtech ) |
||||
* |
||||
* \author Daniel Jaeckle ( STACKFORCE ) |
||||
* |
||||
* \defgroup REGIONAS923 Region AS923 |
||||
* Implementation according to LoRaWAN Specification v1.0.2. |
||||
* \{ |
||||
*/ |
||||
#ifndef __REGION_AS923_H__ |
||||
#define __REGION_AS923_H__ |
||||
|
||||
/*!
|
||||
* LoRaMac maximum number of channels |
||||
*/ |
||||
#define AS923_MAX_NB_CHANNELS 16 |
||||
|
||||
/*!
|
||||
* Number of default channels |
||||
*/ |
||||
#define AS923_NUMB_DEFAULT_CHANNELS 2 |
||||
|
||||
/*!
|
||||
* Number of channels to apply for the CF list |
||||
*/ |
||||
#define AS923_NUMB_CHANNELS_CF_LIST 5 |
||||
|
||||
/*!
|
||||
* Minimal datarate that can be used by the node |
||||
*/ |
||||
#define AS923_TX_MIN_DATARATE DR_0 |
||||
|
||||
/*!
|
||||
* Maximal datarate that can be used by the node |
||||
*/ |
||||
#define AS923_TX_MAX_DATARATE DR_7 |
||||
|
||||
/*!
|
||||
* Minimal datarate that can be used by the node |
||||
*/ |
||||
#define AS923_RX_MIN_DATARATE DR_0 |
||||
|
||||
/*!
|
||||
* Maximal datarate that can be used by the node |
||||
*/ |
||||
#define AS923_RX_MAX_DATARATE DR_7 |
||||
|
||||
/*!
|
||||
* Default datarate used by the node |
||||
*/ |
||||
#define AS923_DEFAULT_DATARATE DR_2 |
||||
|
||||
/*!
|
||||
* The minimum datarate which is used when the |
||||
* dwell time is limited. |
||||
*/ |
||||
#define AS923_DWELL_LIMIT_DATARATE DR_2 |
||||
|
||||
/*!
|
||||
* Minimal Rx1 receive datarate offset |
||||
*/ |
||||
#define AS923_MIN_RX1_DR_OFFSET 0 |
||||
|
||||
/*!
|
||||
* Maximal Rx1 receive datarate offset |
||||
*/ |
||||
#define AS923_MAX_RX1_DR_OFFSET 7 |
||||
|
||||
/*!
|
||||
* Default Rx1 receive datarate offset |
||||
*/ |
||||
#define AS923_DEFAULT_RX1_DR_OFFSET 0 |
||||
|
||||
/*!
|
||||
* Minimal Tx output power that can be used by the node |
||||
*/ |
||||
#define AS923_MIN_TX_POWER TX_POWER_7 |
||||
|
||||
/*!
|
||||
* Maximal Tx output power that can be used by the node |
||||
*/ |
||||
#define AS923_MAX_TX_POWER TX_POWER_0 |
||||
|
||||
/*!
|
||||
* Default Tx output power used by the node |
||||
*/ |
||||
#define AS923_DEFAULT_TX_POWER TX_POWER_0 |
||||
|
||||
/*!
|
||||
* Default uplink dwell time configuration |
||||
*/ |
||||
#define AS923_DEFAULT_UPLINK_DWELL_TIME 1 |
||||
|
||||
/*!
|
||||
* Default downlink dwell time configuration |
||||
*/ |
||||
#define AS923_DEFAULT_DOWNLINK_DWELL_TIME 1 |
||||
|
||||
/*!
|
||||
* Default Max EIRP |
||||
*/ |
||||
#define AS923_DEFAULT_MAX_EIRP 16.0f |
||||
|
||||
/*!
|
||||
* Default antenna gain |
||||
*/ |
||||
#define AS923_DEFAULT_ANTENNA_GAIN 2.15f |
||||
|
||||
/*!
|
||||
* ADR Ack limit |
||||
*/ |
||||
#define AS923_ADR_ACK_LIMIT 64 |
||||
|
||||
/*!
|
||||
* ADR Ack delay |
||||
*/ |
||||
#define AS923_ADR_ACK_DELAY 32 |
||||
|
||||
/*!
|
||||
* Enabled or disabled the duty cycle |
||||
*/ |
||||
#define AS923_DUTY_CYCLE_ENABLED 0 |
||||
|
||||
/*!
|
||||
* Maximum RX window duration |
||||
*/ |
||||
#define AS923_MAX_RX_WINDOW 3000 |
||||
|
||||
/*!
|
||||
* Receive delay 1 |
||||
*/ |
||||
#define AS923_RECEIVE_DELAY1 1000 |
||||
|
||||
/*!
|
||||
* Receive delay 2 |
||||
*/ |
||||
#define AS923_RECEIVE_DELAY2 2000 |
||||
|
||||
/*!
|
||||
* Join accept delay 1 |
||||
*/ |
||||
#define AS923_JOIN_ACCEPT_DELAY1 5000 |
||||
|
||||
/*!
|
||||
* Join accept delay 2 |
||||
*/ |
||||
#define AS923_JOIN_ACCEPT_DELAY2 6000 |
||||
|
||||
/*!
|
||||
* Maximum frame counter gap |
||||
*/ |
||||
#define AS923_MAX_FCNT_GAP 16384 |
||||
|
||||
/*!
|
||||
* Ack timeout |
||||
*/ |
||||
#define AS923_ACKTIMEOUT 2000 |
||||
|
||||
/*!
|
||||
* Random ack timeout limits |
||||
*/ |
||||
#define AS923_ACK_TIMEOUT_RND 1000 |
||||
|
||||
#if ( AS923_DEFAULT_DATARATE > DR_5 ) |
||||
#error "A default DR higher than DR_5 may lead to connectivity loss." |
||||
#endif |
||||
|
||||
/*!
|
||||
* Second reception window channel frequency definition. |
||||
*/ |
||||
#define AS923_RX_WND_2_FREQ 923200000 |
||||
|
||||
/*!
|
||||
* Second reception window channel datarate definition. |
||||
*/ |
||||
#define AS923_RX_WND_2_DR DR_2 |
||||
|
||||
/*!
|
||||
* Maximum number of bands |
||||
*/ |
||||
#define AS923_MAX_NB_BANDS 1 |
||||
|
||||
/*!
|
||||
* Band 0 definition |
||||
* { DutyCycle, TxMaxPower, LastTxDoneTime, TimeOff } |
||||
*/ |
||||
#define AS923_BAND0 { 100, AS923_MAX_TX_POWER, 0, 0 } // 1.0 %
|
||||
|
||||
/*!
|
||||
* LoRaMac default channel 1 |
||||
* Channel = { Frequency [Hz], RX1 Frequency [Hz], { ( ( DrMax << 4 ) | DrMin ) }, Band } |
||||
*/ |
||||
#define AS923_LC1 { 923200000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 } |
||||
|
||||
/*!
|
||||
* LoRaMac default channel 2 |
||||
* Channel = { Frequency [Hz], RX1 Frequency [Hz], { ( ( DrMax << 4 ) | DrMin ) }, Band } |
||||
*/ |
||||
#define AS923_LC2 { 923400000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 } |
||||
|
||||
/*!
|
||||
* LoRaMac channels which are allowed for the join procedure |
||||
*/ |
||||
#define AS923_JOIN_CHANNELS ( uint16_t )( LC( 1 ) | LC( 2 ) ) |
||||
|
||||
/*!
|
||||
* RSSI threshold for a free channel [dBm] |
||||
*/ |
||||
#define AS923_RSSI_FREE_TH -85 |
||||
|
||||
/*!
|
||||
* Specifies the time the node performs a carrier sense |
||||
*/ |
||||
#define AS923_CARRIER_SENSE_TIME 6 |
||||
|
||||
/*!
|
||||
* Data rates table definition |
||||
*/ |
||||
static const uint8_t DataratesAS923[] = { 12, 11, 10, 9, 8, 7, 7, 50 }; |
||||
|
||||
/*!
|
||||
* Bandwidths table definition in Hz |
||||
*/ |
||||
static const uint32_t BandwidthsAS923[] = { 125000, 125000, 125000, 125000, 125000, 125000, 250000, 0 }; |
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Cannot operate with repeater. |
||||
* The table is valid for the dwell time configuration of 0 for uplinks and downlinks. |
||||
*/ |
||||
static const uint8_t MaxPayloadOfDatarateDwell0AS923[] = { 51, 51, 51, 115, 242, 242, 242, 242 }; |
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Can operate with repeater. |
||||
* The table is valid for the dwell time configuration of 0 for uplinks and downlinks. The table provides |
||||
* repeater support. |
||||
*/ |
||||
static const uint8_t MaxPayloadOfDatarateRepeaterDwell0AS923[] = { 51, 51, 51, 115, 222, 222, 222, 222 }; |
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Can operate with and without repeater. |
||||
* The table proides repeater support. The table is only valid for uplinks. |
||||
*/ |
||||
static const uint8_t MaxPayloadOfDatarateDwell1UpAS923[] = { 0, 0, 11, 53, 125, 242, 242, 242 }; |
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Can operate with and without repeater. |
||||
* The table proides repeater support. The table is only valid for downlinks. |
||||
*/ |
||||
static const uint8_t MaxPayloadOfDatarateDwell1DownAS923[] = { 0, 0, 11, 53, 126, 242, 242, 242 }; |
||||
|
||||
/*!
|
||||
* Effective datarate offsets for receive window 1. |
||||
*/ |
||||
static const int8_t EffectiveRx1DrOffsetAS923[] = { 0, 1, 2, 3, 4, 5, -1, -2 }; |
||||
|
||||
/*!
|
||||
* \brief The function gets a value of a specific phy attribute. |
||||
* |
||||
* \param [IN] getPhy Pointer to the function parameters. |
||||
* |
||||
* \retval Returns a structure containing the PHY parameter. |
||||
*/ |
||||
PhyParam_t RegionAS923GetPhyParam( GetPhyParams_t* getPhy ); |
||||
|
||||
/*!
|
||||
* \brief Updates the last TX done parameters of the current channel. |
||||
* |
||||
* \param [IN] txDone Pointer to the function parameters. |
||||
*/ |
||||
void RegionAS923SetBandTxDone( SetBandTxDoneParams_t* txDone ); |
||||
|
||||
/*!
|
||||
* \brief Initializes the channels masks and the channels. |
||||
* |
||||
* \param [IN] type Sets the initialization type. |
||||
*/ |
||||
void RegionAS923InitDefaults( InitType_t type ); |
||||
|
||||
/*!
|
||||
* \brief Verifies a parameter. |
||||
* |
||||
* \param [IN] verify Pointer to the function parameters. |
||||
* |
||||
* \param [IN] type Sets the initialization type. |
||||
* |
||||
* \retval Returns true, if the parameter is valid. |
||||
*/ |
||||
bool RegionAS923Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute ); |
||||
|
||||
/*!
|
||||
* \brief The function parses the input buffer and sets up the channels of the |
||||
* CF list. |
||||
* |
||||
* \param [IN] applyCFList Pointer to the function parameters. |
||||
*/ |
||||
void RegionAS923ApplyCFList( ApplyCFListParams_t* applyCFList ); |
||||
|
||||
/*!
|
||||
* \brief Sets a channels mask. |
||||
* |
||||
* \param [IN] chanMaskSet Pointer to the function parameters. |
||||
* |
||||
* \retval Returns true, if the channels mask could be set. |
||||
*/ |
||||
bool RegionAS923ChanMaskSet( ChanMaskSetParams_t* chanMaskSet ); |
||||
|
||||
/*!
|
||||
* \brief Calculates the next datarate to set, when ADR is on or off. |
||||
* |
||||
* \param [IN] adrNext Pointer to the function parameters. |
||||
* |
||||
* \param [OUT] drOut The calculated datarate for the next TX. |
||||
* |
||||
* \param [OUT] txPowOut The TX power for the next TX. |
||||
* |
||||
* \param [OUT] adrAckCounter The calculated ADR acknowledgement counter. |
||||
* |
||||
* \retval Returns true, if an ADR request should be performed. |
||||
*/ |
||||
bool RegionAS923AdrNext( AdrNextParams_t* adrNext, int8_t* drOut, int8_t* txPowOut, uint32_t* adrAckCounter ); |
||||
|
||||
/*!
|
||||
* Computes the Rx window timeout and offset. |
||||
* |
||||
* \param [IN] datarate Rx window datarate index to be used |
||||
* |
||||
* \param [IN] minRxSymbols Minimum required number of symbols to detect an Rx frame. |
||||
* |
||||
* \param [IN] rxError System maximum timing error of the receiver. In milliseconds |
||||
* The receiver will turn on in a [-rxError : +rxError] ms |
||||
* interval around RxOffset |
||||
* |
||||
* \param [OUT]rxConfigParams Returns updated WindowTimeout and WindowOffset fields. |
||||
*/ |
||||
void RegionAS923ComputeRxWindowParameters( int8_t datarate, uint8_t minRxSymbols, uint32_t rxError, RxConfigParams_t *rxConfigParams ); |
||||
|
||||
/*!
|
||||
* \brief Configuration of the RX windows. |
||||
* |
||||
* \param [IN] rxConfig Pointer to the function parameters. |
||||
* |
||||
* \param [OUT] datarate The datarate index which was set. |
||||
* |
||||
* \retval Returns true, if the configuration was applied successfully. |
||||
*/ |
||||
bool RegionAS923RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate ); |
||||
|
||||
/*!
|
||||
* \brief TX configuration. |
||||
* |
||||
* \param [IN] txConfig Pointer to the function parameters. |
||||
* |
||||
* \param [OUT] txPower The tx power index which was set. |
||||
* |
||||
* \param [OUT] txTimeOnAir The time-on-air of the frame. |
||||
* |
||||
* \retval Returns true, if the configuration was applied successfully. |
||||
*/ |
||||
bool RegionAS923TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime_t* txTimeOnAir ); |
||||
|
||||
/*!
|
||||
* \brief The function processes a Link ADR Request. |
||||
* |
||||
* \param [IN] linkAdrReq Pointer to the function parameters. |
||||
* |
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification. |
||||
*/ |
||||
uint8_t RegionAS923LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, int8_t* txPowOut, uint8_t* nbRepOut, uint8_t* nbBytesParsed ); |
||||
|
||||
/*!
|
||||
* \brief The function processes a RX Parameter Setup Request. |
||||
* |
||||
* \param [IN] rxParamSetupReq Pointer to the function parameters. |
||||
* |
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification. |
||||
*/ |
||||
uint8_t RegionAS923RxParamSetupReq( RxParamSetupReqParams_t* rxParamSetupReq ); |
||||
|
||||
/*!
|
||||
* \brief The function processes a Channel Request. |
||||
* |
||||
* \param [IN] newChannelReq Pointer to the function parameters. |
||||
* |
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification. |
||||
*/ |
||||
uint8_t RegionAS923NewChannelReq( NewChannelReqParams_t* newChannelReq ); |
||||
|
||||
/*!
|
||||
* \brief The function processes a TX ParamSetup Request. |
||||
* |
||||
* \param [IN] txParamSetupReq Pointer to the function parameters. |
||||
* |
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification. |
||||
* Returns -1, if the functionality is not implemented. In this case, the end node |
||||
* shall not process the command. |
||||
*/ |
||||
int8_t RegionAS923TxParamSetupReq( TxParamSetupReqParams_t* txParamSetupReq ); |
||||
|
||||
/*!
|
||||
* \brief The function processes a DlChannel Request. |
||||
* |
||||
* \param [IN] dlChannelReq Pointer to the function parameters. |
||||
* |
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification. |
||||
*/ |
||||
uint8_t RegionAS923DlChannelReq( DlChannelReqParams_t* dlChannelReq ); |
||||
|
||||
/*!
|
||||
* \brief Alternates the datarate of the channel for the join request. |
||||
* |
||||
* \param [IN] alternateDr Pointer to the function parameters. |
||||
* |
||||
* \retval Datarate to apply. |
||||
*/ |
||||
int8_t RegionAS923AlternateDr( AlternateDrParams_t* alternateDr ); |
||||
|
||||
/*!
|
||||
* \brief Calculates the back-off time. |
||||
* |
||||
* \param [IN] calcBackOff Pointer to the function parameters. |
||||
*/ |
||||
void RegionAS923CalcBackOff( CalcBackOffParams_t* calcBackOff ); |
||||
|
||||
/*!
|
||||
* \brief Searches and set the next random available channel |
||||
* |
||||
* \param [OUT] channel Next channel to use for TX. |
||||
* |
||||
* \param [OUT] time Time to wait for the next transmission according to the duty |
||||
* cycle. |
||||
* |
||||
* \param [OUT] aggregatedTimeOff Updates the aggregated time off. |
||||
* |
||||
* \retval Function status [1: OK, 0: Unable to find a channel on the current datarate] |
||||
*/ |
||||
bool RegionAS923NextChannel( NextChanParams_t* nextChanParams, uint8_t* channel, TimerTime_t* time, TimerTime_t* aggregatedTimeOff ); |
||||
|
||||
/*!
|
||||
* \brief Adds a channel. |
||||
* |
||||
* \param [IN] channelAdd Pointer to the function parameters. |
||||
* |
||||
* \retval Status of the operation. |
||||
*/ |
||||
LoRaMacStatus_t RegionAS923ChannelAdd( ChannelAddParams_t* channelAdd ); |
||||
|
||||
/*!
|
||||
* \brief Removes a channel. |
||||
* |
||||
* \param [IN] channelRemove Pointer to the function parameters. |
||||
* |
||||
* \retval Returns true, if the channel was removed successfully. |
||||
*/ |
||||
bool RegionAS923ChannelsRemove( ChannelRemoveParams_t* channelRemove ); |
||||
|
||||
/*!
|
||||
* \brief Sets the radio into continuous wave mode. |
||||
* |
||||
* \param [IN] continuousWave Pointer to the function parameters. |
||||
*/ |
||||
void RegionAS923SetContinuousWave( ContinuousWaveParams_t* continuousWave ); |
||||
|
||||
/*!
|
||||
* \brief Computes new datarate according to the given offset |
||||
* |
||||
* \param [IN] downlinkDwellTime Downlink dwell time configuration. 0: No limit, 1: 400ms |
||||
* |
||||
* \param [IN] dr Current datarate |
||||
* |
||||
* \param [IN] drOffset Offset to be applied |
||||
* |
||||
* \retval newDr Computed datarate. |
||||
*/ |
||||
uint8_t RegionAS923ApplyDrOffset( uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset ); |
||||
|
||||
/*! \} defgroup REGIONAS923 */ |
||||
|
||||
#endif // __REGION_AS923_H__
|
@ -0,0 +1,863 @@ |
||||
/*
|
||||
/ _____) _ | | |
||||
( (____ _____ ____ _| |_ _____ ____| |__ |
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | | |
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_| |
||||
(C)2013 Semtech |
||||
___ _____ _ ___ _ _____ ___ ___ ___ ___ |
||||
/ __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| |
||||
\__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| |
||||
|___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| |
||||
embedded.connectivity.solutions=============== |
||||
|
||||
Description: LoRa MAC region AU915 implementation |
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project |
||||
|
||||
Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jaeckle ( STACKFORCE ) |
||||
*/ |
||||
#include <stdbool.h> |
||||
#include <string.h> |
||||
#include <stdint.h> |
||||
#include <math.h> |
||||
|
||||
#include "radio.h" |
||||
#include "timer.h" |
||||
#include "LoRaMac.h" |
||||
|
||||
#include "utilities.h" |
||||
|
||||
#include "Region.h" |
||||
#include "RegionCommon.h" |
||||
#include "RegionAU915.h" |
||||
#include "debug.h" |
||||
|
||||
// Definitions
|
||||
#define CHANNELS_MASK_SIZE 6 |
||||
|
||||
// Global attributes
|
||||
/*!
|
||||
* LoRaMAC channels |
||||
*/ |
||||
static ChannelParams_t Channels[AU915_MAX_NB_CHANNELS]; |
||||
|
||||
/*!
|
||||
* LoRaMac bands |
||||
*/ |
||||
static Band_t Bands[AU915_MAX_NB_BANDS] = |
||||
{ |
||||
AU915_BAND0 |
||||
}; |
||||
|
||||
/*!
|
||||
* LoRaMac channels mask |
||||
*/ |
||||
static uint16_t ChannelsMask[CHANNELS_MASK_SIZE]; |
||||
|
||||
/*!
|
||||
* LoRaMac channels remaining |
||||
*/ |
||||
static uint16_t ChannelsMaskRemaining[CHANNELS_MASK_SIZE]; |
||||
|
||||
/*!
|
||||
* LoRaMac channels default mask |
||||
*/ |
||||
static uint16_t ChannelsDefaultMask[CHANNELS_MASK_SIZE]; |
||||
|
||||
// Static functions
|
||||
static int8_t GetNextLowerTxDr( int8_t dr, int8_t minDr ) |
||||
{ |
||||
uint8_t nextLowerDr = 0; |
||||
|
||||
if( dr == minDr ) |
||||
{ |
||||
nextLowerDr = minDr; |
||||
} |
||||
else |
||||
{ |
||||
nextLowerDr = dr - 1; |
||||
} |
||||
return nextLowerDr; |
||||
} |
||||
|
||||
static uint32_t GetBandwidth( uint32_t drIndex ) |
||||
{ |
||||
switch( BandwidthsAU915[drIndex] ) |
||||
{ |
||||
default: |
||||
case 125000: |
||||
return 0; |
||||
case 250000: |
||||
return 1; |
||||
case 500000: |
||||
return 2; |
||||
} |
||||
} |
||||
|
||||
static int8_t LimitTxPower( int8_t txPower, int8_t maxBandTxPower, int8_t datarate, uint16_t* channelsMask ) |
||||
{ |
||||
int8_t txPowerResult = txPower; |
||||
|
||||
// Limit tx power to the band max
|
||||
txPowerResult = MAX( txPower, maxBandTxPower ); |
||||
|
||||
return txPowerResult; |
||||
} |
||||
|
||||
static uint8_t CountNbOfEnabledChannels( uint8_t datarate, uint16_t* channelsMask, ChannelParams_t* channels, Band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx ) |
||||
{ |
||||
uint8_t nbEnabledChannels = 0; |
||||
uint8_t delayTransmission = 0; |
||||
|
||||
for( uint8_t i = 0, k = 0; i < AU915_MAX_NB_CHANNELS; i += 16, k++ ) |
||||
{ |
||||
for( uint8_t j = 0; j < 16; j++ ) |
||||
{ |
||||
if( ( channelsMask[k] & ( 1 << j ) ) != 0 ) |
||||
{ |
||||
if( channels[i + j].Frequency == 0 ) |
||||
{ // Check if the channel is enabled
|
||||
continue; |
||||
} |
||||
if( RegionCommonValueInRange( datarate, channels[i + j].DrRange.Fields.Min, |
||||
channels[i + j].DrRange.Fields.Max ) == false ) |
||||
{ // Check if the current channel selection supports the given datarate
|
||||
continue; |
||||
} |
||||
if( bands[channels[i + j].Band].TimeOff > 0 ) |
||||
{ // Check if the band is available for transmission
|
||||
delayTransmission++; |
||||
continue; |
||||
} |
||||
enabledChannels[nbEnabledChannels++] = i + j; |
||||
} |
||||
} |
||||
} |
||||
|
||||
*delayTx = delayTransmission; |
||||
return nbEnabledChannels; |
||||
} |
||||
|
||||
PhyParam_t RegionAU915GetPhyParam( GetPhyParams_t* getPhy ) |
||||
{ |
||||
PhyParam_t phyParam = { 0 }; |
||||
|
||||
switch( getPhy->Attribute ) |
||||
{ |
||||
case PHY_MIN_RX_DR: |
||||
{ |
||||
phyParam.Value = AU915_RX_MIN_DATARATE; |
||||
break; |
||||
} |
||||
case PHY_MIN_TX_DR: |
||||
{ |
||||
phyParam.Value = AU915_TX_MIN_DATARATE; |
||||
break; |
||||
} |
||||
case PHY_DEF_TX_DR: |
||||
{ |
||||
phyParam.Value = AU915_DEFAULT_DATARATE; |
||||
break; |
||||
} |
||||
case PHY_NEXT_LOWER_TX_DR: |
||||
{ |
||||
phyParam.Value = GetNextLowerTxDr( getPhy->Datarate, AU915_TX_MIN_DATARATE ); |
||||
break; |
||||
} |
||||
case PHY_DEF_TX_POWER: |
||||
{ |
||||
phyParam.Value = AU915_DEFAULT_TX_POWER; |
||||
break; |
||||
} |
||||
case PHY_MAX_PAYLOAD: |
||||
{ |
||||
phyParam.Value = MaxPayloadOfDatarateAU915[getPhy->Datarate]; |
||||
break; |
||||
} |
||||
case PHY_MAX_PAYLOAD_REPEATER: |
||||
{ |
||||
phyParam.Value = MaxPayloadOfDatarateRepeaterAU915[getPhy->Datarate]; |
||||
break; |
||||
} |
||||
case PHY_DUTY_CYCLE: |
||||
{ |
||||
phyParam.Value = AU915_DUTY_CYCLE_ENABLED; |
||||
break; |
||||
} |
||||
case PHY_MAX_RX_WINDOW: |
||||
{ |
||||
phyParam.Value = AU915_MAX_RX_WINDOW; |
||||
break; |
||||
} |
||||
case PHY_RECEIVE_DELAY1: |
||||
{ |
||||
phyParam.Value = AU915_RECEIVE_DELAY1; |
||||
break; |
||||
} |
||||
case PHY_RECEIVE_DELAY2: |
||||
{ |
||||
phyParam.Value = AU915_RECEIVE_DELAY2; |
||||
break; |
||||
} |
||||
case PHY_JOIN_ACCEPT_DELAY1: |
||||
{ |
||||
phyParam.Value = AU915_JOIN_ACCEPT_DELAY1; |
||||
break; |
||||
} |
||||
case PHY_JOIN_ACCEPT_DELAY2: |
||||
{ |
||||
phyParam.Value = AU915_JOIN_ACCEPT_DELAY2; |
||||
break; |
||||
} |
||||
case PHY_MAX_FCNT_GAP: |
||||
{ |
||||
phyParam.Value = AU915_MAX_FCNT_GAP; |
||||
break; |
||||
} |
||||
case PHY_ACK_TIMEOUT: |
||||
{ |
||||
phyParam.Value = ( AU915_ACKTIMEOUT + randr( -AU915_ACK_TIMEOUT_RND, AU915_ACK_TIMEOUT_RND ) ); |
||||
break; |
||||
} |
||||
case PHY_DEF_DR1_OFFSET: |
||||
{ |
||||
phyParam.Value = AU915_DEFAULT_RX1_DR_OFFSET; |
||||
break; |
||||
} |
||||
case PHY_DEF_RX2_FREQUENCY: |
||||
{ |
||||
phyParam.Value = AU915_RX_WND_2_FREQ; |
||||
break; |
||||
} |
||||
case PHY_DEF_RX2_DR: |
||||
{ |
||||
phyParam.Value = AU915_RX_WND_2_DR; |
||||
break; |
||||
} |
||||
case PHY_CHANNELS_MASK: |
||||
{ |
||||
phyParam.ChannelsMask = ChannelsMask; |
||||
break; |
||||
} |
||||
case PHY_CHANNELS_DEFAULT_MASK: |
||||
{ |
||||
phyParam.ChannelsMask = ChannelsDefaultMask; |
||||
break; |
||||
} |
||||
case PHY_MAX_NB_CHANNELS: |
||||
{ |
||||
phyParam.Value = AU915_MAX_NB_CHANNELS; |
||||
break; |
||||
} |
||||
case PHY_CHANNELS: |
||||
{ |
||||
phyParam.Channels = Channels; |
||||
break; |
||||
} |
||||
case PHY_DEF_UPLINK_DWELL_TIME: |
||||
case PHY_DEF_DOWNLINK_DWELL_TIME: |
||||
{ |
||||
phyParam.Value = 0; |
||||
break; |
||||
} |
||||
case PHY_DEF_MAX_EIRP: |
||||
{ |
||||
phyParam.fValue = AU915_DEFAULT_MAX_EIRP; |
||||
break; |
||||
} |
||||
case PHY_DEF_ANTENNA_GAIN: |
||||
{ |
||||
phyParam.fValue = AU915_DEFAULT_ANTENNA_GAIN; |
||||
break; |
||||
} |
||||
case PHY_NB_JOIN_TRIALS: |
||||
case PHY_DEF_NB_JOIN_TRIALS: |
||||
{ |
||||
phyParam.Value = 2; |
||||
break; |
||||
} |
||||
default: |
||||
{ |
||||
break; |
||||
} |
||||
} |
||||
|
||||
return phyParam; |
||||
} |
||||
|
||||
void RegionAU915SetBandTxDone( SetBandTxDoneParams_t* txDone ) |
||||
{ |
||||
RegionCommonSetBandTxDone( txDone->Joined, &Bands[Channels[txDone->Channel].Band], txDone->LastTxDoneTime ); |
||||
} |
||||
|
||||
void RegionAU915InitDefaults( InitType_t type ) |
||||
{ |
||||
switch( type ) |
||||
{ |
||||
case INIT_TYPE_INIT: |
||||
{ |
||||
// Channels
|
||||
// 125 kHz channels
|
||||
for( uint8_t i = 0; i < AU915_MAX_NB_CHANNELS - 8; i++ ) |
||||
{ |
||||
Channels[i].Frequency = 915200000 + i * 200000; |
||||
Channels[i].DrRange.Value = ( DR_5 << 4 ) | DR_0; |
||||
Channels[i].Band = 0; |
||||
} |
||||
// 500 kHz channels
|
||||
for( uint8_t i = AU915_MAX_NB_CHANNELS - 8; i < AU915_MAX_NB_CHANNELS; i++ ) |
||||
{ |
||||
Channels[i].Frequency = 915900000 + ( i - ( AU915_MAX_NB_CHANNELS - 8 ) ) * 1600000; |
||||
Channels[i].DrRange.Value = ( DR_6 << 4 ) | DR_6; |
||||
Channels[i].Band = 0; |
||||
} |
||||
|
||||
// Initialize channels default mask
|
||||
ChannelsDefaultMask[0] = 0xFFFF; |
||||
ChannelsDefaultMask[1] = 0xFFFF; |
||||
ChannelsDefaultMask[2] = 0xFFFF; |
||||
ChannelsDefaultMask[3] = 0xFFFF; |
||||
ChannelsDefaultMask[4] = 0x00FF; |
||||
ChannelsDefaultMask[5] = 0x0000; |
||||
|
||||
// Copy channels default mask
|
||||
RegionCommonChanMaskCopy( ChannelsMask, ChannelsDefaultMask, 6 ); |
||||
|
||||
// Copy into channels mask remaining
|
||||
RegionCommonChanMaskCopy( ChannelsMaskRemaining, ChannelsMask, 6 ); |
||||
break; |
||||
} |
||||
case INIT_TYPE_RESTORE: |
||||
{ |
||||
// Copy channels default mask
|
||||
RegionCommonChanMaskCopy( ChannelsMask, ChannelsDefaultMask, 6 ); |
||||
|
||||
for( uint8_t i = 0; i < 6; i++ ) |
||||
{ // Copy-And the channels mask
|
||||
ChannelsMaskRemaining[i] &= ChannelsMask[i]; |
||||
} |
||||
break; |
||||
} |
||||
default: |
||||
{ |
||||
break; |
||||
} |
||||
} |
||||
} |
||||
|
||||
bool RegionAU915Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute ) |
||||
{ |
||||
switch( phyAttribute ) |
||||
{ |
||||
case PHY_TX_DR: |
||||
case PHY_DEF_TX_DR: |
||||
{ |
||||
return RegionCommonValueInRange( verify->DatarateParams.Datarate, AU915_TX_MIN_DATARATE, AU915_TX_MAX_DATARATE ); |
||||
} |
||||
case PHY_RX_DR: |
||||
{ |
||||
return RegionCommonValueInRange( verify->DatarateParams.Datarate, AU915_RX_MIN_DATARATE, AU915_RX_MAX_DATARATE ); |
||||
} |
||||
case PHY_DEF_TX_POWER: |
||||
case PHY_TX_POWER: |
||||
{ |
||||
// Remark: switched min and max!
|
||||
return RegionCommonValueInRange( verify->TxPower, AU915_MAX_TX_POWER, AU915_MIN_TX_POWER ); |
||||
} |
||||
case PHY_DUTY_CYCLE: |
||||
{ |
||||
return AU915_DUTY_CYCLE_ENABLED; |
||||
} |
||||
case PHY_NB_JOIN_TRIALS: |
||||
{ |
||||
if( verify->NbJoinTrials < 2 ) |
||||
{ |
||||
return false; |
||||
} |
||||
break; |
||||
} |
||||
default: |
||||
return false; |
||||
} |
||||
return true; |
||||
} |
||||
|
||||
void RegionAU915ApplyCFList( ApplyCFListParams_t* applyCFList ) |
||||
{ |
||||
return; |
||||
} |
||||
|
||||
bool RegionAU915ChanMaskSet( ChanMaskSetParams_t* chanMaskSet ) |
||||
{ |
||||
uint8_t nbChannels = RegionCommonCountChannels( chanMaskSet->ChannelsMaskIn, 0, 4 ); |
||||
|
||||
// Check the number of active channels
|
||||
// According to ACMA regulation, we require at least 20 125KHz channels, if
|
||||
// the node shall utilize 125KHz channels.
|
||||
if( ( nbChannels < 20 ) && |
||||
( nbChannels > 0 ) ) |
||||
{ |
||||
return false; |
||||
} |
||||
|
||||
switch( chanMaskSet->ChannelsMaskType ) |
||||
{ |
||||
case CHANNELS_MASK: |
||||
{ |
||||
RegionCommonChanMaskCopy( ChannelsMask, chanMaskSet->ChannelsMaskIn, 6 ); |
||||
|
||||
for( uint8_t i = 0; i < 6; i++ ) |
||||
{ // Copy-And the channels mask
|
||||
ChannelsMaskRemaining[i] &= ChannelsMask[i]; |
||||
} |
||||
break; |
||||
} |
||||
case CHANNELS_DEFAULT_MASK: |
||||
{ |
||||
RegionCommonChanMaskCopy( ChannelsDefaultMask, chanMaskSet->ChannelsMaskIn, 6 ); |
||||
break; |
||||
} |
||||
default: |
||||
return false; |
||||
} |
||||
return true; |
||||
} |
||||
|
||||
bool RegionAU915AdrNext( AdrNextParams_t* adrNext, int8_t* drOut, int8_t* txPowOut, uint32_t* adrAckCounter ) |
||||
{ |
||||
bool adrAckReq = false; |
||||
int8_t datarate = adrNext->Datarate; |
||||
int8_t txPower = adrNext->TxPower; |
||||
GetPhyParams_t getPhy; |
||||
PhyParam_t phyParam; |
||||
|
||||
// Report back the adr ack counter
|
||||
*adrAckCounter = adrNext->AdrAckCounter; |
||||
|
||||
if( adrNext->AdrEnabled == true ) |
||||
{ |
||||
if( datarate == AU915_TX_MIN_DATARATE ) |
||||
{ |
||||
*adrAckCounter = 0; |
||||
adrAckReq = false; |
||||
} |
||||
else |
||||
{ |
||||
if( adrNext->AdrAckCounter >= AU915_ADR_ACK_LIMIT ) |
||||
{ |
||||
adrAckReq = true; |
||||
txPower = AU915_MAX_TX_POWER; |
||||
} |
||||
else |
||||
{ |
||||
adrAckReq = false; |
||||
} |
||||
if( adrNext->AdrAckCounter >= ( AU915_ADR_ACK_LIMIT + AU915_ADR_ACK_DELAY ) ) |
||||
{ |
||||
if( ( adrNext->AdrAckCounter % AU915_ADR_ACK_DELAY ) == 1 ) |
||||
{ |
||||
// Decrease the datarate
|
||||
getPhy.Attribute = PHY_NEXT_LOWER_TX_DR; |
||||
getPhy.Datarate = datarate; |
||||
getPhy.UplinkDwellTime = adrNext->UplinkDwellTime; |
||||
phyParam = RegionAU915GetPhyParam( &getPhy ); |
||||
datarate = phyParam.Value; |
||||
|
||||
if( datarate == AU915_TX_MIN_DATARATE ) |
||||
{ |
||||
// We must set adrAckReq to false as soon as we reach the lowest datarate
|
||||
adrAckReq = false; |
||||
if( adrNext->UpdateChanMask == true ) |
||||
{ |
||||
// Re-enable default channels
|
||||
ChannelsMask[0] = 0xFFFF; |
||||
ChannelsMask[1] = 0xFFFF; |
||||
ChannelsMask[2] = 0xFFFF; |
||||
ChannelsMask[3] = 0xFFFF; |
||||
ChannelsMask[4] = 0x00FF; |
||||
ChannelsMask[5] = 0x0000; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
*drOut = datarate; |
||||
*txPowOut = txPower; |
||||
return adrAckReq; |
||||
} |
||||
|
||||
void RegionAU915ComputeRxWindowParameters( int8_t datarate, uint8_t minRxSymbols, uint32_t rxError, RxConfigParams_t *rxConfigParams ) |
||||
{ |
||||
double tSymbol = 0.0; |
||||
uint32_t radioWakeUpTime; |
||||
|
||||
// Get the datarate, perform a boundary check
|
||||
rxConfigParams->Datarate = MIN( datarate, AU915_RX_MAX_DATARATE ); |
||||
rxConfigParams->Bandwidth = GetBandwidth( rxConfigParams->Datarate ); |
||||
|
||||
tSymbol = RegionCommonComputeSymbolTimeLoRa( DataratesAU915[rxConfigParams->Datarate], BandwidthsAU915[rxConfigParams->Datarate] ); |
||||
|
||||
radioWakeUpTime = Radio.GetRadioWakeUpTime( ); |
||||
RegionCommonComputeRxWindowParameters( tSymbol, minRxSymbols, rxError, radioWakeUpTime, &rxConfigParams->WindowTimeout, &rxConfigParams->WindowOffset ); |
||||
} |
||||
|
||||
bool RegionAU915RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate ) |
||||
{ |
||||
int8_t dr = rxConfig->Datarate; |
||||
uint8_t maxPayload = 0; |
||||
int8_t phyDr = 0; |
||||
uint32_t frequency = rxConfig->Frequency; |
||||
|
||||
if( Radio.GetStatus( ) != RF_IDLE ) |
||||
{ |
||||
return false; |
||||
} |
||||
|
||||
if( rxConfig->Window == 0 ) |
||||
{ |
||||
// Apply window 1 frequency
|
||||
frequency = AU915_FIRST_RX1_CHANNEL + ( rxConfig->Channel % 8 ) * AU915_STEPWIDTH_RX1_CHANNEL; |
||||
} |
||||
|
||||
// Read the physical datarate from the datarates table
|
||||
phyDr = DataratesAU915[dr]; |
||||
|
||||
Radio.SetChannel( frequency ); |
||||
|
||||
// Radio configuration
|
||||
Radio.SetRxConfig( MODEM_LORA, rxConfig->Bandwidth, phyDr, 1, 0, 8, rxConfig->WindowTimeout, false, 0, false, 0, 0, true, rxConfig->RxContinuous ); |
||||
|
||||
if( rxConfig->RepeaterSupport == true ) |
||||
{ |
||||
maxPayload = MaxPayloadOfDatarateRepeaterAU915[dr]; |
||||
} |
||||
else |
||||
{ |
||||
maxPayload = MaxPayloadOfDatarateAU915[dr]; |
||||
} |
||||
Radio.SetMaxPayloadLength( MODEM_LORA, maxPayload + LORA_MAC_FRMPAYLOAD_OVERHEAD ); |
||||
DBG_PRINTF( "RX on freq %d Hz at DR %d\n\r", frequency, dr ); |
||||
|
||||
*datarate = (uint8_t) dr; |
||||
return true; |
||||
} |
||||
|
||||
bool RegionAU915TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime_t* txTimeOnAir ) |
||||
{ |
||||
int8_t phyDr = DataratesAU915[txConfig->Datarate]; |
||||
int8_t txPowerLimited = LimitTxPower( txConfig->TxPower, Bands[Channels[txConfig->Channel].Band].TxMaxPower, txConfig->Datarate, ChannelsMask ); |
||||
uint32_t bandwidth = GetBandwidth( txConfig->Datarate ); |
||||
int8_t phyTxPower = 0; |
||||
|
||||
// Calculate physical TX power
|
||||
phyTxPower = RegionCommonComputeTxPower( txPowerLimited, txConfig->MaxEirp, txConfig->AntennaGain ); |
||||
|
||||
// Setup the radio frequency
|
||||
Radio.SetChannel( Channels[txConfig->Channel].Frequency ); |
||||
|
||||
Radio.SetTxConfig( MODEM_LORA, phyTxPower, 0, bandwidth, phyDr, 1, 8, false, true, 0, 0, false, 3000 ); |
||||
DBG_PRINTF( "TX on freq %d Hz at DR %d\n\r", Channels[txConfig->Channel].Frequency, txConfig->Datarate ); |
||||
|
||||
// Setup maximum payload lenght of the radio driver
|
||||
Radio.SetMaxPayloadLength( MODEM_LORA, txConfig->PktLen ); |
||||
|
||||
*txTimeOnAir = Radio.TimeOnAir( MODEM_LORA, txConfig->PktLen ); |
||||
*txPower = txPowerLimited; |
||||
|
||||
return true; |
||||
} |
||||
|
||||
uint8_t RegionAU915LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, int8_t* txPowOut, uint8_t* nbRepOut, uint8_t* nbBytesParsed ) |
||||
{ |
||||
uint8_t status = 0x07; |
||||
RegionCommonLinkAdrParams_t linkAdrParams; |
||||
uint8_t nextIndex = 0; |
||||
uint8_t bytesProcessed = 0; |
||||
uint16_t channelsMask[6] = { 0, 0, 0, 0, 0, 0 }; |
||||
GetPhyParams_t getPhy; |
||||
PhyParam_t phyParam; |
||||
RegionCommonLinkAdrReqVerifyParams_t linkAdrVerifyParams; |
||||
|
||||
// Initialize local copy of channels mask
|
||||
RegionCommonChanMaskCopy( channelsMask, ChannelsMask, 6 ); |
||||
|
||||
while( bytesProcessed < linkAdrReq->PayloadSize ) |
||||
{ |
||||
nextIndex = RegionCommonParseLinkAdrReq( &( linkAdrReq->Payload[bytesProcessed] ), &linkAdrParams ); |
||||
|
||||
if( nextIndex == 0 ) |
||||
break; // break loop, since no more request has been found
|
||||
|
||||
// Update bytes processed
|
||||
bytesProcessed += nextIndex; |
||||
|
||||
// Revert status, as we only check the last ADR request for the channel mask KO
|
||||
status = 0x07; |
||||
|
||||
if( linkAdrParams.ChMaskCtrl == 6 ) |
||||
{ |
||||
// Enable all 125 kHz channels
|
||||
channelsMask[0] = 0xFFFF; |
||||
channelsMask[1] = 0xFFFF; |
||||
channelsMask[2] = 0xFFFF; |
||||
channelsMask[3] = 0xFFFF; |
||||
// Apply chMask to channels 64 to 71
|
||||
channelsMask[4] = linkAdrParams.ChMask; |
||||
} |
||||
else if( linkAdrParams.ChMaskCtrl == 7 ) |
||||
{ |
||||
// Disable all 125 kHz channels
|
||||
channelsMask[0] = 0x0000; |
||||
channelsMask[1] = 0x0000; |
||||
channelsMask[2] = 0x0000; |
||||
channelsMask[3] = 0x0000; |
||||
// Apply chMask to channels 64 to 71
|
||||
channelsMask[4] = linkAdrParams.ChMask; |
||||
} |
||||
else if( linkAdrParams.ChMaskCtrl == 5 ) |
||||
{ |
||||
// RFU
|
||||
status &= 0xFE; // Channel mask KO
|
||||
} |
||||
else |
||||
{ |
||||
channelsMask[linkAdrParams.ChMaskCtrl] = linkAdrParams.ChMask; |
||||
} |
||||
} |
||||
|
||||
// FCC 15.247 paragraph F mandates to hop on at least 2 125 kHz channels
|
||||
if( ( linkAdrParams.Datarate < DR_6 ) && ( RegionCommonCountChannels( channelsMask, 0, 4 ) < 2 ) ) |
||||
{ |
||||
status &= 0xFE; // Channel mask KO
|
||||
} |
||||
|
||||
// Get the minimum possible datarate
|
||||
getPhy.Attribute = PHY_MIN_TX_DR; |
||||
getPhy.UplinkDwellTime = linkAdrReq->UplinkDwellTime; |
||||
phyParam = RegionAU915GetPhyParam( &getPhy ); |
||||
|
||||
linkAdrVerifyParams.Status = status; |
||||
linkAdrVerifyParams.AdrEnabled = linkAdrReq->AdrEnabled; |
||||
linkAdrVerifyParams.Datarate = linkAdrParams.Datarate; |
||||
linkAdrVerifyParams.TxPower = linkAdrParams.TxPower; |
||||
linkAdrVerifyParams.NbRep = linkAdrParams.NbRep; |
||||
linkAdrVerifyParams.CurrentDatarate = linkAdrReq->CurrentDatarate; |
||||
linkAdrVerifyParams.CurrentTxPower = linkAdrReq->CurrentTxPower; |
||||
linkAdrVerifyParams.CurrentNbRep = linkAdrReq->CurrentNbRep; |
||||
linkAdrVerifyParams.NbChannels = AU915_MAX_NB_CHANNELS; |
||||
linkAdrVerifyParams.ChannelsMask = channelsMask; |
||||
linkAdrVerifyParams.MinDatarate = ( int8_t )phyParam.Value; |
||||
linkAdrVerifyParams.MaxDatarate = AU915_TX_MAX_DATARATE; |
||||
linkAdrVerifyParams.Channels = Channels; |
||||
linkAdrVerifyParams.MinTxPower = AU915_MIN_TX_POWER; |
||||
linkAdrVerifyParams.MaxTxPower = AU915_MAX_TX_POWER; |
||||
|
||||
// Verify the parameters and update, if necessary
|
||||
status = RegionCommonLinkAdrReqVerifyParams( &linkAdrVerifyParams, &linkAdrParams.Datarate, &linkAdrParams.TxPower, &linkAdrParams.NbRep ); |
||||
|
||||
// Update channelsMask if everything is correct
|
||||
if( status == 0x07 ) |
||||
{ |
||||
// Copy Mask
|
||||
RegionCommonChanMaskCopy( ChannelsMask, channelsMask, 6 ); |
||||
|
||||
ChannelsMaskRemaining[0] &= ChannelsMask[0]; |
||||
ChannelsMaskRemaining[1] &= ChannelsMask[1]; |
||||
ChannelsMaskRemaining[2] &= ChannelsMask[2]; |
||||
ChannelsMaskRemaining[3] &= ChannelsMask[3]; |
||||
ChannelsMaskRemaining[4] = ChannelsMask[4]; |
||||
ChannelsMaskRemaining[5] = ChannelsMask[5]; |
||||
} |
||||
|
||||
// Update status variables
|
||||
*drOut = linkAdrParams.Datarate; |
||||
*txPowOut = linkAdrParams.TxPower; |
||||
*nbRepOut = linkAdrParams.NbRep; |
||||
*nbBytesParsed = bytesProcessed; |
||||
|
||||
return status; |
||||
} |
||||
|
||||
uint8_t RegionAU915RxParamSetupReq( RxParamSetupReqParams_t* rxParamSetupReq ) |
||||
{ |
||||
uint8_t status = 0x07; |
||||
uint32_t freq = rxParamSetupReq->Frequency; |
||||
|
||||
// Verify radio frequency
|
||||
if( ( Radio.CheckRfFrequency( freq ) == false ) || |
||||
( freq < AU915_FIRST_RX1_CHANNEL ) || |
||||
( freq > AU915_LAST_RX1_CHANNEL ) || |
||||
( ( ( freq - ( uint32_t ) AU915_FIRST_RX1_CHANNEL ) % ( uint32_t ) AU915_STEPWIDTH_RX1_CHANNEL ) != 0 ) ) |
||||
{ |
||||
status &= 0xFE; // Channel frequency KO
|
||||
} |
||||
|
||||
// Verify datarate
|
||||
if( RegionCommonValueInRange( rxParamSetupReq->Datarate, AU915_RX_MIN_DATARATE, AU915_RX_MAX_DATARATE ) == false ) |
||||
{ |
||||
status &= 0xFD; // Datarate KO
|
||||
} |
||||
if( ( rxParamSetupReq->Datarate == DR_7 ) || |
||||
( rxParamSetupReq->Datarate > DR_13 ) ) |
||||
{ |
||||
status &= 0xFD; // Datarate KO
|
||||
} |
||||
|
||||
// Verify datarate offset
|
||||
if( RegionCommonValueInRange( rxParamSetupReq->DrOffset, AU915_MIN_RX1_DR_OFFSET, AU915_MAX_RX1_DR_OFFSET ) == false ) |
||||
{ |
||||
status &= 0xFB; // Rx1DrOffset range KO
|
||||
} |
||||
|
||||
return status; |
||||
} |
||||
|
||||
uint8_t RegionAU915NewChannelReq( NewChannelReqParams_t* newChannelReq ) |
||||
{ |
||||
// Datarate and frequency KO
|
||||
return 0; |
||||
} |
||||
|
||||
int8_t RegionAU915TxParamSetupReq( TxParamSetupReqParams_t* txParamSetupReq ) |
||||
{ |
||||
return -1; |
||||
} |
||||
|
||||
uint8_t RegionAU915DlChannelReq( DlChannelReqParams_t* dlChannelReq ) |
||||
{ |
||||
return 0; |
||||
} |
||||
|
||||
int8_t RegionAU915AlternateDr( AlternateDrParams_t* alternateDr ) |
||||
{ |
||||
int8_t datarate = 0; |
||||
|
||||
// Re-enable 500 kHz default channels
|
||||
ChannelsMask[4] = 0x00FF; |
||||
|
||||
if( ( alternateDr->NbTrials & 0x01 ) == 0x01 ) |
||||
{ |
||||
datarate = DR_6; |
||||
} |
||||
else |
||||
{ |
||||
datarate = DR_0; |
||||
} |
||||
return datarate; |
||||
} |
||||
|
||||
void RegionAU915CalcBackOff( CalcBackOffParams_t* calcBackOff ) |
||||
{ |
||||
RegionCommonCalcBackOffParams_t calcBackOffParams; |
||||
|
||||
calcBackOffParams.Channels = Channels; |
||||
calcBackOffParams.Bands = Bands; |
||||
calcBackOffParams.LastTxIsJoinRequest = calcBackOff->LastTxIsJoinRequest; |
||||
calcBackOffParams.Joined = calcBackOff->Joined; |
||||
calcBackOffParams.DutyCycleEnabled = calcBackOff->DutyCycleEnabled; |
||||
calcBackOffParams.Channel = calcBackOff->Channel; |
||||
calcBackOffParams.ElapsedTime = calcBackOff->ElapsedTime; |
||||
calcBackOffParams.TxTimeOnAir = calcBackOff->TxTimeOnAir; |
||||
|
||||
RegionCommonCalcBackOff( &calcBackOffParams ); |
||||
} |
||||
|
||||
bool RegionAU915NextChannel( NextChanParams_t* nextChanParams, uint8_t* channel, TimerTime_t* time, TimerTime_t* aggregatedTimeOff ) |
||||
{ |
||||
uint8_t nbEnabledChannels = 0; |
||||
uint8_t delayTx = 0; |
||||
uint8_t enabledChannels[AU915_MAX_NB_CHANNELS] = { 0 }; |
||||
TimerTime_t nextTxDelay = 0; |
||||
|
||||
// Count 125kHz channels
|
||||
if( RegionCommonCountChannels( ChannelsMaskRemaining, 0, 4 ) == 0 ) |
||||
{ // Reactivate default channels
|
||||
RegionCommonChanMaskCopy( ChannelsMaskRemaining, ChannelsMask, 4 ); |
||||
} |
||||
// Check other channels
|
||||
if( nextChanParams->Datarate >= DR_6 ) |
||||
{ |
||||
if( ( ChannelsMaskRemaining[4] & 0x00FF ) == 0 ) |
||||
{ |
||||
ChannelsMaskRemaining[4] = ChannelsMask[4]; |
||||
} |
||||
} |
||||
|
||||
if( nextChanParams->AggrTimeOff <= TimerGetElapsedTime( nextChanParams->LastAggrTx ) ) |
||||
{ |
||||
// Reset Aggregated time off
|
||||
*aggregatedTimeOff = 0; |
||||
|
||||
// Update bands Time OFF
|
||||
nextTxDelay = RegionCommonUpdateBandTimeOff( nextChanParams->Joined, nextChanParams->DutyCycleEnabled, Bands, AU915_MAX_NB_BANDS ); |
||||
|
||||
// Search how many channels are enabled
|
||||
nbEnabledChannels = CountNbOfEnabledChannels( nextChanParams->Datarate, |
||||
ChannelsMaskRemaining, Channels, |
||||
Bands, enabledChannels, &delayTx ); |
||||
} |
||||
else |
||||
{ |
||||
delayTx++; |
||||
nextTxDelay = nextChanParams->AggrTimeOff - TimerGetElapsedTime( nextChanParams->LastAggrTx ); |
||||
} |
||||
|
||||
if( nbEnabledChannels > 0 ) |
||||
{ |
||||
// We found a valid channel
|
||||
*channel = enabledChannels[randr( 0, nbEnabledChannels - 1 )]; |
||||
// Disable the channel in the mask
|
||||
RegionCommonChanDisable( ChannelsMaskRemaining, *channel, AU915_MAX_NB_CHANNELS - 8 ); |
||||
|
||||
*time = 0; |
||||
return true; |
||||
} |
||||
else |
||||
{ |
||||
if( delayTx > 0 ) |
||||
{ |
||||
// Delay transmission due to AggregatedTimeOff or to a band time off
|
||||
*time = nextTxDelay; |
||||
return true; |
||||
} |
||||
// Datarate not supported by any channel
|
||||
*time = 0; |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
LoRaMacStatus_t RegionAU915ChannelAdd( ChannelAddParams_t* channelAdd ) |
||||
{ |
||||
return LORAMAC_STATUS_PARAMETER_INVALID; |
||||
} |
||||
|
||||
bool RegionAU915ChannelsRemove( ChannelRemoveParams_t* channelRemove ) |
||||
{ |
||||
return LORAMAC_STATUS_PARAMETER_INVALID; |
||||
} |
||||
|
||||
void RegionAU915SetContinuousWave( ContinuousWaveParams_t* continuousWave ) |
||||
{ |
||||
int8_t txPowerLimited = LimitTxPower( continuousWave->TxPower, Bands[Channels[continuousWave->Channel].Band].TxMaxPower, continuousWave->Datarate, ChannelsMask ); |
||||
int8_t phyTxPower = 0; |
||||
uint32_t frequency = Channels[continuousWave->Channel].Frequency; |
||||
|
||||
// Calculate physical TX power
|
||||
phyTxPower = RegionCommonComputeTxPower( txPowerLimited, continuousWave->MaxEirp, continuousWave->AntennaGain ); |
||||
|
||||
Radio.SetTxContinuousWave( frequency, phyTxPower, continuousWave->Timeout ); |
||||
} |
||||
|
||||
uint8_t RegionAU915ApplyDrOffset( uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset ) |
||||
{ |
||||
int8_t datarate = DatarateOffsetsAU915[dr][drOffset]; |
||||
|
||||
if( datarate < 0 ) |
||||
{ |
||||
datarate = DR_0; |
||||
} |
||||
return datarate; |
||||
} |
@ -0,0 +1,455 @@ |
||||
/*!
|
||||
* \file RegionAU915.h |
||||
* |
||||
* \brief Region definition for AU915 |
||||
* |
||||
* \copyright Revised BSD License, see section \ref LICENSE. |
||||
* |
||||
* \code |
||||
* ______ _ |
||||
* / _____) _ | | |
||||
* ( (____ _____ ____ _| |_ _____ ____| |__ |
||||
* \____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
* _____) ) ____| | | || |_| ____( (___| | | | |
||||
* (______/|_____)_|_|_| \__)_____)\____)_| |_| |
||||
* (C)2013 Semtech |
||||
* |
||||
* ___ _____ _ ___ _ _____ ___ ___ ___ ___ |
||||
* / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| |
||||
* \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| |
||||
* |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| |
||||
* embedded.connectivity.solutions=============== |
||||
* |
||||
* \endcode |
||||
* |
||||
* \author Miguel Luis ( Semtech ) |
||||
* |
||||
* \author Gregory Cristian ( Semtech ) |
||||
* |
||||
* \author Daniel Jaeckle ( STACKFORCE ) |
||||
* |
||||
* \defgroup REGIONAU915 Region AU915 |
||||
* Implementation according to LoRaWAN Specification v1.0.2. |
||||
* \{ |
||||
*/ |
||||
#ifndef __REGION_AU915_H__ |
||||
#define __REGION_AU915_H__ |
||||
|
||||
/*!
|
||||
* LoRaMac maximum number of channels |
||||
*/ |
||||
#define AU915_MAX_NB_CHANNELS 72 |
||||
|
||||
/*!
|
||||
* Minimal datarate that can be used by the node |
||||
*/ |
||||
#define AU915_TX_MIN_DATARATE DR_0 |
||||
|
||||
/*!
|
||||
* Maximal datarate that can be used by the node |
||||
*/ |
||||
#define AU915_TX_MAX_DATARATE DR_6 |
||||
|
||||
/*!
|
||||
* Minimal datarate that can be used by the node |
||||
*/ |
||||
#define AU915_RX_MIN_DATARATE DR_8 |
||||
|
||||
/*!
|
||||
* Maximal datarate that can be used by the node |
||||
*/ |
||||
#define AU915_RX_MAX_DATARATE DR_13 |
||||
|
||||
/*!
|
||||
* Default datarate used by the node |
||||
*/ |
||||
#define AU915_DEFAULT_DATARATE DR_0 |
||||
|
||||
/*!
|
||||
* Minimal Rx1 receive datarate offset |
||||
*/ |
||||
#define AU915_MIN_RX1_DR_OFFSET 0 |
||||
|
||||
/*!
|
||||
* Maximal Rx1 receive datarate offset |
||||
*/ |
||||
#define AU915_MAX_RX1_DR_OFFSET 6 |
||||
|
||||
/*!
|
||||
* Default Rx1 receive datarate offset |
||||
*/ |
||||
#define AU915_DEFAULT_RX1_DR_OFFSET 0 |
||||
|
||||
/*!
|
||||
* Minimal Tx output power that can be used by the node |
||||
*/ |
||||
#define AU915_MIN_TX_POWER TX_POWER_10 |
||||
|
||||
/*!
|
||||
* Maximal Tx output power that can be used by the node |
||||
*/ |
||||
#define AU915_MAX_TX_POWER TX_POWER_0 |
||||
|
||||
/*!
|
||||
* Default Tx output power used by the node |
||||
*/ |
||||
#define AU915_DEFAULT_TX_POWER TX_POWER_0 |
||||
|
||||
/*!
|
||||
* Default Max EIRP |
||||
*/ |
||||
#define AU915_DEFAULT_MAX_EIRP 30.0f |
||||
|
||||
/*!
|
||||
* Default antenna gain |
||||
*/ |
||||
#define AU915_DEFAULT_ANTENNA_GAIN 2.15f |
||||
|
||||
/*!
|
||||
* ADR Ack limit |
||||
*/ |
||||
#define AU915_ADR_ACK_LIMIT 64 |
||||
|
||||
/*!
|
||||
* ADR Ack delay |
||||
*/ |
||||
#define AU915_ADR_ACK_DELAY 32 |
||||
|
||||
/*!
|
||||
* Enabled or disabled the duty cycle |
||||
*/ |
||||
#define AU915_DUTY_CYCLE_ENABLED 0 |
||||
|
||||
/*!
|
||||
* Maximum RX window duration |
||||
*/ |
||||
#define AU915_MAX_RX_WINDOW 3000 |
||||
|
||||
/*!
|
||||
* Receive delay 1 |
||||
*/ |
||||
#define AU915_RECEIVE_DELAY1 1000 |
||||
|
||||
/*!
|
||||
* Receive delay 2 |
||||
*/ |
||||
#define AU915_RECEIVE_DELAY2 2000 |
||||
|
||||
/*!
|
||||
* Join accept delay 1 |
||||
*/ |
||||
#define AU915_JOIN_ACCEPT_DELAY1 5000 |
||||
|
||||
/*!
|
||||
* Join accept delay 2 |
||||
*/ |
||||
#define AU915_JOIN_ACCEPT_DELAY2 6000 |
||||
|
||||
/*!
|
||||
* Maximum frame counter gap |
||||
*/ |
||||
#define AU915_MAX_FCNT_GAP 16384 |
||||
|
||||
/*!
|
||||
* Ack timeout |
||||
*/ |
||||
#define AU915_ACKTIMEOUT 2000 |
||||
|
||||
/*!
|
||||
* Random ack timeout limits |
||||
*/ |
||||
#define AU915_ACK_TIMEOUT_RND 1000 |
||||
|
||||
/*!
|
||||
* Second reception window channel frequency definition. |
||||
*/ |
||||
#define AU915_RX_WND_2_FREQ 923300000 |
||||
|
||||
/*!
|
||||
* Second reception window channel datarate definition. |
||||
*/ |
||||
#define AU915_RX_WND_2_DR DR_8 |
||||
|
||||
/*!
|
||||
* LoRaMac maximum number of bands |
||||
*/ |
||||
#define AU915_MAX_NB_BANDS 1 |
||||
|
||||
/*!
|
||||
* Band 0 definition |
||||
* { DutyCycle, TxMaxPower, LastTxDoneTime, TimeOff } |
||||
*/ |
||||
#define AU915_BAND0 { 1, AU915_MAX_TX_POWER, 0, 0 } // 100.0 %
|
||||
|
||||
/*!
|
||||
* Defines the first channel for RX window 1 for US band |
||||
*/ |
||||
#define AU915_FIRST_RX1_CHANNEL ( (uint32_t) 923300000 ) |
||||
|
||||
/*!
|
||||
* Defines the last channel for RX window 1 for US band |
||||
*/ |
||||
#define AU915_LAST_RX1_CHANNEL ( (uint32_t) 927500000 ) |
||||
|
||||
/*!
|
||||
* Defines the step width of the channels for RX window 1 |
||||
*/ |
||||
#define AU915_STEPWIDTH_RX1_CHANNEL ( (uint32_t) 600000 ) |
||||
|
||||
/*!
|
||||
* Data rates table definition |
||||
*/ |
||||
static const uint8_t DataratesAU915[] = { 12, 11, 10, 9, 8, 7, 8, 0, 12, 11, 10, 9, 8, 7, 0, 0 }; |
||||
|
||||
/*!
|
||||
* Bandwidths table definition in Hz |
||||
*/ |
||||
static const uint32_t BandwidthsAU915[] = { 125000, 125000, 125000, 125000, 125000, 125000, 500000, 0, 500000, 500000, 500000, 500000, 500000, 500000, 0, 0 }; |
||||
|
||||
/*!
|
||||
* Up/Down link data rates offset definition |
||||
*/ |
||||
static const int8_t DatarateOffsetsAU915[7][6] = |
||||
{ |
||||
{ DR_8 , DR_8 , DR_8 , DR_8 , DR_8 , DR_8 }, // DR_0
|
||||
{ DR_9 , DR_8 , DR_8 , DR_8 , DR_8 , DR_8 }, // DR_1
|
||||
{ DR_10, DR_9 , DR_8 , DR_8 , DR_8 , DR_8 }, // DR_2
|
||||
{ DR_11, DR_10, DR_9 , DR_8 , DR_8 , DR_8 }, // DR_3
|
||||
{ DR_12, DR_11, DR_10, DR_9 , DR_8 , DR_8 }, // DR_4
|
||||
{ DR_13, DR_12, DR_11, DR_10, DR_9 , DR_8 }, // DR_5
|
||||
{ DR_13, DR_13, DR_12, DR_11, DR_10, DR_9 }, // DR_6
|
||||
}; |
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Cannot operate with repeater. |
||||
*/ |
||||
static const uint8_t MaxPayloadOfDatarateAU915[] = { 51, 51, 51, 115, 242, 242, 242, 0, 53, 129, 242, 242, 242, 242, 0, 0 }; |
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Can operate with repeater. |
||||
*/ |
||||
static const uint8_t MaxPayloadOfDatarateRepeaterAU915[] = { 51, 51, 51, 115, 222, 222, 222, 0, 33, 109, 222, 222, 222, 222, 0, 0 }; |
||||
|
||||
/*!
|
||||
* \brief The function gets a value of a specific phy attribute. |
||||
* |
||||
* \param [IN] getPhy Pointer to the function parameters. |
||||
* |
||||
* \retval Returns a structure containing the PHY parameter. |
||||
*/ |
||||
PhyParam_t RegionAU915GetPhyParam( GetPhyParams_t* getPhy ); |
||||
|
||||
/*!
|
||||
* \brief Updates the last TX done parameters of the current channel. |
||||
* |
||||
* \param [IN] txDone Pointer to the function parameters. |
||||
*/ |
||||
void RegionAU915SetBandTxDone( SetBandTxDoneParams_t* txDone ); |
||||
|
||||
/*!
|
||||
* \brief Initializes the channels masks and the channels. |
||||
* |
||||
* \param [IN] type Sets the initialization type. |
||||
*/ |
||||
void RegionAU915InitDefaults( InitType_t type ); |
||||
|
||||
/*!
|
||||
* \brief Verifies a parameter. |
||||
* |
||||
* \param [IN] verify Pointer to the function parameters. |
||||
* |
||||
* \param [IN] type Sets the initialization type. |
||||
* |
||||
* \retval Returns true, if the parameter is valid. |
||||
*/ |
||||
bool RegionAU915Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute ); |
||||
|
||||
/*!
|
||||
* \brief The function parses the input buffer and sets up the channels of the |
||||
* CF list. |
||||
* |
||||
* \param [IN] applyCFList Pointer to the function parameters. |
||||
*/ |
||||
void RegionAU915ApplyCFList( ApplyCFListParams_t* applyCFList ); |
||||
|
||||
/*!
|
||||
* \brief Sets a channels mask. |
||||
* |
||||
* \param [IN] chanMaskSet Pointer to the function parameters. |
||||
* |
||||
* \retval Returns true, if the channels mask could be set. |
||||
*/ |
||||
bool RegionAU915ChanMaskSet( ChanMaskSetParams_t* chanMaskSet ); |
||||
|
||||
/*!
|
||||
* \brief Calculates the next datarate to set, when ADR is on or off. |
||||
* |
||||
* \param [IN] adrNext Pointer to the function parameters. |
||||
* |
||||
* \param [OUT] drOut The calculated datarate for the next TX. |
||||
* |
||||
* \param [OUT] txPowOut The TX power for the next TX. |
||||
* |
||||
* \param [OUT] adrAckCounter The calculated ADR acknowledgement counter. |
||||
* |
||||
* \retval Returns true, if an ADR request should be performed. |
||||
*/ |
||||
bool RegionAU915AdrNext( AdrNextParams_t* adrNext, int8_t* drOut, int8_t* txPowOut, uint32_t* adrAckCounter ); |
||||
|
||||
/*!
|
||||
* Computes the Rx window timeout and offset. |
||||
* |
||||
* \param [IN] datarate Rx window datarate index to be used |
||||
* |
||||
* \param [IN] minRxSymbols Minimum required number of symbols to detect an Rx frame. |
||||
* |
||||
* \param [IN] rxError System maximum timing error of the receiver. In milliseconds |
||||
* The receiver will turn on in a [-rxError : +rxError] ms |
||||
* interval around RxOffset |
||||
* |
||||
* \param [OUT]rxConfigParams Returns updated WindowTimeout and WindowOffset fields. |
||||
*/ |
||||
void RegionAU915ComputeRxWindowParameters( int8_t datarate, uint8_t minRxSymbols, uint32_t rxError, RxConfigParams_t *rxConfigParams ); |
||||
|
||||
/*!
|
||||
* \brief Configuration of the RX windows. |
||||
* |
||||
* \param [IN] rxConfig Pointer to the function parameters. |
||||
* |
||||
* \param [OUT] datarate The datarate index which was set. |
||||
* |
||||
* \retval Returns true, if the configuration was applied successfully. |
||||
*/ |
||||
bool RegionAU915RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate ); |
||||
|
||||
/*!
|
||||
* \brief TX configuration. |
||||
* |
||||
* \param [IN] txConfig Pointer to the function parameters. |
||||
* |
||||
* \param [OUT] txPower The tx power index which was set. |
||||
* |
||||
* \param [OUT] txTimeOnAir The time-on-air of the frame. |
||||
* |
||||
* \retval Returns true, if the configuration was applied successfully. |
||||
*/ |
||||
bool RegionAU915TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime_t* txTimeOnAir ); |
||||
|
||||
/*!
|
||||
* \brief The function processes a Link ADR Request. |
||||
* |
||||
* \param [IN] linkAdrReq Pointer to the function parameters. |
||||
* |
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification. |
||||
*/ |
||||
uint8_t RegionAU915LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, int8_t* txPowOut, uint8_t* nbRepOut, uint8_t* nbBytesParsed ); |
||||
|
||||
/*!
|
||||
* \brief The function processes a RX Parameter Setup Request. |
||||
* |
||||
* \param [IN] rxParamSetupReq Pointer to the function parameters. |
||||
* |
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification. |
||||
*/ |
||||
uint8_t RegionAU915RxParamSetupReq( RxParamSetupReqParams_t* rxParamSetupReq ); |
||||
|
||||
/*!
|
||||
* \brief The function processes a Channel Request. |
||||
* |
||||
* \param [IN] newChannelReq Pointer to the function parameters. |
||||
* |
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification. |
||||
*/ |
||||
uint8_t RegionAU915NewChannelReq( NewChannelReqParams_t* newChannelReq ); |
||||
|
||||
/*!
|
||||
* \brief The function processes a TX ParamSetup Request. |
||||
* |
||||
* \param [IN] txParamSetupReq Pointer to the function parameters. |
||||
* |
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification. |
||||
* Returns -1, if the functionality is not implemented. In this case, the end node |
||||
* shall not process the command. |
||||
*/ |
||||
int8_t RegionAU915TxParamSetupReq( TxParamSetupReqParams_t* txParamSetupReq ); |
||||
|
||||
/*!
|
||||
* \brief The function processes a DlChannel Request. |
||||
* |
||||
* \param [IN] dlChannelReq Pointer to the function parameters. |
||||
* |
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification. |
||||
*/ |
||||
uint8_t RegionAU915DlChannelReq( DlChannelReqParams_t* dlChannelReq ); |
||||
|
||||
/*!
|
||||
* \brief Alternates the datarate of the channel for the join request. |
||||
* |
||||
* \param [IN] alternateDr Pointer to the function parameters. |
||||
* |
||||
* \retval Datarate to apply. |
||||
*/ |
||||
int8_t RegionAU915AlternateDr( AlternateDrParams_t* alternateDr ); |
||||
|
||||
/*!
|
||||
* \brief Calculates the back-off time. |
||||
* |
||||
* \param [IN] calcBackOff Pointer to the function parameters. |
||||
*/ |
||||
void RegionAU915CalcBackOff( CalcBackOffParams_t* calcBackOff ); |
||||
|
||||
/*!
|
||||
* \brief Searches and set the next random available channel |
||||
* |
||||
* \param [OUT] channel Next channel to use for TX. |
||||
* |
||||
* \param [OUT] time Time to wait for the next transmission according to the duty |
||||
* cycle. |
||||
* |
||||
* \param [OUT] aggregatedTimeOff Updates the aggregated time off. |
||||
* |
||||
* \retval Function status [1: OK, 0: Unable to find a channel on the current datarate] |
||||
*/ |
||||
bool RegionAU915NextChannel( NextChanParams_t* nextChanParams, uint8_t* channel, TimerTime_t* time, TimerTime_t* aggregatedTimeOff ); |
||||
|
||||
/*!
|
||||
* \brief Adds a channel. |
||||
* |
||||
* \param [IN] channelAdd Pointer to the function parameters. |
||||
* |
||||
* \retval Status of the operation. |
||||
*/ |
||||
LoRaMacStatus_t RegionAU915ChannelAdd( ChannelAddParams_t* channelAdd ); |
||||
|
||||
/*!
|
||||
* \brief Removes a channel. |
||||
* |
||||
* \param [IN] channelRemove Pointer to the function parameters. |
||||
* |
||||
* \retval Returns true, if the channel was removed successfully. |
||||
*/ |
||||
bool RegionAU915ChannelsRemove( ChannelRemoveParams_t* channelRemove ); |
||||
|
||||
/*!
|
||||
* \brief Sets the radio into continuous wave mode. |
||||
* |
||||
* \param [IN] continuousWave Pointer to the function parameters. |
||||
*/ |
||||
void RegionAU915SetContinuousWave( ContinuousWaveParams_t* continuousWave ); |
||||
|
||||
/*!
|
||||
* \brief Computes new datarate according to the given offset |
||||
* |
||||
* \param [IN] downlinkDwellTime Downlink dwell time configuration. 0: No limit, 1: 400ms |
||||
* |
||||
* \param [IN] dr Current datarate |
||||
* |
||||
* \param [IN] drOffset Offset to be applied |
||||
* |
||||
* \retval newDr Computed datarate. |
||||
*/ |
||||
uint8_t RegionAU915ApplyDrOffset( uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset ); |
||||
|
||||
/*! \} defgroup REGIONAU915 */ |
||||
|
||||
#endif // __REGION_AU915_H__
|
@ -0,0 +1,814 @@ |
||||
/*
|
||||
/ _____) _ | | |
||||
( (____ _____ ____ _| |_ _____ ____| |__ |
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | | |
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_| |
||||
(C)2013 Semtech |
||||
___ _____ _ ___ _ _____ ___ ___ ___ ___ |
||||
/ __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| |
||||
\__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| |
||||
|___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| |
||||
embedded.connectivity.solutions=============== |
||||
|
||||
Description: LoRa MAC region CN470 implementation |
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project |
||||
|
||||
Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jaeckle ( STACKFORCE ) |
||||
*/ |
||||
#include <stdbool.h> |
||||
#include <string.h> |
||||
#include <stdint.h> |
||||
#include <math.h> |
||||
|
||||
#include "radio.h" |
||||
#include "timer.h" |
||||
#include "LoRaMac.h" |
||||
|
||||
#include "utilities.h" |
||||
|
||||
#include "Region.h" |
||||
#include "RegionCommon.h" |
||||
#include "RegionCN470.h" |
||||
#include "debug.h" |
||||
|
||||
// Definitions
|
||||
#define CHANNELS_MASK_SIZE 6 |
||||
|
||||
// Global attributes
|
||||
/*!
|
||||
* LoRaMAC channels |
||||
*/ |
||||
static ChannelParams_t Channels[CN470_MAX_NB_CHANNELS]; |
||||
|
||||
/*!
|
||||
* LoRaMac bands |
||||
*/ |
||||
static Band_t Bands[CN470_MAX_NB_BANDS] = |
||||
{ |
||||
CN470_BAND0 |
||||
}; |
||||
|
||||
/*!
|
||||
* LoRaMac channels mask |
||||
*/ |
||||
static uint16_t ChannelsMask[CHANNELS_MASK_SIZE]; |
||||
|
||||
/*!
|
||||
* LoRaMac channels default mask |
||||
*/ |
||||
static uint16_t ChannelsDefaultMask[CHANNELS_MASK_SIZE]; |
||||
|
||||
// Static functions
|
||||
static int8_t GetNextLowerTxDr( int8_t dr, int8_t minDr ) |
||||
{ |
||||
uint8_t nextLowerDr = 0; |
||||
|
||||
if( dr == minDr ) |
||||
{ |
||||
nextLowerDr = minDr; |
||||
} |
||||
else |
||||
{ |
||||
nextLowerDr = dr - 1; |
||||
} |
||||
return nextLowerDr; |
||||
} |
||||
|
||||
static uint32_t GetBandwidth( uint32_t drIndex ) |
||||
{ |
||||
switch( BandwidthsCN470[drIndex] ) |
||||
{ |
||||
default: |
||||
case 125000: |
||||
return 0; |
||||
case 250000: |
||||
return 1; |
||||
case 500000: |
||||
return 2; |
||||
} |
||||
} |
||||
|
||||
static int8_t LimitTxPower( int8_t txPower, int8_t maxBandTxPower, int8_t datarate, uint16_t* channelsMask ) |
||||
{ |
||||
int8_t txPowerResult = txPower; |
||||
|
||||
// Limit tx power to the band max
|
||||
txPowerResult = MAX( txPower, maxBandTxPower ); |
||||
|
||||
return txPowerResult; |
||||
} |
||||
|
||||
static uint8_t CountNbOfEnabledChannels( uint8_t datarate, uint16_t* channelsMask, ChannelParams_t* channels, Band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx ) |
||||
{ |
||||
uint8_t nbEnabledChannels = 0; |
||||
uint8_t delayTransmission = 0; |
||||
|
||||
for( uint8_t i = 0, k = 0; i < CN470_MAX_NB_CHANNELS; i += 16, k++ ) |
||||
{ |
||||
for( uint8_t j = 0; j < 16; j++ ) |
||||
{ |
||||
if( ( channelsMask[k] & ( 1 << j ) ) != 0 ) |
||||
{ |
||||
if( channels[i + j].Frequency == 0 ) |
||||
{ // Check if the channel is enabled
|
||||
continue; |
||||
} |
||||
if( RegionCommonValueInRange( datarate, channels[i + j].DrRange.Fields.Min, |
||||
channels[i + j].DrRange.Fields.Max ) == false ) |
||||
{ // Check if the current channel selection supports the given datarate
|
||||
continue; |
||||
} |
||||
if( bands[channels[i + j].Band].TimeOff > 0 ) |
||||
{ // Check if the band is available for transmission
|
||||
delayTransmission++; |
||||
continue; |
||||
} |
||||
enabledChannels[nbEnabledChannels++] = i + j; |
||||
} |
||||
} |
||||
} |
||||
|
||||
*delayTx = delayTransmission; |
||||
return nbEnabledChannels; |
||||
} |
||||
|
||||
PhyParam_t RegionCN470GetPhyParam( GetPhyParams_t* getPhy ) |
||||
{ |
||||
PhyParam_t phyParam = { 0 }; |
||||
|
||||
switch( getPhy->Attribute ) |
||||
{ |
||||
case PHY_MIN_RX_DR: |
||||
{ |
||||
phyParam.Value = CN470_RX_MIN_DATARATE; |
||||
break; |
||||
} |
||||
case PHY_MIN_TX_DR: |
||||
{ |
||||
phyParam.Value = CN470_TX_MIN_DATARATE; |
||||
break; |
||||
} |
||||
case PHY_DEF_TX_DR: |
||||
{ |
||||
phyParam.Value = CN470_DEFAULT_DATARATE; |
||||
break; |
||||
} |
||||
case PHY_NEXT_LOWER_TX_DR: |
||||
{ |
||||
phyParam.Value = GetNextLowerTxDr( getPhy->Datarate, CN470_TX_MIN_DATARATE ); |
||||
break; |
||||
} |
||||
case PHY_DEF_TX_POWER: |
||||
{ |
||||
phyParam.Value = CN470_DEFAULT_TX_POWER; |
||||
break; |
||||
} |
||||
case PHY_MAX_PAYLOAD: |
||||
{ |
||||
phyParam.Value = MaxPayloadOfDatarateCN470[getPhy->Datarate]; |
||||
break; |
||||
} |
||||
case PHY_MAX_PAYLOAD_REPEATER: |
||||
{ |
||||
phyParam.Value = MaxPayloadOfDatarateRepeaterCN470[getPhy->Datarate]; |
||||
break; |
||||
} |
||||
case PHY_DUTY_CYCLE: |
||||
{ |
||||
phyParam.Value = CN470_DUTY_CYCLE_ENABLED; |
||||
break; |
||||
} |
||||
case PHY_MAX_RX_WINDOW: |
||||
{ |
||||
phyParam.Value = CN470_MAX_RX_WINDOW; |
||||
break; |
||||
} |
||||
case PHY_RECEIVE_DELAY1: |
||||
{ |
||||
phyParam.Value = CN470_RECEIVE_DELAY1; |
||||
break; |
||||
} |
||||
case PHY_RECEIVE_DELAY2: |
||||
{ |
||||
phyParam.Value = CN470_RECEIVE_DELAY2; |
||||
break; |
||||
} |
||||
case PHY_JOIN_ACCEPT_DELAY1: |
||||
{ |
||||
phyParam.Value = CN470_JOIN_ACCEPT_DELAY1; |
||||
break; |
||||
} |
||||
case PHY_JOIN_ACCEPT_DELAY2: |
||||
{ |
||||
phyParam.Value = CN470_JOIN_ACCEPT_DELAY2; |
||||
break; |
||||
} |
||||
case PHY_MAX_FCNT_GAP: |
||||
{ |
||||
phyParam.Value = CN470_MAX_FCNT_GAP; |
||||
break; |
||||
} |
||||
case PHY_ACK_TIMEOUT: |
||||
{ |
||||
phyParam.Value = ( CN470_ACKTIMEOUT + randr( -CN470_ACK_TIMEOUT_RND, CN470_ACK_TIMEOUT_RND ) ); |
||||
break; |
||||
} |
||||
case PHY_DEF_DR1_OFFSET: |
||||
{ |
||||
phyParam.Value = CN470_DEFAULT_RX1_DR_OFFSET; |
||||
break; |
||||
} |
||||
case PHY_DEF_RX2_FREQUENCY: |
||||
{ |
||||
phyParam.Value = CN470_RX_WND_2_FREQ; |
||||
break; |
||||
} |
||||
case PHY_DEF_RX2_DR: |
||||
{ |
||||
phyParam.Value = CN470_RX_WND_2_DR; |
||||
break; |
||||
} |
||||
case PHY_CHANNELS_MASK: |
||||
{ |
||||
phyParam.ChannelsMask = ChannelsMask; |
||||
break; |
||||
} |
||||
case PHY_CHANNELS_DEFAULT_MASK: |
||||
{ |
||||
phyParam.ChannelsMask = ChannelsDefaultMask; |
||||
break; |
||||
} |
||||
case PHY_MAX_NB_CHANNELS: |
||||
{ |
||||
phyParam.Value = CN470_MAX_NB_CHANNELS; |
||||
break; |
||||
} |
||||
case PHY_CHANNELS: |
||||
{ |
||||
phyParam.Channels = Channels; |
||||
break; |
||||
} |
||||
case PHY_DEF_UPLINK_DWELL_TIME: |
||||
case PHY_DEF_DOWNLINK_DWELL_TIME: |
||||
{ |
||||
phyParam.Value = 0; |
||||
break; |
||||
} |
||||
case PHY_DEF_MAX_EIRP: |
||||
{ |
||||
phyParam.fValue = CN470_DEFAULT_MAX_EIRP; |
||||
break; |
||||
} |
||||
case PHY_DEF_ANTENNA_GAIN: |
||||
{ |
||||
phyParam.fValue = CN470_DEFAULT_ANTENNA_GAIN; |
||||
break; |
||||
} |
||||
case PHY_NB_JOIN_TRIALS: |
||||
case PHY_DEF_NB_JOIN_TRIALS: |
||||
{ |
||||
phyParam.Value = 48; |
||||
break; |
||||
} |
||||
default: |
||||
{ |
||||
break; |
||||
} |
||||
} |
||||
|
||||
return phyParam; |
||||
} |
||||
|
||||
void RegionCN470SetBandTxDone( SetBandTxDoneParams_t* txDone ) |
||||
{ |
||||
RegionCommonSetBandTxDone( txDone->Joined, &Bands[Channels[txDone->Channel].Band], txDone->LastTxDoneTime ); |
||||
} |
||||
|
||||
void RegionCN470InitDefaults( InitType_t type ) |
||||
{ |
||||
switch( type ) |
||||
{ |
||||
case INIT_TYPE_INIT: |
||||
{ |
||||
// Channels
|
||||
// 125 kHz channels
|
||||
for( uint8_t i = 0; i < CN470_MAX_NB_CHANNELS; i++ ) |
||||
{ |
||||
Channels[i].Frequency = 470300000 + i * 200000; |
||||
Channels[i].DrRange.Value = ( DR_5 << 4 ) | DR_0; |
||||
Channels[i].Band = 0; |
||||
} |
||||
|
||||
// Initialize the channels default mask
|
||||
ChannelsDefaultMask[0] = 0xFFFF; |
||||
ChannelsDefaultMask[1] = 0xFFFF; |
||||
ChannelsDefaultMask[2] = 0xFFFF; |
||||
ChannelsDefaultMask[3] = 0xFFFF; |
||||
ChannelsDefaultMask[4] = 0xFFFF; |
||||
ChannelsDefaultMask[5] = 0xFFFF; |
||||
|
||||
// Update the channels mask
|
||||
RegionCommonChanMaskCopy( ChannelsMask, ChannelsDefaultMask, 6 ); |
||||
break; |
||||
} |
||||
case INIT_TYPE_RESTORE: |
||||
{ |
||||
// Restore channels default mask
|
||||
RegionCommonChanMaskCopy( ChannelsMask, ChannelsDefaultMask, 6 ); |
||||
break; |
||||
} |
||||
default: |
||||
{ |
||||
break; |
||||
} |
||||
} |
||||
} |
||||
|
||||
bool RegionCN470Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute ) |
||||
{ |
||||
switch( phyAttribute ) |
||||
{ |
||||
case PHY_TX_DR: |
||||
case PHY_DEF_TX_DR: |
||||
{ |
||||
return RegionCommonValueInRange( verify->DatarateParams.Datarate, CN470_TX_MIN_DATARATE, CN470_TX_MAX_DATARATE ); |
||||
} |
||||
case PHY_RX_DR: |
||||
{ |
||||
return RegionCommonValueInRange( verify->DatarateParams.Datarate, CN470_RX_MIN_DATARATE, CN470_RX_MAX_DATARATE ); |
||||
} |
||||
case PHY_DEF_TX_POWER: |
||||
case PHY_TX_POWER: |
||||
{ |
||||
// Remark: switched min and max!
|
||||
return RegionCommonValueInRange( verify->TxPower, CN470_MAX_TX_POWER, CN470_MIN_TX_POWER ); |
||||
} |
||||
case PHY_DUTY_CYCLE: |
||||
{ |
||||
return CN470_DUTY_CYCLE_ENABLED; |
||||
} |
||||
case PHY_NB_JOIN_TRIALS: |
||||
{ |
||||
if( verify->NbJoinTrials < 48 ) |
||||
{ |
||||
return false; |
||||
} |
||||
break; |
||||
} |
||||
default: |
||||
return false; |
||||
} |
||||
return true; |
||||
} |
||||
|
||||
void RegionCN470ApplyCFList( ApplyCFListParams_t* applyCFList ) |
||||
{ |
||||
return; |
||||
} |
||||
|
||||
bool RegionCN470ChanMaskSet( ChanMaskSetParams_t* chanMaskSet ) |
||||
{ |
||||
switch( chanMaskSet->ChannelsMaskType ) |
||||
{ |
||||
case CHANNELS_MASK: |
||||
{ |
||||
RegionCommonChanMaskCopy( ChannelsMask, chanMaskSet->ChannelsMaskIn, 6 ); |
||||
break; |
||||
} |
||||
case CHANNELS_DEFAULT_MASK: |
||||
{ |
||||
RegionCommonChanMaskCopy( ChannelsDefaultMask, chanMaskSet->ChannelsMaskIn, 6 ); |
||||
break; |
||||
} |
||||
default: |
||||
return false; |
||||
} |
||||
return true; |
||||
} |
||||
|
||||
bool RegionCN470AdrNext( AdrNextParams_t* adrNext, int8_t* drOut, int8_t* txPowOut, uint32_t* adrAckCounter ) |
||||
{ |
||||
bool adrAckReq = false; |
||||
int8_t datarate = adrNext->Datarate; |
||||
int8_t txPower = adrNext->TxPower; |
||||
GetPhyParams_t getPhy; |
||||
PhyParam_t phyParam; |
||||
|
||||
// Report back the adr ack counter
|
||||
*adrAckCounter = adrNext->AdrAckCounter; |
||||
|
||||
if( adrNext->AdrEnabled == true ) |
||||
{ |
||||
if( datarate == CN470_TX_MIN_DATARATE ) |
||||
{ |
||||
*adrAckCounter = 0; |
||||
adrAckReq = false; |
||||
} |
||||
else |
||||
{ |
||||
if( adrNext->AdrAckCounter >= CN470_ADR_ACK_LIMIT ) |
||||
{ |
||||
adrAckReq = true; |
||||
txPower = CN470_MAX_TX_POWER; |
||||
} |
||||
else |
||||
{ |
||||
adrAckReq = false; |
||||
} |
||||
if( adrNext->AdrAckCounter >= ( CN470_ADR_ACK_LIMIT + CN470_ADR_ACK_DELAY ) ) |
||||
{ |
||||
if( ( adrNext->AdrAckCounter % CN470_ADR_ACK_DELAY ) == 1 ) |
||||
{ |
||||
// Decrease the datarate
|
||||
getPhy.Attribute = PHY_NEXT_LOWER_TX_DR; |
||||
getPhy.Datarate = datarate; |
||||
getPhy.UplinkDwellTime = adrNext->UplinkDwellTime; |
||||
phyParam = RegionCN470GetPhyParam( &getPhy ); |
||||
datarate = phyParam.Value; |
||||
|
||||
if( datarate == CN470_TX_MIN_DATARATE ) |
||||
{ |
||||
// We must set adrAckReq to false as soon as we reach the lowest datarate
|
||||
adrAckReq = false; |
||||
if( adrNext->UpdateChanMask == true ) |
||||
{ |
||||
// Re-enable default channels
|
||||
ChannelsMask[0] = 0xFFFF; |
||||
ChannelsMask[1] = 0xFFFF; |
||||
ChannelsMask[2] = 0xFFFF; |
||||
ChannelsMask[3] = 0xFFFF; |
||||
ChannelsMask[4] = 0xFFFF; |
||||
ChannelsMask[5] = 0xFFFF; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
*drOut = datarate; |
||||
*txPowOut = txPower; |
||||
return adrAckReq; |
||||
} |
||||
|
||||
void RegionCN470ComputeRxWindowParameters( int8_t datarate, uint8_t minRxSymbols, uint32_t rxError, RxConfigParams_t *rxConfigParams ) |
||||
{ |
||||
double tSymbol = 0.0; |
||||
uint32_t radioWakeUpTime; |
||||
|
||||
// Get the datarate, perform a boundary check
|
||||
rxConfigParams->Datarate = MIN( datarate, CN470_RX_MAX_DATARATE ); |
||||
rxConfigParams->Bandwidth = GetBandwidth( rxConfigParams->Datarate ); |
||||
|
||||
tSymbol = RegionCommonComputeSymbolTimeLoRa( DataratesCN470[rxConfigParams->Datarate], BandwidthsCN470[rxConfigParams->Datarate] ); |
||||
|
||||
radioWakeUpTime = Radio.GetRadioWakeUpTime( ); |
||||
RegionCommonComputeRxWindowParameters( tSymbol, minRxSymbols, rxError, radioWakeUpTime, &rxConfigParams->WindowTimeout, &rxConfigParams->WindowOffset ); |
||||
} |
||||
|
||||
bool RegionCN470RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate ) |
||||
{ |
||||
int8_t dr = rxConfig->Datarate; |
||||
uint8_t maxPayload = 0; |
||||
int8_t phyDr = 0; |
||||
uint32_t frequency = rxConfig->Frequency; |
||||
|
||||
if( Radio.GetStatus( ) != RF_IDLE ) |
||||
{ |
||||
return false; |
||||
} |
||||
|
||||
if( rxConfig->Window == 0 ) |
||||
{ |
||||
// Apply window 1 frequency
|
||||
frequency = CN470_FIRST_RX1_CHANNEL + ( rxConfig->Channel % 48 ) * CN470_STEPWIDTH_RX1_CHANNEL; |
||||
} |
||||
|
||||
// Read the physical datarate from the datarates table
|
||||
phyDr = DataratesCN470[dr]; |
||||
|
||||
Radio.SetChannel( frequency ); |
||||
|
||||
// Radio configuration
|
||||
Radio.SetRxConfig( MODEM_LORA, rxConfig->Bandwidth, phyDr, 1, 0, 8, rxConfig->WindowTimeout, false, 0, false, 0, 0, true, rxConfig->RxContinuous ); |
||||
|
||||
if( rxConfig->RepeaterSupport == true ) |
||||
{ |
||||
maxPayload = MaxPayloadOfDatarateRepeaterCN470[dr]; |
||||
} |
||||
else |
||||
{ |
||||
maxPayload = MaxPayloadOfDatarateCN470[dr]; |
||||
} |
||||
Radio.SetMaxPayloadLength( MODEM_LORA, maxPayload + LORA_MAC_FRMPAYLOAD_OVERHEAD ); |
||||
DBG_PRINTF( "RX on freq %d Hz at DR %d\n\r", frequency, dr ); |
||||
|
||||
*datarate = (uint8_t) dr; |
||||
return true; |
||||
} |
||||
|
||||
bool RegionCN470TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime_t* txTimeOnAir ) |
||||
{ |
||||
int8_t phyDr = DataratesCN470[txConfig->Datarate]; |
||||
int8_t txPowerLimited = LimitTxPower( txConfig->TxPower, Bands[Channels[txConfig->Channel].Band].TxMaxPower, txConfig->Datarate, ChannelsMask ); |
||||
int8_t phyTxPower = 0; |
||||
|
||||
// Calculate physical TX power
|
||||
phyTxPower = RegionCommonComputeTxPower( txPowerLimited, txConfig->MaxEirp, txConfig->AntennaGain ); |
||||
|
||||
// Setup the radio frequency
|
||||
Radio.SetChannel( Channels[txConfig->Channel].Frequency ); |
||||
|
||||
Radio.SetTxConfig( MODEM_LORA, phyTxPower, 0, 0, phyDr, 1, 8, false, true, 0, 0, false, 3000 ); |
||||
DBG_PRINTF( "TX on freq %d Hz at DR %d\n\r", Channels[txConfig->Channel].Frequency, txConfig->Datarate ); |
||||
|
||||
// Setup maximum payload lenght of the radio driver
|
||||
Radio.SetMaxPayloadLength( MODEM_LORA, txConfig->PktLen ); |
||||
// Get the time-on-air of the next tx frame
|
||||
*txTimeOnAir = Radio.TimeOnAir( MODEM_LORA, txConfig->PktLen ); |
||||
*txPower = txPowerLimited; |
||||
|
||||
return true; |
||||
} |
||||
|
||||
uint8_t RegionCN470LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, int8_t* txPowOut, uint8_t* nbRepOut, uint8_t* nbBytesParsed ) |
||||
{ |
||||
uint8_t status = 0x07; |
||||
RegionCommonLinkAdrParams_t linkAdrParams; |
||||
uint8_t nextIndex = 0; |
||||
uint8_t bytesProcessed = 0; |
||||
uint16_t channelsMask[6] = { 0, 0, 0, 0, 0, 0 }; |
||||
GetPhyParams_t getPhy; |
||||
PhyParam_t phyParam; |
||||
RegionCommonLinkAdrReqVerifyParams_t linkAdrVerifyParams; |
||||
|
||||
// Initialize local copy of channels mask
|
||||
RegionCommonChanMaskCopy( channelsMask, ChannelsMask, 6 ); |
||||
|
||||
while( bytesProcessed < linkAdrReq->PayloadSize ) |
||||
{ |
||||
// Get ADR request parameters
|
||||
nextIndex = RegionCommonParseLinkAdrReq( &( linkAdrReq->Payload[bytesProcessed] ), &linkAdrParams ); |
||||
|
||||
if( nextIndex == 0 ) |
||||
break; // break loop, since no more request has been found
|
||||
|
||||
// Update bytes processed
|
||||
bytesProcessed += nextIndex; |
||||
|
||||
// Revert status, as we only check the last ADR request for the channel mask KO
|
||||
status = 0x07; |
||||
|
||||
if( linkAdrParams.ChMaskCtrl == 6 ) |
||||
{ |
||||
// Enable all 125 kHz channels
|
||||
channelsMask[0] = 0xFFFF; |
||||
channelsMask[1] = 0xFFFF; |
||||
channelsMask[2] = 0xFFFF; |
||||
channelsMask[3] = 0xFFFF; |
||||
channelsMask[4] = 0xFFFF; |
||||
channelsMask[5] = 0xFFFF; |
||||
} |
||||
else if( linkAdrParams.ChMaskCtrl == 7 ) |
||||
{ |
||||
status &= 0xFE; // Channel mask KO
|
||||
} |
||||
else |
||||
{ |
||||
for( uint8_t i = 0; i < 16; i++ ) |
||||
{ |
||||
if( ( ( linkAdrParams.ChMask & ( 1 << i ) ) != 0 ) && |
||||
( Channels[linkAdrParams.ChMaskCtrl * 16 + i].Frequency == 0 ) ) |
||||
{// Trying to enable an undefined channel
|
||||
status &= 0xFE; // Channel mask KO
|
||||
} |
||||
} |
||||
channelsMask[linkAdrParams.ChMaskCtrl] = linkAdrParams.ChMask; |
||||
} |
||||
} |
||||
|
||||
// Get the minimum possible datarate
|
||||
getPhy.Attribute = PHY_MIN_TX_DR; |
||||
getPhy.UplinkDwellTime = linkAdrReq->UplinkDwellTime; |
||||
phyParam = RegionCN470GetPhyParam( &getPhy ); |
||||
|
||||
linkAdrVerifyParams.Status = status; |
||||
linkAdrVerifyParams.AdrEnabled = linkAdrReq->AdrEnabled; |
||||
linkAdrVerifyParams.Datarate = linkAdrParams.Datarate; |
||||
linkAdrVerifyParams.TxPower = linkAdrParams.TxPower; |
||||
linkAdrVerifyParams.NbRep = linkAdrParams.NbRep; |
||||
linkAdrVerifyParams.CurrentDatarate = linkAdrReq->CurrentDatarate; |
||||
linkAdrVerifyParams.CurrentTxPower = linkAdrReq->CurrentTxPower; |
||||
linkAdrVerifyParams.CurrentNbRep = linkAdrReq->CurrentNbRep; |
||||
linkAdrVerifyParams.NbChannels = CN470_MAX_NB_CHANNELS; |
||||
linkAdrVerifyParams.ChannelsMask = channelsMask; |
||||
linkAdrVerifyParams.MinDatarate = ( int8_t )phyParam.Value; |
||||
linkAdrVerifyParams.MaxDatarate = CN470_TX_MAX_DATARATE; |
||||
linkAdrVerifyParams.Channels = Channels; |
||||
linkAdrVerifyParams.MinTxPower = CN470_MIN_TX_POWER; |
||||
linkAdrVerifyParams.MaxTxPower = CN470_MAX_TX_POWER; |
||||
|
||||
// Verify the parameters and update, if necessary
|
||||
status = RegionCommonLinkAdrReqVerifyParams( &linkAdrVerifyParams, &linkAdrParams.Datarate, &linkAdrParams.TxPower, &linkAdrParams.NbRep ); |
||||
|
||||
// Update channelsMask if everything is correct
|
||||
if( status == 0x07 ) |
||||
{ |
||||
// Copy Mask
|
||||
RegionCommonChanMaskCopy( ChannelsMask, channelsMask, 6 ); |
||||
} |
||||
|
||||
// Update status variables
|
||||
*drOut = linkAdrParams.Datarate; |
||||
*txPowOut = linkAdrParams.TxPower; |
||||
*nbRepOut = linkAdrParams.NbRep; |
||||
*nbBytesParsed = bytesProcessed; |
||||
|
||||
return status; |
||||
} |
||||
|
||||
uint8_t RegionCN470RxParamSetupReq( RxParamSetupReqParams_t* rxParamSetupReq ) |
||||
{ |
||||
uint8_t status = 0x07; |
||||
uint32_t freq = rxParamSetupReq->Frequency; |
||||
|
||||
// Verify radio frequency
|
||||
if( ( Radio.CheckRfFrequency( freq ) == false ) || |
||||
( freq < CN470_FIRST_RX1_CHANNEL ) || |
||||
( freq > CN470_LAST_RX1_CHANNEL ) || |
||||
( ( ( freq - ( uint32_t ) CN470_FIRST_RX1_CHANNEL ) % ( uint32_t ) CN470_STEPWIDTH_RX1_CHANNEL ) != 0 ) ) |
||||
{ |
||||
status &= 0xFE; // Channel frequency KO
|
||||
} |
||||
|
||||
// Verify datarate
|
||||
if( RegionCommonValueInRange( rxParamSetupReq->Datarate, CN470_RX_MIN_DATARATE, CN470_RX_MAX_DATARATE ) == false ) |
||||
{ |
||||
status &= 0xFD; // Datarate KO
|
||||
} |
||||
|
||||
// Verify datarate offset
|
||||
if( RegionCommonValueInRange( rxParamSetupReq->DrOffset, CN470_MIN_RX1_DR_OFFSET, CN470_MAX_RX1_DR_OFFSET ) == false ) |
||||
{ |
||||
status &= 0xFB; // Rx1DrOffset range KO
|
||||
} |
||||
|
||||
return status; |
||||
} |
||||
|
||||
uint8_t RegionCN470NewChannelReq( NewChannelReqParams_t* newChannelReq ) |
||||
{ |
||||
// Datarate and frequency KO
|
||||
return 0; |
||||
} |
||||
|
||||
int8_t RegionCN470TxParamSetupReq( TxParamSetupReqParams_t* txParamSetupReq ) |
||||
{ |
||||
return -1; |
||||
} |
||||
|
||||
uint8_t RegionCN470DlChannelReq( DlChannelReqParams_t* dlChannelReq ) |
||||
{ |
||||
return 0; |
||||
} |
||||
|
||||
int8_t RegionCN470AlternateDr( AlternateDrParams_t* alternateDr ) |
||||
{ |
||||
int8_t datarate = 0; |
||||
|
||||
if( ( alternateDr->NbTrials % 48 ) == 0 ) |
||||
{ |
||||
datarate = DR_0; |
||||
} |
||||
else if( ( alternateDr->NbTrials % 32 ) == 0 ) |
||||
{ |
||||
datarate = DR_1; |
||||
} |
||||
else if( ( alternateDr->NbTrials % 24 ) == 0 ) |
||||
{ |
||||
datarate = DR_2; |
||||
} |
||||
else if( ( alternateDr->NbTrials % 16 ) == 0 ) |
||||
{ |
||||
datarate = DR_3; |
||||
} |
||||
else if( ( alternateDr->NbTrials % 8 ) == 0 ) |
||||
{ |
||||
datarate = DR_4; |
||||
} |
||||
else |
||||
{ |
||||
datarate = DR_5; |
||||
} |
||||
return datarate; |
||||
} |
||||
|
||||
void RegionCN470CalcBackOff( CalcBackOffParams_t* calcBackOff ) |
||||
{ |
||||
RegionCommonCalcBackOffParams_t calcBackOffParams; |
||||
|
||||
calcBackOffParams.Channels = Channels; |
||||
calcBackOffParams.Bands = Bands; |
||||
calcBackOffParams.LastTxIsJoinRequest = calcBackOff->LastTxIsJoinRequest; |
||||
calcBackOffParams.Joined = calcBackOff->Joined; |
||||
calcBackOffParams.DutyCycleEnabled = calcBackOff->DutyCycleEnabled; |
||||
calcBackOffParams.Channel = calcBackOff->Channel; |
||||
calcBackOffParams.ElapsedTime = calcBackOff->ElapsedTime; |
||||
calcBackOffParams.TxTimeOnAir = calcBackOff->TxTimeOnAir; |
||||
|
||||
RegionCommonCalcBackOff( &calcBackOffParams ); |
||||
} |
||||
|
||||
bool RegionCN470NextChannel( NextChanParams_t* nextChanParams, uint8_t* channel, TimerTime_t* time, TimerTime_t* aggregatedTimeOff ) |
||||
{ |
||||
uint8_t nbEnabledChannels = 0; |
||||
uint8_t delayTx = 0; |
||||
uint8_t enabledChannels[CN470_MAX_NB_CHANNELS] = { 0 }; |
||||
TimerTime_t nextTxDelay = 0; |
||||
|
||||
// Count 125kHz channels
|
||||
if( RegionCommonCountChannels( ChannelsMask, 0, 6 ) == 0 ) |
||||
{ // Reactivate default channels
|
||||
ChannelsMask[0] = 0xFFFF; |
||||
ChannelsMask[1] = 0xFFFF; |
||||
ChannelsMask[2] = 0xFFFF; |
||||
ChannelsMask[3] = 0xFFFF; |
||||
ChannelsMask[4] = 0xFFFF; |
||||
ChannelsMask[5] = 0xFFFF; |
||||
} |
||||
|
||||
if( nextChanParams->AggrTimeOff <= TimerGetElapsedTime( nextChanParams->LastAggrTx ) ) |
||||
{ |
||||
// Reset Aggregated time off
|
||||
*aggregatedTimeOff = 0; |
||||
|
||||
// Update bands Time OFF
|
||||
nextTxDelay = RegionCommonUpdateBandTimeOff( nextChanParams->Joined, nextChanParams->DutyCycleEnabled, Bands, CN470_MAX_NB_BANDS ); |
||||
|
||||
// Search how many channels are enabled
|
||||
nbEnabledChannels = CountNbOfEnabledChannels( nextChanParams->Datarate, |
||||
ChannelsMask, Channels, |
||||
Bands, enabledChannels, &delayTx ); |
||||
} |
||||
else |
||||
{ |
||||
delayTx++; |
||||
nextTxDelay = nextChanParams->AggrTimeOff - TimerGetElapsedTime( nextChanParams->LastAggrTx ); |
||||
} |
||||
|
||||
if( nbEnabledChannels > 0 ) |
||||
{ |
||||
// We found a valid channel
|
||||
*channel = enabledChannels[randr( 0, nbEnabledChannels - 1 )]; |
||||
|
||||
*time = 0; |
||||
return true; |
||||
} |
||||
else |
||||
{ |
||||
if( delayTx > 0 ) |
||||
{ |
||||
// Delay transmission due to AggregatedTimeOff or to a band time off
|
||||
*time = nextTxDelay; |
||||
return true; |
||||
} |
||||
// Datarate not supported by any channel
|
||||
*time = 0; |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
LoRaMacStatus_t RegionCN470ChannelAdd( ChannelAddParams_t* channelAdd ) |
||||
{ |
||||
return LORAMAC_STATUS_PARAMETER_INVALID; |
||||
} |
||||
|
||||
bool RegionCN470ChannelsRemove( ChannelRemoveParams_t* channelRemove ) |
||||
{ |
||||
return LORAMAC_STATUS_PARAMETER_INVALID; |
||||
} |
||||
|
||||
void RegionCN470SetContinuousWave( ContinuousWaveParams_t* continuousWave ) |
||||
{ |
||||
int8_t txPowerLimited = LimitTxPower( continuousWave->TxPower, Bands[Channels[continuousWave->Channel].Band].TxMaxPower, continuousWave->Datarate, ChannelsMask ); |
||||
int8_t phyTxPower = 0; |
||||
uint32_t frequency = Channels[continuousWave->Channel].Frequency; |
||||
|
||||
// Calculate physical TX power
|
||||
phyTxPower = RegionCommonComputeTxPower( txPowerLimited, continuousWave->MaxEirp, continuousWave->AntennaGain ); |
||||
|
||||
Radio.SetTxContinuousWave( frequency, phyTxPower, continuousWave->Timeout ); |
||||
} |
||||
|
||||
uint8_t RegionCN470ApplyDrOffset( uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset ) |
||||
{ |
||||
int8_t datarate = dr - drOffset; |
||||
|
||||
if( datarate < 0 ) |
||||
{ |
||||
datarate = DR_0; |
||||
} |
||||
return datarate; |
||||
} |
@ -0,0 +1,441 @@ |
||||
/*!
|
||||
* \file RegionCN470.h |
||||
* |
||||
* \brief Region definition for CN470 |
||||
* |
||||
* \copyright Revised BSD License, see section \ref LICENSE. |
||||
* |
||||
* \code |
||||
* ______ _ |
||||
* / _____) _ | | |
||||
* ( (____ _____ ____ _| |_ _____ ____| |__ |
||||
* \____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
* _____) ) ____| | | || |_| ____( (___| | | | |
||||
* (______/|_____)_|_|_| \__)_____)\____)_| |_| |
||||
* (C)2013 Semtech |
||||
* |
||||
* ___ _____ _ ___ _ _____ ___ ___ ___ ___ |
||||
* / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| |
||||
* \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| |
||||
* |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| |
||||
* embedded.connectivity.solutions=============== |
||||
* |
||||
* \endcode |
||||
* |
||||
* \author Miguel Luis ( Semtech ) |
||||
* |
||||
* \author Gregory Cristian ( Semtech ) |
||||
* |
||||
* \author Daniel Jaeckle ( STACKFORCE ) |
||||
* |
||||
* \defgroup REGIONCN470 Region CN470 |
||||
* Implementation according to LoRaWAN Specification v1.0.2. |
||||
* \{ |
||||
*/ |
||||
#ifndef __REGION_CN470_H__ |
||||
#define __REGION_CN470_H__ |
||||
|
||||
/*!
|
||||
* LoRaMac maximum number of channels |
||||
*/ |
||||
#define CN470_MAX_NB_CHANNELS 96 |
||||
|
||||
/*!
|
||||
* Minimal datarate that can be used by the node |
||||
*/ |
||||
#define CN470_TX_MIN_DATARATE DR_0 |
||||
|
||||
/*!
|
||||
* Maximal datarate that can be used by the node |
||||
*/ |
||||
#define CN470_TX_MAX_DATARATE DR_5 |
||||
|
||||
/*!
|
||||
* Minimal datarate that can be used by the node |
||||
*/ |
||||
#define CN470_RX_MIN_DATARATE DR_0 |
||||
|
||||
/*!
|
||||
* Maximal datarate that can be used by the node |
||||
*/ |
||||
#define CN470_RX_MAX_DATARATE DR_5 |
||||
|
||||
/*!
|
||||
* Default datarate used by the node |
||||
*/ |
||||
#define CN470_DEFAULT_DATARATE DR_0 |
||||
|
||||
/*!
|
||||
* Minimal Rx1 receive datarate offset |
||||
*/ |
||||
#define CN470_MIN_RX1_DR_OFFSET 0 |
||||
|
||||
/*!
|
||||
* Maximal Rx1 receive datarate offset |
||||
*/ |
||||
#define CN470_MAX_RX1_DR_OFFSET 3 |
||||
|
||||
/*!
|
||||
* Default Rx1 receive datarate offset |
||||
*/ |
||||
#define CN470_DEFAULT_RX1_DR_OFFSET 0 |
||||
|
||||
/*!
|
||||
* Minimal Tx output power that can be used by the node |
||||
*/ |
||||
#define CN470_MIN_TX_POWER TX_POWER_7 |
||||
|
||||
/*!
|
||||
* Maximal Tx output power that can be used by the node |
||||
*/ |
||||
#define CN470_MAX_TX_POWER TX_POWER_0 |
||||
|
||||
/*!
|
||||
* Default Tx output power used by the node |
||||
*/ |
||||
#define CN470_DEFAULT_TX_POWER TX_POWER_0 |
||||
|
||||
/*!
|
||||
* Default Max EIRP |
||||
*/ |
||||
#define CN470_DEFAULT_MAX_EIRP 19.15f |
||||
|
||||
/*!
|
||||
* Default antenna gain |
||||
*/ |
||||
#define CN470_DEFAULT_ANTENNA_GAIN 2.15f |
||||
|
||||
/*!
|
||||
* ADR Ack limit |
||||
*/ |
||||
#define CN470_ADR_ACK_LIMIT 64 |
||||
|
||||
/*!
|
||||
* ADR Ack delay |
||||
*/ |
||||
#define CN470_ADR_ACK_DELAY 32 |
||||
|
||||
/*!
|
||||
* Enabled or disabled the duty cycle |
||||
*/ |
||||
#define CN470_DUTY_CYCLE_ENABLED 0 |
||||
|
||||
/*!
|
||||
* Maximum RX window duration |
||||
*/ |
||||
#define CN470_MAX_RX_WINDOW 3000 |
||||
|
||||
/*!
|
||||
* Receive delay 1 |
||||
*/ |
||||
#define CN470_RECEIVE_DELAY1 1000 |
||||
|
||||
/*!
|
||||
* Receive delay 2 |
||||
*/ |
||||
#define CN470_RECEIVE_DELAY2 2000 |
||||
|
||||
/*!
|
||||
* Join accept delay 1 |
||||
*/ |
||||
#define CN470_JOIN_ACCEPT_DELAY1 5000 |
||||
|
||||
/*!
|
||||
* Join accept delay 2 |
||||
*/ |
||||
#define CN470_JOIN_ACCEPT_DELAY2 6000 |
||||
|
||||
/*!
|
||||
* Maximum frame counter gap |
||||
*/ |
||||
#define CN470_MAX_FCNT_GAP 16384 |
||||
|
||||
/*!
|
||||
* Ack timeout |
||||
*/ |
||||
#define CN470_ACKTIMEOUT 2000 |
||||
|
||||
/*!
|
||||
* Random ack timeout limits |
||||
*/ |
||||
#define CN470_ACK_TIMEOUT_RND 1000 |
||||
|
||||
/*!
|
||||
* Second reception window channel frequency definition. |
||||
*/ |
||||
#define CN470_RX_WND_2_FREQ 505300000 |
||||
|
||||
/*!
|
||||
* Second reception window channel datarate definition. |
||||
*/ |
||||
#define CN470_RX_WND_2_DR DR_0 |
||||
|
||||
/*!
|
||||
* LoRaMac maximum number of bands |
||||
*/ |
||||
#define CN470_MAX_NB_BANDS 1 |
||||
|
||||
/*!
|
||||
* Band 0 definition |
||||
* { DutyCycle, TxMaxPower, LastTxDoneTime, TimeOff } |
||||
*/ |
||||
#define CN470_BAND0 { 1, CN470_MAX_TX_POWER, 0, 0 } // 100.0 %
|
||||
|
||||
/*!
|
||||
* Defines the first channel for RX window 1 for CN470 band |
||||
*/ |
||||
#define CN470_FIRST_RX1_CHANNEL ( (uint32_t) 500300000 ) |
||||
|
||||
/*!
|
||||
* Defines the last channel for RX window 1 for CN470 band |
||||
*/ |
||||
#define CN470_LAST_RX1_CHANNEL ( (uint32_t) 509700000 ) |
||||
|
||||
/*!
|
||||
* Defines the step width of the channels for RX window 1 |
||||
*/ |
||||
#define CN470_STEPWIDTH_RX1_CHANNEL ( (uint32_t) 200000 ) |
||||
|
||||
/*!
|
||||
* Data rates table definition |
||||
*/ |
||||
static const uint8_t DataratesCN470[] = { 12, 11, 10, 9, 8, 7 }; |
||||
|
||||
/*!
|
||||
* Bandwidths table definition in Hz |
||||
*/ |
||||
static const uint32_t BandwidthsCN470[] = { 125000, 125000, 125000, 125000, 125000, 125000 }; |
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Cannot operate with repeater. |
||||
*/ |
||||
static const uint8_t MaxPayloadOfDatarateCN470[] = { 51, 51, 51, 115, 222, 222 }; |
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Can operate with repeater. |
||||
*/ |
||||
static const uint8_t MaxPayloadOfDatarateRepeaterCN470[] = { 51, 51, 51, 115, 222, 222 }; |
||||
|
||||
/*!
|
||||
* \brief The function gets a value of a specific phy attribute. |
||||
* |
||||
* \param [IN] getPhy Pointer to the function parameters. |
||||
* |
||||
* \retval Returns a structure containing the PHY parameter. |
||||
*/ |
||||
PhyParam_t RegionCN470GetPhyParam( GetPhyParams_t* getPhy ); |
||||
|
||||
/*!
|
||||
* \brief Updates the last TX done parameters of the current channel. |
||||
* |
||||
* \param [IN] txDone Pointer to the function parameters. |
||||
*/ |
||||
void RegionCN470SetBandTxDone( SetBandTxDoneParams_t* txDone ); |
||||
|
||||
/*!
|
||||
* \brief Initializes the channels masks and the channels. |
||||
* |
||||
* \param [IN] type Sets the initialization type. |
||||
*/ |
||||
void RegionCN470InitDefaults( InitType_t type ); |
||||
|
||||
/*!
|
||||
* \brief Verifies a parameter. |
||||
* |
||||
* \param [IN] verify Pointer to the function parameters. |
||||
* |
||||
* \param [IN] type Sets the initialization type. |
||||
* |
||||
* \retval Returns true, if the parameter is valid. |
||||
*/ |
||||
bool RegionCN470Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute ); |
||||
|
||||
/*!
|
||||
* \brief The function parses the input buffer and sets up the channels of the |
||||
* CF list. |
||||
* |
||||
* \param [IN] applyCFList Pointer to the function parameters. |
||||
*/ |
||||
void RegionCN470ApplyCFList( ApplyCFListParams_t* applyCFList ); |
||||
|
||||
/*!
|
||||
* \brief Sets a channels mask. |
||||
* |
||||
* \param [IN] chanMaskSet Pointer to the function parameters. |
||||
* |
||||
* \retval Returns true, if the channels mask could be set. |
||||
*/ |
||||
bool RegionCN470ChanMaskSet( ChanMaskSetParams_t* chanMaskSet ); |
||||
|
||||
/*!
|
||||
* \brief Calculates the next datarate to set, when ADR is on or off. |
||||
* |
||||
* \param [IN] adrNext Pointer to the function parameters. |
||||
* |
||||
* \param [OUT] drOut The calculated datarate for the next TX. |
||||
* |
||||
* \param [OUT] txPowOut The TX power for the next TX. |
||||
* |
||||
* \param [OUT] adrAckCounter The calculated ADR acknowledgement counter. |
||||
* |
||||
* \retval Returns true, if an ADR request should be performed. |
||||
*/ |
||||
bool RegionCN470AdrNext( AdrNextParams_t* adrNext, int8_t* drOut, int8_t* txPowOut, uint32_t* adrAckCounter ); |
||||
|
||||
/*!
|
||||
* Computes the Rx window timeout and offset. |
||||
* |
||||
* \param [IN] datarate Rx window datarate index to be used |
||||
* |
||||
* \param [IN] minRxSymbols Minimum required number of symbols to detect an Rx frame. |
||||
* |
||||
* \param [IN] rxError System maximum timing error of the receiver. In milliseconds |
||||
* The receiver will turn on in a [-rxError : +rxError] ms |
||||
* interval around RxOffset |
||||
* |
||||
* \param [OUT]rxConfigParams Returns updated WindowTimeout and WindowOffset fields. |
||||
*/ |
||||
void RegionCN470ComputeRxWindowParameters( int8_t datarate, uint8_t minRxSymbols, uint32_t rxError, RxConfigParams_t *rxConfigParams ); |
||||
|
||||
/*!
|
||||
* \brief Configuration of the RX windows. |
||||
* |
||||
* \param [IN] rxConfig Pointer to the function parameters. |
||||
* |
||||
* \param [OUT] datarate The datarate index which was set. |
||||
* |
||||
* \retval Returns true, if the configuration was applied successfully. |
||||
*/ |
||||
bool RegionCN470RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate ); |
||||
|
||||
/*!
|
||||
* \brief TX configuration. |
||||
* |
||||
* \param [IN] txConfig Pointer to the function parameters. |
||||
* |
||||
* \param [OUT] txPower The tx power index which was set. |
||||
* |
||||
* \param [OUT] txTimeOnAir The time-on-air of the frame. |
||||
* |
||||
* \retval Returns true, if the configuration was applied successfully. |
||||
*/ |
||||
bool RegionCN470TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime_t* txTimeOnAir ); |
||||
|
||||
/*!
|
||||
* \brief The function processes a Link ADR Request. |
||||
* |
||||
* \param [IN] linkAdrReq Pointer to the function parameters. |
||||
* |
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification. |
||||
*/ |
||||
uint8_t RegionCN470LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, int8_t* txPowOut, uint8_t* nbRepOut, uint8_t* nbBytesParsed ); |
||||
|
||||
/*!
|
||||
* \brief The function processes a RX Parameter Setup Request. |
||||
* |
||||
* \param [IN] rxParamSetupReq Pointer to the function parameters. |
||||
* |
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification. |
||||
*/ |
||||
uint8_t RegionCN470RxParamSetupReq( RxParamSetupReqParams_t* rxParamSetupReq ); |
||||
|
||||
/*!
|
||||
* \brief The function processes a Channel Request. |
||||
* |
||||
* \param [IN] newChannelReq Pointer to the function parameters. |
||||
* |
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification. |
||||
*/ |
||||
uint8_t RegionCN470NewChannelReq( NewChannelReqParams_t* newChannelReq ); |
||||
|
||||
/*!
|
||||
* \brief The function processes a TX ParamSetup Request. |
||||
* |
||||
* \param [IN] txParamSetupReq Pointer to the function parameters. |
||||
* |
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification. |
||||
* Returns -1, if the functionality is not implemented. In this case, the end node |
||||
* shall not process the command. |
||||
*/ |
||||
int8_t RegionCN470TxParamSetupReq( TxParamSetupReqParams_t* txParamSetupReq ); |
||||
|
||||
/*!
|
||||
* \brief The function processes a DlChannel Request. |
||||
* |
||||
* \param [IN] dlChannelReq Pointer to the function parameters. |
||||
* |
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification. |
||||
*/ |
||||
uint8_t RegionCN470DlChannelReq( DlChannelReqParams_t* dlChannelReq ); |
||||
|
||||
/*!
|
||||
* \brief Alternates the datarate of the channel for the join request. |
||||
* |
||||
* \param [IN] alternateDr Pointer to the function parameters. |
||||
* |
||||
* \retval Datarate to apply. |
||||
*/ |
||||
int8_t RegionCN470AlternateDr( AlternateDrParams_t* alternateDr ); |
||||
|
||||
/*!
|
||||
* \brief Calculates the back-off time. |
||||
* |
||||
* \param [IN] calcBackOff Pointer to the function parameters. |
||||
*/ |
||||
void RegionCN470CalcBackOff( CalcBackOffParams_t* calcBackOff ); |
||||
|
||||
/*!
|
||||
* \brief Searches and set the next random available channel |
||||
* |
||||
* \param [OUT] channel Next channel to use for TX. |
||||
* |
||||
* \param [OUT] time Time to wait for the next transmission according to the duty |
||||
* cycle. |
||||
* |
||||
* \param [OUT] aggregatedTimeOff Updates the aggregated time off. |
||||
* |
||||
* \retval Function status [1: OK, 0: Unable to find a channel on the current datarate] |
||||
*/ |
||||
bool RegionCN470NextChannel( NextChanParams_t* nextChanParams, uint8_t* channel, TimerTime_t* time, TimerTime_t* aggregatedTimeOff ); |
||||
|
||||
/*!
|
||||
* \brief Adds a channel. |
||||
* |
||||
* \param [IN] channelAdd Pointer to the function parameters. |
||||
* |
||||
* \retval Status of the operation. |
||||
*/ |
||||
LoRaMacStatus_t RegionCN470ChannelAdd( ChannelAddParams_t* channelAdd ); |
||||
|
||||
/*!
|
||||
* \brief Removes a channel. |
||||
* |
||||
* \param [IN] channelRemove Pointer to the function parameters. |
||||
* |
||||
* \retval Returns true, if the channel was removed successfully. |
||||
*/ |
||||
bool RegionCN470ChannelsRemove( ChannelRemoveParams_t* channelRemove ); |
||||
|
||||
/*!
|
||||
* \brief Sets the radio into continuous wave mode. |
||||
* |
||||
* \param [IN] continuousWave Pointer to the function parameters. |
||||
*/ |
||||
void RegionCN470SetContinuousWave( ContinuousWaveParams_t* continuousWave ); |
||||
|
||||
/*!
|
||||
* \brief Computes new datarate according to the given offset |
||||
* |
||||
* \param [IN] downlinkDwellTime Downlink dwell time configuration. 0: No limit, 1: 400ms |
||||
* |
||||
* \param [IN] dr Current datarate |
||||
* |
||||
* \param [IN] drOffset Offset to be applied |
||||
* |
||||
* \retval newDr Computed datarate. |
||||
*/ |
||||
uint8_t RegionCN470ApplyDrOffset( uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset ); |
||||
|
||||
/*! \} defgroup REGIONCN470 */ |
||||
|
||||
#endif // __REGION_CN470_H__
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,465 @@ |
||||
/*!
|
||||
* \file RegionCN779.h |
||||
* |
||||
* \brief Region definition for CN779 |
||||
* |
||||
* \copyright Revised BSD License, see section \ref LICENSE. |
||||
* |
||||
* \code |
||||
* ______ _ |
||||
* / _____) _ | | |
||||
* ( (____ _____ ____ _| |_ _____ ____| |__ |
||||
* \____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
* _____) ) ____| | | || |_| ____( (___| | | | |
||||
* (______/|_____)_|_|_| \__)_____)\____)_| |_| |
||||
* (C)2013 Semtech |
||||
* |
||||
* ___ _____ _ ___ _ _____ ___ ___ ___ ___ |
||||
* / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| |
||||
* \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| |
||||
* |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| |
||||
* embedded.connectivity.solutions=============== |
||||
* |
||||
* \endcode |
||||
* |
||||
* \author Miguel Luis ( Semtech ) |
||||
* |
||||
* \author Gregory Cristian ( Semtech ) |
||||
* |
||||
* \author Daniel Jaeckle ( STACKFORCE ) |
||||
* |
||||
* \defgroup REGIONCN779 Region CN779 |
||||
* Implementation according to LoRaWAN Specification v1.0.2. |
||||
* \{ |
||||
*/ |
||||
#ifndef __REGION_CN779_H__ |
||||
#define __REGION_CN779_H__ |
||||
|
||||
/*!
|
||||
* LoRaMac maximum number of channels |
||||
*/ |
||||
#define CN779_MAX_NB_CHANNELS 16 |
||||
|
||||
/*!
|
||||
* Number of default channels |
||||
*/ |
||||
#define CN779_NUMB_DEFAULT_CHANNELS 3 |
||||
|
||||
/*!
|
||||
* Number of channels to apply for the CF list |
||||
*/ |
||||
#define CN779_NUMB_CHANNELS_CF_LIST 5 |
||||
|
||||
/*!
|
||||
* Minimal datarate that can be used by the node |
||||
*/ |
||||
#define CN779_TX_MIN_DATARATE DR_0 |
||||
|
||||
/*!
|
||||
* Maximal datarate that can be used by the node |
||||
*/ |
||||
#define CN779_TX_MAX_DATARATE DR_7 |
||||
|
||||
/*!
|
||||
* Minimal datarate that can be used by the node |
||||
*/ |
||||
#define CN779_RX_MIN_DATARATE DR_0 |
||||
|
||||
/*!
|
||||
* Maximal datarate that can be used by the node |
||||
*/ |
||||
#define CN779_RX_MAX_DATARATE DR_7 |
||||
|
||||
/*!
|
||||
* Default datarate used by the node |
||||
*/ |
||||
#define CN779_DEFAULT_DATARATE DR_0 |
||||
|
||||
/*!
|
||||
* Minimal Rx1 receive datarate offset |
||||
*/ |
||||
#define CN779_MIN_RX1_DR_OFFSET 0 |
||||
|
||||
/*!
|
||||
* Maximal Rx1 receive datarate offset |
||||
*/ |
||||
#define CN779_MAX_RX1_DR_OFFSET 5 |
||||
|
||||
/*!
|
||||
* Default Rx1 receive datarate offset |
||||
*/ |
||||
#define CN779_DEFAULT_RX1_DR_OFFSET 0 |
||||
|
||||
/*!
|
||||
* Minimal Tx output power that can be used by the node |
||||
*/ |
||||
#define CN779_MIN_TX_POWER TX_POWER_5 |
||||
|
||||
/*!
|
||||
* Maximal Tx output power that can be used by the node |
||||
*/ |
||||
#define CN779_MAX_TX_POWER TX_POWER_0 |
||||
|
||||
/*!
|
||||
* Default Tx output power used by the node |
||||
*/ |
||||
#define CN779_DEFAULT_TX_POWER TX_POWER_0 |
||||
|
||||
/*!
|
||||
* Default Max EIRP |
||||
*/ |
||||
#define CN779_DEFAULT_MAX_EIRP 12.15f |
||||
|
||||
/*!
|
||||
* Default antenna gain |
||||
*/ |
||||
#define CN779_DEFAULT_ANTENNA_GAIN 2.15f |
||||
|
||||
/*!
|
||||
* ADR Ack limit |
||||
*/ |
||||
#define CN779_ADR_ACK_LIMIT 64 |
||||
|
||||
/*!
|
||||
* ADR Ack delay |
||||
*/ |
||||
#define CN779_ADR_ACK_DELAY 32 |
||||
|
||||
/*!
|
||||
* Enabled or disabled the duty cycle |
||||
*/ |
||||
#define CN779_DUTY_CYCLE_ENABLED 1 |
||||
|
||||
/*!
|
||||
* Maximum RX window duration |
||||
*/ |
||||
#define CN779_MAX_RX_WINDOW 3000 |
||||
|
||||
/*!
|
||||
* Receive delay 1 |
||||
*/ |
||||
#define CN779_RECEIVE_DELAY1 1000 |
||||
|
||||
/*!
|
||||
* Receive delay 2 |
||||
*/ |
||||
#define CN779_RECEIVE_DELAY2 2000 |
||||
|
||||
/*!
|
||||
* Join accept delay 1 |
||||
*/ |
||||
#define CN779_JOIN_ACCEPT_DELAY1 5000 |
||||
|
||||
/*!
|
||||
* Join accept delay 2 |
||||
*/ |
||||
#define CN779_JOIN_ACCEPT_DELAY2 6000 |
||||
|
||||
/*!
|
||||
* Maximum frame counter gap |
||||
*/ |
||||
#define CN779_MAX_FCNT_GAP 16384 |
||||
|
||||
/*!
|
||||
* Ack timeout |
||||
*/ |
||||
#define CN779_ACKTIMEOUT 2000 |
||||
|
||||
/*!
|
||||
* Random ack timeout limits |
||||
*/ |
||||
#define CN779_ACK_TIMEOUT_RND 1000 |
||||
|
||||
/*!
|
||||
* Verification of default datarate |
||||
*/ |
||||
#if ( CN779_DEFAULT_DATARATE > DR_5 ) |
||||
#error "A default DR higher than DR_5 may lead to connectivity loss." |
||||
#endif |
||||
|
||||
/*!
|
||||
* Second reception window channel frequency definition. |
||||
*/ |
||||
#define CN779_RX_WND_2_FREQ 786000000 |
||||
|
||||
/*!
|
||||
* Second reception window channel datarate definition. |
||||
*/ |
||||
#define CN779_RX_WND_2_DR DR_0 |
||||
|
||||
/*!
|
||||
* LoRaMac maximum number of bands |
||||
*/ |
||||
#define CN779_MAX_NB_BANDS 1 |
||||
|
||||
/*!
|
||||
* Band 0 definition |
||||
* { DutyCycle, TxMaxPower, LastTxDoneTime, TimeOff } |
||||
*/ |
||||
#define CN779_BAND0 { 100, CN779_MAX_TX_POWER, 0, 0 } // 1.0 %
|
||||
|
||||
/*!
|
||||
* LoRaMac default channel 1 |
||||
* Channel = { Frequency [Hz], RX1 Frequency [Hz], { ( ( DrMax << 4 ) | DrMin ) }, Band } |
||||
*/ |
||||
#define CN779_LC1 { 779500000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 } |
||||
/*!
|
||||
* LoRaMac default channel 2 |
||||
* Channel = { Frequency [Hz], RX1 Frequency [Hz], { ( ( DrMax << 4 ) | DrMin ) }, Band } |
||||
*/ |
||||
#define CN779_LC2 { 779700000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 } |
||||
|
||||
/*!
|
||||
* LoRaMac default channel 3 |
||||
* Channel = { Frequency [Hz], RX1 Frequency [Hz], { ( ( DrMax << 4 ) | DrMin ) }, Band } |
||||
*/ |
||||
#define CN779_LC3 { 779900000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 } |
||||
|
||||
/*!
|
||||
* LoRaMac channels which are allowed for the join procedure |
||||
*/ |
||||
#define CN779_JOIN_CHANNELS ( uint16_t )( LC( 1 ) | LC( 2 ) | LC( 3 ) ) |
||||
|
||||
/*!
|
||||
* Data rates table definition |
||||
*/ |
||||
static const uint8_t DataratesCN779[] = { 12, 11, 10, 9, 8, 7, 7, 50 }; |
||||
|
||||
/*!
|
||||
* Bandwidths table definition in Hz |
||||
*/ |
||||
static const uint32_t BandwidthsCN779[] = { 125000, 125000, 125000, 125000, 125000, 125000, 250000, 0 }; |
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Cannot operate with repeater. |
||||
*/ |
||||
static const uint8_t MaxPayloadOfDatarateCN779[] = { 51, 51, 51, 115, 242, 242, 242, 242 }; |
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Can operate with repeater. |
||||
*/ |
||||
static const uint8_t MaxPayloadOfDatarateRepeaterCN779[] = { 51, 51, 51, 115, 222, 222, 222, 222 }; |
||||
|
||||
/*!
|
||||
* \brief The function gets a value of a specific phy attribute. |
||||
* |
||||
* \param [IN] getPhy Pointer to the function parameters. |
||||
* |
||||
* \retval Returns a structure containing the PHY parameter. |
||||
*/ |
||||
PhyParam_t RegionCN779GetPhyParam( GetPhyParams_t* getPhy ); |
||||
|
||||
/*!
|
||||
* \brief Updates the last TX done parameters of the current channel. |
||||
* |
||||
* \param [IN] txDone Pointer to the function parameters. |
||||
*/ |
||||
void RegionCN779SetBandTxDone( SetBandTxDoneParams_t* txDone ); |
||||
|
||||
/*!
|
||||
* \brief Initializes the channels masks and the channels. |
||||
* |
||||
* \param [IN] type Sets the initialization type. |
||||
*/ |
||||
void RegionCN779InitDefaults( InitType_t type ); |
||||
|
||||
/*!
|
||||
* \brief Verifies a parameter. |
||||
* |
||||
* \param [IN] verify Pointer to the function parameters. |
||||
* |
||||
* \param [IN] type Sets the initialization type. |
||||
* |
||||
* \retval Returns true, if the parameter is valid. |
||||
*/ |
||||
bool RegionCN779Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute ); |
||||
|
||||
/*!
|
||||
* \brief The function parses the input buffer and sets up the channels of the |
||||
* CF list. |
||||
* |
||||
* \param [IN] applyCFList Pointer to the function parameters. |
||||
*/ |
||||
void RegionCN779ApplyCFList( ApplyCFListParams_t* applyCFList ); |
||||
|
||||
/*!
|
||||
* \brief Sets a channels mask. |
||||
* |
||||
* \param [IN] chanMaskSet Pointer to the function parameters. |
||||
* |
||||
* \retval Returns true, if the channels mask could be set. |
||||
*/ |
||||
bool RegionCN779ChanMaskSet( ChanMaskSetParams_t* chanMaskSet ); |
||||
|
||||
/*!
|
||||
* \brief Calculates the next datarate to set, when ADR is on or off. |
||||
* |
||||
* \param [IN] adrNext Pointer to the function parameters. |
||||
* |
||||
* \param [OUT] drOut The calculated datarate for the next TX. |
||||
* |
||||
* \param [OUT] txPowOut The TX power for the next TX. |
||||
* |
||||
* \param [OUT] adrAckCounter The calculated ADR acknowledgement counter. |
||||
* |
||||
* \retval Returns true, if an ADR request should be performed. |
||||
*/ |
||||
bool RegionCN779AdrNext( AdrNextParams_t* adrNext, int8_t* drOut, int8_t* txPowOut, uint32_t* adrAckCounter ); |
||||
|
||||
/*!
|
||||
* Computes the Rx window timeout and offset. |
||||
* |
||||
* \param [IN] datarate Rx window datarate index to be used |
||||
* |
||||
* \param [IN] minRxSymbols Minimum required number of symbols to detect an Rx frame. |
||||
* |
||||
* \param [IN] rxError System maximum timing error of the receiver. In milliseconds |
||||
* The receiver will turn on in a [-rxError : +rxError] ms |
||||
* interval around RxOffset |
||||
* |
||||
* \param [OUT]rxConfigParams Returns updated WindowTimeout and WindowOffset fields. |
||||
*/ |
||||
void RegionCN779ComputeRxWindowParameters( int8_t datarate, uint8_t minRxSymbols, uint32_t rxError, RxConfigParams_t *rxConfigParams ); |
||||
|
||||
/*!
|
||||
* \brief Configuration of the RX windows. |
||||
* |
||||
* \param [IN] rxConfig Pointer to the function parameters. |
||||
* |
||||
* \param [OUT] datarate The datarate index which was set. |
||||
* |
||||
* \retval Returns true, if the configuration was applied successfully. |
||||
*/ |
||||
bool RegionCN779RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate ); |
||||
|
||||
/*!
|
||||
* \brief TX configuration. |
||||
* |
||||
* \param [IN] txConfig Pointer to the function parameters. |
||||
* |
||||
* \param [OUT] txPower The tx power index which was set. |
||||
* |
||||
* \param [OUT] txTimeOnAir The time-on-air of the frame. |
||||
* |
||||
* \retval Returns true, if the configuration was applied successfully. |
||||
*/ |
||||
bool RegionCN779TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime_t* txTimeOnAir ); |
||||
|
||||
/*!
|
||||
* \brief The function processes a Link ADR Request. |
||||
* |
||||
* \param [IN] linkAdrReq Pointer to the function parameters. |
||||
* |
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification. |
||||
*/ |
||||
uint8_t RegionCN779LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, int8_t* txPowOut, uint8_t* nbRepOut, uint8_t* nbBytesParsed ); |
||||
|
||||
/*!
|
||||
* \brief The function processes a RX Parameter Setup Request. |
||||
* |
||||
* \param [IN] rxParamSetupReq Pointer to the function parameters. |
||||
* |
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification. |
||||
*/ |
||||
uint8_t RegionCN779RxParamSetupReq( RxParamSetupReqParams_t* rxParamSetupReq ); |
||||
|
||||
/*!
|
||||
* \brief The function processes a Channel Request. |
||||
* |
||||
* \param [IN] newChannelReq Pointer to the function parameters. |
||||
* |
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification. |
||||
*/ |
||||
uint8_t RegionCN779NewChannelReq( NewChannelReqParams_t* newChannelReq ); |
||||
|
||||
/*!
|
||||
* \brief The function processes a TX ParamSetup Request. |
||||
* |
||||
* \param [IN] txParamSetupReq Pointer to the function parameters. |
||||
* |
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification. |
||||
* Returns -1, if the functionality is not implemented. In this case, the end node |
||||
* shall not process the command. |
||||
*/ |
||||
int8_t RegionCN779TxParamSetupReq( TxParamSetupReqParams_t* txParamSetupReq ); |
||||
|
||||
/*!
|
||||
* \brief The function processes a DlChannel Request. |
||||
* |
||||
* \param [IN] dlChannelReq Pointer to the function parameters. |
||||
* |
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification. |
||||
*/ |
||||
uint8_t RegionCN779DlChannelReq( DlChannelReqParams_t* dlChannelReq ); |
||||
|
||||
/*!
|
||||
* \brief Alternates the datarate of the channel for the join request. |
||||
* |
||||
* \param [IN] alternateDr Pointer to the function parameters. |
||||
* |
||||
* \retval Datarate to apply. |
||||
*/ |
||||
int8_t RegionCN779AlternateDr( AlternateDrParams_t* alternateDr ); |
||||
|
||||
/*!
|
||||
* \brief Calculates the back-off time. |
||||
* |
||||
* \param [IN] calcBackOff Pointer to the function parameters. |
||||
*/ |
||||
void RegionCN779CalcBackOff( CalcBackOffParams_t* calcBackOff ); |
||||
|
||||
/*!
|
||||
* \brief Searches and set the next random available channel |
||||
* |
||||
* \param [OUT] channel Next channel to use for TX. |
||||
* |
||||
* \param [OUT] time Time to wait for the next transmission according to the duty |
||||
* cycle. |
||||
* |
||||
* \param [OUT] aggregatedTimeOff Updates the aggregated time off. |
||||
* |
||||
* \retval Function status [1: OK, 0: Unable to find a channel on the current datarate] |
||||
*/ |
||||
bool RegionCN779NextChannel( NextChanParams_t* nextChanParams, uint8_t* channel, TimerTime_t* time, TimerTime_t* aggregatedTimeOff ); |
||||
|
||||
/*!
|
||||
* \brief Adds a channel. |
||||
* |
||||
* \param [IN] channelAdd Pointer to the function parameters. |
||||
* |
||||
* \retval Status of the operation. |
||||
*/ |
||||
LoRaMacStatus_t RegionCN779ChannelAdd( ChannelAddParams_t* channelAdd ); |
||||
|
||||
/*!
|
||||
* \brief Removes a channel. |
||||
* |
||||
* \param [IN] channelRemove Pointer to the function parameters. |
||||
* |
||||
* \retval Returns true, if the channel was removed successfully. |
||||
*/ |
||||
bool RegionCN779ChannelsRemove( ChannelRemoveParams_t* channelRemove ); |
||||
|
||||
/*!
|
||||
* \brief Sets the radio into continuous wave mode. |
||||
* |
||||
* \param [IN] continuousWave Pointer to the function parameters. |
||||
*/ |
||||
void RegionCN779SetContinuousWave( ContinuousWaveParams_t* continuousWave ); |
||||
|
||||
/*!
|
||||
* \brief Computes new datarate according to the given offset |
||||
* |
||||
* \param [IN] downlinkDwellTime Downlink dwell time configuration. 0: No limit, 1: 400ms |
||||
* |
||||
* \param [IN] dr Current datarate |
||||
* |
||||
* \param [IN] drOffset Offset to be applied |
||||
* |
||||
* \retval newDr Computed datarate. |
||||
*/ |
||||
uint8_t RegionCN779ApplyDrOffset( uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset ); |
||||
|
||||
/*! \} defgroup REGIONCN779 */ |
||||
|
||||
#endif // __REGION_CN779_H__
|
@ -0,0 +1,362 @@ |
||||
/*
|
||||
/ _____) _ | | |
||||
( (____ _____ ____ _| |_ _____ ____| |__ |
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | | |
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_| |
||||
(C)2013 Semtech |
||||
___ _____ _ ___ _ _____ ___ ___ ___ ___ |
||||
/ __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| |
||||
\__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| |
||||
|___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| |
||||
embedded.connectivity.solutions=============== |
||||
|
||||
Description: LoRa MAC common region implementation |
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project |
||||
|
||||
Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jaeckle ( STACKFORCE ) |
||||
*/ |
||||
|
||||
#include <stdbool.h> |
||||
#include <string.h> |
||||
#include <stdint.h> |
||||
#include <math.h> |
||||
|
||||
#include "timer.h" |
||||
#include "utilities.h" |
||||
#include "LoRaMac.h" |
||||
#include "RegionCommon.h" |
||||
|
||||
|
||||
|
||||
#define BACKOFF_DC_1_HOUR 100 |
||||
#define BACKOFF_DC_10_HOURS 1000 |
||||
#define BACKOFF_DC_24_HOURS 10000 |
||||
|
||||
|
||||
|
||||
static uint8_t CountChannels( uint16_t mask, uint8_t nbBits ) |
||||
{ |
||||
uint8_t nbActiveBits = 0; |
||||
|
||||
for( uint8_t j = 0; j < nbBits; j++ ) |
||||
{ |
||||
if( ( mask & ( 1 << j ) ) == ( 1 << j ) ) |
||||
{ |
||||
nbActiveBits++; |
||||
} |
||||
} |
||||
return nbActiveBits; |
||||
} |
||||
|
||||
|
||||
|
||||
uint16_t RegionCommonGetJoinDc( TimerTime_t elapsedTime ) |
||||
{ |
||||
uint16_t dutyCycle = 0; |
||||
|
||||
if( elapsedTime < 3600000 ) |
||||
{ |
||||
dutyCycle = BACKOFF_DC_1_HOUR; |
||||
} |
||||
else if( elapsedTime < ( 3600000 + 36000000 ) ) |
||||
{ |
||||
dutyCycle = BACKOFF_DC_10_HOURS; |
||||
} |
||||
else |
||||
{ |
||||
dutyCycle = BACKOFF_DC_24_HOURS; |
||||
} |
||||
return dutyCycle; |
||||
} |
||||
|
||||
bool RegionCommonChanVerifyDr( uint8_t nbChannels, uint16_t* channelsMask, int8_t dr, int8_t minDr, int8_t maxDr, ChannelParams_t* channels ) |
||||
{ |
||||
if( RegionCommonValueInRange( dr, minDr, maxDr ) == 0 ) |
||||
{ |
||||
return false; |
||||
} |
||||
|
||||
for( uint8_t i = 0, k = 0; i < nbChannels; i += 16, k++ ) |
||||
{ |
||||
for( uint8_t j = 0; j < 16; j++ ) |
||||
{ |
||||
if( ( ( channelsMask[k] & ( 1 << j ) ) != 0 ) ) |
||||
{// Check datarate validity for enabled channels
|
||||
if( RegionCommonValueInRange( dr, ( channels[i + j].DrRange.Fields.Min & 0x0F ), |
||||
( channels[i + j].DrRange.Fields.Max & 0x0F ) ) == 1 ) |
||||
{ |
||||
// At least 1 channel has been found we can return OK.
|
||||
return true; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
uint8_t RegionCommonValueInRange( int8_t value, int8_t min, int8_t max ) |
||||
{ |
||||
if( ( value >= min ) && ( value <= max ) ) |
||||
{ |
||||
return 1; |
||||
} |
||||
return 0; |
||||
} |
||||
|
||||
bool RegionCommonChanDisable( uint16_t* channelsMask, uint8_t id, uint8_t maxChannels ) |
||||
{ |
||||
uint8_t index = id / 16; |
||||
|
||||
if( ( index > ( maxChannels / 16 ) ) || ( id >= maxChannels ) ) |
||||
{ |
||||
return false; |
||||
} |
||||
|
||||
// Deactivate channel
|
||||
channelsMask[index] &= ~( 1 << ( id % 16 ) ); |
||||
|
||||
return true; |
||||
} |
||||
|
||||
uint8_t RegionCommonCountChannels( uint16_t* channelsMask, uint8_t startIdx, uint8_t stopIdx ) |
||||
{ |
||||
uint8_t nbChannels = 0; |
||||
|
||||
if( channelsMask == NULL ) |
||||
{ |
||||
return 0; |
||||
} |
||||
|
||||
for( uint8_t i = startIdx; i < stopIdx; i++ ) |
||||
{ |
||||
nbChannels += CountChannels( channelsMask[i], 16 ); |
||||
} |
||||
|
||||
return nbChannels; |
||||
} |
||||
|
||||
void RegionCommonChanMaskCopy( uint16_t* channelsMaskDest, uint16_t* channelsMaskSrc, uint8_t len ) |
||||
{ |
||||
if( ( channelsMaskDest != NULL ) && ( channelsMaskSrc != NULL ) ) |
||||
{ |
||||
for( uint8_t i = 0; i < len; i++ ) |
||||
{ |
||||
channelsMaskDest[i] = channelsMaskSrc[i]; |
||||
} |
||||
} |
||||
} |
||||
|
||||
void RegionCommonSetBandTxDone( bool joined, Band_t* band, TimerTime_t lastTxDone ) |
||||
{ |
||||
if( joined == true ) |
||||
{ |
||||
band->LastTxDoneTime = lastTxDone; |
||||
} |
||||
else |
||||
{ |
||||
band->LastTxDoneTime = lastTxDone; |
||||
band->LastJoinTxDoneTime = lastTxDone; |
||||
} |
||||
} |
||||
|
||||
TimerTime_t RegionCommonUpdateBandTimeOff( bool joined, bool dutyCycle, Band_t* bands, uint8_t nbBands ) |
||||
{ |
||||
TimerTime_t nextTxDelay = ( TimerTime_t )( -1 ); |
||||
|
||||
// Update bands Time OFF
|
||||
for( uint8_t i = 0; i < nbBands; i++ ) |
||||
{ |
||||
if( joined == false ) |
||||
{ |
||||
uint32_t txDoneTime = MAX( TimerGetElapsedTime( bands[i].LastJoinTxDoneTime ), |
||||
( dutyCycle == true ) ? TimerGetElapsedTime( bands[i].LastTxDoneTime ) : 0 ); |
||||
|
||||
if( bands[i].TimeOff <= txDoneTime ) |
||||
{ |
||||
bands[i].TimeOff = 0; |
||||
} |
||||
if( bands[i].TimeOff != 0 ) |
||||
{ |
||||
nextTxDelay = MIN( bands[i].TimeOff - txDoneTime, nextTxDelay ); |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
if( dutyCycle == true ) |
||||
{ |
||||
if( bands[i].TimeOff <= TimerGetElapsedTime( bands[i].LastTxDoneTime ) ) |
||||
{ |
||||
bands[i].TimeOff = 0; |
||||
} |
||||
if( bands[i].TimeOff != 0 ) |
||||
{ |
||||
nextTxDelay = MIN( bands[i].TimeOff - TimerGetElapsedTime( bands[i].LastTxDoneTime ), |
||||
nextTxDelay ); |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
nextTxDelay = 0; |
||||
bands[i].TimeOff = 0; |
||||
} |
||||
} |
||||
} |
||||
return nextTxDelay; |
||||
} |
||||
|
||||
uint8_t RegionCommonParseLinkAdrReq( uint8_t* payload, RegionCommonLinkAdrParams_t* linkAdrParams ) |
||||
{ |
||||
uint8_t retIndex = 0; |
||||
|
||||
if( payload[0] == SRV_MAC_LINK_ADR_REQ ) |
||||
{ |
||||
// Parse datarate and tx power
|
||||
linkAdrParams->Datarate = payload[1]; |
||||
linkAdrParams->TxPower = linkAdrParams->Datarate & 0x0F; |
||||
linkAdrParams->Datarate = ( linkAdrParams->Datarate >> 4 ) & 0x0F; |
||||
// Parse ChMask
|
||||
linkAdrParams->ChMask = ( uint16_t )payload[2]; |
||||
linkAdrParams->ChMask |= ( uint16_t )payload[3] << 8; |
||||
// Parse ChMaskCtrl and nbRep
|
||||
linkAdrParams->NbRep = payload[4]; |
||||
linkAdrParams->ChMaskCtrl = ( linkAdrParams->NbRep >> 4 ) & 0x07; |
||||
linkAdrParams->NbRep &= 0x0F; |
||||
|
||||
// LinkAdrReq has 4 bytes length + 1 byte CMD
|
||||
retIndex = 5; |
||||
} |
||||
return retIndex; |
||||
} |
||||
|
||||
uint8_t RegionCommonLinkAdrReqVerifyParams( RegionCommonLinkAdrReqVerifyParams_t* verifyParams, int8_t* dr, int8_t* txPow, uint8_t* nbRep ) |
||||
{ |
||||
uint8_t status = verifyParams->Status; |
||||
int8_t datarate = verifyParams->Datarate; |
||||
int8_t txPower = verifyParams->TxPower; |
||||
int8_t nbRepetitions = verifyParams->NbRep; |
||||
|
||||
// Handle the case when ADR is off.
|
||||
if( verifyParams->AdrEnabled == false ) |
||||
{ |
||||
// When ADR is off, we are allowed to change the channels mask and the NbRep,
|
||||
// if the datarate and the TX power of the LinkAdrReq are set to 0x0F.
|
||||
if( ( verifyParams->Datarate != 0x0F ) || ( verifyParams->TxPower != 0x0F ) ) |
||||
{ |
||||
status = 0; |
||||
nbRepetitions = verifyParams->CurrentNbRep; |
||||
} |
||||
// Get the current datarate and tx power
|
||||
datarate = verifyParams->CurrentDatarate; |
||||
txPower = verifyParams->CurrentTxPower; |
||||
} |
||||
|
||||
if( status != 0 ) |
||||
{ |
||||
// Verify datarate. The variable phyParam. Value contains the minimum allowed datarate.
|
||||
if( RegionCommonChanVerifyDr( verifyParams->NbChannels, verifyParams->ChannelsMask, datarate, |
||||
verifyParams->MinDatarate, verifyParams->MaxDatarate, verifyParams->Channels ) == false ) |
||||
{ |
||||
status &= 0xFD; // Datarate KO
|
||||
} |
||||
|
||||
// Verify tx power
|
||||
if( RegionCommonValueInRange( txPower, verifyParams->MaxTxPower, verifyParams->MinTxPower ) == 0 ) |
||||
{ |
||||
// Verify if the maximum TX power is exceeded
|
||||
if( verifyParams->MaxTxPower > txPower ) |
||||
{ // Apply maximum TX power. Accept TX power.
|
||||
txPower = verifyParams->MaxTxPower; |
||||
} |
||||
else |
||||
{ |
||||
status &= 0xFB; // TxPower KO
|
||||
} |
||||
} |
||||
} |
||||
|
||||
// If the status is ok, verify the NbRep
|
||||
if( status == 0x07 ) |
||||
{ |
||||
if( nbRepetitions == 0 ) |
||||
{ // Keep the current one
|
||||
nbRepetitions = verifyParams->CurrentNbRep; |
||||
} |
||||
} |
||||
|
||||
// Apply changes
|
||||
*dr = datarate; |
||||
*txPow = txPower; |
||||
*nbRep = nbRepetitions; |
||||
|
||||
return status; |
||||
} |
||||
|
||||
double RegionCommonComputeSymbolTimeLoRa( uint8_t phyDr, uint32_t bandwidth ) |
||||
{ |
||||
return ( ( double )( 1 << phyDr ) / ( double )bandwidth ) * 1000; |
||||
} |
||||
|
||||
double RegionCommonComputeSymbolTimeFsk( uint8_t phyDr ) |
||||
{ |
||||
return ( 8.0 / ( double )phyDr ); // 1 symbol equals 1 byte
|
||||
} |
||||
|
||||
void RegionCommonComputeRxWindowParameters( double tSymbol, uint8_t minRxSymbols, uint32_t rxError, uint32_t wakeUpTime, uint32_t* windowTimeout, int32_t* windowOffset ) |
||||
{ |
||||
*windowTimeout = MAX( ( uint32_t )ceil( ( ( 2 * minRxSymbols - 8 ) * tSymbol + 2 * rxError ) / tSymbol ), minRxSymbols ); // Computed number of symbols
|
||||
*windowOffset = ( int32_t )ceil( ( 4.0 * tSymbol ) - ( ( *windowTimeout * tSymbol ) / 2.0 ) - wakeUpTime ); |
||||
} |
||||
|
||||
int8_t RegionCommonComputeTxPower( int8_t txPowerIndex, float maxEirp, float antennaGain ) |
||||
{ |
||||
int8_t phyTxPower = 0; |
||||
|
||||
phyTxPower = ( int8_t )floor( ( maxEirp - ( txPowerIndex * 2U ) ) - antennaGain ); |
||||
|
||||
return phyTxPower; |
||||
} |
||||
|
||||
void RegionCommonCalcBackOff( RegionCommonCalcBackOffParams_t* calcBackOffParams ) |
||||
{ |
||||
uint8_t bandIdx = calcBackOffParams->Channels[calcBackOffParams->Channel].Band; |
||||
uint16_t dutyCycle = calcBackOffParams->Bands[bandIdx].DCycle; |
||||
uint16_t joinDutyCycle = 0; |
||||
|
||||
// Reset time-off to initial value.
|
||||
calcBackOffParams->Bands[bandIdx].TimeOff = 0; |
||||
|
||||
if( calcBackOffParams->Joined == false ) |
||||
{ |
||||
// Get the join duty cycle
|
||||
joinDutyCycle = RegionCommonGetJoinDc( calcBackOffParams->ElapsedTime ); |
||||
// Apply the most restricting duty cycle
|
||||
dutyCycle = MAX( dutyCycle, joinDutyCycle ); |
||||
// Reset the timeoff if the last frame was not a join request and when the duty cycle is not enabled
|
||||
if( ( calcBackOffParams->DutyCycleEnabled == false ) && ( calcBackOffParams->LastTxIsJoinRequest == false ) ) |
||||
{ |
||||
// This is the case when the duty cycle is off and the last uplink frame was not a join.
|
||||
// This could happen in case of a rejoin, e.g. in compliance test mode.
|
||||
// In this special case we have to set the time off to 0, since the join duty cycle shall only
|
||||
// be applied after the first join request.
|
||||
calcBackOffParams->Bands[bandIdx].TimeOff = 0; |
||||
} |
||||
else |
||||
{ |
||||
// Apply band time-off.
|
||||
calcBackOffParams->Bands[bandIdx].TimeOff = calcBackOffParams->TxTimeOnAir * dutyCycle - calcBackOffParams->TxTimeOnAir; |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
if( calcBackOffParams->DutyCycleEnabled == true ) |
||||
{ |
||||
calcBackOffParams->Bands[bandIdx].TimeOff = calcBackOffParams->TxTimeOnAir * dutyCycle - calcBackOffParams->TxTimeOnAir; |
||||
} |
||||
else |
||||
{ |
||||
calcBackOffParams->Bands[bandIdx].TimeOff = 0; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,367 @@ |
||||
/*!
|
||||
* \file RegionCommon.h |
||||
* |
||||
* \brief Region independent implementations which are common to all regions. |
||||
* |
||||
* \copyright Revised BSD License, see section \ref LICENSE. |
||||
* |
||||
* \code |
||||
* ______ _ |
||||
* / _____) _ | | |
||||
* ( (____ _____ ____ _| |_ _____ ____| |__ |
||||
* \____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
* _____) ) ____| | | || |_| ____( (___| | | | |
||||
* (______/|_____)_|_|_| \__)_____)\____)_| |_| |
||||
* (C)2013 Semtech |
||||
* |
||||
* ___ _____ _ ___ _ _____ ___ ___ ___ ___ |
||||
* / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| |
||||
* \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| |
||||
* |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| |
||||
* embedded.connectivity.solutions=============== |
||||
* |
||||
* \endcode |
||||
* |
||||
* \author Miguel Luis ( Semtech ) |
||||
* |
||||
* \author Gregory Cristian ( Semtech ) |
||||
* |
||||
* \author Daniel Jaeckle ( STACKFORCE ) |
||||
* |
||||
* \defgroup REGIONCOMMON Common region implementation |
||||
* Region independent implementations which are common to all regions. |
||||
* \{ |
||||
*/ |
||||
#ifndef __REGIONCOMMON_H__ |
||||
#define __REGIONCOMMON_H__ |
||||
|
||||
typedef struct sRegionCommonLinkAdrParams |
||||
{ |
||||
/*!
|
||||
* Number of repetitions. |
||||
*/ |
||||
uint8_t NbRep; |
||||
/*!
|
||||
* Datarate. |
||||
*/ |
||||
int8_t Datarate; |
||||
/*!
|
||||
* Tx power. |
||||
*/ |
||||
int8_t TxPower; |
||||
/*!
|
||||
* Channels mask control field. |
||||
*/ |
||||
uint8_t ChMaskCtrl; |
||||
/*!
|
||||
* Channels mask field. |
||||
*/ |
||||
uint16_t ChMask; |
||||
}RegionCommonLinkAdrParams_t; |
||||
|
||||
typedef struct sRegionCommonLinkAdrReqVerifyParams |
||||
{ |
||||
/*!
|
||||
* The current status of the AdrLinkRequest. |
||||
*/ |
||||
uint8_t Status; |
||||
/*!
|
||||
* Set to true, if ADR is enabled. |
||||
*/ |
||||
bool AdrEnabled; |
||||
/*!
|
||||
* The datarate the AdrLinkRequest wants to set. |
||||
*/ |
||||
int8_t Datarate; |
||||
/*!
|
||||
* The TX power the AdrLinkRequest wants to set. |
||||
*/ |
||||
int8_t TxPower; |
||||
/*!
|
||||
* The number of repetitions the AdrLinkRequest wants to set. |
||||
*/ |
||||
uint8_t NbRep; |
||||
/*!
|
||||
* The current datarate the node is using. |
||||
*/ |
||||
int8_t CurrentDatarate; |
||||
/*!
|
||||
* The current TX power the node is using. |
||||
*/ |
||||
int8_t CurrentTxPower; |
||||
/*!
|
||||
* The current number of repetitions the node is using. |
||||
*/ |
||||
int8_t CurrentNbRep; |
||||
/*!
|
||||
* The number of channels. |
||||
*/ |
||||
uint8_t NbChannels; |
||||
/*!
|
||||
* Pointer to the first element of the channels mask. |
||||
*/ |
||||
uint16_t* ChannelsMask; |
||||
/*!
|
||||
* The minimum possible datarate. |
||||
*/ |
||||
int8_t MinDatarate; |
||||
/*!
|
||||
* The maximum possible datarate. |
||||
*/ |
||||
int8_t MaxDatarate; |
||||
/*!
|
||||
* Pointer to the channels. |
||||
*/ |
||||
ChannelParams_t* Channels; |
||||
/*!
|
||||
* The minimum possible TX power. |
||||
*/ |
||||
int8_t MinTxPower; |
||||
/*!
|
||||
* The maximum possible TX power. |
||||
*/ |
||||
int8_t MaxTxPower; |
||||
}RegionCommonLinkAdrReqVerifyParams_t; |
||||
|
||||
typedef struct sRegionCommonCalcBackOffParams |
||||
{ |
||||
/*!
|
||||
* A pointer to region specific channels. |
||||
*/ |
||||
ChannelParams_t* Channels; |
||||
/*!
|
||||
* A pointer to region specific bands. |
||||
*/ |
||||
Band_t* Bands; |
||||
/*!
|
||||
* Set to true, if the last uplink was a join request. |
||||
*/ |
||||
bool LastTxIsJoinRequest; |
||||
/*!
|
||||
* Set to true, if the node is joined. |
||||
*/ |
||||
bool Joined; |
||||
/*!
|
||||
* Set to true, if the duty cycle is enabled. |
||||
*/ |
||||
bool DutyCycleEnabled; |
||||
/*!
|
||||
* The current channel. |
||||
*/ |
||||
uint8_t Channel; |
||||
/*!
|
||||
* The elapsed time since initialization. |
||||
*/ |
||||
TimerTime_t ElapsedTime; |
||||
/*!
|
||||
* The time on air of the last Tx frame. |
||||
*/ |
||||
TimerTime_t TxTimeOnAir; |
||||
}RegionCommonCalcBackOffParams_t; |
||||
|
||||
/*!
|
||||
* \brief Calculates the join duty cycle. |
||||
* This is a generic function and valid for all regions. |
||||
* |
||||
* \param [IN] elapsedTime Elapsed time since the start of the device. |
||||
* |
||||
* \retval Duty cycle restriction. |
||||
*/ |
||||
uint16_t RegionCommonGetJoinDc( TimerTime_t elapsedTime ); |
||||
|
||||
/*!
|
||||
* \brief Verifies, if a value is in a given range. |
||||
* This is a generic function and valid for all regions. |
||||
* |
||||
* \param [IN] value Value to verify, if it is in range. |
||||
* |
||||
* \param [IN] min Minimum possible value. |
||||
* |
||||
* \param [IN] max Maximum possible value. |
||||
* |
||||
* \retval Returns 1 if the value is in range, otherwise 0. |
||||
*/ |
||||
uint8_t RegionCommonValueInRange( int8_t value, int8_t min, int8_t max ); |
||||
|
||||
/*!
|
||||
* \brief Verifies, if a datarate is available on an active channel. |
||||
* This is a generic function and valid for all regions. |
||||
* |
||||
* \param [IN] nbChannels Number of channels. |
||||
* |
||||
* \param [IN] channelsMask The channels mask of the region. |
||||
* |
||||
* \param [IN] dr The datarate to verify. |
||||
* |
||||
* \param [IN] minDr Minimum datarate. |
||||
* |
||||
* \param [IN] maxDr Maximum datarate. |
||||
* |
||||
* \param [IN] channels The channels of the region. |
||||
* |
||||
* \retval Returns true if the datarate is supported, false if not. |
||||
*/ |
||||
bool RegionCommonChanVerifyDr( uint8_t nbChannels, uint16_t* channelsMask, int8_t dr, |
||||
int8_t minDr, int8_t maxDr, ChannelParams_t* channels ); |
||||
|
||||
/*!
|
||||
* \brief Disables a channel in a given channels mask. |
||||
* This is a generic function and valid for all regions. |
||||
* |
||||
* \param [IN] channelsMask The channels mask of the region. |
||||
* |
||||
* \param [IN] id The id of the channels mask to disable. |
||||
* |
||||
* \param [IN] maxChannels Maximum number of channels. |
||||
* |
||||
* \retval Returns true if the channel could be disabled, false if not. |
||||
*/ |
||||
bool RegionCommonChanDisable( uint16_t* channelsMask, uint8_t id, uint8_t maxChannels ); |
||||
|
||||
/*!
|
||||
* \brief Counts the number of active channels in a given channels mask. |
||||
* This is a generic function and valid for all regions. |
||||
* |
||||
* \param [IN] channelsMask The channels mask of the region. |
||||
* |
||||
* \param [IN] startIdx Start index. |
||||
* |
||||
* \param [IN] stopIdx Stop index ( the channels of this index will not be counted ). |
||||
* |
||||
* \retval Returns the number of active channels. |
||||
*/ |
||||
uint8_t RegionCommonCountChannels( uint16_t* channelsMask, uint8_t startIdx, uint8_t stopIdx ); |
||||
|
||||
/*!
|
||||
* \brief Copy a channels mask. |
||||
* This is a generic function and valid for all regions. |
||||
* |
||||
* \param [IN] channelsMaskDest The destination channels mask. |
||||
* |
||||
* \param [IN] channelsMaskSrc The source channels mask. |
||||
* |
||||
* \param [IN] len The index length to copy. |
||||
*/ |
||||
void RegionCommonChanMaskCopy( uint16_t* channelsMaskDest, uint16_t* channelsMaskSrc, uint8_t len ); |
||||
|
||||
/*!
|
||||
* \brief Sets the last tx done property. |
||||
* This is a generic function and valid for all regions. |
||||
* |
||||
* \param [IN] joined Set to true, if the node has joined the network |
||||
* |
||||
* \param [IN] band The band to be updated. |
||||
* |
||||
* \param [IN] lastTxDone The time of the last TX done. |
||||
*/ |
||||
void RegionCommonSetBandTxDone( bool joined, Band_t* band, TimerTime_t lastTxDone ); |
||||
|
||||
/*!
|
||||
* \brief Updates the time-offs of the bands. |
||||
* This is a generic function and valid for all regions. |
||||
* |
||||
* \param [IN] joined Set to true, if the node has joined the network |
||||
* |
||||
* \param [IN] dutyCycle Set to true, if the duty cycle is enabled. |
||||
* |
||||
* \param [IN] bands A pointer to the bands. |
||||
* |
||||
* \param [IN] nbBands The number of bands available. |
||||
* |
||||
* \retval Returns the time which must be waited to perform the next uplink. |
||||
*/ |
||||
TimerTime_t RegionCommonUpdateBandTimeOff( bool joined, bool dutyCycle, Band_t* bands, uint8_t nbBands ); |
||||
|
||||
/*!
|
||||
* \brief Parses the parameter of an LinkAdrRequest. |
||||
* This is a generic function and valid for all regions. |
||||
* |
||||
* \param [IN] payload Pointer to the payload containing the MAC commands. The payload |
||||
* must contain the CMD identifier, following by the parameters. |
||||
* |
||||
* \param [OUT] parseLinkAdr The function fills the structure with the ADR parameters. |
||||
* |
||||
* \retval Returns the length of the ADR request, if a request was found. Otherwise, the |
||||
* function returns 0. |
||||
*/ |
||||
uint8_t RegionCommonParseLinkAdrReq( uint8_t* payload, RegionCommonLinkAdrParams_t* parseLinkAdr ); |
||||
|
||||
/*!
|
||||
* \brief Verifies and updates the datarate, the TX power and the number of repetitions |
||||
* of a LinkAdrRequest. This depends on the configuration of ADR also. |
||||
* |
||||
* \param [IN] verifyParams Pointer to a structure containing input parameters. |
||||
* |
||||
* \param [OUT] dr The updated datarate. |
||||
* |
||||
* \param [OUT] txPow The updated TX power. |
||||
* |
||||
* \param [OUT] nbRep The updated number of repetitions. |
||||
* |
||||
* \retval Returns the status according to the LinkAdrRequest definition. |
||||
*/ |
||||
uint8_t RegionCommonLinkAdrReqVerifyParams( RegionCommonLinkAdrReqVerifyParams_t* verifyParams, int8_t* dr, int8_t* txPow, uint8_t* nbRep ); |
||||
|
||||
/*!
|
||||
* \brief Computes the symbol time for LoRa modulation. |
||||
* |
||||
* \param [IN] phyDr Physical datarate to use. |
||||
* |
||||
* \param [IN] bandwidth Bandwidth to use. |
||||
* |
||||
* \retval Returns the symbol time. |
||||
*/ |
||||
double RegionCommonComputeSymbolTimeLoRa( uint8_t phyDr, uint32_t bandwidth ); |
||||
|
||||
/*!
|
||||
* \brief Computes the symbol time for FSK modulation. |
||||
* |
||||
* \param [IN] phyDr Physical datarate to use. |
||||
* |
||||
* \param [IN] bandwidth Bandwidth to use. |
||||
* |
||||
* \retval Returns the symbol time. |
||||
*/ |
||||
double RegionCommonComputeSymbolTimeFsk( uint8_t phyDr ); |
||||
|
||||
/*!
|
||||
* \brief Computes the RX window timeout and the RX window offset. |
||||
* |
||||
* \param [IN] tSymbol Symbol timeout. |
||||
* |
||||
* \param [IN] minRxSymbols Minimum required number of symbols to detect an Rx frame. |
||||
* |
||||
* \param [IN] rxError System maximum timing error of the receiver. In milliseconds |
||||
* The receiver will turn on in a [-rxError : +rxError] ms interval around RxOffset. |
||||
* |
||||
* \param [IN] wakeUpTime Wakeup time of the system. |
||||
* |
||||
* \param [OUT] windowTimeout RX window timeout. |
||||
* |
||||
* \param [OUT] windowOffset RX window time offset to be applied to the RX delay. |
||||
*/ |
||||
void RegionCommonComputeRxWindowParameters( double tSymbol, uint8_t minRxSymbols, uint32_t rxError, uint32_t wakeUpTime, uint32_t* windowTimeout, int32_t* windowOffset ); |
||||
|
||||
/*!
|
||||
* \brief Computes the txPower, based on the max EIRP and the antenna gain. |
||||
* |
||||
* \param [IN] txPower TX power index. |
||||
* |
||||
* \param [IN] maxEirp Maximum EIRP. |
||||
* |
||||
* \param [IN] antennaGain Antenna gain. |
||||
* |
||||
* \retval Returns the physical TX power. |
||||
*/ |
||||
int8_t RegionCommonComputeTxPower( int8_t txPowerIndex, float maxEirp, float antennaGain ); |
||||
|
||||
/*!
|
||||
* \brief Calculates the duty cycle for the current band. |
||||
* |
||||
* \param [IN] calcBackOffParams A pointer to the input parameters. |
||||
*/ |
||||
void RegionCommonCalcBackOff( RegionCommonCalcBackOffParams_t* calcBackOffParams ); |
||||
|
||||
/*! \} defgroup REGIONCOMMON */ |
||||
|
||||
#endif // __REGIONCOMMON_H__
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,466 @@ |
||||
/*!
|
||||
* \file RegionEU433.h |
||||
* |
||||
* \brief Region definition for EU433 |
||||
* |
||||
* \copyright Revised BSD License, see section \ref LICENSE. |
||||
* |
||||
* \code |
||||
* ______ _ |
||||
* / _____) _ | | |
||||
* ( (____ _____ ____ _| |_ _____ ____| |__ |
||||
* \____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
* _____) ) ____| | | || |_| ____( (___| | | | |
||||
* (______/|_____)_|_|_| \__)_____)\____)_| |_| |
||||
* (C)2013 Semtech |
||||
* |
||||
* ___ _____ _ ___ _ _____ ___ ___ ___ ___ |
||||
* / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| |
||||
* \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| |
||||
* |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| |
||||
* embedded.connectivity.solutions=============== |
||||
* |
||||
* \endcode |
||||
* |
||||
* \author Miguel Luis ( Semtech ) |
||||
* |
||||
* \author Gregory Cristian ( Semtech ) |
||||
* |
||||
* \author Daniel Jaeckle ( STACKFORCE ) |
||||
* |
||||
* \defgroup REGIONEU433 Region EU433 |
||||
* Implementation according to LoRaWAN Specification v1.0.2. |
||||
* \{ |
||||
*/ |
||||
#ifndef __REGION_EU433_H__ |
||||
#define __REGION_EU433_H__ |
||||
|
||||
/*!
|
||||
* LoRaMac maximum number of channels |
||||
*/ |
||||
#define EU433_MAX_NB_CHANNELS 16 |
||||
|
||||
/*!
|
||||
* Number of default channels |
||||
*/ |
||||
#define EU433_NUMB_DEFAULT_CHANNELS 3 |
||||
|
||||
/*!
|
||||
* Number of channels to apply for the CF list |
||||
*/ |
||||
#define EU433_NUMB_CHANNELS_CF_LIST 5 |
||||
|
||||
/*!
|
||||
* Minimal datarate that can be used by the node |
||||
*/ |
||||
#define EU433_TX_MIN_DATARATE DR_0 |
||||
|
||||
/*!
|
||||
* Maximal datarate that can be used by the node |
||||
*/ |
||||
#define EU433_TX_MAX_DATARATE DR_7 |
||||
|
||||
/*!
|
||||
* Minimal datarate that can be used by the node |
||||
*/ |
||||
#define EU433_RX_MIN_DATARATE DR_0 |
||||
|
||||
/*!
|
||||
* Maximal datarate that can be used by the node |
||||
*/ |
||||
#define EU433_RX_MAX_DATARATE DR_7 |
||||
|
||||
/*!
|
||||
* Default datarate used by the node |
||||
*/ |
||||
#define EU433_DEFAULT_DATARATE DR_0 |
||||
|
||||
/*!
|
||||
* Minimal Rx1 receive datarate offset |
||||
*/ |
||||
#define EU433_MIN_RX1_DR_OFFSET 0 |
||||
|
||||
/*!
|
||||
* Maximal Rx1 receive datarate offset |
||||
*/ |
||||
#define EU433_MAX_RX1_DR_OFFSET 5 |
||||
|
||||
/*!
|
||||
* Default Rx1 receive datarate offset |
||||
*/ |
||||
#define EU433_DEFAULT_RX1_DR_OFFSET 0 |
||||
|
||||
/*!
|
||||
* Minimal Tx output power that can be used by the node |
||||
*/ |
||||
#define EU433_MIN_TX_POWER TX_POWER_5 |
||||
|
||||
/*!
|
||||
* Maximal Tx output power that can be used by the node |
||||
*/ |
||||
#define EU433_MAX_TX_POWER TX_POWER_0 |
||||
|
||||
/*!
|
||||
* Default Tx output power used by the node |
||||
*/ |
||||
#define EU433_DEFAULT_TX_POWER TX_POWER_0 |
||||
|
||||
/*!
|
||||
* Default Max EIRP |
||||
*/ |
||||
#define EU433_DEFAULT_MAX_EIRP 12.15f |
||||
|
||||
/*!
|
||||
* Default antenna gain |
||||
*/ |
||||
#define EU433_DEFAULT_ANTENNA_GAIN 2.15f |
||||
|
||||
/*!
|
||||
* ADR Ack limit |
||||
*/ |
||||
#define EU433_ADR_ACK_LIMIT 64 |
||||
|
||||
/*!
|
||||
* ADR Ack delay |
||||
*/ |
||||
#define EU433_ADR_ACK_DELAY 32 |
||||
|
||||
/*!
|
||||
* Enabled or disabled the duty cycle |
||||
*/ |
||||
#define EU433_DUTY_CYCLE_ENABLED 1 |
||||
|
||||
/*!
|
||||
* Maximum RX window duration |
||||
*/ |
||||
#define EU433_MAX_RX_WINDOW 3000 |
||||
|
||||
/*!
|
||||
* Receive delay 1 |
||||
*/ |
||||
#define EU433_RECEIVE_DELAY1 1000 |
||||
|
||||
/*!
|
||||
* Receive delay 2 |
||||
*/ |
||||
#define EU433_RECEIVE_DELAY2 2000 |
||||
|
||||
/*!
|
||||
* Join accept delay 1 |
||||
*/ |
||||
#define EU433_JOIN_ACCEPT_DELAY1 5000 |
||||
|
||||
/*!
|
||||
* Join accept delay 2 |
||||
*/ |
||||
#define EU433_JOIN_ACCEPT_DELAY2 6000 |
||||
|
||||
/*!
|
||||
* Maximum frame counter gap |
||||
*/ |
||||
#define EU433_MAX_FCNT_GAP 16384 |
||||
|
||||
/*!
|
||||
* Ack timeout |
||||
*/ |
||||
#define EU433_ACKTIMEOUT 2000 |
||||
|
||||
/*!
|
||||
* Random ack timeout limits |
||||
*/ |
||||
#define EU433_ACK_TIMEOUT_RND 1000 |
||||
|
||||
/*!
|
||||
* Verification of default datarate |
||||
*/ |
||||
#if ( EU433_DEFAULT_DATARATE > DR_5 ) |
||||
#error "A default DR higher than DR_5 may lead to connectivity loss." |
||||
#endif |
||||
|
||||
/*!
|
||||
* Second reception window channel frequency definition. |
||||
*/ |
||||
#define EU433_RX_WND_2_FREQ 434665000 |
||||
|
||||
/*!
|
||||
* Second reception window channel datarate definition. |
||||
*/ |
||||
#define EU433_RX_WND_2_DR DR_0 |
||||
|
||||
/*!
|
||||
* LoRaMac maximum number of bands |
||||
*/ |
||||
#define EU433_MAX_NB_BANDS 1 |
||||
|
||||
/*!
|
||||
* Band 0 definition |
||||
* { DutyCycle, TxMaxPower, LastTxDoneTime, TimeOff } |
||||
*/ |
||||
#define EU433_BAND0 { 100, EU433_MAX_TX_POWER, 0, 0 } // 1.0 %
|
||||
|
||||
/*!
|
||||
* LoRaMac default channel 1 |
||||
* Channel = { Frequency [Hz], RX1 Frequency [Hz], { ( ( DrMax << 4 ) | DrMin ) }, Band } |
||||
*/ |
||||
#define EU433_LC1 { 433175000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 } |
||||
|
||||
/*!
|
||||
* LoRaMac default channel 2 |
||||
* Channel = { Frequency [Hz], RX1 Frequency [Hz], { ( ( DrMax << 4 ) | DrMin ) }, Band } |
||||
*/ |
||||
#define EU433_LC2 { 433375000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 } |
||||
|
||||
/*!
|
||||
* LoRaMac default channel 3 |
||||
* Channel = { Frequency [Hz], RX1 Frequency [Hz], { ( ( DrMax << 4 ) | DrMin ) }, Band } |
||||
*/ |
||||
#define EU433_LC3 { 433575000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 } |
||||
|
||||
/*!
|
||||
* LoRaMac channels which are allowed for the join procedure |
||||
*/ |
||||
#define EU433_JOIN_CHANNELS ( uint16_t )( LC( 1 ) | LC( 2 ) | LC( 3 ) ) |
||||
|
||||
/*!
|
||||
* Data rates table definition |
||||
*/ |
||||
static const uint8_t DataratesEU433[] = { 12, 11, 10, 9, 8, 7, 7, 50 }; |
||||
|
||||
/*!
|
||||
* Bandwidths table definition in Hz |
||||
*/ |
||||
static const uint32_t BandwidthsEU433[] = { 125000, 125000, 125000, 125000, 125000, 125000, 250000, 0 }; |
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Cannot operate with repeater. |
||||
*/ |
||||
static const uint8_t MaxPayloadOfDatarateEU433[] = { 51, 51, 51, 115, 242, 242, 242, 242 }; |
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Can operate with repeater. |
||||
*/ |
||||
static const uint8_t MaxPayloadOfDatarateRepeaterEU433[] = { 51, 51, 51, 115, 222, 222, 222, 222 }; |
||||
|
||||
/*!
|
||||
* \brief The function gets a value of a specific phy attribute. |
||||
* |
||||
* \param [IN] getPhy Pointer to the function parameters. |
||||
* |
||||
* \retval Returns a structure containing the PHY parameter. |
||||
*/ |
||||
PhyParam_t RegionEU433GetPhyParam( GetPhyParams_t* getPhy ); |
||||
|
||||
/*!
|
||||
* \brief Updates the last TX done parameters of the current channel. |
||||
* |
||||
* \param [IN] txDone Pointer to the function parameters. |
||||
*/ |
||||
void RegionEU433SetBandTxDone( SetBandTxDoneParams_t* txDone ); |
||||
|
||||
/*!
|
||||
* \brief Initializes the channels masks and the channels. |
||||
* |
||||
* \param [IN] type Sets the initialization type. |
||||
*/ |
||||
void RegionEU433InitDefaults( InitType_t type ); |
||||
|
||||
/*!
|
||||
* \brief Verifies a parameter. |
||||
* |
||||
* \param [IN] verify Pointer to the function parameters. |
||||
* |
||||
* \param [IN] type Sets the initialization type. |
||||
* |
||||
* \retval Returns true, if the parameter is valid. |
||||
*/ |
||||
bool RegionEU433Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute ); |
||||
|
||||
/*!
|
||||
* \brief The function parses the input buffer and sets up the channels of the |
||||
* CF list. |
||||
* |
||||
* \param [IN] applyCFList Pointer to the function parameters. |
||||
*/ |
||||
void RegionEU433ApplyCFList( ApplyCFListParams_t* applyCFList ); |
||||
|
||||
/*!
|
||||
* \brief Sets a channels mask. |
||||
* |
||||
* \param [IN] chanMaskSet Pointer to the function parameters. |
||||
* |
||||
* \retval Returns true, if the channels mask could be set. |
||||
*/ |
||||
bool RegionEU433ChanMaskSet( ChanMaskSetParams_t* chanMaskSet ); |
||||
|
||||
/*!
|
||||
* \brief Calculates the next datarate to set, when ADR is on or off. |
||||
* |
||||
* \param [IN] adrNext Pointer to the function parameters. |
||||
* |
||||
* \param [OUT] drOut The calculated datarate for the next TX. |
||||
* |
||||
* \param [OUT] txPowOut The TX power for the next TX. |
||||
* |
||||
* \param [OUT] adrAckCounter The calculated ADR acknowledgement counter. |
||||
* |
||||
* \retval Returns true, if an ADR request should be performed. |
||||
*/ |
||||
bool RegionEU433AdrNext( AdrNextParams_t* adrNext, int8_t* drOut, int8_t* txPowOut, uint32_t* adrAckCounter ); |
||||
|
||||
/*!
|
||||
* Computes the Rx window timeout and offset. |
||||
* |
||||
* \param [IN] datarate Rx window datarate index to be used |
||||
* |
||||
* \param [IN] minRxSymbols Minimum required number of symbols to detect an Rx frame. |
||||
* |
||||
* \param [IN] rxError System maximum timing error of the receiver. In milliseconds |
||||
* The receiver will turn on in a [-rxError : +rxError] ms |
||||
* interval around RxOffset |
||||
* |
||||
* \param [OUT]rxConfigParams Returns updated WindowTimeout and WindowOffset fields. |
||||
*/ |
||||
void RegionEU433ComputeRxWindowParameters( int8_t datarate, uint8_t minRxSymbols, uint32_t rxError, RxConfigParams_t *rxConfigParams ); |
||||
|
||||
/*!
|
||||
* \brief Configuration of the RX windows. |
||||
* |
||||
* \param [IN] rxConfig Pointer to the function parameters. |
||||
* |
||||
* \param [OUT] datarate The datarate index which was set. |
||||
* |
||||
* \retval Returns true, if the configuration was applied successfully. |
||||
*/ |
||||
bool RegionEU433RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate ); |
||||
|
||||
/*!
|
||||
* \brief TX configuration. |
||||
* |
||||
* \param [IN] txConfig Pointer to the function parameters. |
||||
* |
||||
* \param [OUT] txPower The tx power index which was set. |
||||
* |
||||
* \param [OUT] txTimeOnAir The time-on-air of the frame. |
||||
* |
||||
* \retval Returns true, if the configuration was applied successfully. |
||||
*/ |
||||
bool RegionEU433TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime_t* txTimeOnAir ); |
||||
|
||||
/*!
|
||||
* \brief The function processes a Link ADR Request. |
||||
* |
||||
* \param [IN] linkAdrReq Pointer to the function parameters. |
||||
* |
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification. |
||||
*/ |
||||
uint8_t RegionEU433LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, int8_t* txPowOut, uint8_t* nbRepOut, uint8_t* nbBytesParsed ); |
||||
|
||||
/*!
|
||||
* \brief The function processes a RX Parameter Setup Request. |
||||
* |
||||
* \param [IN] rxParamSetupReq Pointer to the function parameters. |
||||
* |
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification. |
||||
*/ |
||||
uint8_t RegionEU433RxParamSetupReq( RxParamSetupReqParams_t* rxParamSetupReq ); |
||||
|
||||
/*!
|
||||
* \brief The function processes a Channel Request. |
||||
* |
||||
* \param [IN] newChannelReq Pointer to the function parameters. |
||||
* |
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification. |
||||
*/ |
||||
uint8_t RegionEU433NewChannelReq( NewChannelReqParams_t* newChannelReq ); |
||||
|
||||
/*!
|
||||
* \brief The function processes a TX ParamSetup Request. |
||||
* |
||||
* \param [IN] txParamSetupReq Pointer to the function parameters. |
||||
* |
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification. |
||||
* Returns -1, if the functionality is not implemented. In this case, the end node |
||||
* shall not process the command. |
||||
*/ |
||||
int8_t RegionEU433TxParamSetupReq( TxParamSetupReqParams_t* txParamSetupReq ); |
||||
|
||||
/*!
|
||||
* \brief The function processes a DlChannel Request. |
||||
* |
||||
* \param [IN] dlChannelReq Pointer to the function parameters. |
||||
* |
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification. |
||||
*/ |
||||
uint8_t RegionEU433DlChannelReq( DlChannelReqParams_t* dlChannelReq ); |
||||
|
||||
/*!
|
||||
* \brief Alternates the datarate of the channel for the join request. |
||||
* |
||||
* \param [IN] alternateDr Pointer to the function parameters. |
||||
* |
||||
* \retval Datarate to apply. |
||||
*/ |
||||
int8_t RegionEU433AlternateDr( AlternateDrParams_t* alternateDr ); |
||||
|
||||
/*!
|
||||
* \brief Calculates the back-off time. |
||||
* |
||||
* \param [IN] calcBackOff Pointer to the function parameters. |
||||
*/ |
||||
void RegionEU433CalcBackOff( CalcBackOffParams_t* calcBackOff ); |
||||
|
||||
/*!
|
||||
* \brief Searches and set the next random available channel |
||||
* |
||||
* \param [OUT] channel Next channel to use for TX. |
||||
* |
||||
* \param [OUT] time Time to wait for the next transmission according to the duty |
||||
* cycle. |
||||
* |
||||
* \param [OUT] aggregatedTimeOff Updates the aggregated time off. |
||||
* |
||||
* \retval Function status [1: OK, 0: Unable to find a channel on the current datarate] |
||||
*/ |
||||
bool RegionEU433NextChannel( NextChanParams_t* nextChanParams, uint8_t* channel, TimerTime_t* time, TimerTime_t* aggregatedTimeOff ); |
||||
|
||||
/*!
|
||||
* \brief Adds a channel. |
||||
* |
||||
* \param [IN] channelAdd Pointer to the function parameters. |
||||
* |
||||
* \retval Status of the operation. |
||||
*/ |
||||
LoRaMacStatus_t RegionEU433ChannelAdd( ChannelAddParams_t* channelAdd ); |
||||
|
||||
/*!
|
||||
* \brief Removes a channel. |
||||
* |
||||
* \param [IN] channelRemove Pointer to the function parameters. |
||||
* |
||||
* \retval Returns true, if the channel was removed successfully. |
||||
*/ |
||||
bool RegionEU433ChannelsRemove( ChannelRemoveParams_t* channelRemove ); |
||||
|
||||
/*!
|
||||
* \brief Sets the radio into continuous wave mode. |
||||
* |
||||
* \param [IN] continuousWave Pointer to the function parameters. |
||||
*/ |
||||
void RegionEU433SetContinuousWave( ContinuousWaveParams_t* continuousWave ); |
||||
|
||||
/*!
|
||||
* \brief Computes new datarate according to the given offset |
||||
* |
||||
* \param [IN] downlinkDwellTime Downlink dwell time configuration. 0: No limit, 1: 400ms |
||||
* |
||||
* \param [IN] dr Current datarate |
||||
* |
||||
* \param [IN] drOffset Offset to be applied |
||||
* |
||||
* \retval newDr Computed datarate. |
||||
*/ |
||||
uint8_t RegionEU433ApplyDrOffset( uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset ); |
||||
|
||||
/*! \} defgroup REGIONEU433 */ |
||||
|
||||
#endif // __REGION_EU433_H__
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,487 @@ |
||||
/*!
|
||||
* \file RegionEU868.h |
||||
* |
||||
* \brief Region definition for EU868 |
||||
* |
||||
* \copyright Revised BSD License, see section \ref LICENSE. |
||||
* |
||||
* \code |
||||
* ______ _ |
||||
* / _____) _ | | |
||||
* ( (____ _____ ____ _| |_ _____ ____| |__ |
||||
* \____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
* _____) ) ____| | | || |_| ____( (___| | | | |
||||
* (______/|_____)_|_|_| \__)_____)\____)_| |_| |
||||
* (C)2013 Semtech |
||||
* |
||||
* ___ _____ _ ___ _ _____ ___ ___ ___ ___ |
||||
* / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| |
||||
* \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| |
||||
* |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| |
||||
* embedded.connectivity.solutions=============== |
||||
* |
||||
* \endcode |
||||
* |
||||
* \author Miguel Luis ( Semtech ) |
||||
* |
||||
* \author Gregory Cristian ( Semtech ) |
||||
* |
||||
* \author Daniel Jaeckle ( STACKFORCE ) |
||||
* |
||||
* \defgroup REGIONEU868 Region EU868 |
||||
* Implementation according to LoRaWAN Specification v1.0.2. |
||||
* \{ |
||||
*/ |
||||
#ifndef __REGION_EU868_H__ |
||||
#define __REGION_EU868_H__ |
||||
|
||||
/*!
|
||||
* LoRaMac maximum number of channels |
||||
*/ |
||||
#define EU868_MAX_NB_CHANNELS 16 |
||||
|
||||
/*!
|
||||
* Number of default channels |
||||
*/ |
||||
#define EU868_NUMB_DEFAULT_CHANNELS 3 |
||||
|
||||
/*!
|
||||
* Number of channels to apply for the CF list |
||||
*/ |
||||
#define EU868_NUMB_CHANNELS_CF_LIST 5 |
||||
|
||||
/*!
|
||||
* Minimal datarate that can be used by the node |
||||
*/ |
||||
#define EU868_TX_MIN_DATARATE DR_0 |
||||
|
||||
/*!
|
||||
* Maximal datarate that can be used by the node |
||||
*/ |
||||
#define EU868_TX_MAX_DATARATE DR_7 |
||||
|
||||
/*!
|
||||
* Minimal datarate that can be used by the node |
||||
*/ |
||||
#define EU868_RX_MIN_DATARATE DR_0 |
||||
|
||||
/*!
|
||||
* Maximal datarate that can be used by the node |
||||
*/ |
||||
#define EU868_RX_MAX_DATARATE DR_7 |
||||
|
||||
/*!
|
||||
* Default datarate used by the node |
||||
*/ |
||||
#define EU868_DEFAULT_DATARATE DR_0 |
||||
|
||||
/*!
|
||||
* Minimal Rx1 receive datarate offset |
||||
*/ |
||||
#define EU868_MIN_RX1_DR_OFFSET 0 |
||||
|
||||
/*!
|
||||
* Maximal Rx1 receive datarate offset |
||||
*/ |
||||
#define EU868_MAX_RX1_DR_OFFSET 5 |
||||
|
||||
/*!
|
||||
* Default Rx1 receive datarate offset |
||||
*/ |
||||
#define EU868_DEFAULT_RX1_DR_OFFSET 0 |
||||
|
||||
/*!
|
||||
* Minimal Tx output power that can be used by the node |
||||
*/ |
||||
#define EU868_MIN_TX_POWER TX_POWER_7 |
||||
|
||||
/*!
|
||||
* Maximal Tx output power that can be used by the node |
||||
*/ |
||||
#define EU868_MAX_TX_POWER TX_POWER_0 |
||||
|
||||
/*!
|
||||
* Default Tx output power used by the node |
||||
*/ |
||||
#define EU868_DEFAULT_TX_POWER TX_POWER_0 |
||||
|
||||
/*!
|
||||
* Default Max EIRP |
||||
*/ |
||||
#define EU868_DEFAULT_MAX_EIRP 16.0f |
||||
|
||||
/*!
|
||||
* Default antenna gain |
||||
*/ |
||||
#define EU868_DEFAULT_ANTENNA_GAIN 2.15f |
||||
|
||||
/*!
|
||||
* ADR Ack limit |
||||
*/ |
||||
#define EU868_ADR_ACK_LIMIT 64 |
||||
|
||||
/*!
|
||||
* ADR Ack delay |
||||
*/ |
||||
#define EU868_ADR_ACK_DELAY 32 |
||||
|
||||
/*!
|
||||
* Enabled or disabled the duty cycle |
||||
*/ |
||||
#define EU868_DUTY_CYCLE_ENABLED 1 |
||||
|
||||
/*!
|
||||
* Maximum RX window duration |
||||
*/ |
||||
#define EU868_MAX_RX_WINDOW 3000 |
||||
|
||||
/*!
|
||||
* Receive delay 1 |
||||
*/ |
||||
#define EU868_RECEIVE_DELAY1 1000 |
||||
|
||||
/*!
|
||||
* Receive delay 2 |
||||
*/ |
||||
#define EU868_RECEIVE_DELAY2 2000 |
||||
|
||||
/*!
|
||||
* Join accept delay 1 |
||||
*/ |
||||
#define EU868_JOIN_ACCEPT_DELAY1 5000 |
||||
|
||||
/*!
|
||||
* Join accept delay 2 |
||||
*/ |
||||
#define EU868_JOIN_ACCEPT_DELAY2 6000 |
||||
|
||||
/*!
|
||||
* Maximum frame counter gap |
||||
*/ |
||||
#define EU868_MAX_FCNT_GAP 16384 |
||||
|
||||
/*!
|
||||
* Ack timeout |
||||
*/ |
||||
#define EU868_ACKTIMEOUT 2000 |
||||
|
||||
/*!
|
||||
* Random ack timeout limits |
||||
*/ |
||||
#define EU868_ACK_TIMEOUT_RND 1000 |
||||
|
||||
#if ( EU868_DEFAULT_DATARATE > DR_5 ) |
||||
#error "A default DR higher than DR_5 may lead to connectivity loss." |
||||
#endif |
||||
|
||||
/*!
|
||||
* Second reception window channel frequency definition. |
||||
*/ |
||||
#define EU868_RX_WND_2_FREQ 869525000 |
||||
|
||||
/*!
|
||||
* Second reception window channel datarate definition. |
||||
*/ |
||||
#define EU868_RX_WND_2_DR DR_0 |
||||
|
||||
/*!
|
||||
* Maximum number of bands |
||||
*/ |
||||
#define EU868_MAX_NB_BANDS 5 |
||||
|
||||
/*!
|
||||
* Band 0 definition |
||||
* { DutyCycle, TxMaxPower, LastTxDoneTime, TimeOff } |
||||
*/ |
||||
#define EU868_BAND0 { 100 , EU868_MAX_TX_POWER, 0, 0 } // 1.0 %
|
||||
|
||||
/*!
|
||||
* Band 1 definition |
||||
* { DutyCycle, TxMaxPower, LastTxDoneTime, TimeOff } |
||||
*/ |
||||
#define EU868_BAND1 { 100 , EU868_MAX_TX_POWER, 0, 0 } // 1.0 %
|
||||
|
||||
/*!
|
||||
* Band 2 definition |
||||
* Band = { DutyCycle, TxMaxPower, LastTxDoneTime, TimeOff } |
||||
*/ |
||||
#define EU868_BAND2 { 1000, EU868_MAX_TX_POWER, 0, 0 } // 0.1 %
|
||||
|
||||
/*!
|
||||
* Band 2 definition |
||||
* Band = { DutyCycle, TxMaxPower, LastTxDoneTime, TimeOff } |
||||
*/ |
||||
#define EU868_BAND3 { 10 , EU868_MAX_TX_POWER, 0, 0 } // 10.0 %
|
||||
|
||||
/*!
|
||||
* Band 2 definition |
||||
* Band = { DutyCycle, TxMaxPower, LastTxDoneTime, TimeOff } |
||||
*/ |
||||
#define EU868_BAND4 { 100 , EU868_MAX_TX_POWER, 0, 0 } // 1.0 %
|
||||
|
||||
/*!
|
||||
* LoRaMac default channel 1 |
||||
* Channel = { Frequency [Hz], RX1 Frequency [Hz], { ( ( DrMax << 4 ) | DrMin ) }, Band } |
||||
*/ |
||||
#define EU868_LC1 { 868100000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 1 } |
||||
|
||||
/*!
|
||||
* LoRaMac default channel 2 |
||||
* Channel = { Frequency [Hz], RX1 Frequency [Hz], { ( ( DrMax << 4 ) | DrMin ) }, Band } |
||||
*/ |
||||
#define EU868_LC2 { 868300000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 1 } |
||||
|
||||
/*!
|
||||
* LoRaMac default channel 3 |
||||
* Channel = { Frequency [Hz], RX1 Frequency [Hz], { ( ( DrMax << 4 ) | DrMin ) }, Band } |
||||
*/ |
||||
#define EU868_LC3 { 868500000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 1 } |
||||
|
||||
/*!
|
||||
* LoRaMac channels which are allowed for the join procedure |
||||
*/ |
||||
#define EU868_JOIN_CHANNELS ( uint16_t )( LC( 1 ) | LC( 2 ) | LC( 3 ) ) |
||||
|
||||
/*!
|
||||
* Data rates table definition |
||||
*/ |
||||
static const uint8_t DataratesEU868[] = { 12, 11, 10, 9, 8, 7, 7, 50 }; |
||||
|
||||
/*!
|
||||
* Bandwidths table definition in Hz |
||||
*/ |
||||
static const uint32_t BandwidthsEU868[] = { 125000, 125000, 125000, 125000, 125000, 125000, 250000, 0 }; |
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Cannot operate with repeater. |
||||
*/ |
||||
static const uint8_t MaxPayloadOfDatarateEU868[] = { 51, 51, 51, 115, 242, 242, 242, 242 }; |
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Can operate with repeater. |
||||
*/ |
||||
static const uint8_t MaxPayloadOfDatarateRepeaterEU868[] = { 51, 51, 51, 115, 222, 222, 222, 222 }; |
||||
|
||||
/*!
|
||||
* \brief The function gets a value of a specific phy attribute. |
||||
* |
||||
* \param [IN] getPhy Pointer to the function parameters. |
||||
* |
||||
* \retval Returns a structure containing the PHY parameter. |
||||
*/ |
||||
PhyParam_t RegionEU868GetPhyParam( GetPhyParams_t* getPhy ); |
||||
|
||||
/*!
|
||||
* \brief Updates the last TX done parameters of the current channel. |
||||
* |
||||
* \param [IN] txDone Pointer to the function parameters. |
||||
*/ |
||||
void RegionEU868SetBandTxDone( SetBandTxDoneParams_t* txDone ); |
||||
|
||||
/*!
|
||||
* \brief Initializes the channels masks and the channels. |
||||
* |
||||
* \param [IN] type Sets the initialization type. |
||||
*/ |
||||
void RegionEU868InitDefaults( InitType_t type ); |
||||
|
||||
/*!
|
||||
* \brief Verifies a parameter. |
||||
* |
||||
* \param [IN] verify Pointer to the function parameters. |
||||
* |
||||
* \param [IN] type Sets the initialization type. |
||||
* |
||||
* \retval Returns true, if the parameter is valid. |
||||
*/ |
||||
bool RegionEU868Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute ); |
||||
|
||||
/*!
|
||||
* \brief The function parses the input buffer and sets up the channels of the |
||||
* CF list. |
||||
* |
||||
* \param [IN] applyCFList Pointer to the function parameters. |
||||
*/ |
||||
void RegionEU868ApplyCFList( ApplyCFListParams_t* applyCFList ); |
||||
|
||||
/*!
|
||||
* \brief Sets a channels mask. |
||||
* |
||||
* \param [IN] chanMaskSet Pointer to the function parameters. |
||||
* |
||||
* \retval Returns true, if the channels mask could be set. |
||||
*/ |
||||
bool RegionEU868ChanMaskSet( ChanMaskSetParams_t* chanMaskSet ); |
||||
|
||||
/*!
|
||||
* \brief Calculates the next datarate to set, when ADR is on or off. |
||||
* |
||||
* \param [IN] adrNext Pointer to the function parameters. |
||||
* |
||||
* \param [OUT] drOut The calculated datarate for the next TX. |
||||
* |
||||
* \param [OUT] txPowOut The TX power for the next TX. |
||||
* |
||||
* \param [OUT] adrAckCounter The calculated ADR acknowledgement counter. |
||||
* |
||||
* \retval Returns true, if an ADR request should be performed. |
||||
*/ |
||||
bool RegionEU868AdrNext( AdrNextParams_t* adrNext, int8_t* drOut, int8_t* txPowOut, uint32_t* adrAckCounter ); |
||||
|
||||
/*!
|
||||
* Computes the Rx window timeout and offset. |
||||
* |
||||
* \param [IN] datarate Rx window datarate index to be used |
||||
* |
||||
* \param [IN] minRxSymbols Minimum required number of symbols to detect an Rx frame. |
||||
* |
||||
* \param [IN] rxError System maximum timing error of the receiver. In milliseconds |
||||
* The receiver will turn on in a [-rxError : +rxError] ms |
||||
* interval around RxOffset |
||||
* |
||||
* \param [OUT]rxConfigParams Returns updated WindowTimeout and WindowOffset fields. |
||||
*/ |
||||
void RegionEU868ComputeRxWindowParameters( int8_t datarate, uint8_t minRxSymbols, uint32_t rxError, RxConfigParams_t *rxConfigParams ); |
||||
|
||||
/*!
|
||||
* \brief Configuration of the RX windows. |
||||
* |
||||
* \param [IN] rxConfig Pointer to the function parameters. |
||||
* |
||||
* \param [OUT] datarate The datarate index which was set. |
||||
* |
||||
* \retval Returns true, if the configuration was applied successfully. |
||||
*/ |
||||
bool RegionEU868RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate ); |
||||
|
||||
/*!
|
||||
* \brief TX configuration. |
||||
* |
||||
* \param [IN] txConfig Pointer to the function parameters. |
||||
* |
||||
* \param [OUT] txPower The tx power index which was set. |
||||
* |
||||
* \param [OUT] txTimeOnAir The time-on-air of the frame. |
||||
* |
||||
* \retval Returns true, if the configuration was applied successfully. |
||||
*/ |
||||
bool RegionEU868TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime_t* txTimeOnAir ); |
||||
|
||||
/*!
|
||||
* \brief The function processes a Link ADR Request. |
||||
* |
||||
* \param [IN] linkAdrReq Pointer to the function parameters. |
||||
* |
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification. |
||||
*/ |
||||
uint8_t RegionEU868LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, int8_t* txPowOut, uint8_t* nbRepOut, uint8_t* nbBytesParsed ); |
||||
|
||||
/*!
|
||||
* \brief The function processes a RX Parameter Setup Request. |
||||
* |
||||
* \param [IN] rxParamSetupReq Pointer to the function parameters. |
||||
* |
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification. |
||||
*/ |
||||
uint8_t RegionEU868RxParamSetupReq( RxParamSetupReqParams_t* rxParamSetupReq ); |
||||
|
||||
/*!
|
||||
* \brief The function processes a Channel Request. |
||||
* |
||||
* \param [IN] newChannelReq Pointer to the function parameters. |
||||
* |
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification. |
||||
*/ |
||||
uint8_t RegionEU868NewChannelReq( NewChannelReqParams_t* newChannelReq ); |
||||
|
||||
/*!
|
||||
* \brief The function processes a TX ParamSetup Request. |
||||
* |
||||
* \param [IN] txParamSetupReq Pointer to the function parameters. |
||||
* |
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification. |
||||
* Returns -1, if the functionality is not implemented. In this case, the end node |
||||
* shall not process the command. |
||||
*/ |
||||
int8_t RegionEU868TxParamSetupReq( TxParamSetupReqParams_t* txParamSetupReq ); |
||||
|
||||
/*!
|
||||
* \brief The function processes a DlChannel Request. |
||||
* |
||||
* \param [IN] dlChannelReq Pointer to the function parameters. |
||||
* |
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification. |
||||
*/ |
||||
uint8_t RegionEU868DlChannelReq( DlChannelReqParams_t* dlChannelReq ); |
||||
|
||||
/*!
|
||||
* \brief Alternates the datarate of the channel for the join request. |
||||
* |
||||
* \param [IN] alternateDr Pointer to the function parameters. |
||||
* |
||||
* \retval Datarate to apply. |
||||
*/ |
||||
int8_t RegionEU868AlternateDr( AlternateDrParams_t* alternateDr ); |
||||
|
||||
/*!
|
||||
* \brief Calculates the back-off time. |
||||
* |
||||
* \param [IN] calcBackOff Pointer to the function parameters. |
||||
*/ |
||||
void RegionEU868CalcBackOff( CalcBackOffParams_t* calcBackOff ); |
||||
|
||||
/*!
|
||||
* \brief Searches and set the next random available channel |
||||
* |
||||
* \param [OUT] channel Next channel to use for TX. |
||||
* |
||||
* \param [OUT] time Time to wait for the next transmission according to the duty |
||||
* cycle. |
||||
* |
||||
* \param [OUT] aggregatedTimeOff Updates the aggregated time off. |
||||
* |
||||
* \retval Function status [1: OK, 0: Unable to find a channel on the current datarate] |
||||
*/ |
||||
bool RegionEU868NextChannel( NextChanParams_t* nextChanParams, uint8_t* channel, TimerTime_t* time, TimerTime_t* aggregatedTimeOff ); |
||||
|
||||
/*!
|
||||
* \brief Adds a channel. |
||||
* |
||||
* \param [IN] channelAdd Pointer to the function parameters. |
||||
* |
||||
* \retval Status of the operation. |
||||
*/ |
||||
LoRaMacStatus_t RegionEU868ChannelAdd( ChannelAddParams_t* channelAdd ); |
||||
|
||||
/*!
|
||||
* \brief Removes a channel. |
||||
* |
||||
* \param [IN] channelRemove Pointer to the function parameters. |
||||
* |
||||
* \retval Returns true, if the channel was removed successfully. |
||||
*/ |
||||
bool RegionEU868ChannelsRemove( ChannelRemoveParams_t* channelRemove ); |
||||
|
||||
/*!
|
||||
* \brief Sets the radio into continuous wave mode. |
||||
* |
||||
* \param [IN] continuousWave Pointer to the function parameters. |
||||
*/ |
||||
void RegionEU868SetContinuousWave( ContinuousWaveParams_t* continuousWave ); |
||||
|
||||
/*!
|
||||
* \brief Computes new datarate according to the given offset |
||||
* |
||||
* \param [IN] downlinkDwellTime Downlink dwell time configuration. 0: No limit, 1: 400ms |
||||
* |
||||
* \param [IN] dr Current datarate |
||||
* |
||||
* \param [IN] drOffset Offset to be applied |
||||
* |
||||
* \retval newDr Computed datarate. |
||||
*/ |
||||
uint8_t RegionEU868ApplyDrOffset( uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset ); |
||||
|
||||
/*! \} defgroup REGIONEU868 */ |
||||
|
||||
#endif // __REGION_EU868_H__
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,468 @@ |
||||
/*!
|
||||
* \file RegionIN865.h |
||||
* |
||||
* \brief Region definition for IN865 |
||||
* |
||||
* \copyright Revised BSD License, see section \ref LICENSE. |
||||
* |
||||
* \code |
||||
* ______ _ |
||||
* / _____) _ | | |
||||
* ( (____ _____ ____ _| |_ _____ ____| |__ |
||||
* \____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
* _____) ) ____| | | || |_| ____( (___| | | | |
||||
* (______/|_____)_|_|_| \__)_____)\____)_| |_| |
||||
* (C)2013 Semtech |
||||
* |
||||
* ___ _____ _ ___ _ _____ ___ ___ ___ ___ |
||||
* / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| |
||||
* \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| |
||||
* |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| |
||||
* embedded.connectivity.solutions=============== |
||||
* |
||||
* \endcode |
||||
* |
||||
* \author Miguel Luis ( Semtech ) |
||||
* |
||||
* \author Gregory Cristian ( Semtech ) |
||||
* |
||||
* \author Daniel Jaeckle ( STACKFORCE ) |
||||
* |
||||
* \defgroup REGIONIN865 Region IN865 |
||||
* Implementation according to LoRaWAN Specification v1.0.2. |
||||
* \{ |
||||
*/ |
||||
#ifndef __REGION_IN865_H__ |
||||
#define __REGION_IN865_H__ |
||||
|
||||
/*!
|
||||
* LoRaMac maximum number of channels |
||||
*/ |
||||
#define IN865_MAX_NB_CHANNELS 16 |
||||
|
||||
/*!
|
||||
* Number of default channels |
||||
*/ |
||||
#define IN865_NUMB_DEFAULT_CHANNELS 3 |
||||
|
||||
/*!
|
||||
* Number of channels to apply for the CF list |
||||
*/ |
||||
#define IN865_NUMB_CHANNELS_CF_LIST 5 |
||||
|
||||
/*!
|
||||
* Minimal datarate that can be used by the node |
||||
*/ |
||||
#define IN865_TX_MIN_DATARATE DR_0 |
||||
|
||||
/*!
|
||||
* Maximal datarate that can be used by the node |
||||
*/ |
||||
#define IN865_TX_MAX_DATARATE DR_7 |
||||
|
||||
/*!
|
||||
* Minimal datarate that can be used by the node |
||||
*/ |
||||
#define IN865_RX_MIN_DATARATE DR_0 |
||||
|
||||
/*!
|
||||
* Maximal datarate that can be used by the node |
||||
*/ |
||||
#define IN865_RX_MAX_DATARATE DR_7 |
||||
|
||||
/*!
|
||||
* Default datarate used by the node |
||||
*/ |
||||
#define IN865_DEFAULT_DATARATE DR_0 |
||||
|
||||
/*!
|
||||
* Minimal Rx1 receive datarate offset |
||||
*/ |
||||
#define IN865_MIN_RX1_DR_OFFSET 0 |
||||
|
||||
/*!
|
||||
* Maximal Rx1 receive datarate offset |
||||
*/ |
||||
#define IN865_MAX_RX1_DR_OFFSET 7 |
||||
|
||||
/*!
|
||||
* Default Rx1 receive datarate offset |
||||
*/ |
||||
#define IN865_DEFAULT_RX1_DR_OFFSET 0 |
||||
|
||||
/*!
|
||||
* Minimal Tx output power that can be used by the node |
||||
*/ |
||||
#define IN865_MIN_TX_POWER TX_POWER_10 |
||||
|
||||
/*!
|
||||
* Maximal Tx output power that can be used by the node |
||||
*/ |
||||
#define IN865_MAX_TX_POWER TX_POWER_0 |
||||
|
||||
/*!
|
||||
* Default Tx output power used by the node |
||||
*/ |
||||
#define IN865_DEFAULT_TX_POWER TX_POWER_0 |
||||
|
||||
/*!
|
||||
* Default Max EIRP |
||||
*/ |
||||
#define IN865_DEFAULT_MAX_EIRP 30.0f |
||||
|
||||
/*!
|
||||
* Default antenna gain |
||||
*/ |
||||
#define IN865_DEFAULT_ANTENNA_GAIN 2.15f |
||||
|
||||
/*!
|
||||
* ADR Ack limit |
||||
*/ |
||||
#define IN865_ADR_ACK_LIMIT 64 |
||||
|
||||
/*!
|
||||
* ADR Ack delay |
||||
*/ |
||||
#define IN865_ADR_ACK_DELAY 32 |
||||
|
||||
/*!
|
||||
* Enabled or disabled the duty cycle |
||||
*/ |
||||
#define IN865_DUTY_CYCLE_ENABLED 1 |
||||
|
||||
/*!
|
||||
* Maximum RX window duration |
||||
*/ |
||||
#define IN865_MAX_RX_WINDOW 3000 |
||||
|
||||
/*!
|
||||
* Receive delay 1 |
||||
*/ |
||||
#define IN865_RECEIVE_DELAY1 1000 |
||||
|
||||
/*!
|
||||
* Receive delay 2 |
||||
*/ |
||||
#define IN865_RECEIVE_DELAY2 2000 |
||||
|
||||
/*!
|
||||
* Join accept delay 1 |
||||
*/ |
||||
#define IN865_JOIN_ACCEPT_DELAY1 5000 |
||||
|
||||
/*!
|
||||
* Join accept delay 2 |
||||
*/ |
||||
#define IN865_JOIN_ACCEPT_DELAY2 6000 |
||||
|
||||
/*!
|
||||
* Maximum frame counter gap |
||||
*/ |
||||
#define IN865_MAX_FCNT_GAP 16384 |
||||
|
||||
/*!
|
||||
* Ack timeout |
||||
*/ |
||||
#define IN865_ACKTIMEOUT 2000 |
||||
|
||||
/*!
|
||||
* Random ack timeout limits |
||||
*/ |
||||
#define IN865_ACK_TIMEOUT_RND 1000 |
||||
|
||||
#if ( IN865_DEFAULT_DATARATE > DR_5 ) |
||||
#error "A default DR higher than DR_5 may lead to connectivity loss." |
||||
#endif |
||||
|
||||
/*!
|
||||
* Second reception window channel frequency definition. |
||||
*/ |
||||
#define IN865_RX_WND_2_FREQ 866550000 |
||||
|
||||
/*!
|
||||
* Second reception window channel datarate definition. |
||||
*/ |
||||
#define IN865_RX_WND_2_DR DR_2 |
||||
|
||||
/*!
|
||||
* Maximum number of bands |
||||
*/ |
||||
#define IN865_MAX_NB_BANDS 1 |
||||
|
||||
/*!
|
||||
* Band 0 definition |
||||
* { DutyCycle, TxMaxPower, LastTxDoneTime, TimeOff } |
||||
*/ |
||||
#define IN865_BAND0 { 1 , IN865_MAX_TX_POWER, 0, 0 } // 100.0 %
|
||||
|
||||
/*!
|
||||
* LoRaMac default channel 1 |
||||
* Channel = { Frequency [Hz], RX1 Frequency [Hz], { ( ( DrMax << 4 ) | DrMin ) }, Band } |
||||
*/ |
||||
#define IN865_LC1 { 865062500, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 } |
||||
|
||||
/*!
|
||||
* LoRaMac default channel 2 |
||||
* Channel = { Frequency [Hz], RX1 Frequency [Hz], { ( ( DrMax << 4 ) | DrMin ) }, Band } |
||||
*/ |
||||
#define IN865_LC2 { 865402500, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 } |
||||
|
||||
/*!
|
||||
* LoRaMac default channel 3 |
||||
* Channel = { Frequency [Hz], RX1 Frequency [Hz], { ( ( DrMax << 4 ) | DrMin ) }, Band } |
||||
*/ |
||||
#define IN865_LC3 { 865985000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 } |
||||
|
||||
/*!
|
||||
* LoRaMac channels which are allowed for the join procedure |
||||
*/ |
||||
#define IN865_JOIN_CHANNELS ( uint16_t )( LC( 1 ) | LC( 2 ) | LC( 3 ) ) |
||||
|
||||
/*!
|
||||
* Data rates table definition |
||||
*/ |
||||
static const uint8_t DataratesIN865[] = { 12, 11, 10, 9, 8, 7, 7, 50 }; |
||||
|
||||
/*!
|
||||
* Bandwidths table definition in Hz |
||||
*/ |
||||
static const uint32_t BandwidthsIN865[] = { 125000, 125000, 125000, 125000, 125000, 125000, 250000, 0 }; |
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Cannot operate with repeater. |
||||
*/ |
||||
static const uint8_t MaxPayloadOfDatarateIN865[] = { 51, 51, 51, 115, 242, 242, 242, 242 }; |
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Can operate with repeater. |
||||
*/ |
||||
static const uint8_t MaxPayloadOfDatarateRepeaterIN865[] = { 51, 51, 51, 115, 222, 222, 222, 222 }; |
||||
|
||||
/*!
|
||||
* Effective datarate offsets for receive window 1. |
||||
*/ |
||||
static const int8_t EffectiveRx1DrOffsetIN865[] = { 0, 1, 2, 3, 4, 5, -1, -2 }; |
||||
|
||||
/*!
|
||||
* \brief The function gets a value of a specific phy attribute. |
||||
* |
||||
* \param [IN] getPhy Pointer to the function parameters. |
||||
* |
||||
* \retval Returns a structure containing the PHY parameter. |
||||
*/ |
||||
PhyParam_t RegionIN865GetPhyParam( GetPhyParams_t* getPhy ); |
||||
|
||||
/*!
|
||||
* \brief Updates the last TX done parameters of the current channel. |
||||
* |
||||
* \param [IN] txDone Pointer to the function parameters. |
||||
*/ |
||||
void RegionIN865SetBandTxDone( SetBandTxDoneParams_t* txDone ); |
||||
|
||||
/*!
|
||||
* \brief Initializes the channels masks and the channels. |
||||
* |
||||
* \param [IN] type Sets the initialization type. |
||||
*/ |
||||
void RegionIN865InitDefaults( InitType_t type ); |
||||
|
||||
/*!
|
||||
* \brief Verifies a parameter. |
||||
* |
||||
* \param [IN] verify Pointer to the function parameters. |
||||
* |
||||
* \param [IN] type Sets the initialization type. |
||||
* |
||||
* \retval Returns true, if the parameter is valid. |
||||
*/ |
||||
bool RegionIN865Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute ); |
||||
|
||||
/*!
|
||||
* \brief The function parses the input buffer and sets up the channels of the |
||||
* CF list. |
||||
* |
||||
* \param [IN] applyCFList Pointer to the function parameters. |
||||
*/ |
||||
void RegionIN865ApplyCFList( ApplyCFListParams_t* applyCFList ); |
||||
|
||||
/*!
|
||||
* \brief Sets a channels mask. |
||||
* |
||||
* \param [IN] chanMaskSet Pointer to the function parameters. |
||||
* |
||||
* \retval Returns true, if the channels mask could be set. |
||||
*/ |
||||
bool RegionIN865ChanMaskSet( ChanMaskSetParams_t* chanMaskSet ); |
||||
|
||||
/*!
|
||||
* \brief Calculates the next datarate to set, when ADR is on or off. |
||||
* |
||||
* \param [IN] adrNext Pointer to the function parameters. |
||||
* |
||||
* \param [OUT] drOut The calculated datarate for the next TX. |
||||
* |
||||
* \param [OUT] txPowOut The TX power for the next TX. |
||||
* |
||||
* \param [OUT] adrAckCounter The calculated ADR acknowledgement counter. |
||||
* |
||||
* \retval Returns true, if an ADR request should be performed. |
||||
*/ |
||||
bool RegionIN865AdrNext( AdrNextParams_t* adrNext, int8_t* drOut, int8_t* txPowOut, uint32_t* adrAckCounter ); |
||||
|
||||
/*!
|
||||
* Computes the Rx window timeout and offset. |
||||
* |
||||
* \param [IN] datarate Rx window datarate index to be used |
||||
* |
||||
* \param [IN] minRxSymbols Minimum required number of symbols to detect an Rx frame. |
||||
* |
||||
* \param [IN] rxError System maximum timing error of the receiver. In milliseconds |
||||
* The receiver will turn on in a [-rxError : +rxError] ms |
||||
* interval around RxOffset |
||||
* |
||||
* \param [OUT]rxConfigParams Returns updated WindowTimeout and WindowOffset fields. |
||||
*/ |
||||
void RegionIN865ComputeRxWindowParameters( int8_t datarate, uint8_t minRxSymbols, uint32_t rxError, RxConfigParams_t *rxConfigParams ); |
||||
|
||||
/*!
|
||||
* \brief Configuration of the RX windows. |
||||
* |
||||
* \param [IN] rxConfig Pointer to the function parameters. |
||||
* |
||||
* \param [OUT] datarate The datarate index which was set. |
||||
* |
||||
* \retval Returns true, if the configuration was applied successfully. |
||||
*/ |
||||
bool RegionIN865RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate ); |
||||
|
||||
/*!
|
||||
* \brief TX configuration. |
||||
* |
||||
* \param [IN] txConfig Pointer to the function parameters. |
||||
* |
||||
* \param [OUT] txPower The tx power index which was set. |
||||
* |
||||
* \param [OUT] txTimeOnAir The time-on-air of the frame. |
||||
* |
||||
* \retval Returns true, if the configuration was applied successfully. |
||||
*/ |
||||
bool RegionIN865TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime_t* txTimeOnAir ); |
||||
|
||||
/*!
|
||||
* \brief The function processes a Link ADR Request. |
||||
* |
||||
* \param [IN] linkAdrReq Pointer to the function parameters. |
||||
* |
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification. |
||||
*/ |
||||
uint8_t RegionIN865LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, int8_t* txPowOut, uint8_t* nbRepOut, uint8_t* nbBytesParsed ); |
||||
|
||||
/*!
|
||||
* \brief The function processes a RX Parameter Setup Request. |
||||
* |
||||
* \param [IN] rxParamSetupReq Pointer to the function parameters. |
||||
* |
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification. |
||||
*/ |
||||
uint8_t RegionIN865RxParamSetupReq( RxParamSetupReqParams_t* rxParamSetupReq ); |
||||
|
||||
/*!
|
||||
* \brief The function processes a Channel Request. |
||||
* |
||||
* \param [IN] newChannelReq Pointer to the function parameters. |
||||
* |
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification. |
||||
*/ |
||||
uint8_t RegionIN865NewChannelReq( NewChannelReqParams_t* newChannelReq ); |
||||
|
||||
/*!
|
||||
* \brief The function processes a TX ParamSetup Request. |
||||
* |
||||
* \param [IN] txParamSetupReq Pointer to the function parameters. |
||||
* |
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification. |
||||
* Returns -1, if the functionality is not implemented. In this case, the end node |
||||
* shall not process the command. |
||||
*/ |
||||
int8_t RegionIN865TxParamSetupReq( TxParamSetupReqParams_t* txParamSetupReq ); |
||||
|
||||
/*!
|
||||
* \brief The function processes a DlChannel Request. |
||||
* |
||||
* \param [IN] dlChannelReq Pointer to the function parameters. |
||||
* |
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification. |
||||
*/ |
||||
uint8_t RegionIN865DlChannelReq( DlChannelReqParams_t* dlChannelReq ); |
||||
|
||||
/*!
|
||||
* \brief Alternates the datarate of the channel for the join request. |
||||
* |
||||
* \param [IN] alternateDr Pointer to the function parameters. |
||||
* |
||||
* \retval Datarate to apply. |
||||
*/ |
||||
int8_t RegionIN865AlternateDr( AlternateDrParams_t* alternateDr ); |
||||
|
||||
/*!
|
||||
* \brief Calculates the back-off time. |
||||
* |
||||
* \param [IN] calcBackOff Pointer to the function parameters. |
||||
*/ |
||||
void RegionIN865CalcBackOff( CalcBackOffParams_t* calcBackOff ); |
||||
|
||||
/*!
|
||||
* \brief Searches and set the next random available channel |
||||
* |
||||
* \param [OUT] channel Next channel to use for TX. |
||||
* |
||||
* \param [OUT] time Time to wait for the next transmission according to the duty |
||||
* cycle. |
||||
* |
||||
* \param [OUT] aggregatedTimeOff Updates the aggregated time off. |
||||
* |
||||
* \retval Function status [1: OK, 0: Unable to find a channel on the current datarate] |
||||
*/ |
||||
bool RegionIN865NextChannel( NextChanParams_t* nextChanParams, uint8_t* channel, TimerTime_t* time, TimerTime_t* aggregatedTimeOff ); |
||||
|
||||
/*!
|
||||
* \brief Adds a channel. |
||||
* |
||||
* \param [IN] channelAdd Pointer to the function parameters. |
||||
* |
||||
* \retval Status of the operation. |
||||
*/ |
||||
LoRaMacStatus_t RegionIN865ChannelAdd( ChannelAddParams_t* channelAdd ); |
||||
|
||||
/*!
|
||||
* \brief Removes a channel. |
||||
* |
||||
* \param [IN] channelRemove Pointer to the function parameters. |
||||
* |
||||
* \retval Returns true, if the channel was removed successfully. |
||||
*/ |
||||
bool RegionIN865ChannelsRemove( ChannelRemoveParams_t* channelRemove ); |
||||
|
||||
/*!
|
||||
* \brief Sets the radio into continuous wave mode. |
||||
* |
||||
* \param [IN] continuousWave Pointer to the function parameters. |
||||
*/ |
||||
void RegionIN865SetContinuousWave( ContinuousWaveParams_t* continuousWave ); |
||||
|
||||
/*!
|
||||
* \brief Computes new datarate according to the given offset |
||||
* |
||||
* \param [IN] downlinkDwellTime Downlink dwell time configuration. 0: No limit, 1: 400ms |
||||
* |
||||
* \param [IN] dr Current datarate |
||||
* |
||||
* \param [IN] drOffset Offset to be applied |
||||
* |
||||
* \retval newDr Computed datarate. |
||||
*/ |
||||
uint8_t RegionIN865ApplyDrOffset( uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset ); |
||||
|
||||
/*! \} defgroup REGIONIN865 */ |
||||
|
||||
#endif // __REGION_IN865_H__
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,478 @@ |
||||
/*!
|
||||
* \file RegionKR920.h |
||||
* |
||||
* \brief Region definition for KR920 |
||||
* |
||||
* \copyright Revised BSD License, see section \ref LICENSE. |
||||
* |
||||
* \code |
||||
* ______ _ |
||||
* / _____) _ | | |
||||
* ( (____ _____ ____ _| |_ _____ ____| |__ |
||||
* \____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
* _____) ) ____| | | || |_| ____( (___| | | | |
||||
* (______/|_____)_|_|_| \__)_____)\____)_| |_| |
||||
* (C)2013 Semtech |
||||
* |
||||
* ___ _____ _ ___ _ _____ ___ ___ ___ ___ |
||||
* / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| |
||||
* \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| |
||||
* |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| |
||||
* embedded.connectivity.solutions=============== |
||||
* |
||||
* \endcode |
||||
* |
||||
* \author Miguel Luis ( Semtech ) |
||||
* |
||||
* \author Gregory Cristian ( Semtech ) |
||||
* |
||||
* \author Daniel Jaeckle ( STACKFORCE ) |
||||
* |
||||
* \defgroup REGIONKR920 Region KR920 |
||||
* Implementation according to LoRaWAN Specification v1.0.2. |
||||
* \{ |
||||
*/ |
||||
#ifndef __REGION_KR920_H__ |
||||
#define __REGION_KR920_H__ |
||||
|
||||
/*!
|
||||
* LoRaMac maximum number of channels |
||||
*/ |
||||
#define KR920_MAX_NB_CHANNELS 16 |
||||
|
||||
/*!
|
||||
* Number of default channels |
||||
*/ |
||||
#define KR920_NUMB_DEFAULT_CHANNELS 3 |
||||
|
||||
/*!
|
||||
* Number of channels to apply for the CF list |
||||
*/ |
||||
#define KR920_NUMB_CHANNELS_CF_LIST 5 |
||||
|
||||
/*!
|
||||
* Minimal datarate that can be used by the node |
||||
*/ |
||||
#define KR920_TX_MIN_DATARATE DR_0 |
||||
|
||||
/*!
|
||||
* Maximal datarate that can be used by the node |
||||
*/ |
||||
#define KR920_TX_MAX_DATARATE DR_5 |
||||
|
||||
/*!
|
||||
* Minimal datarate that can be used by the node |
||||
*/ |
||||
#define KR920_RX_MIN_DATARATE DR_0 |
||||
|
||||
/*!
|
||||
* Maximal datarate that can be used by the node |
||||
*/ |
||||
#define KR920_RX_MAX_DATARATE DR_5 |
||||
|
||||
/*!
|
||||
* Default datarate used by the node |
||||
*/ |
||||
#define KR920_DEFAULT_DATARATE DR_0 |
||||
|
||||
/*!
|
||||
* Minimal Rx1 receive datarate offset |
||||
*/ |
||||
#define KR920_MIN_RX1_DR_OFFSET 0 |
||||
|
||||
/*!
|
||||
* Maximal Rx1 receive datarate offset |
||||
*/ |
||||
#define KR920_MAX_RX1_DR_OFFSET 5 |
||||
|
||||
/*!
|
||||
* Default Rx1 receive datarate offset |
||||
*/ |
||||
#define KR920_DEFAULT_RX1_DR_OFFSET 0 |
||||
|
||||
/*!
|
||||
* Minimal Tx output power that can be used by the node |
||||
*/ |
||||
#define KR920_MIN_TX_POWER TX_POWER_7 |
||||
|
||||
/*!
|
||||
* Maximal Tx output power that can be used by the node |
||||
*/ |
||||
#define KR920_MAX_TX_POWER TX_POWER_0 |
||||
|
||||
/*!
|
||||
* Default Tx output power used by the node |
||||
*/ |
||||
#define KR920_DEFAULT_TX_POWER TX_POWER_0 |
||||
|
||||
/*!
|
||||
* Default Max EIRP for frequency 920.9 MHz - 921.9 MHz |
||||
*/ |
||||
#define KR920_DEFAULT_MAX_EIRP_LOW 10.0f |
||||
|
||||
/*!
|
||||
* Default Max EIRP for frequency 922.1 MHz - 923.3 MHz |
||||
*/ |
||||
#define KR920_DEFAULT_MAX_EIRP_HIGH 14.0f |
||||
|
||||
/*!
|
||||
* Default antenna gain |
||||
*/ |
||||
#define KR920_DEFAULT_ANTENNA_GAIN 2.15f |
||||
|
||||
/*!
|
||||
* ADR Ack limit |
||||
*/ |
||||
#define KR920_ADR_ACK_LIMIT 64 |
||||
|
||||
/*!
|
||||
* ADR Ack delay |
||||
*/ |
||||
#define KR920_ADR_ACK_DELAY 32 |
||||
|
||||
/*!
|
||||
* Enabled or disabled the duty cycle |
||||
*/ |
||||
#define KR920_DUTY_CYCLE_ENABLED 0 |
||||
|
||||
/*!
|
||||
* Maximum RX window duration |
||||
*/ |
||||
#define KR920_MAX_RX_WINDOW 4000 |
||||
|
||||
/*!
|
||||
* Receive delay 1 |
||||
*/ |
||||
#define KR920_RECEIVE_DELAY1 1000 |
||||
|
||||
/*!
|
||||
* Receive delay 2 |
||||
*/ |
||||
#define KR920_RECEIVE_DELAY2 2000 |
||||
|
||||
/*!
|
||||
* Join accept delay 1 |
||||
*/ |
||||
#define KR920_JOIN_ACCEPT_DELAY1 5000 |
||||
|
||||
/*!
|
||||
* Join accept delay 2 |
||||
*/ |
||||
#define KR920_JOIN_ACCEPT_DELAY2 6000 |
||||
|
||||
/*!
|
||||
* Maximum frame counter gap |
||||
*/ |
||||
#define KR920_MAX_FCNT_GAP 16384 |
||||
|
||||
/*!
|
||||
* Ack timeout |
||||
*/ |
||||
#define KR920_ACKTIMEOUT 2000 |
||||
|
||||
/*!
|
||||
* Random ack timeout limits |
||||
*/ |
||||
#define KR920_ACK_TIMEOUT_RND 1000 |
||||
|
||||
#if ( KR920_DEFAULT_DATARATE > DR_5 ) |
||||
#error "A default DR higher than DR_5 may lead to connectivity loss." |
||||
#endif |
||||
|
||||
/*!
|
||||
* Second reception window channel frequency definition. |
||||
*/ |
||||
#define KR920_RX_WND_2_FREQ 921900000 |
||||
|
||||
/*!
|
||||
* Second reception window channel datarate definition. |
||||
*/ |
||||
#define KR920_RX_WND_2_DR DR_0 |
||||
|
||||
/*!
|
||||
* Maximum number of bands |
||||
*/ |
||||
#define KR920_MAX_NB_BANDS 1 |
||||
|
||||
/*!
|
||||
* Band 0 definition |
||||
* { DutyCycle, TxMaxPower, LastTxDoneTime, TimeOff } |
||||
*/ |
||||
#define KR920_BAND0 { 1 , KR920_MAX_TX_POWER, 0, 0 } // 100.0 %
|
||||
|
||||
/*!
|
||||
* LoRaMac default channel 1 |
||||
* Channel = { Frequency [Hz], RX1 Frequency [Hz], { ( ( DrMax << 4 ) | DrMin ) }, Band } |
||||
*/ |
||||
#define KR920_LC1 { 922100000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 } |
||||
|
||||
/*!
|
||||
* LoRaMac default channel 2 |
||||
* Channel = { Frequency [Hz], RX1 Frequency [Hz], { ( ( DrMax << 4 ) | DrMin ) }, Band } |
||||
*/ |
||||
#define KR920_LC2 { 922300000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 } |
||||
|
||||
/*!
|
||||
* LoRaMac default channel 3 |
||||
* Channel = { Frequency [Hz], RX1 Frequency [Hz], { ( ( DrMax << 4 ) | DrMin ) }, Band } |
||||
*/ |
||||
#define KR920_LC3 { 922500000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 } |
||||
|
||||
/*!
|
||||
* LoRaMac channels which are allowed for the join procedure |
||||
*/ |
||||
#define KR920_JOIN_CHANNELS ( uint16_t )( LC( 1 ) | LC( 2 ) | LC( 3 ) ) |
||||
|
||||
/*!
|
||||
* RSSI threshold for a free channel [dBm] |
||||
*/ |
||||
#define KR920_RSSI_FREE_TH -65 |
||||
|
||||
/*!
|
||||
* Specifies the time the node performs a carrier sense |
||||
*/ |
||||
#define KR920_CARRIER_SENSE_TIME 6 |
||||
|
||||
/*!
|
||||
* Data rates table definition |
||||
*/ |
||||
static const uint8_t DataratesKR920[] = { 12, 11, 10, 9, 8, 7 }; |
||||
|
||||
/*!
|
||||
* Bandwidths table definition in Hz |
||||
*/ |
||||
static const uint32_t BandwidthsKR920[] = { 125000, 125000, 125000, 125000, 125000, 125000 }; |
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Can operate with and without a repeater. |
||||
*/ |
||||
static const uint8_t MaxPayloadOfDatarateKR920[] = { 51, 51, 51, 115, 242, 242 }; |
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Can operate with repeater. |
||||
*/ |
||||
static const uint8_t MaxPayloadOfDatarateRepeaterKR920[] = { 51, 51, 51, 115, 222, 222 }; |
||||
|
||||
/*!
|
||||
* \brief The function gets a value of a specific phy attribute. |
||||
* |
||||
* \param [IN] getPhy Pointer to the function parameters. |
||||
* |
||||
* \retval Returns a structure containing the PHY parameter. |
||||
*/ |
||||
PhyParam_t RegionKR920GetPhyParam( GetPhyParams_t* getPhy ); |
||||
|
||||
/*!
|
||||
* \brief Updates the last TX done parameters of the current channel. |
||||
* |
||||
* \param [IN] txDone Pointer to the function parameters. |
||||
*/ |
||||
void RegionKR920SetBandTxDone( SetBandTxDoneParams_t* txDone ); |
||||
|
||||
/*!
|
||||
* \brief Initializes the channels masks and the channels. |
||||
* |
||||
* \param [IN] type Sets the initialization type. |
||||
*/ |
||||
void RegionKR920InitDefaults( InitType_t type ); |
||||
|
||||
/*!
|
||||
* \brief Verifies a parameter. |
||||
* |
||||
* \param [IN] verify Pointer to the function parameters. |
||||
* |
||||
* \param [IN] type Sets the initialization type. |
||||
* |
||||
* \retval Returns true, if the parameter is valid. |
||||
*/ |
||||
bool RegionKR920Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute ); |
||||
|
||||
/*!
|
||||
* \brief The function parses the input buffer and sets up the channels of the |
||||
* CF list. |
||||
* |
||||
* \param [IN] applyCFList Pointer to the function parameters. |
||||
*/ |
||||
void RegionKR920ApplyCFList( ApplyCFListParams_t* applyCFList ); |
||||
|
||||
/*!
|
||||
* \brief Sets a channels mask. |
||||
* |
||||
* \param [IN] chanMaskSet Pointer to the function parameters. |
||||
* |
||||
* \retval Returns true, if the channels mask could be set. |
||||
*/ |
||||
bool RegionKR920ChanMaskSet( ChanMaskSetParams_t* chanMaskSet ); |
||||
|
||||
/*!
|
||||
* \brief Calculates the next datarate to set, when ADR is on or off. |
||||
* |
||||
* \param [IN] adrNext Pointer to the function parameters. |
||||
* |
||||
* \param [OUT] drOut The calculated datarate for the next TX. |
||||
* |
||||
* \param [OUT] txPowOut The TX power for the next TX. |
||||
* |
||||
* \param [OUT] adrAckCounter The calculated ADR acknowledgement counter. |
||||
* |
||||
* \retval Returns true, if an ADR request should be performed. |
||||
*/ |
||||
bool RegionKR920AdrNext( AdrNextParams_t* adrNext, int8_t* drOut, int8_t* txPowOut, uint32_t* adrAckCounter ); |
||||
|
||||
/*!
|
||||
* Computes the Rx window timeout and offset. |
||||
* |
||||
* \param [IN] datarate Rx window datarate index to be used |
||||
* |
||||
* \param [IN] minRxSymbols Minimum required number of symbols to detect an Rx frame. |
||||
* |
||||
* \param [IN] rxError System maximum timing error of the receiver. In milliseconds |
||||
* The receiver will turn on in a [-rxError : +rxError] ms |
||||
* interval around RxOffset |
||||
* |
||||
* \param [OUT]rxConfigParams Returns updated WindowTimeout and WindowOffset fields. |
||||
*/ |
||||
void RegionKR920ComputeRxWindowParameters( int8_t datarate, uint8_t minRxSymbols, uint32_t rxError, RxConfigParams_t *rxConfigParams ); |
||||
|
||||
/*!
|
||||
* \brief Configuration of the RX windows. |
||||
* |
||||
* \param [IN] rxConfig Pointer to the function parameters. |
||||
* |
||||
* \param [OUT] datarate The datarate index which was set. |
||||
* |
||||
* \retval Returns true, if the configuration was applied successfully. |
||||
*/ |
||||
bool RegionKR920RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate ); |
||||
|
||||
/*!
|
||||
* \brief TX configuration. |
||||
* |
||||
* \param [IN] txConfig Pointer to the function parameters. |
||||
* |
||||
* \param [OUT] txPower The tx power index which was set. |
||||
* |
||||
* \param [OUT] txTimeOnAir The time-on-air of the frame. |
||||
* |
||||
* \retval Returns true, if the configuration was applied successfully. |
||||
*/ |
||||
bool RegionKR920TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime_t* txTimeOnAir ); |
||||
|
||||
/*!
|
||||
* \brief The function processes a Link ADR Request. |
||||
* |
||||
* \param [IN] linkAdrReq Pointer to the function parameters. |
||||
* |
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification. |
||||
*/ |
||||
uint8_t RegionKR920LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, int8_t* txPowOut, uint8_t* nbRepOut, uint8_t* nbBytesParsed ); |
||||
|
||||
/*!
|
||||
* \brief The function processes a RX Parameter Setup Request. |
||||
* |
||||
* \param [IN] rxParamSetupReq Pointer to the function parameters. |
||||
* |
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification. |
||||
*/ |
||||
uint8_t RegionKR920RxParamSetupReq( RxParamSetupReqParams_t* rxParamSetupReq ); |
||||
|
||||
/*!
|
||||
* \brief The function processes a Channel Request. |
||||
* |
||||
* \param [IN] newChannelReq Pointer to the function parameters. |
||||
* |
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification. |
||||
*/ |
||||
uint8_t RegionKR920NewChannelReq( NewChannelReqParams_t* newChannelReq ); |
||||
|
||||
/*!
|
||||
* \brief The function processes a TX ParamSetup Request. |
||||
* |
||||
* \param [IN] txParamSetupReq Pointer to the function parameters. |
||||
* |
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification. |
||||
* Returns -1, if the functionality is not implemented. In this case, the end node |
||||
* shall not process the command. |
||||
*/ |
||||
int8_t RegionKR920TxParamSetupReq( TxParamSetupReqParams_t* txParamSetupReq ); |
||||
|
||||
/*!
|
||||
* \brief The function processes a DlChannel Request. |
||||
* |
||||
* \param [IN] dlChannelReq Pointer to the function parameters. |
||||
* |
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification. |
||||
*/ |
||||
uint8_t RegionKR920DlChannelReq( DlChannelReqParams_t* dlChannelReq ); |
||||
|
||||
/*!
|
||||
* \brief Alternates the datarate of the channel for the join request. |
||||
* |
||||
* \param [IN] alternateDr Pointer to the function parameters. |
||||
* |
||||
* \retval Datarate to apply. |
||||
*/ |
||||
int8_t RegionKR920AlternateDr( AlternateDrParams_t* alternateDr ); |
||||
|
||||
/*!
|
||||
* \brief Calculates the back-off time. |
||||
* |
||||
* \param [IN] calcBackOff Pointer to the function parameters. |
||||
*/ |
||||
void RegionKR920CalcBackOff( CalcBackOffParams_t* calcBackOff ); |
||||
|
||||
/*!
|
||||
* \brief Searches and set the next random available channel |
||||
* |
||||
* \param [OUT] channel Next channel to use for TX. |
||||
* |
||||
* \param [OUT] time Time to wait for the next transmission according to the duty |
||||
* cycle. |
||||
* |
||||
* \param [OUT] aggregatedTimeOff Updates the aggregated time off. |
||||
* |
||||
* \retval Function status [1: OK, 0: Unable to find a channel on the current datarate] |
||||
*/ |
||||
bool RegionKR920NextChannel( NextChanParams_t* nextChanParams, uint8_t* channel, TimerTime_t* time, TimerTime_t* aggregatedTimeOff ); |
||||
|
||||
/*!
|
||||
* \brief Adds a channel. |
||||
* |
||||
* \param [IN] channelAdd Pointer to the function parameters. |
||||
* |
||||
* \retval Status of the operation. |
||||
*/ |
||||
LoRaMacStatus_t RegionKR920ChannelAdd( ChannelAddParams_t* channelAdd ); |
||||
|
||||
/*!
|
||||
* \brief Removes a channel. |
||||
* |
||||
* \param [IN] channelRemove Pointer to the function parameters. |
||||
* |
||||
* \retval Returns true, if the channel was removed successfully. |
||||
*/ |
||||
bool RegionKR920ChannelsRemove( ChannelRemoveParams_t* channelRemove ); |
||||
|
||||
/*!
|
||||
* \brief Sets the radio into continuous wave mode. |
||||
* |
||||
* \param [IN] continuousWave Pointer to the function parameters. |
||||
*/ |
||||
void RegionKR920SetContinuousWave( ContinuousWaveParams_t* continuousWave ); |
||||
|
||||
/*!
|
||||
* \brief Computes new datarate according to the given offset |
||||
* |
||||
* \param [IN] downlinkDwellTime Downlink dwell time configuration. 0: No limit, 1: 400ms |
||||
* |
||||
* \param [IN] dr Current datarate |
||||
* |
||||
* \param [IN] drOffset Offset to be applied |
||||
* |
||||
* \retval newDr Computed datarate. |
||||
*/ |
||||
uint8_t RegionKR920ApplyDrOffset( uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset ); |
||||
|
||||
/*! \} defgroup REGIONKR920 */ |
||||
|
||||
#endif // __REGION_KR920_H__
|
@ -0,0 +1,964 @@ |
||||
/*
|
||||
/ _____) _ | | |
||||
( (____ _____ ____ _| |_ _____ ____| |__ |
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | | |
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_| |
||||
(C)2013 Semtech |
||||
___ _____ _ ___ _ _____ ___ ___ ___ ___ |
||||
/ __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| |
||||
\__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| |
||||
|___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| |
||||
embedded.connectivity.solutions=============== |
||||
|
||||
Description: LoRa MAC region US915 Hybrid implementation |
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project |
||||
|
||||
Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jaeckle ( STACKFORCE ) |
||||
*/ |
||||
#include <stdbool.h> |
||||
#include <string.h> |
||||
#include <stdint.h> |
||||
#include <math.h> |
||||
|
||||
#include "radio.h" |
||||
#include "timer.h" |
||||
#include "LoRaMac.h" |
||||
|
||||
#include "utilities.h" |
||||
|
||||
#include "Region.h" |
||||
#include "RegionCommon.h" |
||||
#include "RegionUS915-Hybrid.h" |
||||
#include "debug.h" |
||||
|
||||
// Definitions
|
||||
#define CHANNELS_MASK_SIZE 6 |
||||
|
||||
// Global attributes
|
||||
/*!
|
||||
* LoRaMAC channels |
||||
*/ |
||||
static ChannelParams_t Channels[US915_HYBRID_MAX_NB_CHANNELS]; |
||||
|
||||
/*!
|
||||
* LoRaMac bands |
||||
*/ |
||||
static Band_t Bands[US915_HYBRID_MAX_NB_BANDS] = |
||||
{ |
||||
US915_HYBRID_BAND0 |
||||
}; |
||||
|
||||
/*!
|
||||
* LoRaMac channels mask |
||||
*/ |
||||
static uint16_t ChannelsMask[CHANNELS_MASK_SIZE]; |
||||
|
||||
/*!
|
||||
* LoRaMac channels remaining |
||||
*/ |
||||
static uint16_t ChannelsMaskRemaining[CHANNELS_MASK_SIZE]; |
||||
|
||||
/*!
|
||||
* LoRaMac channels default mask |
||||
*/ |
||||
static uint16_t ChannelsDefaultMask[CHANNELS_MASK_SIZE]; |
||||
|
||||
// Static functions
|
||||
static int8_t GetNextLowerTxDr( int8_t dr, int8_t minDr ) |
||||
{ |
||||
uint8_t nextLowerDr = 0; |
||||
|
||||
if( dr == minDr ) |
||||
{ |
||||
nextLowerDr = minDr; |
||||
} |
||||
else |
||||
{ |
||||
nextLowerDr = dr - 1; |
||||
} |
||||
return nextLowerDr; |
||||
} |
||||
|
||||
static uint32_t GetBandwidth( uint32_t drIndex ) |
||||
{ |
||||
switch( BandwidthsUS915_HYBRID[drIndex] ) |
||||
{ |
||||
default: |
||||
case 125000: |
||||
return 0; |
||||
case 250000: |
||||
return 1; |
||||
case 500000: |
||||
return 2; |
||||
} |
||||
} |
||||
|
||||
static void ReenableChannels( uint16_t mask, uint16_t* channelsMask ) |
||||
{ |
||||
uint16_t blockMask = mask; |
||||
|
||||
for( uint8_t i = 0, j = 0; i < 4; i++, j += 2 ) |
||||
{ |
||||
channelsMask[i] = 0; |
||||
if( ( blockMask & ( 1 << j ) ) != 0 ) |
||||
{ |
||||
channelsMask[i] |= 0x00FF; |
||||
} |
||||
if( ( blockMask & ( 1 << ( j + 1 ) ) ) != 0 ) |
||||
{ |
||||
channelsMask[i] |= 0xFF00; |
||||
} |
||||
} |
||||
channelsMask[4] = blockMask; |
||||
channelsMask[5] = 0x0000; |
||||
} |
||||
|
||||
static uint8_t CountBits( uint16_t mask, uint8_t nbBits ) |
||||
{ |
||||
uint8_t nbActiveBits = 0; |
||||
|
||||
for( uint8_t j = 0; j < nbBits; j++ ) |
||||
{ |
||||
if( ( mask & ( 1 << j ) ) == ( 1 << j ) ) |
||||
{ |
||||
nbActiveBits++; |
||||
} |
||||
} |
||||
return nbActiveBits; |
||||
} |
||||
|
||||
static int8_t LimitTxPower( int8_t txPower, int8_t maxBandTxPower, int8_t datarate, uint16_t* channelsMask ) |
||||
{ |
||||
int8_t txPowerResult = txPower; |
||||
|
||||
// Limit tx power to the band max
|
||||
txPowerResult = MAX( txPower, maxBandTxPower ); |
||||
|
||||
if( datarate == DR_4 ) |
||||
{// Limit tx power to max 26dBm
|
||||
txPowerResult = MAX( txPower, TX_POWER_2 ); |
||||
} |
||||
else |
||||
{ |
||||
if( RegionCommonCountChannels( channelsMask, 0, 4 ) < 50 ) |
||||
{// Limit tx power to max 21dBm
|
||||
txPowerResult = MAX( txPower, TX_POWER_5 ); |
||||
} |
||||
} |
||||
return txPowerResult; |
||||
} |
||||
|
||||
static bool ValidateChannelsMask( uint16_t* channelsMask ) |
||||
{ |
||||
bool chanMaskState = false; |
||||
uint16_t block1 = 0; |
||||
uint16_t block2 = 0; |
||||
uint8_t index = 0; |
||||
uint16_t channelsMaskCpy[6]; |
||||
|
||||
// Copy channels mask to not change the input
|
||||
for( uint8_t i = 0; i < 4; i++ ) |
||||
{ |
||||
channelsMaskCpy[i] = channelsMask[i]; |
||||
} |
||||
|
||||
for( uint8_t i = 0; i < 4; i++ ) |
||||
{ |
||||
block1 = channelsMaskCpy[i] & 0x00FF; |
||||
block2 = channelsMaskCpy[i] & 0xFF00; |
||||
|
||||
if( CountBits( block1, 16 ) > 5 ) |
||||
{ |
||||
channelsMaskCpy[i] &= block1; |
||||
channelsMaskCpy[4] = 1 << ( i * 2 ); |
||||
chanMaskState = true; |
||||
index = i; |
||||
break; |
||||
} |
||||
else if( CountBits( block2, 16 ) > 5 ) |
||||
{ |
||||
channelsMaskCpy[i] &= block2; |
||||
channelsMaskCpy[4] = 1 << ( i * 2 + 1 ); |
||||
chanMaskState = true; |
||||
index = i; |
||||
break; |
||||
} |
||||
} |
||||
|
||||
// Do only change the channel mask, if we have found a valid block.
|
||||
if( chanMaskState == true ) |
||||
{ |
||||
// Copy channels mask back again
|
||||
for( uint8_t i = 0; i < 4; i++ ) |
||||
{ |
||||
channelsMask[i] = channelsMaskCpy[i]; |
||||
|
||||
if( i != index ) |
||||
{ |
||||
channelsMask[i] = 0; |
||||
} |
||||
} |
||||
channelsMask[4] = channelsMaskCpy[4]; |
||||
} |
||||
return chanMaskState; |
||||
} |
||||
|
||||
static uint8_t CountNbOfEnabledChannels( uint8_t datarate, uint16_t* channelsMask, ChannelParams_t* channels, Band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx ) |
||||
{ |
||||
uint8_t nbEnabledChannels = 0; |
||||
uint8_t delayTransmission = 0; |
||||
|
||||
for( uint8_t i = 0, k = 0; i < US915_HYBRID_MAX_NB_CHANNELS; i += 16, k++ ) |
||||
{ |
||||
for( uint8_t j = 0; j < 16; j++ ) |
||||
{ |
||||
if( ( channelsMask[k] & ( 1 << j ) ) != 0 ) |
||||
{ |
||||
if( channels[i + j].Frequency == 0 ) |
||||
{ // Check if the channel is enabled
|
||||
continue; |
||||
} |
||||
if( RegionCommonValueInRange( datarate, channels[i + j].DrRange.Fields.Min, |
||||
channels[i + j].DrRange.Fields.Max ) == false ) |
||||
{ // Check if the current channel selection supports the given datarate
|
||||
continue; |
||||
} |
||||
if( bands[channels[i + j].Band].TimeOff > 0 ) |
||||
{ // Check if the band is available for transmission
|
||||
delayTransmission++; |
||||
continue; |
||||
} |
||||
enabledChannels[nbEnabledChannels++] = i + j; |
||||
} |
||||
} |
||||
} |
||||
|
||||
*delayTx = delayTransmission; |
||||
return nbEnabledChannels; |
||||
} |
||||
|
||||
PhyParam_t RegionUS915HybridGetPhyParam( GetPhyParams_t* getPhy ) |
||||
{ |
||||
PhyParam_t phyParam = { 0 }; |
||||
|
||||
switch( getPhy->Attribute ) |
||||
{ |
||||
case PHY_MIN_RX_DR: |
||||
{ |
||||
phyParam.Value = US915_HYBRID_RX_MIN_DATARATE; |
||||
break; |
||||
} |
||||
case PHY_MIN_TX_DR: |
||||
{ |
||||
phyParam.Value = US915_HYBRID_TX_MIN_DATARATE; |
||||
break; |
||||
} |
||||
case PHY_DEF_TX_DR: |
||||
{ |
||||
phyParam.Value = US915_HYBRID_DEFAULT_DATARATE; |
||||
break; |
||||
} |
||||
case PHY_NEXT_LOWER_TX_DR: |
||||
{ |
||||
phyParam.Value = GetNextLowerTxDr( getPhy->Datarate, US915_HYBRID_TX_MIN_DATARATE ); |
||||
break; |
||||
} |
||||
case PHY_DEF_TX_POWER: |
||||
{ |
||||
phyParam.Value = US915_HYBRID_DEFAULT_TX_POWER; |
||||
break; |
||||
} |
||||
case PHY_MAX_PAYLOAD: |
||||
{ |
||||
phyParam.Value = MaxPayloadOfDatarateUS915_HYBRID[getPhy->Datarate]; |
||||
break; |
||||
} |
||||
case PHY_MAX_PAYLOAD_REPEATER: |
||||
{ |
||||
phyParam.Value = MaxPayloadOfDatarateRepeaterUS915_HYBRID[getPhy->Datarate]; |
||||
break; |
||||
} |
||||
case PHY_DUTY_CYCLE: |
||||
{ |
||||
phyParam.Value = US915_HYBRID_DUTY_CYCLE_ENABLED; |
||||
break; |
||||
} |
||||
case PHY_MAX_RX_WINDOW: |
||||
{ |
||||
phyParam.Value = US915_HYBRID_MAX_RX_WINDOW; |
||||
break; |
||||
} |
||||
case PHY_RECEIVE_DELAY1: |
||||
{ |
||||
phyParam.Value = US915_HYBRID_RECEIVE_DELAY1; |
||||
break; |
||||
} |
||||
case PHY_RECEIVE_DELAY2: |
||||
{ |
||||
phyParam.Value = US915_HYBRID_RECEIVE_DELAY2; |
||||
break; |
||||
} |
||||
case PHY_JOIN_ACCEPT_DELAY1: |
||||
{ |
||||
phyParam.Value = US915_HYBRID_JOIN_ACCEPT_DELAY1; |
||||
break; |
||||
} |
||||
case PHY_JOIN_ACCEPT_DELAY2: |
||||
{ |
||||
phyParam.Value = US915_HYBRID_JOIN_ACCEPT_DELAY2; |
||||
break; |
||||
} |
||||
case PHY_MAX_FCNT_GAP: |
||||
{ |
||||
phyParam.Value = US915_HYBRID_MAX_FCNT_GAP; |
||||
break; |
||||
} |
||||
case PHY_ACK_TIMEOUT: |
||||
{ |
||||
phyParam.Value = ( US915_HYBRID_ACKTIMEOUT + randr( -US915_HYBRID_ACK_TIMEOUT_RND, US915_HYBRID_ACK_TIMEOUT_RND ) ); |
||||
break; |
||||
} |
||||
case PHY_DEF_DR1_OFFSET: |
||||
{ |
||||
phyParam.Value = US915_HYBRID_DEFAULT_RX1_DR_OFFSET; |
||||
break; |
||||
} |
||||
case PHY_DEF_RX2_FREQUENCY: |
||||
{ |
||||
phyParam.Value = US915_HYBRID_RX_WND_2_FREQ; |
||||
break; |
||||
} |
||||
case PHY_DEF_RX2_DR: |
||||
{ |
||||
phyParam.Value = US915_HYBRID_RX_WND_2_DR; |
||||
break; |
||||
} |
||||
case PHY_CHANNELS_MASK: |
||||
{ |
||||
phyParam.ChannelsMask = ChannelsMask; |
||||
break; |
||||
} |
||||
case PHY_CHANNELS_DEFAULT_MASK: |
||||
{ |
||||
phyParam.ChannelsMask = ChannelsDefaultMask; |
||||
break; |
||||
} |
||||
case PHY_MAX_NB_CHANNELS: |
||||
{ |
||||
phyParam.Value = US915_HYBRID_MAX_NB_CHANNELS; |
||||
break; |
||||
} |
||||
case PHY_CHANNELS: |
||||
{ |
||||
phyParam.Channels = Channels; |
||||
break; |
||||
} |
||||
case PHY_DEF_UPLINK_DWELL_TIME: |
||||
case PHY_DEF_DOWNLINK_DWELL_TIME: |
||||
{ |
||||
phyParam.Value = 0; |
||||
break; |
||||
} |
||||
case PHY_DEF_MAX_EIRP: |
||||
case PHY_DEF_ANTENNA_GAIN: |
||||
{ |
||||
phyParam.fValue = 0; |
||||
break; |
||||
} |
||||
case PHY_NB_JOIN_TRIALS: |
||||
case PHY_DEF_NB_JOIN_TRIALS: |
||||
{ |
||||
phyParam.Value = 2; |
||||
break; |
||||
} |
||||
default: |
||||
{ |
||||
break; |
||||
} |
||||
} |
||||
|
||||
return phyParam; |
||||
} |
||||
|
||||
void RegionUS915HybridSetBandTxDone( SetBandTxDoneParams_t* txDone ) |
||||
{ |
||||
RegionCommonSetBandTxDone( txDone->Joined, &Bands[Channels[txDone->Channel].Band], txDone->LastTxDoneTime ); |
||||
} |
||||
|
||||
void RegionUS915HybridInitDefaults( InitType_t type ) |
||||
{ |
||||
switch( type ) |
||||
{ |
||||
case INIT_TYPE_INIT: |
||||
{ |
||||
// Channels
|
||||
// 125 kHz channels
|
||||
for( uint8_t i = 0; i < US915_HYBRID_MAX_NB_CHANNELS - 8; i++ ) |
||||
{ |
||||
Channels[i].Frequency = 902300000 + i * 200000; |
||||
Channels[i].DrRange.Value = ( DR_3 << 4 ) | DR_0; |
||||
Channels[i].Band = 0; |
||||
} |
||||
// 500 kHz channels
|
||||
for( uint8_t i = US915_HYBRID_MAX_NB_CHANNELS - 8; i < US915_HYBRID_MAX_NB_CHANNELS; i++ ) |
||||
{ |
||||
Channels[i].Frequency = 903000000 + ( i - ( US915_HYBRID_MAX_NB_CHANNELS - 8 ) ) * 1600000; |
||||
Channels[i].DrRange.Value = ( DR_4 << 4 ) | DR_4; |
||||
Channels[i].Band = 0; |
||||
} |
||||
|
||||
// ChannelsMask
|
||||
ChannelsDefaultMask[0] = 0x00FF; |
||||
ChannelsDefaultMask[1] = 0x0000; |
||||
ChannelsDefaultMask[2] = 0x0000; |
||||
ChannelsDefaultMask[3] = 0x0000; |
||||
ChannelsDefaultMask[4] = 0x0001; |
||||
ChannelsDefaultMask[5] = 0x0000; |
||||
|
||||
// Copy channels default mask
|
||||
RegionCommonChanMaskCopy( ChannelsMask, ChannelsDefaultMask, 6 ); |
||||
|
||||
// Copy into channels mask remaining
|
||||
RegionCommonChanMaskCopy( ChannelsMaskRemaining, ChannelsMask, 6 ); |
||||
break; |
||||
} |
||||
case INIT_TYPE_RESTORE: |
||||
{ |
||||
ReenableChannels( ChannelsDefaultMask[4], ChannelsMask ); |
||||
|
||||
for( uint8_t i = 0; i < 6; i++ ) |
||||
{ // Copy-And the channels mask
|
||||
ChannelsMaskRemaining[i] &= ChannelsMask[i]; |
||||
} |
||||
} |
||||
default: |
||||
{ |
||||
break; |
||||
} |
||||
} |
||||
} |
||||
|
||||
bool RegionUS915HybridVerify( VerifyParams_t* verify, PhyAttribute_t phyAttribute ) |
||||
{ |
||||
switch( phyAttribute ) |
||||
{ |
||||
case PHY_TX_DR: |
||||
{ |
||||
return RegionCommonValueInRange( verify->DatarateParams.Datarate, US915_HYBRID_TX_MIN_DATARATE, US915_HYBRID_TX_MAX_DATARATE ); |
||||
} |
||||
case PHY_DEF_TX_DR: |
||||
{ |
||||
return RegionCommonValueInRange( verify->DatarateParams.Datarate, DR_0, DR_5 ); |
||||
} |
||||
case PHY_RX_DR: |
||||
{ |
||||
return RegionCommonValueInRange( verify->DatarateParams.Datarate, US915_HYBRID_RX_MIN_DATARATE, US915_HYBRID_RX_MAX_DATARATE ); |
||||
} |
||||
case PHY_DEF_TX_POWER: |
||||
case PHY_TX_POWER: |
||||
{ |
||||
// Remark: switched min and max!
|
||||
return RegionCommonValueInRange( verify->TxPower, US915_HYBRID_MAX_TX_POWER, US915_HYBRID_MIN_TX_POWER ); |
||||
} |
||||
case PHY_DUTY_CYCLE: |
||||
{ |
||||
return US915_HYBRID_DUTY_CYCLE_ENABLED; |
||||
} |
||||
case PHY_NB_JOIN_TRIALS: |
||||
{ |
||||
if( verify->NbJoinTrials < 2 ) |
||||
{ |
||||
return false; |
||||
} |
||||
break; |
||||
} |
||||
default: |
||||
return false; |
||||
} |
||||
return true; |
||||
} |
||||
|
||||
void RegionUS915HybridApplyCFList( ApplyCFListParams_t* applyCFList ) |
||||
{ |
||||
return; |
||||
} |
||||
|
||||
bool RegionUS915HybridChanMaskSet( ChanMaskSetParams_t* chanMaskSet ) |
||||
{ |
||||
uint8_t nbChannels = RegionCommonCountChannels( chanMaskSet->ChannelsMaskIn, 0, 4 ); |
||||
|
||||
// Check the number of active channels
|
||||
if( ( nbChannels < 2 ) && |
||||
( nbChannels > 0 ) ) |
||||
{ |
||||
return false; |
||||
} |
||||
|
||||
// Validate the channels mask
|
||||
if( ValidateChannelsMask( chanMaskSet->ChannelsMaskIn ) == false ) |
||||
{ |
||||
return false; |
||||
} |
||||
|
||||
switch( chanMaskSet->ChannelsMaskType ) |
||||
{ |
||||
case CHANNELS_MASK: |
||||
{ |
||||
RegionCommonChanMaskCopy( ChannelsMask, chanMaskSet->ChannelsMaskIn, 6 ); |
||||
|
||||
for( uint8_t i = 0; i < 6; i++ ) |
||||
{ // Copy-And the channels mask
|
||||
ChannelsMaskRemaining[i] &= ChannelsMask[i]; |
||||
} |
||||
break; |
||||
} |
||||
case CHANNELS_DEFAULT_MASK: |
||||
{ |
||||
RegionCommonChanMaskCopy( ChannelsDefaultMask, chanMaskSet->ChannelsMaskIn, 6 ); |
||||
break; |
||||
} |
||||
default: |
||||
return false; |
||||
} |
||||
return true; |
||||
} |
||||
|
||||
bool RegionUS915HybridAdrNext( AdrNextParams_t* adrNext, int8_t* drOut, int8_t* txPowOut, uint32_t* adrAckCounter ) |
||||
{ |
||||
bool adrAckReq = false; |
||||
int8_t datarate = adrNext->Datarate; |
||||
int8_t txPower = adrNext->TxPower; |
||||
GetPhyParams_t getPhy; |
||||
PhyParam_t phyParam; |
||||
|
||||
// Report back the adr ack counter
|
||||
*adrAckCounter = adrNext->AdrAckCounter; |
||||
|
||||
if( adrNext->AdrEnabled == true ) |
||||
{ |
||||
if( datarate == US915_HYBRID_TX_MIN_DATARATE ) |
||||
{ |
||||
*adrAckCounter = 0; |
||||
adrAckReq = false; |
||||
} |
||||
else |
||||
{ |
||||
if( adrNext->AdrAckCounter >= US915_HYBRID_ADR_ACK_LIMIT ) |
||||
{ |
||||
adrAckReq = true; |
||||
txPower = US915_HYBRID_MAX_TX_POWER; |
||||
} |
||||
else |
||||
{ |
||||
adrAckReq = false; |
||||
} |
||||
if( adrNext->AdrAckCounter >= ( US915_HYBRID_ADR_ACK_LIMIT + US915_HYBRID_ADR_ACK_DELAY ) ) |
||||
{ |
||||
if( ( adrNext->AdrAckCounter % US915_HYBRID_ADR_ACK_DELAY ) == 1 ) |
||||
{ |
||||
// Decrease the datarate
|
||||
getPhy.Attribute = PHY_NEXT_LOWER_TX_DR; |
||||
getPhy.Datarate = datarate; |
||||
getPhy.UplinkDwellTime = adrNext->UplinkDwellTime; |
||||
phyParam = RegionUS915HybridGetPhyParam( &getPhy ); |
||||
datarate = phyParam.Value; |
||||
|
||||
if( datarate == US915_HYBRID_TX_MIN_DATARATE ) |
||||
{ |
||||
// We must set adrAckReq to false as soon as we reach the lowest datarate
|
||||
adrAckReq = false; |
||||
if( adrNext->UpdateChanMask == true ) |
||||
{ |
||||
// Re-enable default channels
|
||||
ReenableChannels( ChannelsMask[4], ChannelsMask ); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
*drOut = datarate; |
||||
*txPowOut = txPower; |
||||
return adrAckReq; |
||||
} |
||||
|
||||
void RegionUS915HybridComputeRxWindowParameters( int8_t datarate, uint8_t minRxSymbols, uint32_t rxError, RxConfigParams_t *rxConfigParams ) |
||||
{ |
||||
double tSymbol = 0.0; |
||||
uint32_t radioWakeUpTime; |
||||
|
||||
// Get the datarate, perform a boundary check
|
||||
rxConfigParams->Datarate = MIN( datarate, US915_HYBRID_RX_MAX_DATARATE ); |
||||
rxConfigParams->Bandwidth = GetBandwidth( rxConfigParams->Datarate ); |
||||
|
||||
tSymbol = RegionCommonComputeSymbolTimeLoRa( DataratesUS915_HYBRID[rxConfigParams->Datarate], BandwidthsUS915_HYBRID[rxConfigParams->Datarate] ); |
||||
|
||||
radioWakeUpTime = Radio.GetRadioWakeUpTime( ); |
||||
RegionCommonComputeRxWindowParameters( tSymbol, minRxSymbols, rxError, radioWakeUpTime, &rxConfigParams->WindowTimeout, &rxConfigParams->WindowOffset ); |
||||
} |
||||
|
||||
bool RegionUS915HybridRxConfig( RxConfigParams_t* rxConfig, int8_t* datarate ) |
||||
{ |
||||
int8_t dr = rxConfig->Datarate; |
||||
uint8_t maxPayload = 0; |
||||
int8_t phyDr = 0; |
||||
uint32_t frequency = rxConfig->Frequency; |
||||
|
||||
if( Radio.GetStatus( ) != RF_IDLE ) |
||||
{ |
||||
return false; |
||||
} |
||||
|
||||
if( rxConfig->Window == 0 ) |
||||
{ |
||||
// Apply window 1 frequency
|
||||
frequency = US915_HYBRID_FIRST_RX1_CHANNEL + ( rxConfig->Channel % 8 ) * US915_HYBRID_STEPWIDTH_RX1_CHANNEL; |
||||
} |
||||
|
||||
// Read the physical datarate from the datarates table
|
||||
phyDr = DataratesUS915_HYBRID[dr]; |
||||
|
||||
Radio.SetChannel( frequency ); |
||||
|
||||
// Radio configuration
|
||||
Radio.SetRxConfig( MODEM_LORA, rxConfig->Bandwidth, phyDr, 1, 0, 8, rxConfig->WindowTimeout, false, 0, false, 0, 0, true, rxConfig->RxContinuous ); |
||||
|
||||
if( rxConfig->RepeaterSupport == true ) |
||||
{ |
||||
maxPayload = MaxPayloadOfDatarateRepeaterUS915_HYBRID[dr]; |
||||
} |
||||
else |
||||
{ |
||||
maxPayload = MaxPayloadOfDatarateUS915_HYBRID[dr]; |
||||
} |
||||
Radio.SetMaxPayloadLength( MODEM_LORA, maxPayload + LORA_MAC_FRMPAYLOAD_OVERHEAD ); |
||||
DBG_PRINTF( "RX on freq %d Hz at DR %d\n\r", frequency, dr ); |
||||
|
||||
*datarate = (uint8_t) dr; |
||||
return true; |
||||
} |
||||
|
||||
bool RegionUS915HybridTxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime_t* txTimeOnAir ) |
||||
{ |
||||
int8_t phyDr = DataratesUS915_HYBRID[txConfig->Datarate]; |
||||
int8_t txPowerLimited = LimitTxPower( txConfig->TxPower, Bands[Channels[txConfig->Channel].Band].TxMaxPower, txConfig->Datarate, ChannelsMask ); |
||||
uint32_t bandwidth = GetBandwidth( txConfig->Datarate ); |
||||
int8_t phyTxPower = 0; |
||||
|
||||
// Calculate physical TX power
|
||||
phyTxPower = RegionCommonComputeTxPower( txPowerLimited, US915_HYBRID_DEFAULT_MAX_ERP, 0 ); |
||||
|
||||
// Setup the radio frequency
|
||||
Radio.SetChannel( Channels[txConfig->Channel].Frequency ); |
||||
|
||||
Radio.SetTxConfig( MODEM_LORA, phyTxPower, 0, bandwidth, phyDr, 1, 8, false, true, 0, 0, false, 3000 ); |
||||
DBG_PRINTF( "TX on freq %d Hz at DR %d\n\r", Channels[txConfig->Channel].Frequency, txConfig->Datarate ); |
||||
|
||||
// Setup maximum payload lenght of the radio driver
|
||||
Radio.SetMaxPayloadLength( MODEM_LORA, txConfig->PktLen ); |
||||
// Get the time-on-air of the next tx frame
|
||||
*txTimeOnAir = Radio.TimeOnAir( MODEM_LORA, txConfig->PktLen ); |
||||
*txPower = txPowerLimited; |
||||
|
||||
return true; |
||||
} |
||||
|
||||
uint8_t RegionUS915HybridLinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, int8_t* txPowOut, uint8_t* nbRepOut, uint8_t* nbBytesParsed ) |
||||
{ |
||||
uint8_t status = 0x07; |
||||
RegionCommonLinkAdrParams_t linkAdrParams; |
||||
uint8_t nextIndex = 0; |
||||
uint8_t bytesProcessed = 0; |
||||
uint16_t channelsMask[6] = { 0, 0, 0, 0, 0, 0 }; |
||||
GetPhyParams_t getPhy; |
||||
PhyParam_t phyParam; |
||||
RegionCommonLinkAdrReqVerifyParams_t linkAdrVerifyParams; |
||||
|
||||
// Initialize local copy of channels mask
|
||||
RegionCommonChanMaskCopy( channelsMask, ChannelsMask, 6 ); |
||||
|
||||
while( bytesProcessed < linkAdrReq->PayloadSize ) |
||||
{ |
||||
nextIndex = RegionCommonParseLinkAdrReq( &( linkAdrReq->Payload[bytesProcessed] ), &linkAdrParams ); |
||||
|
||||
if( nextIndex == 0 ) |
||||
break; // break loop, since no more request has been found
|
||||
|
||||
// Update bytes processed
|
||||
bytesProcessed += nextIndex; |
||||
|
||||
// Revert status, as we only check the last ADR request for the channel mask KO
|
||||
status = 0x07; |
||||
|
||||
if( linkAdrParams.ChMaskCtrl == 6 ) |
||||
{ |
||||
// Enable all 125 kHz channels
|
||||
channelsMask[0] = 0xFFFF; |
||||
channelsMask[1] = 0xFFFF; |
||||
channelsMask[2] = 0xFFFF; |
||||
channelsMask[3] = 0xFFFF; |
||||
// Apply chMask to channels 64 to 71
|
||||
channelsMask[4] = linkAdrParams.ChMask; |
||||
} |
||||
else if( linkAdrParams.ChMaskCtrl == 7 ) |
||||
{ |
||||
// Disable all 125 kHz channels
|
||||
channelsMask[0] = 0x0000; |
||||
channelsMask[1] = 0x0000; |
||||
channelsMask[2] = 0x0000; |
||||
channelsMask[3] = 0x0000; |
||||
// Apply chMask to channels 64 to 71
|
||||
channelsMask[4] = linkAdrParams.ChMask; |
||||
} |
||||
else if( linkAdrParams.ChMaskCtrl == 5 ) |
||||
{ |
||||
// RFU
|
||||
status &= 0xFE; // Channel mask KO
|
||||
} |
||||
else |
||||
{ |
||||
channelsMask[linkAdrParams.ChMaskCtrl] = linkAdrParams.ChMask; |
||||
} |
||||
} |
||||
|
||||
// FCC 15.247 paragraph F mandates to hop on at least 2 125 kHz channels
|
||||
if( ( linkAdrParams.Datarate < DR_4 ) && ( RegionCommonCountChannels( channelsMask, 0, 4 ) < 2 ) ) |
||||
{ |
||||
status &= 0xFE; // Channel mask KO
|
||||
} |
||||
|
||||
if( ValidateChannelsMask( channelsMask ) == false ) |
||||
{ |
||||
status &= 0xFE; // Channel mask KO
|
||||
} |
||||
|
||||
// Get the minimum possible datarate
|
||||
getPhy.Attribute = PHY_MIN_TX_DR; |
||||
getPhy.UplinkDwellTime = linkAdrReq->UplinkDwellTime; |
||||
phyParam = RegionUS915HybridGetPhyParam( &getPhy ); |
||||
|
||||
linkAdrVerifyParams.Status = status; |
||||
linkAdrVerifyParams.AdrEnabled = linkAdrReq->AdrEnabled; |
||||
linkAdrVerifyParams.Datarate = linkAdrParams.Datarate; |
||||
linkAdrVerifyParams.TxPower = linkAdrParams.TxPower; |
||||
linkAdrVerifyParams.NbRep = linkAdrParams.NbRep; |
||||
linkAdrVerifyParams.CurrentDatarate = linkAdrReq->CurrentDatarate; |
||||
linkAdrVerifyParams.CurrentTxPower = linkAdrReq->CurrentTxPower; |
||||
linkAdrVerifyParams.CurrentNbRep = linkAdrReq->CurrentNbRep; |
||||
linkAdrVerifyParams.NbChannels = US915_HYBRID_MAX_NB_CHANNELS; |
||||
linkAdrVerifyParams.ChannelsMask = channelsMask; |
||||
linkAdrVerifyParams.MinDatarate = ( int8_t )phyParam.Value; |
||||
linkAdrVerifyParams.MaxDatarate = US915_HYBRID_TX_MAX_DATARATE; |
||||
linkAdrVerifyParams.Channels = Channels; |
||||
linkAdrVerifyParams.MinTxPower = US915_HYBRID_MIN_TX_POWER; |
||||
linkAdrVerifyParams.MaxTxPower = US915_HYBRID_MAX_TX_POWER; |
||||
|
||||
// Verify the parameters and update, if necessary
|
||||
status = RegionCommonLinkAdrReqVerifyParams( &linkAdrVerifyParams, &linkAdrParams.Datarate, &linkAdrParams.TxPower, &linkAdrParams.NbRep ); |
||||
|
||||
// Update channelsMask if everything is correct
|
||||
if( status == 0x07 ) |
||||
{ |
||||
// Copy Mask
|
||||
RegionCommonChanMaskCopy( ChannelsMask, channelsMask, 6 ); |
||||
|
||||
ChannelsMaskRemaining[0] &= ChannelsMask[0]; |
||||
ChannelsMaskRemaining[1] &= ChannelsMask[1]; |
||||
ChannelsMaskRemaining[2] &= ChannelsMask[2]; |
||||
ChannelsMaskRemaining[3] &= ChannelsMask[3]; |
||||
ChannelsMaskRemaining[4] = ChannelsMask[4]; |
||||
ChannelsMaskRemaining[5] = ChannelsMask[5]; |
||||
} |
||||
|
||||
// Update status variables
|
||||
*drOut = linkAdrParams.Datarate; |
||||
*txPowOut = linkAdrParams.TxPower; |
||||
*nbRepOut = linkAdrParams.NbRep; |
||||
*nbBytesParsed = bytesProcessed; |
||||
|
||||
return status; |
||||
} |
||||
|
||||
uint8_t RegionUS915HybridRxParamSetupReq( RxParamSetupReqParams_t* rxParamSetupReq ) |
||||
{ |
||||
uint8_t status = 0x07; |
||||
uint32_t freq = rxParamSetupReq->Frequency; |
||||
|
||||
// Verify radio frequency
|
||||
if( ( Radio.CheckRfFrequency( freq ) == false ) || |
||||
( freq < US915_HYBRID_FIRST_RX1_CHANNEL ) || |
||||
( freq > US915_HYBRID_LAST_RX1_CHANNEL ) || |
||||
( ( ( freq - ( uint32_t ) US915_HYBRID_FIRST_RX1_CHANNEL ) % ( uint32_t ) US915_HYBRID_STEPWIDTH_RX1_CHANNEL ) != 0 ) ) |
||||
{ |
||||
status &= 0xFE; // Channel frequency KO
|
||||
} |
||||
|
||||
// Verify datarate
|
||||
if( RegionCommonValueInRange( rxParamSetupReq->Datarate, US915_HYBRID_RX_MIN_DATARATE, US915_HYBRID_RX_MAX_DATARATE ) == false ) |
||||
{ |
||||
status &= 0xFD; // Datarate KO
|
||||
} |
||||
if( ( RegionCommonValueInRange( rxParamSetupReq->Datarate, DR_5, DR_7 ) == true ) || |
||||
( rxParamSetupReq->Datarate > DR_13 ) ) |
||||
{ |
||||
status &= 0xFD; // Datarate KO
|
||||
} |
||||
|
||||
// Verify datarate offset
|
||||
if( RegionCommonValueInRange( rxParamSetupReq->DrOffset, US915_HYBRID_MIN_RX1_DR_OFFSET, US915_HYBRID_MAX_RX1_DR_OFFSET ) == false ) |
||||
{ |
||||
status &= 0xFB; // Rx1DrOffset range KO
|
||||
} |
||||
|
||||
return status; |
||||
} |
||||
|
||||
uint8_t RegionUS915HybridNewChannelReq( NewChannelReqParams_t* newChannelReq ) |
||||
{ |
||||
// Datarate and frequency KO
|
||||
return 0; |
||||
} |
||||
|
||||
int8_t RegionUS915HybridTxParamSetupReq( TxParamSetupReqParams_t* txParamSetupReq ) |
||||
{ |
||||
return -1; |
||||
} |
||||
|
||||
uint8_t RegionUS915HybridDlChannelReq( DlChannelReqParams_t* dlChannelReq ) |
||||
{ |
||||
return 0; |
||||
} |
||||
|
||||
int8_t RegionUS915HybridAlternateDr( AlternateDrParams_t* alternateDr ) |
||||
{ |
||||
int8_t datarate = 0; |
||||
|
||||
// Re-enable 500 kHz default channels
|
||||
ReenableChannels( ChannelsMask[4], ChannelsMask ); |
||||
|
||||
if( ( alternateDr->NbTrials & 0x01 ) == 0x01 ) |
||||
{ |
||||
datarate = DR_4; |
||||
} |
||||
else |
||||
{ |
||||
datarate = DR_0; |
||||
} |
||||
return datarate; |
||||
} |
||||
|
||||
void RegionUS915HybridCalcBackOff( CalcBackOffParams_t* calcBackOff ) |
||||
{ |
||||
RegionCommonCalcBackOffParams_t calcBackOffParams; |
||||
|
||||
calcBackOffParams.Channels = Channels; |
||||
calcBackOffParams.Bands = Bands; |
||||
calcBackOffParams.LastTxIsJoinRequest = calcBackOff->LastTxIsJoinRequest; |
||||
calcBackOffParams.Joined = calcBackOff->Joined; |
||||
calcBackOffParams.DutyCycleEnabled = calcBackOff->DutyCycleEnabled; |
||||
calcBackOffParams.Channel = calcBackOff->Channel; |
||||
calcBackOffParams.ElapsedTime = calcBackOff->ElapsedTime; |
||||
calcBackOffParams.TxTimeOnAir = calcBackOff->TxTimeOnAir; |
||||
|
||||
RegionCommonCalcBackOff( &calcBackOffParams ); |
||||
} |
||||
|
||||
bool RegionUS915HybridNextChannel( NextChanParams_t* nextChanParams, uint8_t* channel, TimerTime_t* time, TimerTime_t* aggregatedTimeOff ) |
||||
{ |
||||
uint8_t nbEnabledChannels = 0; |
||||
uint8_t delayTx = 0; |
||||
uint8_t enabledChannels[US915_HYBRID_MAX_NB_CHANNELS] = { 0 }; |
||||
TimerTime_t nextTxDelay = 0; |
||||
|
||||
// Count 125kHz channels
|
||||
if( RegionCommonCountChannels( ChannelsMaskRemaining, 0, 4 ) == 0 ) |
||||
{ // Reactivate default channels
|
||||
RegionCommonChanMaskCopy( ChannelsMaskRemaining, ChannelsMask, 4 ); |
||||
} |
||||
// Check other channels
|
||||
if( nextChanParams->Datarate >= DR_4 ) |
||||
{ |
||||
if( ( ChannelsMaskRemaining[4] & 0x00FF ) == 0 ) |
||||
{ |
||||
ChannelsMaskRemaining[4] = ChannelsMask[4]; |
||||
} |
||||
} |
||||
|
||||
if( nextChanParams->AggrTimeOff <= TimerGetElapsedTime( nextChanParams->LastAggrTx ) ) |
||||
{ |
||||
// Reset Aggregated time off
|
||||
*aggregatedTimeOff = 0; |
||||
|
||||
// Update bands Time OFF
|
||||
nextTxDelay = RegionCommonUpdateBandTimeOff( nextChanParams->Joined, nextChanParams->DutyCycleEnabled, Bands, US915_HYBRID_MAX_NB_BANDS ); |
||||
|
||||
// Search how many channels are enabled
|
||||
nbEnabledChannels = CountNbOfEnabledChannels( nextChanParams->Datarate, |
||||
ChannelsMaskRemaining, Channels, |
||||
Bands, enabledChannels, &delayTx ); |
||||
} |
||||
else |
||||
{ |
||||
delayTx++; |
||||
nextTxDelay = nextChanParams->AggrTimeOff - TimerGetElapsedTime( nextChanParams->LastAggrTx ); |
||||
} |
||||
|
||||
if( nbEnabledChannels > 0 ) |
||||
{ |
||||
// We found a valid channel
|
||||
*channel = enabledChannels[randr( 0, nbEnabledChannels - 1 )]; |
||||
// Disable the channel in the mask
|
||||
RegionCommonChanDisable( ChannelsMaskRemaining, *channel, US915_HYBRID_MAX_NB_CHANNELS - 8 ); |
||||
|
||||
*time = 0; |
||||
return true; |
||||
} |
||||
else |
||||
{ |
||||
if( delayTx > 0 ) |
||||
{ |
||||
// Delay transmission due to AggregatedTimeOff or to a band time off
|
||||
*time = nextTxDelay; |
||||
return true; |
||||
} |
||||
// Datarate not supported by any channel
|
||||
*time = 0; |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
LoRaMacStatus_t RegionUS915HybridChannelAdd( ChannelAddParams_t* channelAdd ) |
||||
{ |
||||
return LORAMAC_STATUS_PARAMETER_INVALID; |
||||
} |
||||
|
||||
bool RegionUS915HybridChannelsRemove( ChannelRemoveParams_t* channelRemove ) |
||||
{ |
||||
return LORAMAC_STATUS_PARAMETER_INVALID; |
||||
} |
||||
|
||||
void RegionUS915HybridSetContinuousWave( ContinuousWaveParams_t* continuousWave ) |
||||
{ |
||||
int8_t txPowerLimited = LimitTxPower( continuousWave->TxPower, Bands[Channels[continuousWave->Channel].Band].TxMaxPower, continuousWave->Datarate, ChannelsMask ); |
||||
int8_t phyTxPower = 0; |
||||
uint32_t frequency = Channels[continuousWave->Channel].Frequency; |
||||
|
||||
// Calculate physical TX power
|
||||
phyTxPower = RegionCommonComputeTxPower( txPowerLimited, US915_HYBRID_DEFAULT_MAX_ERP, 0 ); |
||||
|
||||
Radio.SetTxContinuousWave( frequency, phyTxPower, continuousWave->Timeout ); |
||||
} |
||||
|
||||
uint8_t RegionUS915HybridApplyDrOffset( uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset ) |
||||
{ |
||||
int8_t datarate = DatarateOffsetsUS915_HYBRID[dr][drOffset]; |
||||
|
||||
if( datarate < 0 ) |
||||
{ |
||||
datarate = DR_0; |
||||
} |
||||
return datarate; |
||||
} |
@ -0,0 +1,448 @@ |
||||
/*!
|
||||
* \file RegionUS915Hybrid-Hybrid.h |
||||
* |
||||
* \brief Region definition for US915 |
||||
* |
||||
* \copyright Revised BSD License, see section \ref LICENSE. |
||||
* |
||||
* \code |
||||
* ______ _ |
||||
* / _____) _ | | |
||||
* ( (____ _____ ____ _| |_ _____ ____| |__ |
||||
* \____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
* _____) ) ____| | | || |_| ____( (___| | | | |
||||
* (______/|_____)_|_|_| \__)_____)\____)_| |_| |
||||
* (C)2013 Semtech |
||||
* |
||||
* ___ _____ _ ___ _ _____ ___ ___ ___ ___ |
||||
* / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| |
||||
* \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| |
||||
* |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| |
||||
* embedded.connectivity.solutions=============== |
||||
* |
||||
* \endcode |
||||
* |
||||
* \author Miguel Luis ( Semtech ) |
||||
* |
||||
* \author Gregory Cristian ( Semtech ) |
||||
* |
||||
* \author Daniel Jaeckle ( STACKFORCE ) |
||||
* |
||||
* \defgroup REGIONUS915HYB Region US915 in hybrid mode |
||||
* This is a hybrid implementation for US915, supporting 16 uplink channels only. |
||||
* \{ |
||||
*/ |
||||
#ifndef __REGION_US915_HYBRID_H__ |
||||
#define __REGION_US915_HYBRID_H__ |
||||
|
||||
/*!
|
||||
* LoRaMac maximum number of channels |
||||
*/ |
||||
#define US915_HYBRID_MAX_NB_CHANNELS 72 |
||||
|
||||
/*!
|
||||
* Minimal datarate that can be used by the node |
||||
*/ |
||||
#define US915_HYBRID_TX_MIN_DATARATE DR_0 |
||||
|
||||
/*!
|
||||
* Maximal datarate that can be used by the node |
||||
*/ |
||||
#define US915_HYBRID_TX_MAX_DATARATE DR_4 |
||||
|
||||
/*!
|
||||
* Minimal datarate that can be used by the node |
||||
*/ |
||||
#define US915_HYBRID_RX_MIN_DATARATE DR_8 |
||||
|
||||
/*!
|
||||
* Maximal datarate that can be used by the node |
||||
*/ |
||||
#define US915_HYBRID_RX_MAX_DATARATE DR_13 |
||||
|
||||
/*!
|
||||
* Default datarate used by the node |
||||
*/ |
||||
#define US915_HYBRID_DEFAULT_DATARATE DR_0 |
||||
|
||||
/*!
|
||||
* Minimal Rx1 receive datarate offset |
||||
*/ |
||||
#define US915_HYBRID_MIN_RX1_DR_OFFSET 0 |
||||
|
||||
/*!
|
||||
* Maximal Rx1 receive datarate offset |
||||
*/ |
||||
#define US915_HYBRID_MAX_RX1_DR_OFFSET 3 |
||||
|
||||
/*!
|
||||
* Default Rx1 receive datarate offset |
||||
*/ |
||||
#define US915_HYBRID_DEFAULT_RX1_DR_OFFSET 0 |
||||
|
||||
/*!
|
||||
* Minimal Tx output power that can be used by the node |
||||
*/ |
||||
#define US915_HYBRID_MIN_TX_POWER TX_POWER_10 |
||||
|
||||
/*!
|
||||
* Maximal Tx output power that can be used by the node |
||||
*/ |
||||
#define US915_HYBRID_MAX_TX_POWER TX_POWER_0 |
||||
|
||||
/*!
|
||||
* Default Tx output power used by the node |
||||
*/ |
||||
#define US915_HYBRID_DEFAULT_TX_POWER TX_POWER_0 |
||||
|
||||
/*!
|
||||
* Default Max ERP |
||||
*/ |
||||
#define US915_HYBRID_DEFAULT_MAX_ERP 30.0f |
||||
|
||||
/*!
|
||||
* ADR Ack limit |
||||
*/ |
||||
#define US915_HYBRID_ADR_ACK_LIMIT 64 |
||||
|
||||
/*!
|
||||
* ADR Ack delay |
||||
*/ |
||||
#define US915_HYBRID_ADR_ACK_DELAY 32 |
||||
|
||||
/*!
|
||||
* Enabled or disabled the duty cycle |
||||
*/ |
||||
#define US915_HYBRID_DUTY_CYCLE_ENABLED 0 |
||||
|
||||
/*!
|
||||
* Maximum RX window duration |
||||
*/ |
||||
#define US915_HYBRID_MAX_RX_WINDOW 3000 |
||||
|
||||
/*!
|
||||
* Receive delay 1 |
||||
*/ |
||||
#define US915_HYBRID_RECEIVE_DELAY1 1000 |
||||
|
||||
/*!
|
||||
* Receive delay 2 |
||||
*/ |
||||
#define US915_HYBRID_RECEIVE_DELAY2 2000 |
||||
|
||||
/*!
|
||||
* Join accept delay 1 |
||||
*/ |
||||
#define US915_HYBRID_JOIN_ACCEPT_DELAY1 5000 |
||||
|
||||
/*!
|
||||
* Join accept delay 2 |
||||
*/ |
||||
#define US915_HYBRID_JOIN_ACCEPT_DELAY2 6000 |
||||
|
||||
/*!
|
||||
* Maximum frame counter gap |
||||
*/ |
||||
#define US915_HYBRID_MAX_FCNT_GAP 16384 |
||||
|
||||
/*!
|
||||
* Ack timeout |
||||
*/ |
||||
#define US915_HYBRID_ACKTIMEOUT 2000 |
||||
|
||||
/*!
|
||||
* Random ack timeout limits |
||||
*/ |
||||
#define US915_HYBRID_ACK_TIMEOUT_RND 1000 |
||||
|
||||
/*!
|
||||
* Second reception window channel frequency definition. |
||||
*/ |
||||
#define US915_HYBRID_RX_WND_2_FREQ 923300000 |
||||
|
||||
/*!
|
||||
* Second reception window channel datarate definition. |
||||
*/ |
||||
#define US915_HYBRID_RX_WND_2_DR DR_8 |
||||
|
||||
/*!
|
||||
* LoRaMac maximum number of bands |
||||
*/ |
||||
#define US915_HYBRID_MAX_NB_BANDS 1 |
||||
|
||||
/*!
|
||||
* Band 0 definition |
||||
* { DutyCycle, TxMaxPower, LastTxDoneTime, TimeOff } |
||||
*/ |
||||
#define US915_HYBRID_BAND0 { 1, US915_HYBRID_MAX_TX_POWER, 0, 0 } // 100.0 %
|
||||
|
||||
/*!
|
||||
* Defines the first channel for RX window 1 for US band |
||||
*/ |
||||
#define US915_HYBRID_FIRST_RX1_CHANNEL ( (uint32_t) 923300000 ) |
||||
|
||||
/*!
|
||||
* Defines the last channel for RX window 1 for US band |
||||
*/ |
||||
#define US915_HYBRID_LAST_RX1_CHANNEL ( (uint32_t) 927500000 ) |
||||
|
||||
/*!
|
||||
* Defines the step width of the channels for RX window 1 |
||||
*/ |
||||
#define US915_HYBRID_STEPWIDTH_RX1_CHANNEL ( (uint32_t) 600000 ) |
||||
|
||||
/*!
|
||||
* Data rates table definition |
||||
*/ |
||||
static const uint8_t DataratesUS915_HYBRID[] = { 10, 9, 8, 7, 8, 0, 0, 0, 12, 11, 10, 9, 8, 7, 0, 0 }; |
||||
|
||||
/*!
|
||||
* Bandwidths table definition in Hz |
||||
*/ |
||||
static const uint32_t BandwidthsUS915_HYBRID[] = { 125000, 125000, 125000, 125000, 500000, 0, 0, 0, 500000, 500000, 500000, 500000, 500000, 500000, 0, 0 }; |
||||
|
||||
/*!
|
||||
* Up/Down link data rates offset definition |
||||
*/ |
||||
static const int8_t DatarateOffsetsUS915_HYBRID[5][4] = |
||||
{ |
||||
{ DR_10, DR_9 , DR_8 , DR_8 }, // DR_0
|
||||
{ DR_11, DR_10, DR_9 , DR_8 }, // DR_1
|
||||
{ DR_12, DR_11, DR_10, DR_9 }, // DR_2
|
||||
{ DR_13, DR_12, DR_11, DR_10 }, // DR_3
|
||||
{ DR_13, DR_13, DR_12, DR_11 }, // DR_4
|
||||
}; |
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Cannot operate with repeater. |
||||
*/ |
||||
static const uint8_t MaxPayloadOfDatarateUS915_HYBRID[] = { 11, 53, 125, 242, 242, 0, 0, 0, 53, 129, 242, 242, 242, 242, 0, 0 }; |
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Can operate with repeater. |
||||
*/ |
||||
static const uint8_t MaxPayloadOfDatarateRepeaterUS915_HYBRID[] = { 11, 53, 125, 242, 242, 0, 0, 0, 33, 109, 222, 222, 222, 222, 0, 0 }; |
||||
|
||||
/*!
|
||||
* \brief The function gets a value of a specific phy attribute. |
||||
* |
||||
* \param [IN] getPhy Pointer to the function parameters. |
||||
* |
||||
* \retval Returns a structure containing the PHY parameter. |
||||
*/ |
||||
PhyParam_t RegionUS915HybridGetPhyParam( GetPhyParams_t* getPhy ); |
||||
|
||||
/*!
|
||||
* \brief Updates the last TX done parameters of the current channel. |
||||
* |
||||
* \param [IN] txDone Pointer to the function parameters. |
||||
*/ |
||||
void RegionUS915HybridSetBandTxDone( SetBandTxDoneParams_t* txDone ); |
||||
|
||||
/*!
|
||||
* \brief Initializes the channels masks and the channels. |
||||
* |
||||
* \param [IN] type Sets the initialization type. |
||||
*/ |
||||
void RegionUS915HybridInitDefaults( InitType_t type ); |
||||
|
||||
/*!
|
||||
* \brief Verifies a parameter. |
||||
* |
||||
* \param [IN] verify Pointer to the function parameters. |
||||
* |
||||
* \param [IN] type Sets the initialization type. |
||||
* |
||||
* \retval Returns true, if the parameter is valid. |
||||
*/ |
||||
bool RegionUS915HybridVerify( VerifyParams_t* verify, PhyAttribute_t phyAttribute ); |
||||
|
||||
/*!
|
||||
* \brief The function parses the input buffer and sets up the channels of the |
||||
* CF list. |
||||
* |
||||
* \param [IN] applyCFList Pointer to the function parameters. |
||||
*/ |
||||
void RegionUS915HybridApplyCFList( ApplyCFListParams_t* applyCFList ); |
||||
|
||||
/*!
|
||||
* \brief Sets a channels mask. |
||||
* |
||||
* \param [IN] chanMaskSet Pointer to the function parameters. |
||||
* |
||||
* \retval Returns true, if the channels mask could be set. |
||||
*/ |
||||
bool RegionUS915HybridChanMaskSet( ChanMaskSetParams_t* chanMaskSet ); |
||||
|
||||
/*!
|
||||
* \brief Calculates the next datarate to set, when ADR is on or off. |
||||
* |
||||
* \param [IN] adrNext Pointer to the function parameters. |
||||
* |
||||
* \param [OUT] drOut The calculated datarate for the next TX. |
||||
* |
||||
* \param [OUT] txPowOut The TX power for the next TX. |
||||
* |
||||
* \param [OUT] adrAckCounter The calculated ADR acknowledgement counter. |
||||
* |
||||
* \retval Returns true, if an ADR request should be performed. |
||||
*/ |
||||
bool RegionUS915HybridAdrNext( AdrNextParams_t* adrNext, int8_t* drOut, int8_t* txPowOut, uint32_t* adrAckCounter ); |
||||
|
||||
/*!
|
||||
* Computes the Rx window timeout and offset. |
||||
* |
||||
* \param [IN] datarate Rx window datarate index to be used |
||||
* |
||||
* \param [IN] minRxSymbols Minimum required number of symbols to detect an Rx frame. |
||||
* |
||||
* \param [IN] rxError System maximum timing error of the receiver. In milliseconds |
||||
* The receiver will turn on in a [-rxError : +rxError] ms |
||||
* interval around RxOffset |
||||
* |
||||
* \param [OUT]rxConfigParams Returns updated WindowTimeout and WindowOffset fields. |
||||
*/ |
||||
void RegionUS915HybridComputeRxWindowParameters( int8_t datarate, uint8_t minRxSymbols, uint32_t rxError, RxConfigParams_t *rxConfigParams ); |
||||
|
||||
/*!
|
||||
* \brief Configuration of the RX windows. |
||||
* |
||||
* \param [IN] rxConfig Pointer to the function parameters. |
||||
* |
||||
* \param [OUT] datarate The datarate index which was set. |
||||
* |
||||
* \retval Returns true, if the configuration was applied successfully. |
||||
*/ |
||||
bool RegionUS915HybridRxConfig( RxConfigParams_t* rxConfig, int8_t* datarate ); |
||||
|
||||
/*!
|
||||
* \brief TX configuration. |
||||
* |
||||
* \param [IN] txConfig Pointer to the function parameters. |
||||
* |
||||
* \param [OUT] txPower The tx power index which was set. |
||||
* |
||||
* \param [OUT] txTimeOnAir The time-on-air of the frame. |
||||
* |
||||
* \retval Returns true, if the configuration was applied successfully. |
||||
*/ |
||||
bool RegionUS915HybridTxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime_t* txTimeOnAir ); |
||||
|
||||
/*!
|
||||
* \brief The function processes a Link ADR Request. |
||||
* |
||||
* \param [IN] linkAdrReq Pointer to the function parameters. |
||||
* |
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification. |
||||
*/ |
||||
uint8_t RegionUS915HybridLinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, int8_t* txPowOut, uint8_t* nbRepOut, uint8_t* nbBytesParsed ); |
||||
|
||||
/*!
|
||||
* \brief The function processes a RX Parameter Setup Request. |
||||
* |
||||
* \param [IN] rxParamSetupReq Pointer to the function parameters. |
||||
* |
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification. |
||||
*/ |
||||
uint8_t RegionUS915HybridRxParamSetupReq( RxParamSetupReqParams_t* rxParamSetupReq ); |
||||
|
||||
/*!
|
||||
* \brief The function processes a Channel Request. |
||||
* |
||||
* \param [IN] newChannelReq Pointer to the function parameters. |
||||
* |
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification. |
||||
*/ |
||||
uint8_t RegionUS915HybridNewChannelReq( NewChannelReqParams_t* newChannelReq ); |
||||
|
||||
/*!
|
||||
* \brief The function processes a TX ParamSetup Request. |
||||
* |
||||
* \param [IN] txParamSetupReq Pointer to the function parameters. |
||||
* |
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification. |
||||
* Returns -1, if the functionality is not implemented. In this case, the end node |
||||
* shall not process the command. |
||||
*/ |
||||
int8_t RegionUS915HybridTxParamSetupReq( TxParamSetupReqParams_t* txParamSetupReq ); |
||||
|
||||
/*!
|
||||
* \brief The function processes a DlChannel Request. |
||||
* |
||||
* \param [IN] dlChannelReq Pointer to the function parameters. |
||||
* |
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification. |
||||
*/ |
||||
uint8_t RegionUS915HybridDlChannelReq( DlChannelReqParams_t* dlChannelReq ); |
||||
|
||||
/*!
|
||||
* \brief Alternates the datarate of the channel for the join request. |
||||
* |
||||
* \param [IN] alternateDr Pointer to the function parameters. |
||||
* |
||||
* \retval Datarate to apply. |
||||
*/ |
||||
int8_t RegionUS915HybridAlternateDr( AlternateDrParams_t* alternateDr ); |
||||
|
||||
/*!
|
||||
* \brief Calculates the back-off time. |
||||
* |
||||
* \param [IN] calcBackOff Pointer to the function parameters. |
||||
*/ |
||||
void RegionUS915HybridCalcBackOff( CalcBackOffParams_t* calcBackOff ); |
||||
|
||||
/*!
|
||||
* \brief Searches and set the next random available channel |
||||
* |
||||
* \param [OUT] channel Next channel to use for TX. |
||||
* |
||||
* \param [OUT] time Time to wait for the next transmission according to the duty |
||||
* cycle. |
||||
* |
||||
* \param [OUT] aggregatedTimeOff Updates the aggregated time off. |
||||
* |
||||
* \retval Function status [1: OK, 0: Unable to find a channel on the current datarate] |
||||
*/ |
||||
bool RegionUS915HybridNextChannel( NextChanParams_t* nextChanParams, uint8_t* channel, TimerTime_t* time, TimerTime_t* aggregatedTimeOff ); |
||||
|
||||
/*!
|
||||
* \brief Adds a channel. |
||||
* |
||||
* \param [IN] channelAdd Pointer to the function parameters. |
||||
* |
||||
* \retval Status of the operation. |
||||
*/ |
||||
LoRaMacStatus_t RegionUS915HybridChannelAdd( ChannelAddParams_t* channelAdd ); |
||||
|
||||
/*!
|
||||
* \brief Removes a channel. |
||||
* |
||||
* \param [IN] channelRemove Pointer to the function parameters. |
||||
* |
||||
* \retval Returns true, if the channel was removed successfully. |
||||
*/ |
||||
bool RegionUS915HybridChannelsRemove( ChannelRemoveParams_t* channelRemove ); |
||||
|
||||
/*!
|
||||
* \brief Sets the radio into continuous wave mode. |
||||
* |
||||
* \param [IN] continuousWave Pointer to the function parameters. |
||||
*/ |
||||
void RegionUS915HybridSetContinuousWave( ContinuousWaveParams_t* continuousWave ); |
||||
|
||||
/*!
|
||||
* \brief Computes new datarate according to the given offset |
||||
* |
||||
* \param [IN] downlinkDwellTime Downlink dwell time configuration. 0: No limit, 1: 400ms |
||||
* |
||||
* \param [IN] dr Current datarate |
||||
* |
||||
* \param [IN] drOffset Offset to be applied |
||||
* |
||||
* \retval newDr Computed datarate. |
||||
*/ |
||||
uint8_t RegionUS915HybridApplyDrOffset( uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset ); |
||||
|
||||
/*! \} defgroup REGIONUS915HYB */ |
||||
|
||||
#endif // __REGION_US915_HYBRID_H__
|
@ -0,0 +1,871 @@ |
||||
/*
|
||||
/ _____) _ | | |
||||
( (____ _____ ____ _| |_ _____ ____| |__ |
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | | |
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_| |
||||
(C)2013 Semtech |
||||
___ _____ _ ___ _ _____ ___ ___ ___ ___ |
||||
/ __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| |
||||
\__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| |
||||
|___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| |
||||
embedded.connectivity.solutions=============== |
||||
|
||||
Description: LoRa MAC region US915 implementation |
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project |
||||
|
||||
Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jaeckle ( STACKFORCE ) |
||||
*/ |
||||
#include <stdbool.h> |
||||
#include <string.h> |
||||
#include <stdint.h> |
||||
#include <math.h> |
||||
|
||||
#include "radio.h" |
||||
#include "timer.h" |
||||
#include "LoRaMac.h" |
||||
|
||||
#include "utilities.h" |
||||
|
||||
#include "Region.h" |
||||
#include "RegionCommon.h" |
||||
#include "RegionUS915.h" |
||||
#include "debug.h" |
||||
|
||||
// Definitions
|
||||
#define CHANNELS_MASK_SIZE 6 |
||||
|
||||
// Global attributes
|
||||
/*!
|
||||
* LoRaMAC channels |
||||
*/ |
||||
static ChannelParams_t Channels[US915_MAX_NB_CHANNELS]; |
||||
|
||||
/*!
|
||||
* LoRaMac bands |
||||
*/ |
||||
static Band_t Bands[US915_MAX_NB_BANDS] = |
||||
{ |
||||
US915_BAND0 |
||||
}; |
||||
|
||||
/*!
|
||||
* LoRaMac channels mask |
||||
*/ |
||||
static uint16_t ChannelsMask[CHANNELS_MASK_SIZE]; |
||||
|
||||
/*!
|
||||
* LoRaMac channels remaining |
||||
*/ |
||||
static uint16_t ChannelsMaskRemaining[CHANNELS_MASK_SIZE]; |
||||
|
||||
/*!
|
||||
* LoRaMac channels default mask |
||||
*/ |
||||
static uint16_t ChannelsDefaultMask[CHANNELS_MASK_SIZE]; |
||||
|
||||
// Static functions
|
||||
static int8_t GetNextLowerTxDr( int8_t dr, int8_t minDr ) |
||||
{ |
||||
uint8_t nextLowerDr = 0; |
||||
|
||||
if( dr == minDr ) |
||||
{ |
||||
nextLowerDr = minDr; |
||||
} |
||||
else |
||||
{ |
||||
nextLowerDr = dr - 1; |
||||
} |
||||
return nextLowerDr; |
||||
} |
||||
|
||||
static uint32_t GetBandwidth( uint32_t drIndex ) |
||||
{ |
||||
switch( BandwidthsUS915[drIndex] ) |
||||
{ |
||||
default: |
||||
case 125000: |
||||
return 0; |
||||
case 250000: |
||||
return 1; |
||||
case 500000: |
||||
return 2; |
||||
} |
||||
} |
||||
|
||||
static int8_t LimitTxPower( int8_t txPower, int8_t maxBandTxPower, int8_t datarate, uint16_t* channelsMask ) |
||||
{ |
||||
int8_t txPowerResult = txPower; |
||||
|
||||
// Limit tx power to the band max
|
||||
txPowerResult = MAX( txPower, maxBandTxPower ); |
||||
|
||||
if( datarate == DR_4 ) |
||||
{// Limit tx power to max 26dBm
|
||||
txPowerResult = MAX( txPower, TX_POWER_2 ); |
||||
} |
||||
else |
||||
{ |
||||
if( RegionCommonCountChannels( channelsMask, 0, 4 ) < 50 ) |
||||
{// Limit tx power to max 21dBm
|
||||
txPowerResult = MAX( txPower, TX_POWER_5 ); |
||||
} |
||||
} |
||||
return txPowerResult; |
||||
} |
||||
|
||||
static uint8_t CountNbOfEnabledChannels( uint8_t datarate, uint16_t* channelsMask, ChannelParams_t* channels, Band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx ) |
||||
{ |
||||
uint8_t nbEnabledChannels = 0; |
||||
uint8_t delayTransmission = 0; |
||||
|
||||
for( uint8_t i = 0, k = 0; i < US915_MAX_NB_CHANNELS; i += 16, k++ ) |
||||
{ |
||||
for( uint8_t j = 0; j < 16; j++ ) |
||||
{ |
||||
if( ( channelsMask[k] & ( 1 << j ) ) != 0 ) |
||||
{ |
||||
if( channels[i + j].Frequency == 0 ) |
||||
{ // Check if the channel is enabled
|
||||
continue; |
||||
} |
||||
if( RegionCommonValueInRange( datarate, channels[i + j].DrRange.Fields.Min, |
||||
channels[i + j].DrRange.Fields.Max ) == false ) |
||||
{ // Check if the current channel selection supports the given datarate
|
||||
continue; |
||||
} |
||||
if( bands[channels[i + j].Band].TimeOff > 0 ) |
||||
{ // Check if the band is available for transmission
|
||||
delayTransmission++; |
||||
continue; |
||||
} |
||||
enabledChannels[nbEnabledChannels++] = i + j; |
||||
} |
||||
} |
||||
} |
||||
|
||||
*delayTx = delayTransmission; |
||||
return nbEnabledChannels; |
||||
} |
||||
|
||||
PhyParam_t RegionUS915GetPhyParam( GetPhyParams_t* getPhy ) |
||||
{ |
||||
PhyParam_t phyParam = { 0 }; |
||||
|
||||
switch( getPhy->Attribute ) |
||||
{ |
||||
case PHY_MIN_RX_DR: |
||||
{ |
||||
phyParam.Value = US915_RX_MIN_DATARATE; |
||||
break; |
||||
} |
||||
case PHY_MIN_TX_DR: |
||||
{ |
||||
phyParam.Value = US915_TX_MIN_DATARATE; |
||||
break; |
||||
} |
||||
case PHY_DEF_TX_DR: |
||||
{ |
||||
phyParam.Value = US915_DEFAULT_DATARATE; |
||||
break; |
||||
} |
||||
case PHY_NEXT_LOWER_TX_DR: |
||||
{ |
||||
phyParam.Value = GetNextLowerTxDr( getPhy->Datarate, US915_TX_MIN_DATARATE ); |
||||
break; |
||||
} |
||||
case PHY_DEF_TX_POWER: |
||||
{ |
||||
phyParam.Value = US915_DEFAULT_TX_POWER; |
||||
break; |
||||
} |
||||
case PHY_MAX_PAYLOAD: |
||||
{ |
||||
phyParam.Value = MaxPayloadOfDatarateUS915[getPhy->Datarate]; |
||||
break; |
||||
} |
||||
case PHY_MAX_PAYLOAD_REPEATER: |
||||
{ |
||||
phyParam.Value = MaxPayloadOfDatarateRepeaterUS915[getPhy->Datarate]; |
||||
break; |
||||
} |
||||
case PHY_DUTY_CYCLE: |
||||
{ |
||||
phyParam.Value = US915_DUTY_CYCLE_ENABLED; |
||||
break; |
||||
} |
||||
case PHY_MAX_RX_WINDOW: |
||||
{ |
||||
phyParam.Value = US915_MAX_RX_WINDOW; |
||||
break; |
||||
} |
||||
case PHY_RECEIVE_DELAY1: |
||||
{ |
||||
phyParam.Value = US915_RECEIVE_DELAY1; |
||||
break; |
||||
} |
||||
case PHY_RECEIVE_DELAY2: |
||||
{ |
||||
phyParam.Value = US915_RECEIVE_DELAY2; |
||||
break; |
||||
} |
||||
case PHY_JOIN_ACCEPT_DELAY1: |
||||
{ |
||||
phyParam.Value = US915_JOIN_ACCEPT_DELAY1; |
||||
break; |
||||
} |
||||
case PHY_JOIN_ACCEPT_DELAY2: |
||||
{ |
||||
phyParam.Value = US915_JOIN_ACCEPT_DELAY2; |
||||
break; |
||||
} |
||||
case PHY_MAX_FCNT_GAP: |
||||
{ |
||||
phyParam.Value = US915_MAX_FCNT_GAP; |
||||
break; |
||||
} |
||||
case PHY_ACK_TIMEOUT: |
||||
{ |
||||
phyParam.Value = ( US915_ACKTIMEOUT + randr( -US915_ACK_TIMEOUT_RND, US915_ACK_TIMEOUT_RND ) ); |
||||
break; |
||||
} |
||||
case PHY_DEF_DR1_OFFSET: |
||||
{ |
||||
phyParam.Value = US915_DEFAULT_RX1_DR_OFFSET; |
||||
break; |
||||
} |
||||
case PHY_DEF_RX2_FREQUENCY: |
||||
{ |
||||
phyParam.Value = US915_RX_WND_2_FREQ; |
||||
break; |
||||
} |
||||
case PHY_DEF_RX2_DR: |
||||
{ |
||||
phyParam.Value = US915_RX_WND_2_DR; |
||||
break; |
||||
} |
||||
case PHY_CHANNELS_MASK: |
||||
{ |
||||
phyParam.ChannelsMask = ChannelsMask; |
||||
break; |
||||
} |
||||
case PHY_CHANNELS_DEFAULT_MASK: |
||||
{ |
||||
phyParam.ChannelsMask = ChannelsDefaultMask; |
||||
break; |
||||
} |
||||
case PHY_MAX_NB_CHANNELS: |
||||
{ |
||||
phyParam.Value = US915_MAX_NB_CHANNELS; |
||||
break; |
||||
} |
||||
case PHY_CHANNELS: |
||||
{ |
||||
phyParam.Channels = Channels; |
||||
break; |
||||
} |
||||
case PHY_DEF_UPLINK_DWELL_TIME: |
||||
case PHY_DEF_DOWNLINK_DWELL_TIME: |
||||
{ |
||||
phyParam.Value = 0; |
||||
break; |
||||
} |
||||
case PHY_DEF_MAX_EIRP: |
||||
case PHY_DEF_ANTENNA_GAIN: |
||||
{ |
||||
phyParam.fValue = 0; |
||||
break; |
||||
} |
||||
case PHY_NB_JOIN_TRIALS: |
||||
case PHY_DEF_NB_JOIN_TRIALS: |
||||
{ |
||||
phyParam.Value = 2; |
||||
break; |
||||
} |
||||
default: |
||||
{ |
||||
break; |
||||
} |
||||
} |
||||
|
||||
return phyParam; |
||||
} |
||||
|
||||
void RegionUS915SetBandTxDone( SetBandTxDoneParams_t* txDone ) |
||||
{ |
||||
RegionCommonSetBandTxDone( txDone->Joined, &Bands[Channels[txDone->Channel].Band], txDone->LastTxDoneTime ); |
||||
} |
||||
|
||||
void RegionUS915InitDefaults( InitType_t type ) |
||||
{ |
||||
switch( type ) |
||||
{ |
||||
case INIT_TYPE_INIT: |
||||
{ |
||||
// Channels
|
||||
// 125 kHz channels
|
||||
for( uint8_t i = 0; i < US915_MAX_NB_CHANNELS - 8; i++ ) |
||||
{ |
||||
Channels[i].Frequency = 902300000 + i * 200000; |
||||
Channels[i].DrRange.Value = ( DR_3 << 4 ) | DR_0; |
||||
Channels[i].Band = 0; |
||||
} |
||||
// 500 kHz channels
|
||||
for( uint8_t i = US915_MAX_NB_CHANNELS - 8; i < US915_MAX_NB_CHANNELS; i++ ) |
||||
{ |
||||
Channels[i].Frequency = 903000000 + ( i - ( US915_MAX_NB_CHANNELS - 8 ) ) * 1600000; |
||||
Channels[i].DrRange.Value = ( DR_4 << 4 ) | DR_4; |
||||
Channels[i].Band = 0; |
||||
} |
||||
|
||||
// ChannelsMask
|
||||
ChannelsDefaultMask[0] = 0xFFFF; |
||||
ChannelsDefaultMask[1] = 0xFFFF; |
||||
ChannelsDefaultMask[2] = 0xFFFF; |
||||
ChannelsDefaultMask[3] = 0xFFFF; |
||||
ChannelsDefaultMask[4] = 0x00FF; |
||||
ChannelsDefaultMask[5] = 0x0000; |
||||
|
||||
// Copy channels default mask
|
||||
RegionCommonChanMaskCopy( ChannelsMask, ChannelsDefaultMask, 6 ); |
||||
|
||||
// Copy into channels mask remaining
|
||||
RegionCommonChanMaskCopy( ChannelsMaskRemaining, ChannelsMask, 6 ); |
||||
break; |
||||
} |
||||
case INIT_TYPE_RESTORE: |
||||
{ |
||||
// Copy channels default mask
|
||||
RegionCommonChanMaskCopy( ChannelsMask, ChannelsDefaultMask, 6 ); |
||||
|
||||
for( uint8_t i = 0; i < 6; i++ ) |
||||
{ // Copy-And the channels mask
|
||||
ChannelsMaskRemaining[i] &= ChannelsMask[i]; |
||||
} |
||||
break; |
||||
} |
||||
default: |
||||
{ |
||||
break; |
||||
} |
||||
} |
||||
} |
||||
|
||||
bool RegionUS915Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute ) |
||||
{ |
||||
switch( phyAttribute ) |
||||
{ |
||||
case PHY_TX_DR: |
||||
{ |
||||
return RegionCommonValueInRange( verify->DatarateParams.Datarate, US915_TX_MIN_DATARATE, US915_TX_MAX_DATARATE ); |
||||
} |
||||
case PHY_DEF_TX_DR: |
||||
{ |
||||
return RegionCommonValueInRange( verify->DatarateParams.Datarate, DR_0, DR_5 ); |
||||
} |
||||
case PHY_RX_DR: |
||||
{ |
||||
return RegionCommonValueInRange( verify->DatarateParams.Datarate, US915_RX_MIN_DATARATE, US915_RX_MAX_DATARATE ); |
||||
} |
||||
case PHY_DEF_TX_POWER: |
||||
case PHY_TX_POWER: |
||||
{ |
||||
// Remark: switched min and max!
|
||||
return RegionCommonValueInRange( verify->TxPower, US915_MAX_TX_POWER, US915_MIN_TX_POWER ); |
||||
} |
||||
case PHY_DUTY_CYCLE: |
||||
{ |
||||
return US915_DUTY_CYCLE_ENABLED; |
||||
} |
||||
case PHY_NB_JOIN_TRIALS: |
||||
{ |
||||
if( verify->NbJoinTrials < 2 ) |
||||
{ |
||||
return false; |
||||
} |
||||
break; |
||||
} |
||||
default: |
||||
return false; |
||||
} |
||||
return true; |
||||
} |
||||
|
||||
void RegionUS915ApplyCFList( ApplyCFListParams_t* applyCFList ) |
||||
{ |
||||
return; |
||||
} |
||||
|
||||
bool RegionUS915ChanMaskSet( ChanMaskSetParams_t* chanMaskSet ) |
||||
{ |
||||
uint8_t nbChannels = RegionCommonCountChannels( chanMaskSet->ChannelsMaskIn, 0, 4 ); |
||||
|
||||
// Check the number of active channels
|
||||
if( ( nbChannels < 2 ) && |
||||
( nbChannels > 0 ) ) |
||||
{ |
||||
return false; |
||||
} |
||||
|
||||
switch( chanMaskSet->ChannelsMaskType ) |
||||
{ |
||||
case CHANNELS_MASK: |
||||
{ |
||||
RegionCommonChanMaskCopy( ChannelsMask, chanMaskSet->ChannelsMaskIn, 6 ); |
||||
|
||||
for( uint8_t i = 0; i < 6; i++ ) |
||||
{ // Copy-And the channels mask
|
||||
ChannelsMaskRemaining[i] &= ChannelsMask[i]; |
||||
} |
||||
break; |
||||
} |
||||
case CHANNELS_DEFAULT_MASK: |
||||
{ |
||||
RegionCommonChanMaskCopy( ChannelsDefaultMask, chanMaskSet->ChannelsMaskIn, 6 ); |
||||
break; |
||||
} |
||||
default: |
||||
return false; |
||||
} |
||||
return true; |
||||
} |
||||
|
||||
bool RegionUS915AdrNext( AdrNextParams_t* adrNext, int8_t* drOut, int8_t* txPowOut, uint32_t* adrAckCounter ) |
||||
{ |
||||
bool adrAckReq = false; |
||||
int8_t datarate = adrNext->Datarate; |
||||
int8_t txPower = adrNext->TxPower; |
||||
GetPhyParams_t getPhy; |
||||
PhyParam_t phyParam; |
||||
|
||||
// Report back the adr ack counter
|
||||
*adrAckCounter = adrNext->AdrAckCounter; |
||||
|
||||
if( adrNext->AdrEnabled == true ) |
||||
{ |
||||
if( datarate == US915_TX_MIN_DATARATE ) |
||||
{ |
||||
*adrAckCounter = 0; |
||||
adrAckReq = false; |
||||
} |
||||
else |
||||
{ |
||||
if( adrNext->AdrAckCounter >= US915_ADR_ACK_LIMIT ) |
||||
{ |
||||
adrAckReq = true; |
||||
txPower = US915_MAX_TX_POWER; |
||||
} |
||||
else |
||||
{ |
||||
adrAckReq = false; |
||||
} |
||||
if( adrNext->AdrAckCounter >= ( US915_ADR_ACK_LIMIT + US915_ADR_ACK_DELAY ) ) |
||||
{ |
||||
if( ( adrNext->AdrAckCounter % US915_ADR_ACK_DELAY ) == 1 ) |
||||
{ |
||||
// Decrease the datarate
|
||||
getPhy.Attribute = PHY_NEXT_LOWER_TX_DR; |
||||
getPhy.Datarate = datarate; |
||||
getPhy.UplinkDwellTime = adrNext->UplinkDwellTime; |
||||
phyParam = RegionUS915GetPhyParam( &getPhy ); |
||||
datarate = phyParam.Value; |
||||
|
||||
if( datarate == US915_TX_MIN_DATARATE ) |
||||
{ |
||||
// We must set adrAckReq to false as soon as we reach the lowest datarate
|
||||
adrAckReq = false; |
||||
if( adrNext->UpdateChanMask == true ) |
||||
{ |
||||
// Re-enable default channels
|
||||
ChannelsMask[0] = 0xFFFF; |
||||
ChannelsMask[1] = 0xFFFF; |
||||
ChannelsMask[2] = 0xFFFF; |
||||
ChannelsMask[3] = 0xFFFF; |
||||
ChannelsMask[4] = 0x00FF; |
||||
ChannelsMask[5] = 0x0000; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
*drOut = datarate; |
||||
*txPowOut = txPower; |
||||
return adrAckReq; |
||||
} |
||||
|
||||
void RegionUS915ComputeRxWindowParameters( int8_t datarate, uint8_t minRxSymbols, uint32_t rxError, RxConfigParams_t *rxConfigParams ) |
||||
{ |
||||
double tSymbol = 0.0; |
||||
uint32_t radioWakeUpTime; |
||||
|
||||
// Get the datarate, perform a boundary check
|
||||
rxConfigParams->Datarate = MIN( datarate, US915_RX_MAX_DATARATE ); |
||||
rxConfigParams->Bandwidth = GetBandwidth( rxConfigParams->Datarate ); |
||||
|
||||
tSymbol = RegionCommonComputeSymbolTimeLoRa( DataratesUS915[rxConfigParams->Datarate], BandwidthsUS915[rxConfigParams->Datarate] ); |
||||
|
||||
radioWakeUpTime = Radio.GetRadioWakeUpTime( ); |
||||
RegionCommonComputeRxWindowParameters( tSymbol, minRxSymbols, rxError, radioWakeUpTime, &rxConfigParams->WindowTimeout, &rxConfigParams->WindowOffset ); |
||||
} |
||||
|
||||
bool RegionUS915RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate ) |
||||
{ |
||||
int8_t dr = rxConfig->Datarate; |
||||
uint8_t maxPayload = 0; |
||||
int8_t phyDr = 0; |
||||
uint32_t frequency = rxConfig->Frequency; |
||||
|
||||
if( Radio.GetStatus( ) != RF_IDLE ) |
||||
{ |
||||
return false; |
||||
} |
||||
|
||||
if( rxConfig->Window == 0 ) |
||||
{ |
||||
// Apply window 1 frequency
|
||||
frequency = US915_FIRST_RX1_CHANNEL + ( rxConfig->Channel % 8 ) * US915_STEPWIDTH_RX1_CHANNEL; |
||||
} |
||||
|
||||
// Read the physical datarate from the datarates table
|
||||
phyDr = DataratesUS915[dr]; |
||||
|
||||
Radio.SetChannel( frequency ); |
||||
|
||||
// Radio configuration
|
||||
Radio.SetRxConfig( MODEM_LORA, rxConfig->Bandwidth, phyDr, 1, 0, 8, rxConfig->WindowTimeout, false, 0, false, 0, 0, true, rxConfig->RxContinuous ); |
||||
|
||||
if( rxConfig->RepeaterSupport == true ) |
||||
{ |
||||
maxPayload = MaxPayloadOfDatarateRepeaterUS915[dr]; |
||||
} |
||||
else |
||||
{ |
||||
maxPayload = MaxPayloadOfDatarateUS915[dr]; |
||||
} |
||||
Radio.SetMaxPayloadLength( MODEM_LORA, maxPayload + LORA_MAC_FRMPAYLOAD_OVERHEAD ); |
||||
DBG_PRINTF( "RX on freq %d Hz at DR %d\n\r", frequency, dr ); |
||||
|
||||
*datarate = (uint8_t) dr; |
||||
return true; |
||||
} |
||||
|
||||
bool RegionUS915TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime_t* txTimeOnAir ) |
||||
{ |
||||
int8_t phyDr = DataratesUS915[txConfig->Datarate]; |
||||
int8_t txPowerLimited = LimitTxPower( txConfig->TxPower, Bands[Channels[txConfig->Channel].Band].TxMaxPower, txConfig->Datarate, ChannelsMask ); |
||||
uint32_t bandwidth = GetBandwidth( txConfig->Datarate ); |
||||
int8_t phyTxPower = 0; |
||||
|
||||
// Calculate physical TX power
|
||||
phyTxPower = RegionCommonComputeTxPower( txPowerLimited, US915_DEFAULT_MAX_ERP, 0 ); |
||||
|
||||
// Setup the radio frequency
|
||||
Radio.SetChannel( Channels[txConfig->Channel].Frequency ); |
||||
|
||||
Radio.SetTxConfig( MODEM_LORA, phyTxPower, 0, bandwidth, phyDr, 1, 8, false, true, 0, 0, false, 3000 ); |
||||
DBG_PRINTF( "TX on freq %d Hz at DR %d\n\r", Channels[txConfig->Channel].Frequency, txConfig->Datarate ); |
||||
|
||||
// Setup maximum payload lenght of the radio driver
|
||||
Radio.SetMaxPayloadLength( MODEM_LORA, txConfig->PktLen ); |
||||
// Get the time-on-air of the next tx frame
|
||||
*txTimeOnAir = Radio.TimeOnAir( MODEM_LORA, txConfig->PktLen ); |
||||
*txPower = txPowerLimited; |
||||
|
||||
return true; |
||||
} |
||||
|
||||
uint8_t RegionUS915LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, int8_t* txPowOut, uint8_t* nbRepOut, uint8_t* nbBytesParsed ) |
||||
{ |
||||
uint8_t status = 0x07; |
||||
RegionCommonLinkAdrParams_t linkAdrParams; |
||||
uint8_t nextIndex = 0; |
||||
uint8_t bytesProcessed = 0; |
||||
uint16_t channelsMask[6] = { 0, 0, 0, 0, 0, 0 }; |
||||
GetPhyParams_t getPhy; |
||||
PhyParam_t phyParam; |
||||
RegionCommonLinkAdrReqVerifyParams_t linkAdrVerifyParams; |
||||
|
||||
// Initialize local copy of channels mask
|
||||
RegionCommonChanMaskCopy( channelsMask, ChannelsMask, 6 ); |
||||
|
||||
while( bytesProcessed < linkAdrReq->PayloadSize ) |
||||
{ |
||||
nextIndex = RegionCommonParseLinkAdrReq( &( linkAdrReq->Payload[bytesProcessed] ), &linkAdrParams ); |
||||
|
||||
if( nextIndex == 0 ) |
||||
break; // break loop, since no more request has been found
|
||||
|
||||
// Update bytes processed
|
||||
bytesProcessed += nextIndex; |
||||
|
||||
// Revert status, as we only check the last ADR request for the channel mask KO
|
||||
status = 0x07; |
||||
|
||||
if( linkAdrParams.ChMaskCtrl == 6 ) |
||||
{ |
||||
// Enable all 125 kHz channels
|
||||
channelsMask[0] = 0xFFFF; |
||||
channelsMask[1] = 0xFFFF; |
||||
channelsMask[2] = 0xFFFF; |
||||
channelsMask[3] = 0xFFFF; |
||||
// Apply chMask to channels 64 to 71
|
||||
channelsMask[4] = linkAdrParams.ChMask; |
||||
} |
||||
else if( linkAdrParams.ChMaskCtrl == 7 ) |
||||
{ |
||||
// Disable all 125 kHz channels
|
||||
channelsMask[0] = 0x0000; |
||||
channelsMask[1] = 0x0000; |
||||
channelsMask[2] = 0x0000; |
||||
channelsMask[3] = 0x0000; |
||||
// Apply chMask to channels 64 to 71
|
||||
channelsMask[4] = linkAdrParams.ChMask; |
||||
} |
||||
else if( linkAdrParams.ChMaskCtrl == 5 ) |
||||
{ |
||||
// RFU
|
||||
status &= 0xFE; // Channel mask KO
|
||||
} |
||||
else |
||||
{ |
||||
channelsMask[linkAdrParams.ChMaskCtrl] = linkAdrParams.ChMask; |
||||
} |
||||
} |
||||
|
||||
// FCC 15.247 paragraph F mandates to hop on at least 2 125 kHz channels
|
||||
if( ( linkAdrParams.Datarate < DR_4 ) && ( RegionCommonCountChannels( channelsMask, 0, 4 ) < 2 ) ) |
||||
{ |
||||
status &= 0xFE; // Channel mask KO
|
||||
} |
||||
|
||||
// Get the minimum possible datarate
|
||||
getPhy.Attribute = PHY_MIN_TX_DR; |
||||
getPhy.UplinkDwellTime = linkAdrReq->UplinkDwellTime; |
||||
phyParam = RegionUS915GetPhyParam( &getPhy ); |
||||
|
||||
linkAdrVerifyParams.Status = status; |
||||
linkAdrVerifyParams.AdrEnabled = linkAdrReq->AdrEnabled; |
||||
linkAdrVerifyParams.Datarate = linkAdrParams.Datarate; |
||||
linkAdrVerifyParams.TxPower = linkAdrParams.TxPower; |
||||
linkAdrVerifyParams.NbRep = linkAdrParams.NbRep; |
||||
linkAdrVerifyParams.CurrentDatarate = linkAdrReq->CurrentDatarate; |
||||
linkAdrVerifyParams.CurrentTxPower = linkAdrReq->CurrentTxPower; |
||||
linkAdrVerifyParams.CurrentNbRep = linkAdrReq->CurrentNbRep; |
||||
linkAdrVerifyParams.NbChannels = US915_MAX_NB_CHANNELS; |
||||
linkAdrVerifyParams.ChannelsMask = channelsMask; |
||||
linkAdrVerifyParams.MinDatarate = ( int8_t )phyParam.Value; |
||||
linkAdrVerifyParams.MaxDatarate = US915_TX_MAX_DATARATE; |
||||
linkAdrVerifyParams.Channels = Channels; |
||||
linkAdrVerifyParams.MinTxPower = US915_MIN_TX_POWER; |
||||
linkAdrVerifyParams.MaxTxPower = US915_MAX_TX_POWER; |
||||
|
||||
// Verify the parameters and update, if necessary
|
||||
status = RegionCommonLinkAdrReqVerifyParams( &linkAdrVerifyParams, &linkAdrParams.Datarate, &linkAdrParams.TxPower, &linkAdrParams.NbRep ); |
||||
|
||||
// Update channelsMask if everything is correct
|
||||
if( status == 0x07 ) |
||||
{ |
||||
// Copy Mask
|
||||
RegionCommonChanMaskCopy( ChannelsMask, channelsMask, 6 ); |
||||
|
||||
ChannelsMaskRemaining[0] &= ChannelsMask[0]; |
||||
ChannelsMaskRemaining[1] &= ChannelsMask[1]; |
||||
ChannelsMaskRemaining[2] &= ChannelsMask[2]; |
||||
ChannelsMaskRemaining[3] &= ChannelsMask[3]; |
||||
ChannelsMaskRemaining[4] = ChannelsMask[4]; |
||||
ChannelsMaskRemaining[5] = ChannelsMask[5]; |
||||
} |
||||
|
||||
// Update status variables
|
||||
*drOut = linkAdrParams.Datarate; |
||||
*txPowOut = linkAdrParams.TxPower; |
||||
*nbRepOut = linkAdrParams.NbRep; |
||||
*nbBytesParsed = bytesProcessed; |
||||
|
||||
return status; |
||||
} |
||||
|
||||
uint8_t RegionUS915RxParamSetupReq( RxParamSetupReqParams_t* rxParamSetupReq ) |
||||
{ |
||||
uint8_t status = 0x07; |
||||
uint32_t freq = rxParamSetupReq->Frequency; |
||||
|
||||
// Verify radio frequency
|
||||
if( ( Radio.CheckRfFrequency( freq ) == false ) || |
||||
( freq < US915_FIRST_RX1_CHANNEL ) || |
||||
( freq > US915_LAST_RX1_CHANNEL ) || |
||||
( ( ( freq - ( uint32_t ) US915_FIRST_RX1_CHANNEL ) % ( uint32_t ) US915_STEPWIDTH_RX1_CHANNEL ) != 0 ) ) |
||||
{ |
||||
status &= 0xFE; // Channel frequency KO
|
||||
} |
||||
|
||||
// Verify datarate
|
||||
if( RegionCommonValueInRange( rxParamSetupReq->Datarate, US915_RX_MIN_DATARATE, US915_RX_MAX_DATARATE ) == false ) |
||||
{ |
||||
status &= 0xFD; // Datarate KO
|
||||
} |
||||
if( ( RegionCommonValueInRange( rxParamSetupReq->Datarate, DR_5, DR_7 ) == true ) || |
||||
( rxParamSetupReq->Datarate > DR_13 ) ) |
||||
{ |
||||
status &= 0xFD; // Datarate KO
|
||||
} |
||||
|
||||
// Verify datarate offset
|
||||
if( RegionCommonValueInRange( rxParamSetupReq->DrOffset, US915_MIN_RX1_DR_OFFSET, US915_MAX_RX1_DR_OFFSET ) == false ) |
||||
{ |
||||
status &= 0xFB; // Rx1DrOffset range KO
|
||||
} |
||||
|
||||
return status; |
||||
} |
||||
|
||||
uint8_t RegionUS915NewChannelReq( NewChannelReqParams_t* newChannelReq ) |
||||
{ |
||||
// Datarate and frequency KO
|
||||
return 0; |
||||
} |
||||
|
||||
int8_t RegionUS915TxParamSetupReq( TxParamSetupReqParams_t* txParamSetupReq ) |
||||
{ |
||||
return -1; |
||||
} |
||||
|
||||
uint8_t RegionUS915DlChannelReq( DlChannelReqParams_t* dlChannelReq ) |
||||
{ |
||||
return 0; |
||||
} |
||||
|
||||
int8_t RegionUS915AlternateDr( AlternateDrParams_t* alternateDr ) |
||||
{ |
||||
int8_t datarate = 0; |
||||
|
||||
// Re-enable 500 kHz default channels
|
||||
ChannelsMask[4] = 0x00FF; |
||||
|
||||
if( ( alternateDr->NbTrials & 0x01 ) == 0x01 ) |
||||
{ |
||||
datarate = DR_4; |
||||
} |
||||
else |
||||
{ |
||||
datarate = DR_0; |
||||
} |
||||
return datarate; |
||||
} |
||||
|
||||
void RegionUS915CalcBackOff( CalcBackOffParams_t* calcBackOff ) |
||||
{ |
||||
RegionCommonCalcBackOffParams_t calcBackOffParams; |
||||
|
||||
calcBackOffParams.Channels = Channels; |
||||
calcBackOffParams.Bands = Bands; |
||||
calcBackOffParams.LastTxIsJoinRequest = calcBackOff->LastTxIsJoinRequest; |
||||
calcBackOffParams.Joined = calcBackOff->Joined; |
||||
calcBackOffParams.DutyCycleEnabled = calcBackOff->DutyCycleEnabled; |
||||
calcBackOffParams.Channel = calcBackOff->Channel; |
||||
calcBackOffParams.ElapsedTime = calcBackOff->ElapsedTime; |
||||
calcBackOffParams.TxTimeOnAir = calcBackOff->TxTimeOnAir; |
||||
|
||||
RegionCommonCalcBackOff( &calcBackOffParams ); |
||||
} |
||||
|
||||
bool RegionUS915NextChannel( NextChanParams_t* nextChanParams, uint8_t* channel, TimerTime_t* time, TimerTime_t* aggregatedTimeOff ) |
||||
{ |
||||
uint8_t nbEnabledChannels = 0; |
||||
uint8_t delayTx = 0; |
||||
uint8_t enabledChannels[US915_MAX_NB_CHANNELS] = { 0 }; |
||||
TimerTime_t nextTxDelay = 0; |
||||
|
||||
// Count 125kHz channels
|
||||
if( RegionCommonCountChannels( ChannelsMaskRemaining, 0, 4 ) == 0 ) |
||||
{ // Reactivate default channels
|
||||
RegionCommonChanMaskCopy( ChannelsMaskRemaining, ChannelsMask, 4 ); |
||||
} |
||||
// Check other channels
|
||||
if( nextChanParams->Datarate >= DR_4 ) |
||||
{ |
||||
if( ( ChannelsMaskRemaining[4] & 0x00FF ) == 0 ) |
||||
{ |
||||
ChannelsMaskRemaining[4] = ChannelsMask[4]; |
||||
} |
||||
} |
||||
|
||||
if( nextChanParams->AggrTimeOff <= TimerGetElapsedTime( nextChanParams->LastAggrTx ) ) |
||||
{ |
||||
// Reset Aggregated time off
|
||||
*aggregatedTimeOff = 0; |
||||
|
||||
// Update bands Time OFF
|
||||
nextTxDelay = RegionCommonUpdateBandTimeOff( nextChanParams->Joined, nextChanParams->DutyCycleEnabled, Bands, US915_MAX_NB_BANDS ); |
||||
|
||||
// Search how many channels are enabled
|
||||
nbEnabledChannels = CountNbOfEnabledChannels( nextChanParams->Datarate, |
||||
ChannelsMaskRemaining, Channels, |
||||
Bands, enabledChannels, &delayTx ); |
||||
} |
||||
else |
||||
{ |
||||
delayTx++; |
||||
nextTxDelay = nextChanParams->AggrTimeOff - TimerGetElapsedTime( nextChanParams->LastAggrTx ); |
||||
} |
||||
|
||||
if( nbEnabledChannels > 0 ) |
||||
{ |
||||
// We found a valid channel
|
||||
*channel = enabledChannels[randr( 0, nbEnabledChannels - 1 )]; |
||||
// Disable the channel in the mask
|
||||
RegionCommonChanDisable( ChannelsMaskRemaining, *channel, US915_MAX_NB_CHANNELS - 8 ); |
||||
|
||||
*time = 0; |
||||
return true; |
||||
} |
||||
else |
||||
{ |
||||
if( delayTx > 0 ) |
||||
{ |
||||
// Delay transmission due to AggregatedTimeOff or to a band time off
|
||||
*time = nextTxDelay; |
||||
return true; |
||||
} |
||||
// Datarate not supported by any channel
|
||||
*time = 0; |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
LoRaMacStatus_t RegionUS915ChannelAdd( ChannelAddParams_t* channelAdd ) |
||||
{ |
||||
return LORAMAC_STATUS_PARAMETER_INVALID; |
||||
} |
||||
|
||||
bool RegionUS915ChannelsRemove( ChannelRemoveParams_t* channelRemove ) |
||||
{ |
||||
return LORAMAC_STATUS_PARAMETER_INVALID; |
||||
} |
||||
|
||||
void RegionUS915SetContinuousWave( ContinuousWaveParams_t* continuousWave ) |
||||
{ |
||||
int8_t txPowerLimited = LimitTxPower( continuousWave->TxPower, Bands[Channels[continuousWave->Channel].Band].TxMaxPower, continuousWave->Datarate, ChannelsMask ); |
||||
int8_t phyTxPower = 0; |
||||
uint32_t frequency = Channels[continuousWave->Channel].Frequency; |
||||
|
||||
// Calculate physical TX power
|
||||
phyTxPower = RegionCommonComputeTxPower( txPowerLimited, US915_DEFAULT_MAX_ERP, 0 ); |
||||
|
||||
Radio.SetTxContinuousWave( frequency, phyTxPower, continuousWave->Timeout ); |
||||
} |
||||
|
||||
uint8_t RegionUS915ApplyDrOffset( uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset ) |
||||
{ |
||||
int8_t datarate = DatarateOffsetsUS915[dr][drOffset]; |
||||
|
||||
if( datarate < 0 ) |
||||
{ |
||||
datarate = DR_0; |
||||
} |
||||
return datarate; |
||||
} |
@ -0,0 +1,448 @@ |
||||
/*!
|
||||
* \file RegionUS915.h |
||||
* |
||||
* \brief Region definition for US915 |
||||
* |
||||
* \copyright Revised BSD License, see section \ref LICENSE. |
||||
* |
||||
* \code |
||||
* ______ _ |
||||
* / _____) _ | | |
||||
* ( (____ _____ ____ _| |_ _____ ____| |__ |
||||
* \____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
* _____) ) ____| | | || |_| ____( (___| | | | |
||||
* (______/|_____)_|_|_| \__)_____)\____)_| |_| |
||||
* (C)2013 Semtech |
||||
* |
||||
* ___ _____ _ ___ _ _____ ___ ___ ___ ___ |
||||
* / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| |
||||
* \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| |
||||
* |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| |
||||
* embedded.connectivity.solutions=============== |
||||
* |
||||
* \endcode |
||||
* |
||||
* \author Miguel Luis ( Semtech ) |
||||
* |
||||
* \author Gregory Cristian ( Semtech ) |
||||
* |
||||
* \author Daniel Jaeckle ( STACKFORCE ) |
||||
* |
||||
* \defgroup REGIONUS915 Region US915 |
||||
* Implementation according to LoRaWAN Specification v1.0.2. |
||||
* \{ |
||||
*/ |
||||
#ifndef __REGION_US915_H__ |
||||
#define __REGION_US915_H__ |
||||
|
||||
/*!
|
||||
* LoRaMac maximum number of channels |
||||
*/ |
||||
#define US915_MAX_NB_CHANNELS 72 |
||||
|
||||
/*!
|
||||
* Minimal datarate that can be used by the node |
||||
*/ |
||||
#define US915_TX_MIN_DATARATE DR_0 |
||||
|
||||
/*!
|
||||
* Maximal datarate that can be used by the node |
||||
*/ |
||||
#define US915_TX_MAX_DATARATE DR_4 |
||||
|
||||
/*!
|
||||
* Minimal datarate that can be used by the node |
||||
*/ |
||||
#define US915_RX_MIN_DATARATE DR_8 |
||||
|
||||
/*!
|
||||
* Maximal datarate that can be used by the node |
||||
*/ |
||||
#define US915_RX_MAX_DATARATE DR_13 |
||||
|
||||
/*!
|
||||
* Default datarate used by the node |
||||
*/ |
||||
#define US915_DEFAULT_DATARATE DR_0 |
||||
|
||||
/*!
|
||||
* Minimal Rx1 receive datarate offset |
||||
*/ |
||||
#define US915_MIN_RX1_DR_OFFSET 0 |
||||
|
||||
/*!
|
||||
* Maximal Rx1 receive datarate offset |
||||
*/ |
||||
#define US915_MAX_RX1_DR_OFFSET 3 |
||||
|
||||
/*!
|
||||
* Default Rx1 receive datarate offset |
||||
*/ |
||||
#define US915_DEFAULT_RX1_DR_OFFSET 0 |
||||
|
||||
/*!
|
||||
* Minimal Tx output power that can be used by the node |
||||
*/ |
||||
#define US915_MIN_TX_POWER TX_POWER_10 |
||||
|
||||
/*!
|
||||
* Maximal Tx output power that can be used by the node |
||||
*/ |
||||
#define US915_MAX_TX_POWER TX_POWER_0 |
||||
|
||||
/*!
|
||||
* Default Tx output power used by the node |
||||
*/ |
||||
#define US915_DEFAULT_TX_POWER TX_POWER_0 |
||||
|
||||
/*!
|
||||
* Default Max ERP |
||||
*/ |
||||
#define US915_DEFAULT_MAX_ERP 30.0f |
||||
|
||||
/*!
|
||||
* ADR Ack limit |
||||
*/ |
||||
#define US915_ADR_ACK_LIMIT 64 |
||||
|
||||
/*!
|
||||
* ADR Ack delay |
||||
*/ |
||||
#define US915_ADR_ACK_DELAY 32 |
||||
|
||||
/*!
|
||||
* Enabled or disabled the duty cycle |
||||
*/ |
||||
#define US915_DUTY_CYCLE_ENABLED 0 |
||||
|
||||
/*!
|
||||
* Maximum RX window duration |
||||
*/ |
||||
#define US915_MAX_RX_WINDOW 3000 |
||||
|
||||
/*!
|
||||
* Receive delay 1 |
||||
*/ |
||||
#define US915_RECEIVE_DELAY1 1000 |
||||
|
||||
/*!
|
||||
* Receive delay 2 |
||||
*/ |
||||
#define US915_RECEIVE_DELAY2 2000 |
||||
|
||||
/*!
|
||||
* Join accept delay 1 |
||||
*/ |
||||
#define US915_JOIN_ACCEPT_DELAY1 5000 |
||||
|
||||
/*!
|
||||
* Join accept delay 2 |
||||
*/ |
||||
#define US915_JOIN_ACCEPT_DELAY2 6000 |
||||
|
||||
/*!
|
||||
* Maximum frame counter gap |
||||
*/ |
||||
#define US915_MAX_FCNT_GAP 16384 |
||||
|
||||
/*!
|
||||
* Ack timeout |
||||
*/ |
||||
#define US915_ACKTIMEOUT 2000 |
||||
|
||||
/*!
|
||||
* Random ack timeout limits |
||||
*/ |
||||
#define US915_ACK_TIMEOUT_RND 1000 |
||||
|
||||
/*!
|
||||
* Second reception window channel frequency definition. |
||||
*/ |
||||
#define US915_RX_WND_2_FREQ 923300000 |
||||
|
||||
/*!
|
||||
* Second reception window channel datarate definition. |
||||
*/ |
||||
#define US915_RX_WND_2_DR DR_8 |
||||
|
||||
/*!
|
||||
* LoRaMac maximum number of bands |
||||
*/ |
||||
#define US915_MAX_NB_BANDS 1 |
||||
|
||||
/*!
|
||||
* Band 0 definition |
||||
* { DutyCycle, TxMaxPower, LastTxDoneTime, TimeOff } |
||||
*/ |
||||
#define US915_BAND0 { 1, US915_MAX_TX_POWER, 0, 0 } // 100.0 %
|
||||
|
||||
/*!
|
||||
* Defines the first channel for RX window 1 for US band |
||||
*/ |
||||
#define US915_FIRST_RX1_CHANNEL ( (uint32_t) 923300000 ) |
||||
|
||||
/*!
|
||||
* Defines the last channel for RX window 1 for US band |
||||
*/ |
||||
#define US915_LAST_RX1_CHANNEL ( (uint32_t) 927500000 ) |
||||
|
||||
/*!
|
||||
* Defines the step width of the channels for RX window 1 |
||||
*/ |
||||
#define US915_STEPWIDTH_RX1_CHANNEL ( (uint32_t) 600000 ) |
||||
|
||||
/*!
|
||||
* Data rates table definition |
||||
*/ |
||||
static const uint8_t DataratesUS915[] = { 10, 9, 8, 7, 8, 0, 0, 0, 12, 11, 10, 9, 8, 7, 0, 0 }; |
||||
|
||||
/*!
|
||||
* Bandwidths table definition in Hz |
||||
*/ |
||||
static const uint32_t BandwidthsUS915[] = { 125000, 125000, 125000, 125000, 500000, 0, 0, 0, 500000, 500000, 500000, 500000, 500000, 500000, 0, 0 }; |
||||
|
||||
/*!
|
||||
* Up/Down link data rates offset definition |
||||
*/ |
||||
static const int8_t DatarateOffsetsUS915[5][4] = |
||||
{ |
||||
{ DR_10, DR_9 , DR_8 , DR_8 }, // DR_0
|
||||
{ DR_11, DR_10, DR_9 , DR_8 }, // DR_1
|
||||
{ DR_12, DR_11, DR_10, DR_9 }, // DR_2
|
||||
{ DR_13, DR_12, DR_11, DR_10 }, // DR_3
|
||||
{ DR_13, DR_13, DR_12, DR_11 }, // DR_4
|
||||
}; |
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Cannot operate with repeater. |
||||
*/ |
||||
static const uint8_t MaxPayloadOfDatarateUS915[] = { 11, 53, 125, 242, 242, 0, 0, 0, 53, 129, 242, 242, 242, 242, 0, 0 }; |
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Can operate with repeater. |
||||
*/ |
||||
static const uint8_t MaxPayloadOfDatarateRepeaterUS915[] = { 11, 53, 125, 242, 242, 0, 0, 0, 33, 109, 222, 222, 222, 222, 0, 0 }; |
||||
|
||||
/*!
|
||||
* \brief The function gets a value of a specific phy attribute. |
||||
* |
||||
* \param [IN] getPhy Pointer to the function parameters. |
||||
* |
||||
* \retval Returns a structure containing the PHY parameter. |
||||
*/ |
||||
PhyParam_t RegionUS915GetPhyParam( GetPhyParams_t* getPhy ); |
||||
|
||||
/*!
|
||||
* \brief Updates the last TX done parameters of the current channel. |
||||
* |
||||
* \param [IN] txDone Pointer to the function parameters. |
||||
*/ |
||||
void RegionUS915SetBandTxDone( SetBandTxDoneParams_t* txDone ); |
||||
|
||||
/*!
|
||||
* \brief Initializes the channels masks and the channels. |
||||
* |
||||
* \param [IN] type Sets the initialization type. |
||||
*/ |
||||
void RegionUS915InitDefaults( InitType_t type ); |
||||
|
||||
/*!
|
||||
* \brief Verifies a parameter. |
||||
* |
||||
* \param [IN] verify Pointer to the function parameters. |
||||
* |
||||
* \param [IN] type Sets the initialization type. |
||||
* |
||||
* \retval Returns true, if the parameter is valid. |
||||
*/ |
||||
bool RegionUS915Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute ); |
||||
|
||||
/*!
|
||||
* \brief The function parses the input buffer and sets up the channels of the |
||||
* CF list. |
||||
* |
||||
* \param [IN] applyCFList Pointer to the function parameters. |
||||
*/ |
||||
void RegionUS915ApplyCFList( ApplyCFListParams_t* applyCFList ); |
||||
|
||||
/*!
|
||||
* \brief Sets a channels mask. |
||||
* |
||||
* \param [IN] chanMaskSet Pointer to the function parameters. |
||||
* |
||||
* \retval Returns true, if the channels mask could be set. |
||||
*/ |
||||
bool RegionUS915ChanMaskSet( ChanMaskSetParams_t* chanMaskSet ); |
||||
|
||||
/*!
|
||||
* \brief Calculates the next datarate to set, when ADR is on or off. |
||||
* |
||||
* \param [IN] adrNext Pointer to the function parameters. |
||||
* |
||||
* \param [OUT] drOut The calculated datarate for the next TX. |
||||
* |
||||
* \param [OUT] txPowOut The TX power for the next TX. |
||||
* |
||||
* \param [OUT] adrAckCounter The calculated ADR acknowledgement counter. |
||||
* |
||||
* \retval Returns true, if an ADR request should be performed. |
||||
*/ |
||||
bool RegionUS915AdrNext( AdrNextParams_t* adrNext, int8_t* drOut, int8_t* txPowOut, uint32_t* adrAckCounter ); |
||||
|
||||
/*!
|
||||
* Computes the Rx window timeout and offset. |
||||
* |
||||
* \param [IN] datarate Rx window datarate index to be used |
||||
* |
||||
* \param [IN] minRxSymbols Minimum required number of symbols to detect an Rx frame. |
||||
* |
||||
* \param [IN] rxError System maximum timing error of the receiver. In milliseconds |
||||
* The receiver will turn on in a [-rxError : +rxError] ms |
||||
* interval around RxOffset |
||||
* |
||||
* \param [OUT]rxConfigParams Returns updated WindowTimeout and WindowOffset fields. |
||||
*/ |
||||
void RegionUS915ComputeRxWindowParameters( int8_t datarate, uint8_t minRxSymbols, uint32_t rxError, RxConfigParams_t *rxConfigParams ); |
||||
|
||||
/*!
|
||||
* \brief Configuration of the RX windows. |
||||
* |
||||
* \param [IN] rxConfig Pointer to the function parameters. |
||||
* |
||||
* \param [OUT] datarate The datarate index which was set. |
||||
* |
||||
* \retval Returns true, if the configuration was applied successfully. |
||||
*/ |
||||
bool RegionUS915RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate ); |
||||
|
||||
/*!
|
||||
* \brief TX configuration. |
||||
* |
||||
* \param [IN] txConfig Pointer to the function parameters. |
||||
* |
||||
* \param [OUT] txPower The tx power index which was set. |
||||
* |
||||
* \param [OUT] txTimeOnAir The time-on-air of the frame. |
||||
* |
||||
* \retval Returns true, if the configuration was applied successfully. |
||||
*/ |
||||
bool RegionUS915TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime_t* txTimeOnAir ); |
||||
|
||||
/*!
|
||||
* \brief The function processes a Link ADR Request. |
||||
* |
||||
* \param [IN] linkAdrReq Pointer to the function parameters. |
||||
* |
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification. |
||||
*/ |
||||
uint8_t RegionUS915LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, int8_t* txPowOut, uint8_t* nbRepOut, uint8_t* nbBytesParsed ); |
||||
|
||||
/*!
|
||||
* \brief The function processes a RX Parameter Setup Request. |
||||
* |
||||
* \param [IN] rxParamSetupReq Pointer to the function parameters. |
||||
* |
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification. |
||||
*/ |
||||
uint8_t RegionUS915RxParamSetupReq( RxParamSetupReqParams_t* rxParamSetupReq ); |
||||
|
||||
/*!
|
||||
* \brief The function processes a Channel Request. |
||||
* |
||||
* \param [IN] newChannelReq Pointer to the function parameters. |
||||
* |
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification. |
||||
*/ |
||||
uint8_t RegionUS915NewChannelReq( NewChannelReqParams_t* newChannelReq ); |
||||
|
||||
/*!
|
||||
* \brief The function processes a TX ParamSetup Request. |
||||
* |
||||
* \param [IN] txParamSetupReq Pointer to the function parameters. |
||||
* |
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification. |
||||
* Returns -1, if the functionality is not implemented. In this case, the end node |
||||
* shall not process the command. |
||||
*/ |
||||
int8_t RegionUS915TxParamSetupReq( TxParamSetupReqParams_t* txParamSetupReq ); |
||||
|
||||
/*!
|
||||
* \brief The function processes a DlChannel Request. |
||||
* |
||||
* \param [IN] dlChannelReq Pointer to the function parameters. |
||||
* |
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification. |
||||
*/ |
||||
uint8_t RegionUS915DlChannelReq( DlChannelReqParams_t* dlChannelReq ); |
||||
|
||||
/*!
|
||||
* \brief Alternates the datarate of the channel for the join request. |
||||
* |
||||
* \param [IN] alternateDr Pointer to the function parameters. |
||||
* |
||||
* \retval Datarate to apply. |
||||
*/ |
||||
int8_t RegionUS915AlternateDr( AlternateDrParams_t* alternateDr ); |
||||
|
||||
/*!
|
||||
* \brief Calculates the back-off time. |
||||
* |
||||
* \param [IN] calcBackOff Pointer to the function parameters. |
||||
*/ |
||||
void RegionUS915CalcBackOff( CalcBackOffParams_t* calcBackOff ); |
||||
|
||||
/*!
|
||||
* \brief Searches and set the next random available channel |
||||
* |
||||
* \param [OUT] channel Next channel to use for TX. |
||||
* |
||||
* \param [OUT] time Time to wait for the next transmission according to the duty |
||||
* cycle. |
||||
* |
||||
* \param [OUT] aggregatedTimeOff Updates the aggregated time off. |
||||
* |
||||
* \retval Function status [1: OK, 0: Unable to find a channel on the current datarate] |
||||
*/ |
||||
bool RegionUS915NextChannel( NextChanParams_t* nextChanParams, uint8_t* channel, TimerTime_t* time, TimerTime_t* aggregatedTimeOff ); |
||||
|
||||
/*!
|
||||
* \brief Adds a channel. |
||||
* |
||||
* \param [IN] channelAdd Pointer to the function parameters. |
||||
* |
||||
* \retval Status of the operation. |
||||
*/ |
||||
LoRaMacStatus_t RegionUS915ChannelAdd( ChannelAddParams_t* channelAdd ); |
||||
|
||||
/*!
|
||||
* \brief Removes a channel. |
||||
* |
||||
* \param [IN] channelRemove Pointer to the function parameters. |
||||
* |
||||
* \retval Returns true, if the channel was removed successfully. |
||||
*/ |
||||
bool RegionUS915ChannelsRemove( ChannelRemoveParams_t* channelRemove ); |
||||
|
||||
/*!
|
||||
* \brief Sets the radio into continuous wave mode. |
||||
* |
||||
* \param [IN] continuousWave Pointer to the function parameters. |
||||
*/ |
||||
void RegionUS915SetContinuousWave( ContinuousWaveParams_t* continuousWave ); |
||||
|
||||
/*!
|
||||
* \brief Computes new datarate according to the given offset |
||||
* |
||||
* \param [IN] downlinkDwellTime Downlink dwell time configuration. 0: No limit, 1: 400ms |
||||
* |
||||
* \param [IN] dr Current datarate |
||||
* |
||||
* \param [IN] drOffset Offset to be applied |
||||
* |
||||
* \retval newDr Computed datarate. |
||||
*/ |
||||
uint8_t RegionUS915ApplyDrOffset( uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset ); |
||||
|
||||
/*! \} defgroup REGIONUS915 */ |
||||
|
||||
#endif // __REGION_US915_H__
|
@ -0,0 +1,86 @@ |
||||
/*
|
||||
/ _____) _ | | |
||||
( (____ _____ ____ _| |_ _____ ____| |__ |
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | | |
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_| |
||||
(C)2013 Semtech |
||||
|
||||
Description: Timer objects and scheduling management |
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project |
||||
|
||||
Maintainer: Miguel Luis and Gregory Cristian |
||||
*/ |
||||
/******************************************************************************
|
||||
* @file timer.h |
||||
* @author MCD Application Team |
||||
* @version V1.1.2 |
||||
* @date 08-September-2017 |
||||
* @brief wrapper to timer server |
||||
****************************************************************************** |
||||
* @attention |
||||
* |
||||
* <h2><center>© Copyright (c) 2017 STMicroelectronics International N.V.
|
||||
* All rights reserved.</center></h2> |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted, provided that the following conditions are met: |
||||
* |
||||
* 1. Redistribution of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer. |
||||
* 2. 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. |
||||
* 3. Neither the name of STMicroelectronics nor the names of other
|
||||
* contributors to this software may be used to endorse or promote products
|
||||
* derived from this software without specific written permission. |
||||
* 4. This software, including modifications and/or derivative works of this
|
||||
* software, must execute solely and exclusively on microcontroller or |
||||
* microprocessor devices manufactured by or for STMicroelectronics. |
||||
* 5. Redistribution and use of this software other than as permitted under
|
||||
* this license is void and will automatically terminate your rights under
|
||||
* this license.
|
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
* PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY |
||||
* RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT
|
||||
* SHALL STMICROELECTRONICS OR CONTRIBUTORS 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. |
||||
* |
||||
****************************************************************************** |
||||
*/ |
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/ |
||||
#ifndef __TIMER_H__ |
||||
#define __TIMER_H__ |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
/* Includes ------------------------------------------------------------------*/ |
||||
|
||||
#include "timeServer.h" |
||||
|
||||
/* Exported types ------------------------------------------------------------*/ |
||||
|
||||
/*!
|
||||
* \brief Timer object description |
||||
*/ |
||||
|
||||
|
||||
#ifdef __cplusplus |
||||
} |
||||
#endif |
||||
|
||||
#endif /* __TIMER_H__*/ |
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
@ -0,0 +1,350 @@ |
||||
/*
|
||||
/ _____) _ | | |
||||
( (____ _____ ____ _| |_ _____ ____| |__ |
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | | |
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_| |
||||
(C)2013 Semtech |
||||
|
||||
Description: Generic radio driver definition |
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project |
||||
|
||||
Maintainer: Miguel Luis and Gregory Cristian |
||||
*/ |
||||
#ifndef __RADIO_H__ |
||||
#define __RADIO_H__ |
||||
|
||||
/*!
|
||||
* Radio driver supported modems |
||||
*/ |
||||
typedef enum |
||||
{ |
||||
MODEM_FSK = 0, |
||||
MODEM_LORA, |
||||
}RadioModems_t; |
||||
|
||||
/*!
|
||||
* Radio driver internal state machine states definition |
||||
*/ |
||||
typedef enum |
||||
{ |
||||
RF_IDLE = 0, //!< The radio is idle
|
||||
RF_RX_RUNNING, //!< The radio is in reception state
|
||||
RF_TX_RUNNING, //!< The radio is in transmission state
|
||||
RF_CAD, //!< The radio is doing channel activity detection
|
||||
}RadioState_t; |
||||
|
||||
/*!
|
||||
* \brief Radio driver callback functions |
||||
*/ |
||||
typedef struct |
||||
{ |
||||
/*!
|
||||
* \brief Tx Done callback prototype. |
||||
*/ |
||||
void ( *TxDone )( void ); |
||||
/*!
|
||||
* \brief Tx Timeout callback prototype. |
||||
*/ |
||||
void ( *TxTimeout )( void ); |
||||
/*!
|
||||
* \brief Rx Done callback prototype. |
||||
* |
||||
* \param [IN] payload Received buffer pointer |
||||
* \param [IN] size Received buffer size |
||||
* \param [IN] rssi RSSI value computed while receiving the frame [dBm] |
||||
* \param [IN] snr Raw SNR value given by the radio hardware |
||||
* FSK : N/A ( set to 0 ) |
||||
* LoRa: SNR value in dB |
||||
*/ |
||||
void ( *RxDone )( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ); |
||||
/*!
|
||||
* \brief Rx Timeout callback prototype. |
||||
*/ |
||||
void ( *RxTimeout )( void ); |
||||
/*!
|
||||
* \brief Rx Error callback prototype. |
||||
*/ |
||||
void ( *RxError )( void ); |
||||
/*!
|
||||
* \brief FHSS Change Channel callback prototype. |
||||
* |
||||
* \param [IN] currentChannel Index number of the current channel |
||||
*/ |
||||
void ( *FhssChangeChannel )( uint8_t currentChannel ); |
||||
|
||||
/*!
|
||||
* \brief CAD Done callback prototype. |
||||
* |
||||
* \param [IN] channelDetected Channel Activity detected during the CAD |
||||
*/ |
||||
void ( *CadDone ) ( bool channelActivityDetected ); |
||||
}RadioEvents_t; |
||||
|
||||
/*!
|
||||
* \brief Radio driver definition |
||||
*/ |
||||
struct Radio_s |
||||
{ |
||||
/*!
|
||||
* \brief Initializes the io |
||||
*/ |
||||
void ( *IoInit )( void ); |
||||
/*!
|
||||
* \brief Deinitializes the io |
||||
*/ |
||||
void ( *IoDeInit )( void ); |
||||
/*!
|
||||
* \brief Initializes the radio |
||||
* |
||||
* \param [IN] events Structure containing the driver callback functions |
||||
* \param [OUT] returns radioWakeUpTime |
||||
*/ |
||||
uint32_t ( *Init )( RadioEvents_t *events ); |
||||
/*!
|
||||
* Return current radio status |
||||
* |
||||
* \param status Radio status.[RF_IDLE, RF_RX_RUNNING, RF_TX_RUNNING] |
||||
*/ |
||||
RadioState_t ( *GetStatus )( void ); |
||||
/*!
|
||||
* \brief Configures the radio with the given modem |
||||
* |
||||
* \param [IN] modem Modem to be used [0: FSK, 1: LoRa] |
||||
*/ |
||||
void ( *SetModem )( RadioModems_t modem ); |
||||
/*!
|
||||
* \brief Sets the channel frequency |
||||
* |
||||
* \param [IN] freq Channel RF frequency |
||||
*/ |
||||
void ( *SetChannel )( uint32_t freq ); |
||||
/*!
|
||||
* \brief Checks if the channel is free for the given time |
||||
* |
||||
* \param [IN] modem Radio modem to be used [0: FSK, 1: LoRa] |
||||
* \param [IN] freq Channel RF frequency |
||||
* \param [IN] rssiThresh RSSI threshold |
||||
* \param [IN] maxCarrierSenseTime Max time while the RSSI is measured |
||||
* |
||||
* \retval isFree [true: Channel is free, false: Channel is not free] |
||||
*/ |
||||
bool ( *IsChannelFree )( RadioModems_t modem, uint32_t freq, int16_t rssiThresh, uint32_t maxCarrierSenseTime ); |
||||
/*!
|
||||
* \brief Generates a 32 bits random value based on the RSSI readings |
||||
* |
||||
* \remark This function sets the radio in LoRa modem mode and disables |
||||
* all interrupts. |
||||
* After calling this function either Radio.SetRxConfig or |
||||
* Radio.SetTxConfig functions must be called. |
||||
* |
||||
* \retval randomValue 32 bits random value |
||||
*/ |
||||
uint32_t ( *Random )( void ); |
||||
/*!
|
||||
* \brief Sets the reception parameters |
||||
* |
||||
* \param [IN] modem Radio modem to be used [0: FSK, 1: LoRa] |
||||
* \param [IN] bandwidth Sets the bandwidth |
||||
* FSK : >= 2600 and <= 250000 Hz |
||||
* LoRa: [0: 125 kHz, 1: 250 kHz, |
||||
* 2: 500 kHz, 3: Reserved] |
||||
* \param [IN] datarate Sets the Datarate |
||||
* FSK : 600..300000 bits/s |
||||
* LoRa: [6: 64, 7: 128, 8: 256, 9: 512, |
||||
* 10: 1024, 11: 2048, 12: 4096 chips] |
||||
* \param [IN] coderate Sets the coding rate (LoRa only) |
||||
* FSK : N/A ( set to 0 ) |
||||
* LoRa: [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8] |
||||
* \param [IN] bandwidthAfc Sets the AFC Bandwidth (FSK only) |
||||
* FSK : >= 2600 and <= 250000 Hz |
||||
* LoRa: N/A ( set to 0 ) |
||||
* \param [IN] preambleLen Sets the Preamble length |
||||
* FSK : Number of bytes |
||||
* LoRa: Length in symbols (the hardware adds 4 more symbols) |
||||
* \param [IN] symbTimeout Sets the RxSingle timeout value |
||||
* FSK : timeout in number of bytes |
||||
* LoRa: timeout in symbols |
||||
* \param [IN] fixLen Fixed length packets [0: variable, 1: fixed] |
||||
* \param [IN] payloadLen Sets payload length when fixed length is used |
||||
* \param [IN] crcOn Enables/Disables the CRC [0: OFF, 1: ON] |
||||
* \param [IN] freqHopOn Enables disables the intra-packet frequency hopping |
||||
* FSK : N/A ( set to 0 ) |
||||
* LoRa: [0: OFF, 1: ON] |
||||
* \param [IN] hopPeriod Number of symbols between each hop |
||||
* FSK : N/A ( set to 0 ) |
||||
* LoRa: Number of symbols |
||||
* \param [IN] iqInverted Inverts IQ signals (LoRa only) |
||||
* FSK : N/A ( set to 0 ) |
||||
* LoRa: [0: not inverted, 1: inverted] |
||||
* \param [IN] rxContinuous Sets the reception in continuous mode |
||||
* [false: single mode, true: continuous mode] |
||||
*/ |
||||
void ( *SetRxConfig )( RadioModems_t modem, uint32_t bandwidth, |
||||
uint32_t datarate, uint8_t coderate, |
||||
uint32_t bandwidthAfc, uint16_t preambleLen, |
||||
uint16_t symbTimeout, bool fixLen, |
||||
uint8_t payloadLen, |
||||
bool crcOn, bool freqHopOn, uint8_t hopPeriod, |
||||
bool iqInverted, bool rxContinuous ); |
||||
/*!
|
||||
* \brief Sets the transmission parameters |
||||
* |
||||
* \param [IN] modem Radio modem to be used [0: FSK, 1: LoRa] |
||||
* \param [IN] power Sets the output power [dBm] |
||||
* \param [IN] fdev Sets the frequency deviation (FSK only) |
||||
* FSK : [Hz] |
||||
* LoRa: 0 |
||||
* \param [IN] bandwidth Sets the bandwidth (LoRa only) |
||||
* FSK : 0 |
||||
* LoRa: [0: 125 kHz, 1: 250 kHz, |
||||
* 2: 500 kHz, 3: Reserved] |
||||
* \param [IN] datarate Sets the Datarate |
||||
* FSK : 600..300000 bits/s |
||||
* LoRa: [6: 64, 7: 128, 8: 256, 9: 512, |
||||
* 10: 1024, 11: 2048, 12: 4096 chips] |
||||
* \param [IN] coderate Sets the coding rate (LoRa only) |
||||
* FSK : N/A ( set to 0 ) |
||||
* LoRa: [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8] |
||||
* \param [IN] preambleLen Sets the preamble length |
||||
* FSK : Number of bytes |
||||
* LoRa: Length in symbols (the hardware adds 4 more symbols) |
||||
* \param [IN] fixLen Fixed length packets [0: variable, 1: fixed] |
||||
* \param [IN] crcOn Enables disables the CRC [0: OFF, 1: ON] |
||||
* \param [IN] freqHopOn Enables disables the intra-packet frequency hopping |
||||
* FSK : N/A ( set to 0 ) |
||||
* LoRa: [0: OFF, 1: ON] |
||||
* \param [IN] hopPeriod Number of symbols between each hop |
||||
* FSK : N/A ( set to 0 ) |
||||
* LoRa: Number of symbols |
||||
* \param [IN] iqInverted Inverts IQ signals (LoRa only) |
||||
* FSK : N/A ( set to 0 ) |
||||
* LoRa: [0: not inverted, 1: inverted] |
||||
* \param [IN] timeout Transmission timeout [ms] |
||||
*/ |
||||
void ( *SetTxConfig )( RadioModems_t modem, int8_t power, uint32_t fdev, |
||||
uint32_t bandwidth, uint32_t datarate, |
||||
uint8_t coderate, uint16_t preambleLen, |
||||
bool fixLen, bool crcOn, bool freqHopOn, |
||||
uint8_t hopPeriod, bool iqInverted, uint32_t timeout ); |
||||
/*!
|
||||
* \brief Checks if the given RF frequency is supported by the hardware |
||||
* |
||||
* \param [IN] frequency RF frequency to be checked |
||||
* \retval isSupported [true: supported, false: unsupported] |
||||
*/ |
||||
bool ( *CheckRfFrequency )( uint32_t frequency ); |
||||
/*!
|
||||
* \brief Computes the packet time on air in ms for the given payload |
||||
* |
||||
* \Remark Can only be called once SetRxConfig or SetTxConfig have been called |
||||
* |
||||
* \param [IN] modem Radio modem to be used [0: FSK, 1: LoRa] |
||||
* \param [IN] pktLen Packet payload length |
||||
* |
||||
* \retval airTime Computed airTime (ms) for the given packet payload length |
||||
*/ |
||||
uint32_t ( *TimeOnAir )( RadioModems_t modem, uint8_t pktLen ); |
||||
/*!
|
||||
* \brief Sends the buffer of size. Prepares the packet to be sent and sets |
||||
* the radio in transmission |
||||
* |
||||
* \param [IN]: buffer Buffer pointer |
||||
* \param [IN]: size Buffer size |
||||
*/ |
||||
void ( *Send )( uint8_t *buffer, uint8_t size ); |
||||
/*!
|
||||
* \brief Sets the radio in sleep mode |
||||
*/ |
||||
void ( *Sleep )( void ); |
||||
/*!
|
||||
* \brief Sets the radio in standby mode |
||||
*/ |
||||
void ( *Standby )( void ); |
||||
/*!
|
||||
* \brief Sets the radio in reception mode for the given time |
||||
* \param [IN] timeout Reception timeout [ms] |
||||
* [0: continuous, others timeout] |
||||
*/ |
||||
void ( *Rx )( uint32_t timeout ); |
||||
/*!
|
||||
* \brief Start a Channel Activity Detection |
||||
*/ |
||||
void ( *StartCad )( void ); |
||||
/*!
|
||||
* \brief Sets the radio in continuous wave transmission mode |
||||
* |
||||
* \param [IN]: freq Channel RF frequency |
||||
* \param [IN]: power Sets the output power [dBm] |
||||
* \param [IN]: time Transmission mode timeout [s] |
||||
*/ |
||||
void ( *SetTxContinuousWave )( uint32_t freq, int8_t power, uint16_t time ); |
||||
/*!
|
||||
* \brief Reads the current RSSI value |
||||
* |
||||
* \retval rssiValue Current RSSI value in [dBm] |
||||
*/ |
||||
int16_t ( *Rssi )( RadioModems_t modem ); |
||||
/*!
|
||||
* \brief Writes the radio register at the specified address |
||||
* |
||||
* \param [IN]: addr Register address |
||||
* \param [IN]: data New register value |
||||
*/ |
||||
void ( *Write )( uint8_t addr, uint8_t data ); |
||||
/*!
|
||||
* \brief Reads the radio register at the specified address |
||||
* |
||||
* \param [IN]: addr Register address |
||||
* \retval data Register value |
||||
*/ |
||||
uint8_t ( *Read )( uint8_t addr ); |
||||
/*!
|
||||
* \brief Writes multiple radio registers starting at address |
||||
* |
||||
* \param [IN] addr First Radio register address |
||||
* \param [IN] buffer Buffer containing the new register's values |
||||
* \param [IN] size Number of registers to be written |
||||
*/ |
||||
void ( *WriteBuffer )( uint8_t addr, uint8_t *buffer, uint8_t size ); |
||||
/*!
|
||||
* \brief Reads multiple radio registers starting at address |
||||
* |
||||
* \param [IN] addr First Radio register address |
||||
* \param [OUT] buffer Buffer where to copy the registers data |
||||
* \param [IN] size Number of registers to be read |
||||
*/ |
||||
void ( *ReadBuffer )( uint8_t addr, uint8_t *buffer, uint8_t size ); |
||||
/*!
|
||||
* \brief Sets the maximum payload length. |
||||
* |
||||
* \param [IN] modem Radio modem to be used [0: FSK, 1: LoRa] |
||||
* \param [IN] max Maximum payload length in bytes |
||||
*/ |
||||
void ( *SetMaxPayloadLength )( RadioModems_t modem, uint8_t max ); |
||||
/*!
|
||||
* \brief Sets the network to public or private. Updates the sync byte. |
||||
* |
||||
* \remark Applies to LoRa modem only |
||||
* |
||||
* \param [IN] enable if true, it enables a public network |
||||
*/ |
||||
void ( *SetPublicNetwork )( bool enable ); |
||||
/*!
|
||||
* \brief Service to get the radio wake-up time. |
||||
* |
||||
* \retval Value of the radio wake-up time. |
||||
*/ |
||||
uint32_t ( *GetRadioWakeUpTime ) ( void ); |
||||
}; |
||||
|
||||
/*!
|
||||
* \brief Radio driver |
||||
* |
||||
* \remark This variable is defined and initialized in the specific radio |
||||
* board implementation |
||||
*/ |
||||
extern const struct Radio_s Radio; |
||||
|
||||
#endif // __RADIO_H__
|
@ -0,0 +1,77 @@ |
||||
/*
|
||||
/ _____) _ | | |
||||
( (____ _____ ____ _| |_ _____ ____| |__ |
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | | |
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_| |
||||
(C)2013 Semtech |
||||
|
||||
Description: Delay functions implementation |
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project |
||||
|
||||
Maintainer: Miguel Luis and Gregory Cristian |
||||
*/ |
||||
/******************************************************************************
|
||||
* @file delay.c |
||||
* @author MCD Application Team |
||||
* @version V1.1.2 |
||||
* @date 08-September-2017 |
||||
* @brief Delay function |
||||
****************************************************************************** |
||||
* @attention |
||||
* |
||||
* <h2><center>© Copyright (c) 2017 STMicroelectronics International N.V.
|
||||
* All rights reserved.</center></h2> |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted, provided that the following conditions are met: |
||||
* |
||||
* 1. Redistribution of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer. |
||||
* 2. 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. |
||||
* 3. Neither the name of STMicroelectronics nor the names of other
|
||||
* contributors to this software may be used to endorse or promote products
|
||||
* derived from this software without specific written permission. |
||||
* 4. This software, including modifications and/or derivative works of this
|
||||
* software, must execute solely and exclusively on microcontroller or |
||||
* microprocessor devices manufactured by or for STMicroelectronics. |
||||
* 5. Redistribution and use of this software other than as permitted under
|
||||
* this license is void and will automatically terminate your rights under
|
||||
* this license.
|
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
* PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY |
||||
* RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT
|
||||
* SHALL STMICROELECTRONICS OR CONTRIBUTORS 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. |
||||
* |
||||
****************************************************************************** |
||||
*/ |
||||
|
||||
/* Includes ------------------------------------------------------------------*/ |
||||
#include "hw.h" |
||||
#include "timeServer.h" |
||||
|
||||
void DelayMs( uint32_t ms ) |
||||
{ |
||||
HW_RTC_DelayMs( ms ); |
||||
|
||||
} |
||||
|
||||
void Delay( float s ) |
||||
{ |
||||
DelayMs( (uint32_t) (s * 1000.0f) ); |
||||
} |
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
||||
|
@ -0,0 +1,29 @@ |
||||
/*
|
||||
/ _____) _ | | |
||||
( (____ _____ ____ _| |_ _____ ____| |__ |
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | | |
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_| |
||||
(C)2013 Semtech |
||||
|
||||
Description: Delay functions implementation |
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project |
||||
|
||||
Maintainer: Miguel Luis and Gregory Cristian |
||||
*/ |
||||
#ifndef __DELAY_H__ |
||||
#define __DELAY_H__ |
||||
|
||||
/*!
|
||||
* Blocking delay of "s" seconds |
||||
*/ |
||||
void Delay( float s ); |
||||
|
||||
/*!
|
||||
* Blocking delay of "ms" milliseconds |
||||
*/ |
||||
void DelayMs( uint32_t ms ); |
||||
|
||||
#endif // __DELAY_H__
|
||||
|
@ -0,0 +1,149 @@ |
||||
/*******************************************************************************
|
||||
* @file low_power.c |
||||
* @author MCD Application Team |
||||
* @version V1.1.2 |
||||
* @date 08-September-2017 |
||||
* @brief driver for low power |
||||
****************************************************************************** |
||||
* @attention |
||||
* |
||||
* <h2><center>© Copyright (c) 2017 STMicroelectronics International N.V.
|
||||
* All rights reserved.</center></h2> |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted, provided that the following conditions are met: |
||||
* |
||||
* 1. Redistribution of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer. |
||||
* 2. 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. |
||||
* 3. Neither the name of STMicroelectronics nor the names of other
|
||||
* contributors to this software may be used to endorse or promote products
|
||||
* derived from this software without specific written permission. |
||||
* 4. This software, including modifications and/or derivative works of this
|
||||
* software, must execute solely and exclusively on microcontroller or |
||||
* microprocessor devices manufactured by or for STMicroelectronics. |
||||
* 5. Redistribution and use of this software other than as permitted under
|
||||
* this license is void and will automatically terminate your rights under
|
||||
* this license.
|
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
* PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY |
||||
* RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT
|
||||
* SHALL STMICROELECTRONICS OR CONTRIBUTORS 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. |
||||
* |
||||
****************************************************************************** |
||||
*/ |
||||
|
||||
/* Includes ------------------------------------------------------------------*/ |
||||
#include "hw.h" |
||||
#include "low_power.h" |
||||
|
||||
/* Private typedef -----------------------------------------------------------*/ |
||||
/* Private define ------------------------------------------------------------*/ |
||||
/* Private macro -------------------------------------------------------------*/ |
||||
/* Private variables ---------------------------------------------------------*/ |
||||
|
||||
/**
|
||||
* \brief Flag to indicate if MCU can go to low power mode |
||||
* When 0, MCU is authorized to go in low power mode |
||||
*/ |
||||
static uint32_t LowPower_State = 0; |
||||
|
||||
/* Private function prototypes -----------------------------------------------*/ |
||||
|
||||
|
||||
|
||||
/* Exported functions ---------------------------------------------------------*/ |
||||
|
||||
/**
|
||||
* \brief API to set flag allowing power mode |
||||
* |
||||
* \param [IN] enum e_LOW_POWER_State_Id_t
|
||||
*/ |
||||
void LowPower_Disable( e_LOW_POWER_State_Id_t state ) |
||||
{ |
||||
BACKUP_PRIMASK(); |
||||
|
||||
DISABLE_IRQ( ); |
||||
|
||||
LowPower_State |= state; |
||||
|
||||
RESTORE_PRIMASK( ); |
||||
} |
||||
|
||||
/**
|
||||
* \brief API to reset flag allowing power mode |
||||
* |
||||
* \param [IN] enum e_LOW_POWER_State_Id_t
|
||||
*/ |
||||
void LowPower_Enable( e_LOW_POWER_State_Id_t state ) |
||||
{ |
||||
BACKUP_PRIMASK(); |
||||
|
||||
DISABLE_IRQ( ); |
||||
|
||||
LowPower_State &= ~state; |
||||
|
||||
RESTORE_PRIMASK( ); |
||||
} |
||||
|
||||
/**
|
||||
* \brief API to get flag allowing power mode |
||||
* \note When flag is 0, low power mode is allowed |
||||
* \param [IN] state |
||||
* \retval flag state
|
||||
*/ |
||||
uint32_t LowPower_GetState( void ) |
||||
{ |
||||
return LowPower_State; |
||||
} |
||||
|
||||
/**
|
||||
* @brief Handle Low Power |
||||
* @param None |
||||
* @retval None |
||||
*/ |
||||
|
||||
void LowPower_Handler( void ) |
||||
{ |
||||
DBG_GPIO_RST(GPIOB, GPIO_PIN_15); |
||||
|
||||
DBG_GPIO_RST(GPIOB, GPIO_PIN_14); |
||||
|
||||
if ( LowPower_State == 0 ) |
||||
{
|
||||
|
||||
DBG_PRINTF_CRITICAL("dz\n\r"); |
||||
|
||||
HW_EnterStopMode( ); |
||||
|
||||
/* mcu dependent. to be implemented by user*/ |
||||
HW_ExitStopMode(); |
||||
|
||||
DBG_GPIO_SET(GPIOB, GPIO_PIN_15); |
||||
|
||||
HW_RTC_setMcuWakeUpTime( ); |
||||
} |
||||
else |
||||
{ |
||||
DBG_PRINTF_CRITICAL("z\n\r"); |
||||
|
||||
HW_EnterSleepMode( ); |
||||
|
||||
DBG_GPIO_SET(GPIOB, GPIO_PIN_14); |
||||
} |
||||
|
||||
} |
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
||||
|
||||
|
@ -0,0 +1,98 @@ |
||||
/******************************************************************************
|
||||
* @file low_power.h |
||||
* @author MCD Application Team |
||||
* @version V1.1.2 |
||||
* @date 08-September-2017 |
||||
* @brief Header for driver low_power.c module |
||||
****************************************************************************** |
||||
* @attention |
||||
* |
||||
* <h2><center>© Copyright (c) 2017 STMicroelectronics International N.V.
|
||||
* All rights reserved.</center></h2> |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted, provided that the following conditions are met: |
||||
* |
||||
* 1. Redistribution of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer. |
||||
* 2. 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. |
||||
* 3. Neither the name of STMicroelectronics nor the names of other
|
||||
* contributors to this software may be used to endorse or promote products
|
||||
* derived from this software without specific written permission. |
||||
* 4. This software, including modifications and/or derivative works of this
|
||||
* software, must execute solely and exclusively on microcontroller or |
||||
* microprocessor devices manufactured by or for STMicroelectronics. |
||||
* 5. Redistribution and use of this software other than as permitted under
|
||||
* this license is void and will automatically terminate your rights under
|
||||
* this license.
|
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
* PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY |
||||
* RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT
|
||||
* SHALL STMICROELECTRONICS OR CONTRIBUTORS 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. |
||||
* |
||||
****************************************************************************** |
||||
*/ |
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/ |
||||
#ifndef __LOW_POWER_H__ |
||||
#define __LOW_POWER_H__ |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
/* Includes ------------------------------------------------------------------*/ |
||||
/* Exported types ------------------------------------------------------------*/ |
||||
/* Exported constants --------------------------------------------------------*/ |
||||
/* External variables --------------------------------------------------------*/ |
||||
/* Exported macros -----------------------------------------------------------*/ |
||||
/* Exported functions ------------------------------------------------------- */
|
||||
|
||||
/*!
|
||||
* @brief API to set flag allowing power mode |
||||
* |
||||
* @param [IN] enum e_LOW_POWER_State_Id_t |
||||
*/ |
||||
void LowPower_Disable( e_LOW_POWER_State_Id_t state ); |
||||
|
||||
/*!
|
||||
* @brief API to reset flag allowing power mode |
||||
* |
||||
* @param [IN] enum e_LOW_POWER_State_Id_t
|
||||
*/ |
||||
|
||||
void LowPower_Enable( e_LOW_POWER_State_Id_t state ); |
||||
|
||||
/*!
|
||||
* @brief API to get flag allowing power mode |
||||
* @note When flag is 0, low power mode is allowed |
||||
* @param [IN] non |
||||
* @retval flag state
|
||||
*/ |
||||
uint32_t LowPower_GetState( void ); |
||||
|
||||
/*!
|
||||
* @brief Manages the entry into ARM cortex deep-sleep mode |
||||
* @param none |
||||
* @retval none |
||||
*/ |
||||
void LowPower_Handler( void ); |
||||
|
||||
#ifdef __cplusplus |
||||
} |
||||
#endif |
||||
|
||||
#endif /* __LOW_POWER_H__ */ |
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
@ -0,0 +1,406 @@ |
||||
/*
|
||||
/ _____) _ | | |
||||
( (____ _____ ____ _| |_ _____ ____| |__ |
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | | |
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_| |
||||
(C)2013 Semtech |
||||
|
||||
Description: Generic lora driver implementation |
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project |
||||
|
||||
Maintainer: Miguel Luis, Gregory Cristian and Wael Guibene |
||||
*/ |
||||
/******************************************************************************
|
||||
* @file timeserver.c |
||||
* @author MCD Application Team |
||||
* @version V1.1.2 |
||||
* @date 08-September-2017 |
||||
* @brief Time server infrastructure |
||||
****************************************************************************** |
||||
* @attention |
||||
* |
||||
* <h2><center>© Copyright (c) 2017 STMicroelectronics International N.V.
|
||||
* All rights reserved.</center></h2> |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted, provided that the following conditions are met: |
||||
* |
||||
* 1. Redistribution of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer. |
||||
* 2. 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. |
||||
* 3. Neither the name of STMicroelectronics nor the names of other
|
||||
* contributors to this software may be used to endorse or promote products
|
||||
* derived from this software without specific written permission. |
||||
* 4. This software, including modifications and/or derivative works of this
|
||||
* software, must execute solely and exclusively on microcontroller or |
||||
* microprocessor devices manufactured by or for STMicroelectronics. |
||||
* 5. Redistribution and use of this software other than as permitted under
|
||||
* this license is void and will automatically terminate your rights under
|
||||
* this license.
|
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
* PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY |
||||
* RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT
|
||||
* SHALL STMICROELECTRONICS OR CONTRIBUTORS 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. |
||||
* |
||||
****************************************************************************** |
||||
*/ |
||||
|
||||
/* Includes ------------------------------------------------------------------*/ |
||||
#include <time.h> |
||||
#include "hw.h" |
||||
#include "timeServer.h" |
||||
//#include "low_power.h"
|
||||
|
||||
|
||||
/*!
|
||||
* safely execute call back |
||||
*/ |
||||
#define exec_cb( _callback_ ) \ |
||||
do { \
|
||||
if( _callback_ == NULL ) \
|
||||
{ \
|
||||
while(1); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
_callback_( ); \
|
||||
} \
|
||||
} while(0);
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
* Timers list head pointer |
||||
*/ |
||||
static TimerEvent_t *TimerListHead = NULL; |
||||
|
||||
/*!
|
||||
* \brief Adds or replace the head timer of the list. |
||||
* |
||||
* \remark The list is automatically sorted. The list head always contains the |
||||
* next timer to expire. |
||||
* |
||||
* \param [IN] obj Timer object to be become the new head |
||||
* \param [IN] remainingTime Remaining time of the previous head to be replaced |
||||
*/ |
||||
static void TimerInsertNewHeadTimer( TimerEvent_t *obj ); |
||||
|
||||
/*!
|
||||
* \brief Adds a timer to the list. |
||||
* |
||||
* \remark The list is automatically sorted. The list head always contains the |
||||
* next timer to expire. |
||||
* |
||||
* \param [IN] obj Timer object to be added to the list |
||||
* \param [IN] remainingTime Remaining time of the running head after which the object may be added |
||||
*/ |
||||
static void TimerInsertTimer( TimerEvent_t *obj ); |
||||
|
||||
/*!
|
||||
* \brief Sets a timeout with the duration "timestamp" |
||||
*
|
||||
* \param [IN] timestamp Delay duration |
||||
*/ |
||||
static void TimerSetTimeout( TimerEvent_t *obj ); |
||||
|
||||
/*!
|
||||
* \brief Check if the Object to be added is not already in the list |
||||
*
|
||||
* \param [IN] timestamp Delay duration |
||||
* \retval true (the object is already in the list) or false
|
||||
*/ |
||||
static bool TimerExists( TimerEvent_t *obj ); |
||||
|
||||
|
||||
|
||||
void TimerInit( TimerEvent_t *obj, void ( *callback )( void ) ) |
||||
{ |
||||
obj->Timestamp = 0; |
||||
obj->ReloadValue = 0; |
||||
obj->IsRunning = false; |
||||
obj->Callback = callback; |
||||
obj->Next = NULL; |
||||
} |
||||
|
||||
void TimerStart( TimerEvent_t *obj ) |
||||
{ |
||||
uint32_t elapsedTime = 0; |
||||
|
||||
BACKUP_PRIMASK(); |
||||
|
||||
DISABLE_IRQ( ); |
||||
|
||||
|
||||
if( ( obj == NULL ) || ( TimerExists( obj ) == true ) ) |
||||
{ |
||||
RESTORE_PRIMASK( ); |
||||
return; |
||||
} |
||||
obj->Timestamp = obj->ReloadValue; |
||||
obj->IsRunning = false; |
||||
|
||||
if( TimerListHead == NULL ) |
||||
{ |
||||
HW_RTC_SetTimerContext( ); |
||||
TimerInsertNewHeadTimer( obj ); // insert a timeout at now+obj->Timestamp
|
||||
} |
||||
else
|
||||
{ |
||||
elapsedTime = HW_RTC_GetTimerElapsedTime( ); |
||||
obj->Timestamp += elapsedTime; |
||||
|
||||
if( obj->Timestamp < TimerListHead->Timestamp ) |
||||
{ |
||||
TimerInsertNewHeadTimer( obj); |
||||
} |
||||
else |
||||
{ |
||||
TimerInsertTimer( obj); |
||||
} |
||||
} |
||||
RESTORE_PRIMASK( ); |
||||
} |
||||
|
||||
static void TimerInsertTimer( TimerEvent_t *obj) |
||||
{ |
||||
TimerEvent_t* cur = TimerListHead; |
||||
TimerEvent_t* next = TimerListHead->Next; |
||||
|
||||
while (cur->Next != NULL ) |
||||
{
|
||||
if( obj->Timestamp > next->Timestamp ) |
||||
{ |
||||
cur = next; |
||||
next = next->Next; |
||||
} |
||||
else |
||||
{ |
||||
cur->Next = obj; |
||||
obj->Next = next; |
||||
return; |
||||
|
||||
} |
||||
} |
||||
cur->Next = obj; |
||||
obj->Next = NULL; |
||||
} |
||||
|
||||
static void TimerInsertNewHeadTimer( TimerEvent_t *obj ) |
||||
{ |
||||
TimerEvent_t* cur = TimerListHead; |
||||
|
||||
if( cur != NULL ) |
||||
{ |
||||
cur->IsRunning = false; |
||||
} |
||||
|
||||
obj->Next = cur; |
||||
TimerListHead = obj; |
||||
TimerSetTimeout( TimerListHead ); |
||||
} |
||||
|
||||
void TimerIrqHandler( void ) |
||||
{ |
||||
TimerEvent_t* cur; |
||||
TimerEvent_t* next; |
||||
|
||||
|
||||
|
||||
uint32_t old = HW_RTC_GetTimerContext( ); |
||||
uint32_t now = HW_RTC_SetTimerContext( ); |
||||
uint32_t DeltaContext = now - old; //intentionnal wrap around
|
||||
|
||||
/* update timeStamp based upon new Time Reference*/ |
||||
/* beacuse delta context should never exceed 2^32*/ |
||||
if ( TimerListHead != NULL ) |
||||
{ |
||||
for (cur=TimerListHead; cur->Next != NULL; cur= cur->Next) |
||||
{ |
||||
next =cur->Next; |
||||
if (next->Timestamp > DeltaContext) |
||||
{ |
||||
next->Timestamp -= DeltaContext; |
||||
} |
||||
else |
||||
{ |
||||
next->Timestamp = 0 ; |
||||
} |
||||
} |
||||
} |
||||
|
||||
/* execute imediately the alarm callback */ |
||||
if ( TimerListHead != NULL ) |
||||
{ |
||||
cur = TimerListHead; |
||||
TimerListHead = TimerListHead->Next; |
||||
exec_cb( cur->Callback ); |
||||
} |
||||
|
||||
|
||||
// remove all the expired object from the list
|
||||
while( ( TimerListHead != NULL ) && ( TimerListHead->Timestamp < HW_RTC_GetTimerElapsedTime( ) )) |
||||
{ |
||||
cur = TimerListHead; |
||||
TimerListHead = TimerListHead->Next; |
||||
exec_cb( cur->Callback ); |
||||
} |
||||
|
||||
/* start the next TimerListHead if it exists AND NOT running */ |
||||
if(( TimerListHead != NULL ) && (TimerListHead->IsRunning == false)) |
||||
{ |
||||
TimerSetTimeout( TimerListHead ); |
||||
} |
||||
} |
||||
|
||||
void TimerStop( TimerEvent_t *obj )
|
||||
{ |
||||
BACKUP_PRIMASK(); |
||||
|
||||
DISABLE_IRQ( ); |
||||
|
||||
TimerEvent_t* prev = TimerListHead; |
||||
TimerEvent_t* cur = TimerListHead; |
||||
|
||||
// List is empty or the Obj to stop does not exist
|
||||
if( ( TimerListHead == NULL ) || ( obj == NULL ) ) |
||||
{ |
||||
RESTORE_PRIMASK( ); |
||||
return; |
||||
} |
||||
|
||||
if( TimerListHead == obj ) // Stop the Head
|
||||
{ |
||||
if( TimerListHead->IsRunning == true ) // The head is already running
|
||||
{
|
||||
if( TimerListHead->Next != NULL ) |
||||
{ |
||||
TimerListHead->IsRunning = false; |
||||
TimerListHead = TimerListHead->Next; |
||||
TimerSetTimeout( TimerListHead ); |
||||
} |
||||
else |
||||
{ |
||||
HW_RTC_StopAlarm( ); |
||||
TimerListHead = NULL; |
||||
} |
||||
} |
||||
else // Stop the head before it is started
|
||||
{
|
||||
if( TimerListHead->Next != NULL )
|
||||
{ |
||||
TimerListHead = TimerListHead->Next; |
||||
} |
||||
else |
||||
{ |
||||
TimerListHead = NULL; |
||||
} |
||||
} |
||||
} |
||||
else // Stop an object within the list
|
||||
{
|
||||
while( cur != NULL ) |
||||
{ |
||||
if( cur == obj ) |
||||
{ |
||||
if( cur->Next != NULL ) |
||||
{ |
||||
cur = cur->Next; |
||||
prev->Next = cur; |
||||
} |
||||
else |
||||
{ |
||||
cur = NULL; |
||||
prev->Next = cur; |
||||
} |
||||
break; |
||||
} |
||||
else |
||||
{ |
||||
prev = cur; |
||||
cur = cur->Next; |
||||
} |
||||
}
|
||||
} |
||||
|
||||
RESTORE_PRIMASK( ); |
||||
}
|
||||
|
||||
static bool TimerExists( TimerEvent_t *obj ) |
||||
{ |
||||
TimerEvent_t* cur = TimerListHead; |
||||
|
||||
while( cur != NULL ) |
||||
{ |
||||
if( cur == obj ) |
||||
{ |
||||
return true; |
||||
} |
||||
cur = cur->Next; |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
void TimerReset( TimerEvent_t *obj ) |
||||
{ |
||||
TimerStop( obj ); |
||||
TimerStart( obj ); |
||||
} |
||||
|
||||
void TimerSetValue( TimerEvent_t *obj, uint32_t value ) |
||||
{ |
||||
uint32_t minValue = 0; |
||||
uint32_t ticks = HW_RTC_ms2Tick( value ); |
||||
|
||||
TimerStop( obj ); |
||||
|
||||
minValue = HW_RTC_GetMinimumTimeout( ); |
||||
|
||||
if( ticks < minValue ) |
||||
{ |
||||
ticks = minValue; |
||||
} |
||||
|
||||
obj->Timestamp = ticks; |
||||
obj->ReloadValue = ticks; |
||||
} |
||||
|
||||
TimerTime_t TimerGetCurrentTime( void ) |
||||
{ |
||||
uint32_t now = HW_RTC_GetTimerValue( ); |
||||
return HW_RTC_Tick2ms(now); |
||||
} |
||||
|
||||
TimerTime_t TimerGetElapsedTime( TimerTime_t past ) |
||||
{ |
||||
uint32_t nowInTicks = HW_RTC_GetTimerValue( ); |
||||
uint32_t pastInTicks = HW_RTC_ms2Tick( past ); |
||||
/* intentional wrap around. Works Ok if tick duation below 1ms */ |
||||
return HW_RTC_Tick2ms( nowInTicks- pastInTicks ); |
||||
} |
||||
|
||||
static void TimerSetTimeout( TimerEvent_t *obj ) |
||||
{ |
||||
int32_t minTicks= HW_RTC_GetMinimumTimeout( ); |
||||
obj->IsRunning = true;
|
||||
|
||||
//in case deadline too soon
|
||||
if(obj->Timestamp < (HW_RTC_GetTimerElapsedTime( ) + minTicks) ) |
||||
{ |
||||
obj->Timestamp = HW_RTC_GetTimerElapsedTime( ) + minTicks; |
||||
} |
||||
HW_RTC_SetAlarm( obj->Timestamp ); |
||||
} |
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
@ -0,0 +1,164 @@ |
||||
/*
|
||||
/ _____) _ | | |
||||
( (____ _____ ____ _| |_ _____ ____| |__ |
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | | |
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_| |
||||
(C)2013 Semtech |
||||
|
||||
Description: Timer objects and scheduling management |
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project |
||||
|
||||
Maintainer: Miguel Luis and Gregory Cristian |
||||
*/ |
||||
/******************************************************************************
|
||||
* @file timeServer.h |
||||
* @author MCD Application Team |
||||
* @version V1.1.2 |
||||
* @date 08-September-2017 |
||||
* @brief is the timer server driver |
||||
****************************************************************************** |
||||
* @attention |
||||
* |
||||
* <h2><center>© Copyright (c) 2017 STMicroelectronics International N.V.
|
||||
* All rights reserved.</center></h2> |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted, provided that the following conditions are met: |
||||
* |
||||
* 1. Redistribution of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer. |
||||
* 2. 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. |
||||
* 3. Neither the name of STMicroelectronics nor the names of other
|
||||
* contributors to this software may be used to endorse or promote products
|
||||
* derived from this software without specific written permission. |
||||
* 4. This software, including modifications and/or derivative works of this
|
||||
* software, must execute solely and exclusively on microcontroller or |
||||
* microprocessor devices manufactured by or for STMicroelectronics. |
||||
* 5. Redistribution and use of this software other than as permitted under
|
||||
* this license is void and will automatically terminate your rights under
|
||||
* this license.
|
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
* PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY |
||||
* RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT
|
||||
* SHALL STMICROELECTRONICS OR CONTRIBUTORS 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. |
||||
* |
||||
****************************************************************************** |
||||
*/ |
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/ |
||||
#ifndef __TIMESERVER_H__ |
||||
#define __TIMESERVER_H__ |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
/* Includes ------------------------------------------------------------------*/ |
||||
|
||||
#include "utilities.h" |
||||
|
||||
/* Exported types ------------------------------------------------------------*/ |
||||
|
||||
/*!
|
||||
* \brief Timer object description |
||||
*/ |
||||
typedef struct TimerEvent_s |
||||
{ |
||||
uint32_t Timestamp; //! Expiring timer value in ticks from TimerContext
|
||||
uint32_t ReloadValue; //! Reload Value when Timer is restarted
|
||||
bool IsRunning; //! Is the timer currently running
|
||||
void ( *Callback )( void ); //! Timer IRQ callback function
|
||||
struct TimerEvent_s *Next; //! Pointer to the next Timer object.
|
||||
} TimerEvent_t; |
||||
|
||||
|
||||
/* Exported constants --------------------------------------------------------*/ |
||||
/* External variables --------------------------------------------------------*/ |
||||
/* Exported macros -----------------------------------------------------------*/ |
||||
/* Exported functions ------------------------------------------------------- */
|
||||
|
||||
/*!
|
||||
* \brief Initializes the timer object |
||||
* |
||||
* \remark TimerSetValue function must be called before starting the timer. |
||||
* this function initializes timestamp and reload value at 0. |
||||
* |
||||
* \param [IN] obj Structure containing the timer object parameters |
||||
* \param [IN] callback Function callback called at the end of the timeout |
||||
*/ |
||||
void TimerInit( TimerEvent_t *obj, void ( *callback )( void ) ); |
||||
|
||||
/*!
|
||||
* \brief Timer IRQ event handler |
||||
* |
||||
* \note Head Timer Object is automaitcally removed from the List |
||||
* |
||||
* \note e.g. it is snot needded to stop it |
||||
*/ |
||||
void TimerIrqHandler( void ); |
||||
|
||||
/*!
|
||||
* \brief Starts and adds the timer object to the list of timer events |
||||
* |
||||
* \param [IN] obj Structure containing the timer object parameters |
||||
*/ |
||||
void TimerStart( TimerEvent_t *obj ); |
||||
|
||||
/*!
|
||||
* \brief Stops and removes the timer object from the list of timer events |
||||
* |
||||
* \param [IN] obj Structure containing the timer object parameters |
||||
*/ |
||||
void TimerStop( TimerEvent_t *obj ); |
||||
|
||||
/*!
|
||||
* \brief Resets the timer object |
||||
* |
||||
* \param [IN] obj Structure containing the timer object parameters |
||||
*/ |
||||
void TimerReset( TimerEvent_t *obj ); |
||||
|
||||
/*!
|
||||
* \brief Set timer new timeout value |
||||
* |
||||
* \param [IN] obj Structure containing the timer object parameters |
||||
* \param [IN] value New timer timeout value |
||||
*/ |
||||
void TimerSetValue( TimerEvent_t *obj, uint32_t value ); |
||||
|
||||
|
||||
/*!
|
||||
* \brief Read the current time |
||||
* |
||||
* \retval returns current time in ms |
||||
*/ |
||||
TimerTime_t TimerGetCurrentTime( void ); |
||||
|
||||
/*!
|
||||
* \brief Return the Time elapsed since a fix moment in Time |
||||
* |
||||
* \param [IN] savedTime fix moment in Time |
||||
* \retval time returns elapsed time in ms |
||||
*/ |
||||
TimerTime_t TimerGetElapsedTime( TimerTime_t savedTime ); |
||||
|
||||
#ifdef __cplusplus |
||||
} |
||||
#endif |
||||
|
||||
#endif /* __TIMESERVER_H__*/ |
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
@ -0,0 +1,85 @@ |
||||
/*
|
||||
/ _____) _ | | |
||||
( (____ _____ ____ _| |_ _____ ____| |__ |
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | | |
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_| |
||||
(C)2013 Semtech |
||||
|
||||
Description: Helper functions implementation |
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project |
||||
|
||||
Maintainer: Miguel Luis and Gregory Cristian |
||||
*/ |
||||
#include <stdlib.h> |
||||
#include <stdio.h> |
||||
#include <stdint.h> |
||||
#include "utilities.h" |
||||
|
||||
/*!
|
||||
* Redefinition of rand() and srand() standard C functions. |
||||
* These functions are redefined in order to get the same behavior across |
||||
* different compiler toolchains implementations. |
||||
*/ |
||||
// Standard random functions redefinition start
|
||||
#define RAND_LOCAL_MAX 2147483647L |
||||
|
||||
static uint32_t next = 1; |
||||
|
||||
int32_t rand1( void ) |
||||
{ |
||||
return ( ( next = next * 1103515245L + 12345L ) % RAND_LOCAL_MAX ); |
||||
} |
||||
|
||||
void srand1( uint32_t seed ) |
||||
{ |
||||
next = seed; |
||||
} |
||||
// Standard random functions redefinition end
|
||||
|
||||
int32_t randr( int32_t min, int32_t max ) |
||||
{ |
||||
return ( int32_t )rand1( ) % ( max - min + 1 ) + min; |
||||
} |
||||
|
||||
void memcpy1( uint8_t *dst, const uint8_t *src, uint16_t size ) |
||||
{ |
||||
while( size-- ) |
||||
{ |
||||
*dst++ = *src++; |
||||
} |
||||
} |
||||
|
||||
void memcpyr( uint8_t *dst, const uint8_t *src, uint16_t size ) |
||||
{ |
||||
dst = dst + ( size - 1 ); |
||||
while( size-- ) |
||||
{ |
||||
*dst-- = *src++; |
||||
} |
||||
} |
||||
|
||||
void memset1( uint8_t *dst, uint8_t value, uint16_t size ) |
||||
{ |
||||
while( size-- ) |
||||
{ |
||||
*dst++ = value; |
||||
} |
||||
} |
||||
|
||||
int8_t Nibble2HexChar( uint8_t a ) |
||||
{ |
||||
if( a < 10 ) |
||||
{ |
||||
return '0' + a; |
||||
} |
||||
else if( a < 16 ) |
||||
{ |
||||
return 'A' + ( a - 10 ); |
||||
} |
||||
else |
||||
{ |
||||
return '?'; |
||||
} |
||||
} |
@ -0,0 +1,175 @@ |
||||
/*
|
||||
/ _____) _ | | |
||||
( (____ _____ ____ _| |_ _____ ____| |__ |
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | | |
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_| |
||||
(C)2013 Semtech |
||||
|
||||
Description: Helper functions implementation |
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project |
||||
|
||||
Maintainer: Miguel Luis and Gregory Cristian |
||||
*/ |
||||
/******************************************************************************
|
||||
* @file utilities.h |
||||
* @author MCD Application Team |
||||
* @version V1.1.2 |
||||
* @date 08-September-2017 |
||||
* @brief Header for driver utilities.c module |
||||
****************************************************************************** |
||||
* @attention |
||||
* |
||||
* <h2><center>© Copyright (c) 2017 STMicroelectronics International N.V.
|
||||
* All rights reserved.</center></h2> |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted, provided that the following conditions are met: |
||||
* |
||||
* 1. Redistribution of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer. |
||||
* 2. 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. |
||||
* 3. Neither the name of STMicroelectronics nor the names of other
|
||||
* contributors to this software may be used to endorse or promote products
|
||||
* derived from this software without specific written permission. |
||||
* 4. This software, including modifications and/or derivative works of this
|
||||
* software, must execute solely and exclusively on microcontroller or |
||||
* microprocessor devices manufactured by or for STMicroelectronics. |
||||
* 5. Redistribution and use of this software other than as permitted under
|
||||
* this license is void and will automatically terminate your rights under
|
||||
* this license.
|
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
* PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY |
||||
* RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT
|
||||
* SHALL STMICROELECTRONICS OR CONTRIBUTORS 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 __UTILITIES_H__ |
||||
#define __UTILITIES_H__ |
||||
|
||||
#include "hw_conf.h" |
||||
|
||||
|
||||
/* BACKUP_PRIMASK MUST be implemented at the begining of the funtion
|
||||
that implement a critical section
|
||||
PRIMASK is saved on STACK and recovered at the end of the funtion |
||||
That way RESTORE_PRIMASK ensures that no irq would be triggered in case of |
||||
unbalanced enable/disable, reentrant code etc...*/ |
||||
#define BACKUP_PRIMASK() uint32_t primask_bit= __get_PRIMASK() |
||||
#define DISABLE_IRQ() __disable_irq() |
||||
#define ENABLE_IRQ() __enable_irq() |
||||
#define RESTORE_PRIMASK() __set_PRIMASK(primask_bit) |
||||
|
||||
/* prepocessor directive to align buffer*/ |
||||
#define ALIGN(n) __attribute__((aligned(n))) |
||||
|
||||
typedef uint32_t TimerTime_t; |
||||
|
||||
/*!
|
||||
* \brief Returns the minimum value between a and b |
||||
* |
||||
* \param [IN] a 1st value |
||||
* \param [IN] b 2nd value |
||||
* \retval minValue Minimum value |
||||
*/ |
||||
#define MIN( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) ) |
||||
|
||||
/*!
|
||||
* \brief Returns the maximum value between a and b |
||||
* |
||||
* \param [IN] a 1st value |
||||
* \param [IN] b 2nd value |
||||
* \retval maxValue Maximum value |
||||
*/ |
||||
#define MAX( a, b ) ( ( ( a ) > ( b ) ) ? ( a ) : ( b ) ) |
||||
|
||||
/*!
|
||||
* \brief Returns 2 raised to the power of n |
||||
* |
||||
* \param [IN] n power value |
||||
* \retval result of raising 2 to the power n |
||||
*/ |
||||
#define POW2( n ) ( 1 << n ) |
||||
|
||||
/*!
|
||||
* \brief Find First Set |
||||
* This function identifies the least significant index or position of the |
||||
* bits set to one in the word |
||||
* |
||||
* \param [in] value Value to find least significant index |
||||
* \retval bitIndex Index of least significat bit at one |
||||
*/ |
||||
__STATIC_INLINE uint8_t __ffs( uint32_t value ) |
||||
{ |
||||
return( uint32_t )( 32 - __CLZ( value & ( -value ) ) ); |
||||
} |
||||
|
||||
/*!
|
||||
* \brief Initializes the pseudo random generator initial value |
||||
* |
||||
* \param [IN] seed Pseudo random generator initial value |
||||
*/ |
||||
void srand1( uint32_t seed ); |
||||
|
||||
/*!
|
||||
* \brief Computes a random number between min and max |
||||
* |
||||
* \param [IN] min range minimum value |
||||
* \param [IN] max range maximum value |
||||
* \retval random random value in range min..max |
||||
*/ |
||||
int32_t randr( int32_t min, int32_t max ); |
||||
|
||||
/*!
|
||||
* \brief Copies size elements of src array to dst array |
||||
* |
||||
* \remark STM32 Standard memcpy function only works on pointers that are aligned |
||||
* |
||||
* \param [OUT] dst Destination array |
||||
* \param [IN] src Source array |
||||
* \param [IN] size Number of bytes to be copied |
||||
*/ |
||||
void memcpy1( uint8_t *dst, const uint8_t *src, uint16_t size ); |
||||
|
||||
/*!
|
||||
* \brief Copies size elements of src array to dst array reversing the byte order |
||||
* |
||||
* \param [OUT] dst Destination array |
||||
* \param [IN] src Source array |
||||
* \param [IN] size Number of bytes to be copied |
||||
*/ |
||||
void memcpyr( uint8_t *dst, const uint8_t *src, uint16_t size ); |
||||
|
||||
/*!
|
||||
* \brief Set size elements of dst array with value |
||||
* |
||||
* \remark STM32 Standard memset function only works on pointers that are aligned |
||||
* |
||||
* \param [OUT] dst Destination array |
||||
* \param [IN] value Default value |
||||
* \param [IN] size Number of bytes to be copied |
||||
*/ |
||||
void memset1( uint8_t *dst, uint8_t value, uint16_t size ); |
||||
|
||||
/*!
|
||||
* \brief Converts a nibble to an hexadecimal character |
||||
* |
||||
* \param [IN] a Nibble to be converted |
||||
* \retval hexChar Converted hexadecimal character |
||||
*/ |
||||
int8_t Nibble2HexChar( uint8_t a ); |
||||
|
||||
#endif // __UTILITIES_H__
|
@ -0,0 +1,750 @@ |
||||
/ _____) _ | | |
||||
( (____ _____ ____ _| |_ _____ ____| |__ |
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \ |
||||
_____) ) ____| | | || |_| ____( (___| | | | |
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_| |
||||
(C)2013 Semtech |
||||
|
||||
LoRaWAN endpoint stack implementation and example projects. |
||||
===================================== |
||||
|
||||
1. Introduction |
||||
---------------- |
||||
The aim of this project is to show an example of the endpoint LoRaWAN stack implementation. |
||||
|
||||
This LoRaWAN stack implements all regions defined in "LoRaWAN Regional Parameters v1.0.2rB" document. Class A and Class C endpoint implementation |
||||
is fully compatible with "LoRaWAN specification 1.0.2". |
||||
|
||||
Each LoRaWAN application example includes the LoRaWAN certification protocol implementation. |
||||
|
||||
SX1272/76 radio drivers are also provided. |
||||
In case only point to point links are required a Ping-Pong application is provided as example. |
||||
|
||||
*The LoRaWAN stack API documentation can be found at: http://stackforce.github.io/LoRaMac-doc/* |
||||
|
||||
**Note 1:** |
||||
|
||||
*A port of this project can be found on [MBED Semtech Team page](http://developer.mbed.org/teams/Semtech/)* |
||||
|
||||
*The example projects are:* |
||||
|
||||
1. [LoRaWAN-demo-72](http://developer.mbed.org/teams/Semtech/code/LoRaWAN-demo-72/) |
||||
2. [LoRaWAN-demo-76](http://developer.mbed.org/teams/Semtech/code/LoRaWAN-demo-76/) |
||||
|
||||
|
||||
2. System schematic and definitions |
||||
------------------------------------ |
||||
The available supported hardware platforms schematics can be found in the Doc directory. |
||||
|
||||
3. Acknowledgments |
||||
------------------- |
||||
The mbed (https://mbed.org/) project was used at the beginning as source of |
||||
inspiration. |
||||
|
||||
This program uses the AES algorithm implementation (http://www.gladman.me.uk/) |
||||
by Brian Gladman. |
||||
|
||||
This program uses the CMAC algorithm implementation |
||||
(http://www.cse.chalmers.se/research/group/dcs/masters/contikisec/) by |
||||
Lander Casado, Philippas Tsigas. |
||||
|
||||
4. Dependencies |
||||
---------------- |
||||
This program depends on specific hardware platforms. Currently the supported |
||||
platforms are: |
||||
|
||||
- LoRaMote |
||||
MCU : STM32L151CB - 128K FLASH, 10K RAM, Timers, SPI, I2C, |
||||
USART, |
||||
USB 2.0 full-speed device/host/OTG controller, |
||||
DAC, ADC, DMA |
||||
RADIO : SX1272 |
||||
ANTENNA : Printed circuit antenna |
||||
BUTTONS : No |
||||
LEDS : 3 |
||||
SENSORS : Proximity, Magnetic, 3 axis Accelerometer, Pressure, |
||||
Temperature |
||||
GPS : Yes, UP501 module |
||||
EXTENSION HEADER : Yes, 20 pins |
||||
REMARK : The MCU and Radio are on an IMST iM880A module |
||||
|
||||
- MoteII |
||||
MCU : STM32L051C8 - 64K FLASH, 8K RAM, Timers, SPI, I2C, |
||||
USART, |
||||
USB 2.0 full-speed device/host/OTG controller (Not used), |
||||
DAC, ADC, DMA |
||||
RADIO : SX1272 |
||||
ANTENNA : Printed circuit antenna |
||||
BUTTONS : 3 |
||||
LEDS : 3 |
||||
SENSORS : Magnetic, 3 axis Accelerometer, Pressure, |
||||
Temperature |
||||
GPS : Yes, PAM7Q module |
||||
Display : OLED |
||||
ST-Link : Yes, MBED like |
||||
EXTENSION HEADER : Yes, 20 pins |
||||
REMARK : The MCU and Radio are on an IMST iM881A module |
||||
|
||||
- NAMote72 |
||||
MCU : STM32L152RC - 256K FLASH, 32K RAM, Timers, SPI, I2C, |
||||
USART, |
||||
USB 2.0 full-speed device/host/OTG controller (Not used), |
||||
DAC, ADC, DMA |
||||
RADIO : SX1272 |
||||
ANTENNA : Printed circuit antenna |
||||
BUTTONS : No |
||||
LEDS : 4 |
||||
SENSORS : Magnetic, 3 axis Accelerometer, Pressure, |
||||
Temperature |
||||
GPS : Yes, SIM39EA module |
||||
Display : OLED |
||||
ST-Link : Yes, MBED like |
||||
EXTENSION HEADER : Yes, Arduino connectors |
||||
REMARK : None |
||||
|
||||
- SensorNode |
||||
MCU : STM32L151CBU6 - 128K FLASH, 16K RAM, Timers, SPI, I2C, |
||||
USART, |
||||
USB 2.0 full-speed device/host/OTG controller, |
||||
DAC, ADC, DMA |
||||
RADIO : SX1276 |
||||
ANTENNA : Printed circuit antenna |
||||
BUTTONS : Power ON/OFF, General purpose button |
||||
LEDS : 3 |
||||
SENSORS : Proximity, Magnetic, 3 axis Accelerometer, Pressure, |
||||
Temperature |
||||
GPS : Yes, SIM39EA module |
||||
EXTENSION No |
||||
REMARK : The MCU and Radio are on an NYMTEK Cherry-LCC module |
||||
|
||||
- SK-iM880A ( IMST starter kit ) |
||||
MCU : STM32L151CB - 128K FLASH, 10K RAM, Timers, SPI, I2C, |
||||
USART, |
||||
USB 2.0 full-speed device/host/OTG controller, |
||||
DAC, ADC, DMA |
||||
RADIO : SX1272 |
||||
ANTENNA : Connector for external antenna |
||||
BUTTONS : 1 Reset, 3 buttons + 2 DIP-Switch |
||||
LEDS : 3 |
||||
SENSORS : Potentiometer |
||||
GPS : Possible through pin header GPS module connection |
||||
SDCARD : No |
||||
EXTENSION HEADER : Yes, all IMST iM880A module pins |
||||
REMARK : None |
||||
|
||||
5. Usage |
||||
--------- |
||||
Projects for CooCox-CoIDE and Keil Integrated Development Environments are available. |
||||
|
||||
One project is available per application and for each hardware platform in each |
||||
development environment. Different targets/configurations have been created in |
||||
the different projects in order to select different options such as the usage or |
||||
not of a bootloader and the radio frequency band to be used. |
||||
|
||||
6. Changelog |
||||
------------- |
||||
2017-09-08, V4.4.0 |
||||
* General |
||||
1. First release based on "LoRaWAN specification 1.0.2" and "LoRaWAN Regional Parameters v1.0.2rB" |
||||
2. This version has passed the LoRa-Alliance compliance tests for the regions shown in the below table. |
||||
3. GitHub reported issues corrections. |
||||
4. Updated radio driver to perform the LBT carrier sense continuously for a given period of time. |
||||
|
||||
* LoRaWAN |
||||
1. GitHub reported issues corrections. |
||||
2. Updated implementation to support 1.0.2 specification additions. |
||||
3. Added the support for all "LoRaWAN Regional Parameters v1.0.2rB" document defined regions. |
||||
|
||||
**LoRaWAN certification results** |
||||
|
||||
| Region | Verdict | # Test houses | Comments | |
||||
| ------------- |:-------------:|:-------------:|:--------------| |
||||
| EU868 | <font color='green'>PASS</font> | 2 | - | |
||||
| US915 | <font color='green'>PASS</font> | 2 | - | |
||||
| CN779 | <font color='orange'>Partial PASS</font> | 1 | No certification specification - tests based on EU868 certification - All tests PASS except 1. Join Accept Rx2 parameters not being applied (under investigation) | |
||||
| EU433 | <font color='green'>PASS</font> | 1 | No certification specification - tests based on EU868 certification | |
||||
| AU915 | <font color='orange'>Not tested yet</font> | 0 | No certification specification | |
||||
| CN470 | <font color='orange'>Not tested yet</font> | 0 | No certification specification | |
||||
| AS923 | <font color='green'>PASS</font> | 2 | - | |
||||
| KR920 | <font color='green'>PASS</font> | 1 | As of today only one test house has sent a report. We decided to perform the release anyway | |
||||
| IN865 | <font color='orange'>PASS</font> | 1 | No certification specification - tests based on EU868 certification | |
||||
|
||||
2017-04-19, V4.3.2 |
||||
* General (Last release based on LoRaWAN specification 1.0.1) |
||||
1. This version has passed EU868 and US915 LoRa-Alliance compliance tests. |
||||
2. GitHub reported issues corrections. |
||||
3. Added an algorithm to automatically compute the Rx windows parameters. (Window symbolTimeout and Offset from downlink expected time) |
||||
4. Added a workaround to reset the radio in case a TxTimeout occurs. |
||||
5. Modified FSK modem handling to use the provided symbolTimeout (1 symbol equals 1 byte) when in RxSingle mode. |
||||
6. Added newly defined TxCw(Tx Continuous Wave) certification protocol command. |
||||
7. Added a fix for an overflow issue that could happen with NmeaStringSize variable. |
||||
8. Improved GpioMcuInit function to first configure the output pin state before activating the pin. |
||||
|
||||
* LoRaWAN |
||||
1. GitHub reported issues corrections. |
||||
2. Changed the AdrAckCounter handling as expected by the test houses. |
||||
3. Fix an issue where the node stopped transmitting. |
||||
4. Removed useless LoRaMacPayload buffer. |
||||
5. MAC layer indications handling simplification. |
||||
6. Relocate parameter settings from ResetMacParameters to the initialization. |
||||
|
||||
2017-02-27, V4.3.1 |
||||
* General |
||||
1. This version has passed EU868 and US915 LoRa-Alliance compliance tests. |
||||
2. Update the MAC layer in order to be LoRaWAN version 1.0.1 compliant (Mainly US915 bug fixes) |
||||
3. Removed api-v3 support from the project. |
||||
4. GitHub reported issues corrections. |
||||
5. Updated SensorNode projects according to the new MCU reference STM32L151CBU6. Bigger memories. |
||||
6. Addition of MoteII platform based on the IMST module iM881A (STM32L051C8) |
||||
7. Addition of NAMote72 platform |
||||
8. Correct compliance test protocol command 0x06 behaviour |
||||
9. Added TxCw (Tx continuous wave) LoRaWAN compliance protocol command. |
||||
10. Added TxContinuousWave support to the radio drivers. |
||||
11. Updated ST HAL drivers. |
||||
- STM32L1xx_HAL-Driver : V1.2.0 |
||||
- STM32L0xx_HAL_Driver : V1.7.0 |
||||
|
||||
* LoRaWAN |
||||
1. US band corrections in order to pass the LoRaWAN certification. |
||||
2. GitHub reported issues corrections. |
||||
3. Add region CN470 support. |
||||
|
||||
2016-06-22, V4.3.0 |
||||
* General |
||||
1. This version has passed all LoRa-Alliance compliance tests. |
||||
2. Update the MAC layer in order to be LoRaWAN version 1.0.1 compliant |
||||
3. Applied to all application files the certification protocol change for LoRaWAN 1.0.1 compliance tests. |
||||
|
||||
**REMARK**: api-v3 application files aren't updated. |
||||
|
||||
4. Add radio RX_TIMEOUT irq clear into the irq handler. |
||||
5. Removed the end less loop from HAL_UART_ErrorCallback. |
||||
6. Update of the STM32L0 HAL to version 1.6.0 |
||||
7. Consolidated the line endings across all project files. |
||||
Windows line endings has been choose for almost every file. |
||||
|
||||
* LoRaWAN |
||||
1. Updated maximum payload size for US band. |
||||
2. Update datarate offset table for US band. |
||||
3. Make MAC commands sticky |
||||
4. Add retransmission back-off |
||||
5. Remove the TxPower limitation for US band on LoRaMacMibSetRequestConfirm function. The power will be limited anyway when the SendFrameOnChannel functions is called. |
||||
6. Issue(#81): Bug fix in function LoRaMacMlmeRequest case MLME_JOIN. Function will return LORAMAC_STATUS_BUSY in case the MAC is in status MAC_TX_DELAYED. |
||||
7. Add debug pin support to LoRaMote platform. |
||||
8. Updated and improved MPL3115 device driver. |
||||
9. Issue(#83): Bug fix in parameter validation |
||||
10. Issue(#84): Fix issue of CalibrateTimer function. |
||||
11. RTC driver major update |
||||
12. Applied pull request #87. |
||||
13. Add a function to verify the RX frequency of window 2 for US band. |
||||
14. Issue(#88): Bug fix in function PrepareFrame where repeated MAC commands were not handled correctly. |
||||
15. Bug fix in OnRadioRxDone. Node now drops frames on port 0 with fOpts > 0. |
||||
16. Bug fix in OnRadioRxDone. Node now receives frames with fOpts > 0 when no payload is present. |
||||
|
||||
2016-05-13, V4.2.0 |
||||
* General |
||||
1. This version has passed all LoRa-Alliance compliance tests. |
||||
2. Update STM32L1xx_HAL_Driver version to 1.5. Update related drivers and implementations accordingly. |
||||
|
||||
**REMARK**: This change implies that the time base had to be changed from microseconds to milliseconds. |
||||
|
||||
3. Corrected the frequency check condition for // ERRATA 2.1 - Sensitivity Optimization with a 500 kHz Bandwidth |
||||
4. Optimize radio drivers regarding FSK PER |
||||
5. Resolve issue when calling SX127xInit function more than once |
||||
6. Add a definition for the LoRaWAN device address. Add an IEEE_OUI for the LoRaWAN device EUI. |
||||
7. Add a definition for the default datarate. |
||||
8. Issue(#66) correction of functions SX1276SetOpMode and SX1272SetOpMode. |
||||
9. Issue(#68): Fix for low level RF switch control. |
||||
10. Increase RTC tick frequency for higher resolution. |
||||
11. Update the radio wake up time. |
||||
|
||||
* LoRaWAN |
||||
1. Issue(#56) correction |
||||
2. Update channel mask handling for US915 hybrid mode to support any block in the channel mask. |
||||
3. Issue(#63) correct the maximum payload length in RX mode. |
||||
4. Fix Tx power setting loss for repeated join requests on US band. |
||||
5. Introduce individual MIN and MAX datarates for RX and TX. |
||||
6. Add the possibility to set and get the ChannelsDefaultDatarate. |
||||
7. Optimization of the RX symbol timeout. |
||||
8. Issue(#59): Add the possibility to set the uplink and downlink counter. |
||||
9. Replace definition LORAMAC_DEFAULT_DATARATE by ChannelsDefaultDatarate in LoRaMacChannelAdd. |
||||
10. Issue(#72): Fix of possible array overrun in LoRaMacChannelRemove. |
||||
11. Introduce a new status MAC_RX_ABORT. Reset MAC_TX_RUNNING only in OnMacStateCheckTimerEvent. |
||||
12. Accept MAC information of duplicated, confirmed downlinks. |
||||
13. Issue(#74): Drop frames with a downlink counter difference greater or equal to MAX_FCNT_GAP. |
||||
|
||||
2016-03-10, V4.1.0 |
||||
* General |
||||
1. This version has passed all mandatory LoRa-Alliance compliance tests. |
||||
|
||||
*One of the optional tests is unsuccessful (FSK downlinks PER on Rx1 and Rx2 windows) and is currently under investigation.* |
||||
2. Removed support for Raisonance Ride7 IDE (Reduces the amount of work to be done at each new release) |
||||
3. Removed the Bleeper-72 and Bleeper-76 platforms support as these are now deprecated. |
||||
4. Application state machine. Relocate setting sleep state and update the duty cycle in compliance test mode. |
||||
5. Bug fix in TimerIrqHandler. Now, it is possible to insert timers in callback. |
||||
6. Changed TimerHwDelayMs function to be re-entrant. |
||||
7. Corrected FSK modem packets bigger than 64 bytes handling (Issue #36) |
||||
|
||||
* LoRaWAN |
||||
1. Rename attribute nbRetries to NbTrials in structure McpsReqConfirmed_t. (Issue #37) |
||||
2. Updated implementation of SetNextChannel. Added enabling default channels in case of join request. (Issue #39) |
||||
3. Add missing documentation about MIB_REPEATER_SUPPORT. (Issue #42). |
||||
4. Add a new LoRaMacState to allow adding channels during TX procedure. (Issue #43) |
||||
5. Relocate the activation of LoRaMacFlags.Bits.McpsInd in OnRadioRxDone. |
||||
6. Add a new function PrepareRxDoneAbort to prepare a break-out of OnRadioRxDone in case of an error |
||||
7. Activate default channels in case all others are disabled. (Issue #39) |
||||
8. Bug fix in setting the default channel in case none is enabled. |
||||
9. SRV_MAC_NEW_CHANNEL_REQ MAC command added a fix to the macIndex variable on US915 band. |
||||
10. Start the MacStateCheckTimer in OnRxDone and related error cases with a short interval to handle events promptly. (Issue #44) |
||||
11. Reset status of NodeAckRequested if we received an ACK or in case of timeout. |
||||
12. Removed additional EU868 channels from the LoRaWAN implementation files. GitHub (Issue #49) |
||||
The creation of these additional channels has been moved to the application example. |
||||
13. Improved and corrected AdrNextDr function. |
||||
|
||||
2015-12-18, V4.0.0 |
||||
* General |
||||
1. STACKFORCE new API integration |
||||
2. Reverse the EUIs arrays in the MAC layer. |
||||
3. LoRaWAN certification protocol implementation |
||||
4. All reported issues and Pull requests have been addressed. |
||||
|
||||
2015-10-06, V3.4.1 |
||||
* General |
||||
1. Bug fixes |
||||
|
||||
* LoRaWAN |
||||
1. Corrected downlink counter roll over management when several downlinks were missed. |
||||
2. Corrected the Radio maximum payload length management. Radio was filtering received frames with a length bigger than the transmitted one. |
||||
3. Applied Pull request #22 solution proposition. |
||||
|
||||
2015-10-30, V3.4.0 |
||||
* General |
||||
1. Changed all applications in order to have preprocessing definitions on top of the files and added relevant comments |
||||
2. Applications LED control is no more done into the timer callback functions but instead on the main while loop. |
||||
3. Added TimerStop function calls to each timer event callback. |
||||
4. Corrected timings comments. Timing values are most of the time us based. |
||||
5. Changed types names for stdint.h names. Helps on code portability |
||||
6. Renamed rand and srand to rand1 and srand1. Helps on code portability |
||||
7. Added some missing variables casts. Helps on code portability |
||||
8. Removed NULL definition from board.h |
||||
9. Added const variable attribute when necessary to functions prototypes |
||||
10. Moved ID1, ID2 and ID3 definition from board.h to board.c, usb-cdc-board.c and usb-dfu-board.c |
||||
11. Removed the definition of RAND_SEED. It has been replaced by a function named BoardGetRandomSeed |
||||
12. Renamed BoardMeasureBatterieLevel to BoardGetBatteryLevel |
||||
13. Added SetMaxPayloadLength API function to SX1272 and SX1276 radio drivers |
||||
14. Changed the name of Radio API Status function to GetStatus |
||||
15. AES/CMAC Changed types names for stdint.h names. Helps on code portability (Issue #20) |
||||
16. Moved __ffs function from utilities.h to spi-board.c. This function is only used there. |
||||
17. Utilities.c removed fputc function redefinition. |
||||
18. Replaced the usage of __IO attribute by volatile. |
||||
|
||||
* LoRaWAN |
||||
1. Added support for the US915 band (Normal mode and hybrid mode. Hybrid mode is a temporary configuration up until servers support it automatically) (Issue #16) |
||||
2. Corrected and simplified the downlink sequence counter management. |
||||
3. Removed the usage of PACKED attribute for data structures. |
||||
4. Renamed LoRaMacEvent_t into LoRaMacCallbacks_t and added a function pointer for getting battery level status |
||||
5. Renamed LoRaMacSetDutyCycleOn into LoRaMacSetTestDutyCycleOn |
||||
6. Renamed LoRaMacSetMicTest into LoRaMacTestSetMic |
||||
7. Increased the PHY buffer size to 250 |
||||
8. Removed IsChannelFree check on LoRaMacSetNextChannel function. LoRaWAN is an ALHOA protocol. (Pull request #8) |
||||
9. LoRaMacEventInfo.TxDatarate now returns LoRaWAN datarate (DR0 -> DR7) instead of (SF12 -> DF7) |
||||
10. Corrected channel mask management for EU868 band. |
||||
11. Corrected LoRaMacPrepareFrame behavior function when no applicative payload is present. |
||||
12. LoRaMac-board.h now implements the settings for the PHY layers specified by LoRaWAN 1.0 specification. ( EU433, CN780, EU868, US915 ) (Issue #19) |
||||
13. Added LORAMAC_MIN_RX1_DR_OFFSET and LORAMAC_MAX_RX1_DR_OFFSET definitions to LoRaMac-board.h. Can be different upon used PHY layer |
||||
14. Added the limitation of output power according to the number of enabled channels for US915 band. |
||||
15. Added the limitation of the applicative payload length according to the datarate. Does not yet take in account the MAC commands buffer. (Issue #15) |
||||
16. Corrected MacCommandBufferIndex management. (Issue #18) |
||||
|
||||
2015-08-07, v3.3.0 |
||||
* General |
||||
1. Added the support for LoRaWAN Class C devices. |
||||
2. Implemented the radios errata note workarounds. SX1276 errata 2.3 "Receiver Spurious Reception of a LoRa Signal" is not yet implemented. |
||||
3. Increased FSK SyncWord timeout value in order to listen for longer time if a down link is available or not. Makes FSK downlink more reliable. |
||||
4. Increased the UART USB FIFO buffer size in order to handle bigger chunks of data. |
||||
|
||||
* LoRaWAN |
||||
1. Renamed data rates as per LoRaWAN specification. |
||||
2. Added the support for LoRaWAN Class C devices. |
||||
3. Handling of the MAC commands was done incorrectly the condition to verify the length of the buffer has changed from < to <=. |
||||
4. Added the possibility to change the channel mask and number of repetitions trough SRV_MAC_LINK_ADR_REQ command when ADR is disabled. |
||||
5. Corrected Rx1DrOffset management. In previous version DR1 was missing for all offsets. |
||||
6. Changed confirmed messages function to use default datarate when ADR control is off. |
||||
7. After a Join accept the node falls back to the default datarate. Enables the user to Join a network using a different datarate from its own default one. |
||||
8. Corrected default FSK channel frequency. |
||||
9. Solved a firmware freezing when one of the following situations arrived in OnRxDone callback: bad address, bad MIC, bad frame. (Pull request #10) |
||||
10. Moved the MAC commands processing to the right places. FOpts field before the Payload and Port 0 just after the decryption. (Pull request #9) |
||||
11. Weird conditions to check datarate on cmd mac SRV_MAC_NEW_CHANNEL_REQ (Pull request #7) |
||||
12. Ignore join accept message if already joined (Pull request #6) |
||||
13. Channel index verification should use OR on SRV_MAC_NEW_CHANNEL_REQ command (Pull request #5) |
||||
14. Corrected the CFList management on JoinAccept. The for loop indexes were wrong. (Pull request #4) |
||||
15. Correction of AES key size (Pull request #3) |
||||
|
||||
2015-04-30, v3.2.0 |
||||
* General |
||||
1. Updated LoRaMac implementation according to LoRaWAN R1.0 specification |
||||
2. General cosmetics corrections |
||||
3. Added the support of packed structures when using IAR tool chain |
||||
4. Timers: Added a function to get the time in us. |
||||
5. Timers: Added a typedef for time variables (TimerTime_t) |
||||
6. Radios: Changed the TimeOnAir radio function to return a uint32_t value instead of a double. The value is in us. |
||||
7. Radios: Corrected the 250 kHz bandwidth choice for the FSK modem |
||||
8. GPS: Added a function that returns if the GPS has a fix or not. |
||||
9. GPS: Changed the GetPosition functions to return a latitude and longitude of 0 and altitude of 65535 when no GPS fix. |
||||
|
||||
* LoRaWAN |
||||
1. Removed support for previous LoRaMac/LoRaWAN specifications |
||||
2. Added missing MAC commands and updated others when necessary |
||||
* Corrected the Port 0 MAC commands decryption |
||||
* Changed the way the upper layer is notified. Now it is only notified |
||||
when all the operations are finished. |
||||
|
||||
When a ClassA Tx cycle starts a timer is launched to check every second if everything is finished. |
||||
|
||||
* Added a new parameter to LoRaMacEventFlags structure that indicates on which Rx window the data has been received. |
||||
* Added a new parameter to LoRaMacEventFlags structure that indicates if there is applicative data on the received payload. |
||||
* Corrected ADR MAC command behavior |
||||
* DutyCycle enforcement implementation (EU868 PHY only) |
||||
|
||||
**REMARK 1** *The regulatory duty cycle enforcement is enabled by default |
||||
which means that for lower data rates the node may not transmit a new |
||||
frame as quickly as requested. |
||||
The formula used to compute the node idle time is* |
||||
|
||||
*Toff = TimeOnAir / DutyCycle - TxTimeOnAir* |
||||
|
||||
*Example:* |
||||
*A device just transmitted a 0.5 s long frame on one default channel. |
||||
This channel is in a sub-band allowing 1% duty-cycle. Therefore this |
||||
whole sub-band (868 MHz - 868.6 MHz) will be unavailable for 49.5 s.* |
||||
|
||||
**REMARK 2** *The duty cycle enforcement can be disabled for test |
||||
purposes by calling the LoRaMacSetDutyCycleOn function with false |
||||
parameter.* |
||||
* Implemented aggregated duty cycle management |
||||
* Added a function to create new channels |
||||
* Implemented the missing features on the JoinAccept MAC command |
||||
* Updated LoRaMacJoinDecrypt function to handle the CFList field. |
||||
3. Due to duty cycle management the applicative API has changed. |
||||
All applications must be updated accordingly. |
||||
4. Added the possibility to chose to use either public or private networks |
||||
|
||||
2015-01-30, v3.1.0 |
||||
* General |
||||
1. Started to add support for CooCox CoIDE Integrated Development Environment. |
||||
Currently only LoRaMote and SensorNode platform projects are available. |
||||
2. Updated GCC compiler linker scripts. |
||||
3. Added the support of different tool chains for the HardFault_Handler function. |
||||
|
||||
4. Corrected Radio drivers I&Q signals inversion to be possible in Rx and in Tx. |
||||
Added some missing radio state machine initialization. |
||||
5. Changed the RSSI values type from int8_t to int16_t. We can have RSSI values below -128 dBm. |
||||
6. Corrected SNR computation on RxDone interrupt. |
||||
7. Updated radio API to support FHSS and CAD handling. |
||||
8. Corrected in SetRxConfig function the FSK modem preamble register name. |
||||
9. Added an invalid bandwidth to the Bandwidths table in order to avoid an error |
||||
when selecting 250 kHz bandwidth when using FSK modem. |
||||
|
||||
10. Corrected RTC alarm setup which could be set to an invalid date. |
||||
11. Added another timer in order increment the tick counter without blocking the normal timer count. |
||||
12. Added the possibility to switch between low power timers and normal timers on the fly. |
||||
13. I2C driver corrected the 2 bytes internal address management. |
||||
Corrected buffer read function when more that 1 byte was to be read. |
||||
Added a function to wait for the I2C bus to become IDLE. |
||||
14. Added an I2C EEPROM driver. |
||||
15. Corrected and improved USB Virtual COM Port management files. |
||||
Corrected the USB CDC and USB UART drivers. |
||||
16. Added the possibility to analyze a hard fault interrupt. |
||||
|
||||
* LoRaMac |
||||
1. Corrected RxWindow2 Datarate management. |
||||
2. SrvAckRequested variable was never reset. |
||||
3. Corrected tstIndoor applications for LoRaMac R3.0 support. |
||||
4. LoRaMac added the possibility to configure almost all the MAC parameters. |
||||
5. Corrected the LoRaMacSetNextChannel function. |
||||
6. Corrected the port 0 MAC command decoding. |
||||
7. Changed all structures declarations to be packed. |
||||
8. Corrected the Acknowledgment retries management when only 1 trial is needed. |
||||
Before the device was issuing at least 2 trials. |
||||
9. Corrected server mac new channel req answer. |
||||
10. Added the functions to read the Up and Down Link sequence counters. |
||||
11. Corrected SRV_MAC_RX2_SETUP_REQ frequency handling. Added a 100 multiplication. |
||||
12. Corrected SRV_MAC_NEW_CHANNEL_REQ. Removed the DutyCycle parameter decoding. |
||||
13. Automatically activate the channel once it is created. |
||||
14. Corrected NbRepTimeoutTimer initial value. RxWindow2Delay already contains RxWindow1Delay in it. |
||||
|
||||
2014-07-18, v3.0.0 |
||||
* General |
||||
1. Added to Radio API the possibility to select the modem. |
||||
2. Corrected RSSI reading formulas as well as changed the RSSI and SNR values from double to int8_t type. |
||||
3. Changed radio callbacks events to timeout when it is a timeout event and error when it is a CRC error. |
||||
4. Radio API updated. |
||||
5. Updated ping-pong applications. |
||||
6. Updated tx-cw applications. |
||||
7. Updated LoRaMac applications in order to handle LoRaMac returned functions calls status. |
||||
8. Updated LoRaMac applications to toggle LED2 each time there is an application payload down link. |
||||
9. Updated tstIndoor application to handle correctly more than 6 channels. |
||||
10. Changed the MPL3115 altitude variable from unsigned to signed value. |
||||
11. Replaced the usage of pow(2, n) by defining POW2 functions. Saves ~2 KBytes of code. |
||||
12. Corrected an issue potentially arriving when LOW_POWER_MODE_ENABLE wasn't defined. |
||||
A timer interrupt could be generated while the TimerList could already be emptied. |
||||
|
||||
|
||||
* LoRaMac |
||||
1. Implemented LoRaMac specification R3.0 changes. |
||||
|
||||
2. MAC commands implemented |
||||
* LinkCheckReq **YES** |
||||
* LinkCheckAns **YES** |
||||
* LinkADRReq **YES** |
||||
* LinkADRAns **YES** |
||||
* DutyCycleReq **YES** |
||||
* DutyCycleAns **YES** |
||||
* Rx2SetupReq **YES** |
||||
* Rx2SetupAns **YES** |
||||
* DevStatusReq **YES** |
||||
* DevStatusAns **YES** |
||||
* JoinReq **YES** |
||||
* JoinAccept **YES** |
||||
* NewChannelReq **YES** |
||||
* NewChannelAns **YES** |
||||
|
||||
3. Features implemented |
||||
* Possibility to shut-down the device **YES** |
||||
|
||||
Possible by issuing DutyCycleReq MAC command. |
||||
* Duty cycle management enforcement **NO** |
||||
* Acknowledgments retries **YES** |
||||
* Unconfirmed messages retries **YES** |
||||
|
||||
2014-07-10, v2.3.RC2 |
||||
* General |
||||
1. Corrected all radios antenna switch low power mode handling. |
||||
2. SX1276: Corrected antenna switch control. |
||||
|
||||
2014-06-06, v2.3.RC1 |
||||
* General |
||||
1. Added the support for SX1276 radio. |
||||
2. Radio continuous reception mode correction. |
||||
3. Radio driver RxDone callback function API has changed ( size parameter is no more a pointer). |
||||
Previous function prototype: |
||||
|
||||
void ( *RxDone )( uint8_t *payload, uint16_t *size, double rssi, double snr, uint8_t rawSnr ); |
||||
|
||||
New function prototype: |
||||
|
||||
void ( *RxDone )( uint8_t *payload, uint16_t size, double rssi, double snr, uint8_t rawSnr ); |
||||
|
||||
4. Added Bleeper-76 and SensorNode platforms support. |
||||
5. Added to the radio drivers a function that generates a random value from |
||||
RSSI readings. |
||||
6. Added a project to transmit a continuous wave and a project to measure the |
||||
the radio sensitivity. |
||||
7. Added a bootloader project for the LoRaMote and SensorNode platforms. |
||||
8. The LoRaMac application for Bleeper platforms now sends the Selector and LED status plus the sensors values. |
||||
* The application payload for the Bleeper platforms is as follows: |
||||
|
||||
LoRaMac port 1: |
||||
|
||||
{ 0xX0/0xX1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } |
||||
---------- ---------- ---------- ---------- ---- |
||||
| | | | | |
||||
SELECTOR/LED PRESSURE TEMPERATURE ALTITUDE BATTERY |
||||
MSB nibble = SELECTOR (barometric) |
||||
LSB bit = LED |
||||
9. Redefined rand() and srand() standard C functions. These functions are |
||||
redefined in order to get the same behavior across different compiler |
||||
tool chains implementations. |
||||
10. GPS driver improvements. Made independent of the board platform. |
||||
11. Simplified the RTC management. |
||||
12. Added a function to the timer driver that checks if a timer is already in |
||||
the list or not. |
||||
13. Added the UART Overrun bit exception handling to the UART driver. |
||||
14. Removed dependency of spi-board files to the "__builtin_ffs" function. |
||||
This function is only available on GNU compiler tool suite. Removed --gnu |
||||
compiler option from Keil projects. Added own __ffs function |
||||
implementation to utilities.h file. |
||||
15. Removed obsolete class1 devices support. |
||||
16. Known bugs correction. |
||||
|
||||
* LoRaMac |
||||
1. MAC commands implemented |
||||
* LinkCheckReq **YES** |
||||
* LinkCheckAns **YES** |
||||
* LinkADRReq **YES** |
||||
* LinkADRAns **YES** |
||||
* DutyCycleReq **YES** (LoRaMac specification R2.2.1) |
||||
* DutyCycleAns **YES** (LoRaMac specification R2.2.1) |
||||
* Rx2SetupReq **YES** (LoRaMac specification R2.2.1) |
||||
* Rx2SetupAns **YES** (LoRaMac specification R2.2.1) |
||||
* DevStatusReq **YES** |
||||
* DevStatusAns **YES** |
||||
* JoinReq **YES** |
||||
* JoinAccept **YES** (LoRaMac specification R2.2.1) |
||||
* NewChannelReq **YES** (LoRaMac specification R2.2.1) |
||||
* NewChannelAns **YES** (LoRaMac specification R2.2.1) |
||||
2. Features implemented |
||||
* Possibility to shut-down the device **YES** |
||||
|
||||
Possible by issuing DutyCycleReq MAC command. |
||||
* Duty cycle management enforcement **NO** |
||||
* Acknowledgments retries **WORK IN PROGRESS** |
||||
|
||||
Not fully debugged. Disabled by default. |
||||
* Unconfirmed messages retries **WORK IN PROGRESS** (LoRaMac specification R2.2.1) |
||||
3. Implemented LoRaMac specification R2.2.1 changes. |
||||
4. Due to new specification the LoRaMacInitNwkIds LoRaMac API function had |
||||
to be modified. |
||||
|
||||
Previous function prototype: |
||||
|
||||
void LoRaMacInitNwkIds( uint32_t devAddr, uint8_t *nwkSKey, uint8_t *appSKey ); |
||||
|
||||
New function prototype: |
||||
|
||||
void LoRaMacInitNwkIds( uint32_t netID, uint32_t devAddr, uint8_t *nwkSKey, uint8_t *appSKey ); |
||||
5. Changed the LoRaMac channels management. |
||||
6. LoRaMac channels definition has been moved to LoRaMac-board.h file |
||||
located in each specific board directory. |
||||
|
||||
2014-04-07, v2.2.0 |
||||
* General |
||||
1. Added IMST SK-iM880A starter kit board support to the project. |
||||
* The application payload for the SK-iM880A platform is as follows: |
||||
|
||||
LoRaMac port 3: |
||||
|
||||
{ 0x00/0x01, 0x00, 0x00, 0x00 } |
||||
---------- ----- ---------- |
||||
| | | |
||||
LED POTI VDD |
||||
2. Ping-Pong applications have been split per supported board. |
||||
3. Corrected the SX1272 output power management. |
||||
Added a variable to store the current Radio channel. |
||||
Added missing FSK bit definition. |
||||
4. Made fifo functions coding style coherent with the project. |
||||
5. UART driver is now independent of the used MCU |
||||
|
||||
2014-03-28, v2.1.0 |
||||
* General |
||||
1. The timers and RTC management has been rewritten. |
||||
2. Improved the UART and UP501 GPS drivers. |
||||
3. Corrected GPIO pin names management. |
||||
4. Corrected the antenna switch management in the SX1272 driver. |
||||
5. Added to the radio driver the possibility to choose the preamble length |
||||
and rxSingle symbol timeout in reception. |
||||
6. Added Hex coder selector driver for the Bleeper board. |
||||
7. Changed copyright Unicode character to (C) in all source files. |
||||
|
||||
* LoRaMac |
||||
1. MAC commands implemented |
||||
* LinkCheckReq **YES** |
||||
* LinkCheckAns **YES** |
||||
* LinkADRReq **YES** |
||||
* LinkADRAns **YES** |
||||
* DevStatusReq **YES** |
||||
* DevStatusAns **YES** |
||||
* JoinReq **YES** |
||||
* JoinAccept **YES** |
||||
2. Added acknowledgments retries management. |
||||
Split the LoRaMacSendOnChannel function in LoRaMacPrepareFrame and |
||||
LoRaMacSendFrameOnChannel. LoRaMacSendOnChannel now calls the 2 newly |
||||
defined functions. |
||||
|
||||
**WARNING**: By default the acknowledgment retries specific code isn't |
||||
enabled. The current http://iot.semtech.com server version doesn't support |
||||
it. |
||||
|
||||
3. Corrected issues on JoinRequest and JoinAccept MAC commands. |
||||
Added LORAMAC_EVENT_INFO_STATUS_MAC_ERROR event info status. |
||||
|
||||
2014-02-21, v2.0.0 |
||||
|
||||
* General |
||||
1. The LoRaMac applications now sends the LED status plus the sensors values. |
||||
For the LoRaMote platform the application also sends the GPS coordinates. |
||||
* The application payload for the Bleeper platform is as follows: |
||||
|
||||
LoRaMac port 1: |
||||
|
||||
{ 0x00/0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } |
||||
---------- ---------- ---------- ---------- ---- |
||||
| | | | | |
||||
LED PRESSURE TEMPERATURE ALTITUDE BATTERY |
||||
(barometric) |
||||
* The application payload for the LoRaMote platform is as follows: |
||||
|
||||
LoRaMac port 2: |
||||
|
||||
{ 0x00/0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } |
||||
---------- ---------- ---------- ---------- ---- ---------------- ---------------- ---------- |
||||
| | | | | | | | |
||||
LED PRESSURE TEMPERATURE ALTITUDE BATTERY LATITUDE LONGITUDE ALTITUDE |
||||
(barometric) (gps) |
||||
2. Adapted applications to the new MAC layer API. |
||||
3. Added sensors drivers implementation. |
||||
4. Corrected new or known issues. |
||||
* LoRaMac |
||||
1. MAC commands implemented |
||||
* LinkCheckReq **YES** |
||||
* LinkCheckAns **YES** |
||||
* LinkADRReq **YES** |
||||
* LinkADRAns **YES** |
||||
* DevStatusReq **YES** |
||||
* DevStatusAns **YES** |
||||
* JoinReq **YES (Not tested)** |
||||
* JoinAccept **YES (Not tested)** |
||||
2. New MAC layer application API implementation. |
||||
* Timers and RTC. |
||||
1. Still some issues. They will be corrected on next revisions of the firmware. |
||||
|
||||
2014-01-24, v1.1.0 |
||||
|
||||
* LoRaMac |
||||
1. MAC commands implemented |
||||
* LinkCheckReq **NO** |
||||
* LinkCheckAns **NO** |
||||
* LinkADRReq **YES** |
||||
* LinkADRAns **YES** |
||||
* DevStatusReq **YES** |
||||
* DevStatusAns **YES** |
||||
2. Implemented an application LED control |
||||
If the server sends on port 1 an application payload of one byte with |
||||
the following contents: |
||||
|
||||
0: LED off |
||||
1: LED on |
||||
The node transmits periodically on port 1 the LED status on 1st byte and |
||||
the message "Hello World!!!!" the array looks like: |
||||
|
||||
{ 0, 'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', '!', '!', '!', '!' } |
||||
* Timers and RTC. |
||||
1. Corrected issues existing in the previous version |
||||
2. Known bugs are: |
||||
* There is an issue when launching an asynchronous Timer. Will be solved |
||||
in a future version |
||||
|
||||
2014-01-20, v1.1.RC1 |
||||
|
||||
* Added Doc directory. The directory contains: |
||||
1. LoRa MAC specification |
||||
2. Bleeper board schematic |
||||
* LoRaMac has been updated according to Release1 of the specification. Main changes are: |
||||
1. MAC API changed. |
||||
2. Frame format. |
||||
3. ClassA first ADR implementation. |
||||
4. MAC commands implemented |
||||
* LinkCheckReq **NO** |
||||
* LinkCheckAns **NO** |
||||
* LinkADRReq **YES** |
||||
* LinkADRAns **NO** |
||||
* DevStatusReq **NO** |
||||
* DevStatusAns **NO** |
||||
|
||||
* Timers and RTC rewriting. Known bugs are: |
||||
1. The Radio wakeup time is taken in account for all timings. |
||||
2. When opening the second reception window the microcontroller sometimes doesn't enter in low power mode. |
||||
|
||||
2013-11-28, v1.0.0 |
||||
|
||||
* Initial version of the LoRa MAC node firmware implementation. |
@ -0,0 +1,182 @@ |
||||
@verbatim |
||||
****************************************************************************** |
||||
* |
||||
* Portions COPYRIGHT 2017 STMicroelectronics |
||||
* |
||||
* @file st_readme.txt |
||||
* @author MCD Application Team |
||||
* @brief This file lists the main modification done by STMicroelectronics on |
||||
* LoRa for integration with STM32Cube solution. |
||||
* For more details on LoRa implementation on STM32Cube, please refer |
||||
* to UM2073 "STM32 LORA01 software expansion for STM32Cube " |
||||
****************************************************************************** |
||||
* @attention |
||||
* |
||||
* <h2><center>© Copyright (c) 2017 STMicroelectronics International N.V. |
||||
* All rights reserved.</center></h2> |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted, provided that the following conditions are met: |
||||
* |
||||
* 1. Redistribution of source code must retain the above copyright notice, |
||||
* this list of conditions and the following disclaimer. |
||||
* 2. 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. |
||||
* 3. Neither the name of STMicroelectronics nor the names of other |
||||
* contributors to this software may be used to endorse or promote products |
||||
* derived from this software without specific written permission. |
||||
* 4. This software, including modifications and/or derivative works of this |
||||
* software, must execute solely and exclusively on microcontroller or |
||||
* microprocessor devices manufactured by or for STMicroelectronics. |
||||
* 5. Redistribution and use of this software other than as permitted under |
||||
* this license is void and will automatically terminate your rights under |
||||
* this license. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" |
||||
* AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT |
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A |
||||
* PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY |
||||
* RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT |
||||
* SHALL STMICROELECTRONICS OR CONTRIBUTORS 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. |
||||
* |
||||
****************************************************************************** |
||||
@endverbatim |
||||
|
||||
### V1.1.2/08-September-2017 ### |
||||
=============================== |
||||
+ Implements LoRa Mac 4.4.0 release from Semtech/StackForce |
||||
https://github.com/Lora-net/LoRaMac-node/tree/f42be67be402a40b3586724800771bfe13fb18e6 |
||||
|
||||
+ AckTimeoutRetriesCounter must be reset every time a new request (unconfirmed or confirmed) is performed. |
||||
+ Added verification for the power parameter in order to check that it is greater or equal to 0. |
||||
|
||||
+ Enhancement for regions without FSK modulation support. |
||||
+ Bug fix for RX window 2 in class c mode. |
||||
+ AdrAckReq bit must be set to false as soon as we reach the lowest datarate. |
||||
+ MacCommandsBufferIndex must be reset when the mac commands are being sent on port 0. |
||||
+ Fixed RegionCommonSetBandTxDone in order to also update band->LastTxDoneTime when performing the Join procedure. |
||||
+ Added verification of payload size for Unconfirmed and Confirmed messages depending on Dwell time. |
||||
|
||||
+ Added missing Rx1 timeout handling. |
||||
+ Updated all regions to use MAX output power by default. |
||||
+ Merge remote-tracking branch 'origin/develop' into develop |
||||
+ Bug fix in KR920 - update the maxEIRP calculation for continuous wave |
||||
+ Bug fix in IN865 - Update the band of the default channels |
||||
+ Bug fix in AS923 - for RX use always the payload limitation of dwell 0 |
||||
+ Update function RegionCommonChanVerifyDr. Perform an 'AND' operation for security |
||||
+ Move the verification of ADR parameters into the common section. Update all regions with the related changes |
||||
+ Update comment for function RegionLinkAdrReq |
||||
+ Apply variables to data structure LinkAdrReqParams_t |
||||
+ Bug fix for KR920 |
||||
+ Rename data structure LinkAdrParams_t |
||||
+ Issue(#238): Apply missing variable in sSetBandTxDoneParams |
||||
+ Bug fix in processing MAC commands for case SRV_MAC_TX_PARAM_SETUP_REQ. |
||||
+ Isse(#238): Apply missing variable in struct sBand |
||||
+ Update the MAC to enable the server to control the Channels Mask and the number of transmissions even ADR is off |
||||
+ Issue(#238): Update the backoff procedure for all regions. Move code parts into the common section |
||||
+ Update implementation to allow automatic MAC answers on port 0 |
||||
+ Issue(#253): Delete all preconfigured channels when performing a join request |
||||
+ Initialize variable phyParam in functions RegionXXGetPhyParam |
||||
+ Remove assert_param from the radio drivers |
||||
+ Synchronize function RegionXXTxConfig |
||||
+ Update carrier sense functionality for LBT |
||||
+ Issue(#259): Update comment for variable HasLoopedThroughMain |
||||
+ Issue(#257): Fix typo in OnRxWindow2TimerEvent |
||||
+ Change scientific notation to numeric notation |
||||
+ Merge pull request #260 from clmklk/AU915 |
||||
|
||||
+ AU915: update Datarate limits according to LoRaWan 1.0.2rB |
||||
+ AU915: update Downstream datarate table according to LoRaWan 1.0.2rB |
||||
|
||||
+ Merge pull request #225 from OpenChirp/patch_1 |
||||
|
||||
### V1.1.1/01-June-2017 ### |
||||
=============================== |
||||
+ Implements LoRa Mac from Semtech/StackForce develop branch (30-May-2017 commits, 4.4.0 release candidate) |
||||
https://github.com/Lora-net/LoRaMac-node/tree/e2f35db75c1b449379d3b520c2d4e5922a9f5c81 |
||||
|
||||
+ Issue(235): Update functions RegionXXNextChannel. |
||||
+ Issue(238): Update initialization value of nextTxDelay. |
||||
+ Issue(234): Report back the aggregated time off. |
||||
+ Issue(232): Relocate function call to CalculateBackOff. |
||||
+ Issue(239): Update band TX power to the maximum. |
||||
+ Update LimitTxPower for US915. |
||||
+ Bug fix in function RegionCN470Verify. |
||||
+ Bug fix in function RegionAU915Verify. |
||||
+ Issue(229): Fix issue when receiving frames in second RX2 in Class C. |
||||
+ Add a ommand to get the next lower datarate. |
||||
+ Group initializations |
||||
+ Update regional definitions of KR920. |
||||
+ Update regional definitions of EU868. |
||||
+ Issue(239): Update regional definitions of AU915. |
||||
+ Update regional definitions of AU915. |
||||
+ Update regional definitions of AS923. |
||||
+ Update TX power computations. |
||||
|
||||
+ Remove duplicated call to ApplyDrOffset in function RegionRxConfig. |
||||
+ Relocate the datarate, up- and downlink dwell time into a structure. |
||||
+ Change API of RegionGetPhyParam and the related functions. |
||||
+ Bug fix in function LoRaMacQueryTxPossible. |
||||
+ Apply patch for dwell time and minimum datarate. |
||||
+ Change the default datarate to DR_2 for AS923. |
||||
+ Take dwell time for ADR calculations and datarate settings into account. |
||||
+ Update LoRaMacQueryTxPossible to reset the MAC commands buffer. |
||||
|
||||
+ Issue(#221): Add the dwell time in function ValidatePayloadLength. |
||||
+ Increase the transmission and reception timeout for KR920. |
||||
+ Bug fix in functions OnRxWindowXTimerEvent. |
||||
+ Remove datarate assignment. |
||||
+ Setup the downlink and uplink dwell time default value to 1. |
||||
+ Add frequency range check for AS923 |
||||
+ Issue(#221): Bug fix in max payload size calculation. |
||||
|
||||
+ GitHub reported issues corrections. |
||||
+ Changed the AdrAckCounter handling as expected by the test houses. |
||||
+ Fix an issue where the node stopped transmitting. |
||||
+ Removed useless LoRaMacPayload buffer. |
||||
+ MAC layer indications handling simplification. |
||||
+ Relocate parameter settings from ResetMacParameters to the initialization. |
||||
|
||||
### V1.1.0/27-February-2017 ### |
||||
=============================== |
||||
+ Implements LoRa Mac 4.4.0 from Semtech/StackForce from the develop branch |
||||
|
||||
### V1.0.3/01-January-2017 ### |
||||
=============================== |
||||
+ Read date between 2 successive read time to make sure date is ok |
||||
|
||||
### V1.0.2/15-November-2016 ### |
||||
=============================== |
||||
+ Corrected 1 bug in LoRaMac-board.h: RX_WND_2_CHANNEL for EU is now back at DR_0 |
||||
+ Corrected 1 bug in LoRaMac.c for dataRate adaptation |
||||
|
||||
### V1.0.1/15-September-2016 ### |
||||
=============================== |
||||
+ Implements LoRa Mac 4.3.0 from Semtech/StackForce |
||||
|
||||
### V1.0.0/01-July-2016 ### |
||||
=============================== |
||||
+ First R1.0.0 customized version for STM32Cube solution. |
||||
+ Comissioning_template.h in /Conf contains all Lora Ids to connect on LoRa network |
||||
It is provided as a template. It must be moved to /Projects/inc/ as Comissioning.h |
||||
+ All files in Conf/src are provided as template and must be copied in /Projects/src. |
||||
+ All files in Conf/inc are provided as template and must be copied in /Projects/inc. |
||||
#if 0 and #endif must be removed to enable the template in the user directory |
||||
+ Implements LoRa Mac 4.2.0 from Semtech/StackForce |
||||
+ \Lora\Mac\LoRaMac.c : replace floating exponent e3 and e6 by int number |
||||
+ \Lora\Utilities\delay.c : cast uint32_t |
||||
+ Modified intensively timeServer.c |
||||
+ new low layer interfacing Cube HAL (hw_rtc.c, hw_gpio.c and hw_spi.c) |
||||
+ added lora.c as an interface layer to ease product integration |
||||
|
||||
|
||||
* <h3><center>© COPYRIGHT STMicroelectronics</center></h3> |
||||
*/ |
||||
|
Loading…
Reference in new issue