feat support webserver function include net_4g/net_lora for xishutong-arm32, compile OK

This commit is contained in:
Liu_Weichao 2023-12-22 15:14:20 +08:00
parent e7047a752d
commit e292ce2fc8
93 changed files with 24135 additions and 142 deletions

3
.gitmodules vendored
View File

@ -22,9 +22,6 @@
[submodule "Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/xidatong-riscv64/kendryte-sdk/kendryte-sdk-source"]
path = Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/xidatong-riscv64/kendryte-sdk/kendryte-sdk-source
url = https://www.gitlink.org.cn/chunyexixiaoyu/kendryte-sdk-source.git
[submodule "APP_Framework/lib/lorawan/lora_radio_driver"]
path = APP_Framework/lib/lorawan/lora_radio_driver
url = https://gitlink.org.cn/xuos/lora_radio_driver
[submodule "APP_Framework/lib/lorawan/lorawan_devicenode"]
path = APP_Framework/lib/lorawan/lorawan_devicenode
url = https://gitlink.org.cn/xuos/lorawan_devicenode.git

View File

@ -4,3 +4,8 @@ menuconfig USE_MONGOOSE
select BSP_USING_SDIO
select BSP_USING_W5500
select BSP_USING_ETHERNET
select SUPPORT_CONNECTION_FRAMEWORK
select CONNECTION_ADAPTER_4G
select ADAPTER_EC200A
select LIB_USING_LORAWAN
select LIB_USING_LORA_RADIO

View File

@ -34,6 +34,7 @@ Modification:
#include <sys_arch.h>
#include <lwip/sockets.h>
#include "lwip/sys.h"
#include <adapter.h>
/*******************************************************************************
* Local variable definitions ('static')
@ -50,6 +51,26 @@ static struct netdev* p_netdev_webserver;
static struct netdev* p_netdev_ethernet;
static pthread_t tid;
#define WB_EVENT_TASK_STACK_SIZE 4096
#define WB_EVENT_TASK_PRIO 20
#define WB_4G_CONNECT 0x0001
#define WB_4G_DISCONNECT 0x0002
#define WB_MQTT_CONNECT 0x0004
#define WB_MQTT_DISCONNECT 0x0008
#define WB_LORA_CONNECT 0x0010
#define WB_LORA_DISCONNECT 0x0020
#define WB_ETHERNET_CONNECT 0x0040
#define WB_ETHERNET_DISCONNECT 0x0080
#define WB_EVENT_ALL (WB_4G_CONNECT | WB_4G_DISCONNECT | \
WB_MQTT_CONNECT | WB_MQTT_DISCONNECT | \
WB_LORA_CONNECT | WB_LORA_DISCONNECT | \
WB_ETHERNET_CONNECT | WB_ETHERNET_DISCONNECT)
static int wb_event;
static unsigned int status = 0;
static pthread_t wb_event_task;
/*define device info*/
static const char* device_name = "矽数通4G";
static const char* device_type = "xishutong-arm32";
@ -76,10 +97,11 @@ static struct net_4g_info {
char map_ip[20];
char connect_ip[20];
char operator[20];
int signal_strength;
char signal_strength[20];
char connect_port[20];
} net_4g_info;
int close_4g_function = 0;
struct Adapter* adapter;
static struct net_4g_mqtt_info {
char topic[20];
@ -88,10 +110,17 @@ static struct net_4g_mqtt_info {
int client_id;
int connect_status;
} net_4g_mqtt_info;
int close_mqtt_function = 0;
/*define net LoRa info*/
struct net_lora_info
{
uint32_t frequency; // frequency
uint8_t sf; // spreadfactor
uint8_t bw; // bandwidth
uint32_t connect_status; //connect status
uint8_t lora_init_flag; //if 1 means already init
} net_lora_info;
/*define net Ethernet info*/
static struct net_ethernet_info {
@ -106,17 +135,6 @@ static struct net_ethernet_info {
int connect_status;
} net_ethernet_info;
#define LWIP_TCP_CLIENT_TASK_STACK_SIZE 4096
#define LWIP_TCP_CLIENT_TASK_PRIO 20
#define ETHERNET_CONNECT 0x01
#define ETHERNET_DISCONNECT 0x02
#define ETHERNET_ALL (ETHERNET_CONNECT | ETHERNET_DISCONNECT)
static int ethernet_event;
static unsigned int status = 0;
static pthread_t tcp_client_task;
static int socket_fd = -1;
static char tcp_ethernet_ipaddr[] = {192, 168, 130, 77};
@ -210,6 +228,70 @@ static void Rs485Configure(int baud_rate, int data_bit, int stop_bit, int parity
baud_rate, data_bit, stop_bit, parity);
}
/*******************************************************************************
* Function implementation - define net 4G info
******************************************************************************/
static void Net4gGetInfo(char *ip, char *operator, char *signal_strength)
{
//to do
}
static void Net4gConnect(void)
{
int ec200a_baud_rate = 115200;
const char *send_msg = "Adapter_4G Test";
adapter->socket.socket_id = 0;
AdapterDeviceOpen(adapter);
AdapterDeviceControl(adapter, OPE_INT, &ec200a_baud_rate);
AdapterDeviceConnect(adapter, CLIENT, net_4g_info.connect_ip, net_4g_info.connect_port, IPV4);
}
static void Net4gDisconnect(void)
{
uint8_t priv_net_group = IP_PROTOCOL;
AdapterDeviceDisconnect(adapter, &priv_net_group);
}
/*******************************************************************************
* Function implementation - define net 4G MQTT info
******************************************************************************/
static void NetMqttConnect(void)
{
//to do
}
static void NetMqttDisconnect(void)
{
//to do
}
/*******************************************************************************
* Function implementation - define net LoRa info
******************************************************************************/
static void NetLoraConnect(void)
{
char* init_params[2] = {"TestLoraRadio", "probe"};
char* tx_params[4] = {"TestLoraRadio", "tx", "1", "2000"};
extern int TestLoraRadio(int argc, char *argv[]);
if (0 == net_lora_info.lora_init_flag) {
TestLoraRadio(2, init_params);
net_lora_info.lora_init_flag = 1;
}
TestLoraRadio(4, tx_params);
net_lora_info.connect_status = 1;
}
static void NetLoraDisconnect(void)
{
char* disconnect_params[2] = {"TestLoraRadio", "txdone"};
extern int TestLoraRadio(int argc, char *argv[]);
TestLoraRadio(2, disconnect_params);
net_lora_info.connect_status = 0;
}
/*******************************************************************************
* Function implementation - define net Ethernet info
******************************************************************************/
@ -271,6 +353,7 @@ static void TcpClientConnect(void)
}
printf("TCP connect %s:%d success, start to send.\n", net_ethernet_info.targetIp, tcp_socket_port);
net_ethernet_info.connect_status = 1;
while (cnt --) {
printf("Lwip client is running.\n");
@ -287,37 +370,7 @@ static void TcpClientDisconnect(void)
{
printf("TCP disconnect\n");
closesocket(socket_fd);
}
static void *TcpSocketClientTask(void *arg)
{
ethernet_event = PrivEventCreate(LINKLIST_FLAG_FIFO);
while(1) {
if (0 == PrivEventProcess(ethernet_event, ETHERNET_ALL, EVENT_OR | EVENT_AUTOCLEAN, 0, &status)) {
switch( status ) {
case ETHERNET_CONNECT:
TcpClientConnect();
break;
case ETHERNET_DISCONNECT:
TcpClientDisconnect();
break;
}
}
}
}
static void TcpClientSocket(void)
{
char task_name[] = "tcp_client_task";
pthread_args_t args;
args.pthread_name = task_name;
pthread_attr_t attr;
attr.schedparam.sched_priority = LWIP_TCP_CLIENT_TASK_PRIO;
attr.stacksize = LWIP_TCP_CLIENT_TASK_STACK_SIZE;
PrivTaskCreate(&tcp_client_task, &attr, &TcpSocketClientTask, (void *)&args);
PrivTaskStartup(&tcp_client_task);
net_ethernet_info.connect_status = 0;
}
/*******************************************************************************
@ -341,6 +394,58 @@ static void PlcInfoWriteToSd(const char *json)
}
}
/*******************************************************************************
* Function implementation - WebserverEventTask
******************************************************************************/
static void *WebserverEventTask(void *arg)
{
wb_event = PrivEventCreate(LINKLIST_FLAG_FIFO);
while(1) {
if (0 == PrivEventProcess(wb_event, WB_EVENT_ALL, EVENT_OR | EVENT_AUTOCLEAN, 0, &status)) {
switch( status ) {
case WB_4G_CONNECT:
Net4gConnect();
break;
case WB_4G_DISCONNECT:
Net4gDisconnect();
break;
case WB_MQTT_CONNECT:
NetMqttConnect();
break;
case WB_MQTT_DISCONNECT:
NetMqttDisconnect();
break;
case WB_LORA_CONNECT:
NetLoraConnect();
break;
case WB_LORA_DISCONNECT:
NetLoraDisconnect();
break;
case WB_ETHERNET_CONNECT:
TcpClientConnect();
break;
case WB_ETHERNET_DISCONNECT:
TcpClientDisconnect();
break;
}
}
}
}
static void WbEventInit(void)
{
char task_name[] = "wb_event_task";
pthread_args_t args;
args.pthread_name = task_name;
pthread_attr_t attr;
attr.schedparam.sched_priority = WB_EVENT_TASK_PRIO;
attr.stacksize = WB_EVENT_TASK_STACK_SIZE;
PrivTaskCreate(&wb_event_task, &attr, &WebserverEventTask, (void *)&args);
PrivTaskStartup(&wb_event_task);
}
/*******************************************************************************
* Function implementation - webserver
******************************************************************************/
@ -418,21 +523,26 @@ static void fn(struct mg_connection* c, int ev, void* ev_data, void* fn_data)
}
/*define net 4G info*/
else if (mg_http_match_uri(hm, "/net/get4gInfo")) {
Net4gGetInfo(net_4g_info.map_ip, net_4g_info.operator, net_4g_info.signal_strength);
mg_http_reply(c, 200, "Content-Type: application/json\r\n",
"{%m:%m, %m:%m, %m:%d}\n",
MG_ESC("mapIp"), MG_ESC(net_4g_info.map_ip),
MG_ESC("operator"), MG_ESC(net_4g_info.operator),
MG_ESC("signalIntensity"), net_4g_info.signal_strength);
MG_ESC("signalIntensity"), MG_ESC(net_4g_info.signal_strength));
} else if (mg_http_match_uri(hm, "/net/set4gInfo")) {
struct mg_str json = hm->body;
update_config_array(json, "$.publicIp", net_4g_info.connect_ip);
update_config_array(json, "$.publicPort", net_4g_info.connect_port);
close_4g_function = mg_json_get_long(json, "$.close4G", 0);
mg_http_reply(c, 200, "Content-Type: application/json\r\n", "{\"status\":\"success\"}\r\n");
} else if (mg_http_match_uri(hm, "/net/connect4G")) {
close_4g_function = 0;//enable 4G connect function
//enable 4G connect function
PrivEvenTrigger(wb_event, WB_4G_CONNECT);
} else if (mg_http_match_uri(hm, "/net/disconnect4G")) {
close_4g_function = 1;//disable 4G connect function
//disable 4G connect function
PrivEvenTrigger(wb_event, WB_4G_CONNECT);
} else if (mg_http_match_uri(hm, "/net/getMQTTInfo")) {
mg_http_reply(c, 200, "Content-Type: application/json\r\n",
"{%m:%m, %m:%m, %m:%m, %m:%d, %m:%d}\n",
@ -449,12 +559,39 @@ static void fn(struct mg_connection* c, int ev, void* ev_data, void* fn_data)
net_4g_mqtt_info.client_id = mg_json_get_long(json, "$.client_id", 0);
mg_http_reply(c, 200, "Content-Type: application/json\r\n", "{\"status\":\"success\"}\r\n");
} else if (mg_http_match_uri(hm, "/net/connectMQTT")) {
close_mqtt_function = 0;//enable 4G MQTT connect function
//enable 4G MQTT connect function
PrivEvenTrigger(wb_event, WB_MQTT_CONNECT);
} else if (mg_http_match_uri(hm, "/net/disconnectMQTT")) {
close_mqtt_function = 1;//disable 4G MQTT connect function
//disable 4G MQTT connect function
PrivEvenTrigger(wb_event, WB_MQTT_DISCONNECT);
}
/*define net LoRa info*/
else if (mg_http_match_uri(hm, "/net/getLoraInfo")) {
mg_http_reply(c, 200, "Content-Type: application/json\r\n",
"{%m:%d, %m:%d, %m:%d, %m:%d}\n",
MG_ESC("range"), net_lora_info.frequency,
MG_ESC("bandwidth"), net_lora_info.bw,
MG_ESC("factor"), net_lora_info.sf,
MG_ESC("status"), net_lora_info.connect_status);
}
else if (mg_http_match_uri(hm, "/net/setLoraInfo")) {
struct mg_str json = hm->body;
printf("json: %s\n", json.ptr);
net_lora_info.frequency = mg_json_get_long(json, "$.range", 0);
net_lora_info.sf = mg_json_get_long(json, "$.factor", 0);
net_lora_info.bw = mg_json_get_long(json, "$.bandwidth", 0);
mg_http_reply(c, 200, "Content-Type: application/json\r\n", "{\"status\":\"success\"}\r\n");
extern void LoraRadioParamsUpdate(uint32_t frequency, uint8_t sf, uint8_t bw);
LoraRadioParamsUpdate(net_lora_info.frequency, net_lora_info.sf, net_lora_info.bw);
} else if (mg_http_match_uri(hm, "/net/ConnectLora")) {
//enable LoRa connect function
PrivEvenTrigger(wb_event, WB_LORA_CONNECT);
} else if (mg_http_match_uri(hm, "/net/DisonnectLora")) {
//disable LoRa connect function
PrivEvenTrigger(wb_event, WB_LORA_DISCONNECT);
}
/*define net Ethernet info*/
else if (mg_http_match_uri(hm, "/net/getEthernetInfo")) {
mg_http_reply(c, 200, "Content-Type: application/json\r\n",
@ -467,7 +604,7 @@ static void fn(struct mg_connection* c, int ev, void* ev_data, void* fn_data)
MG_ESC("targetPort"), MG_ESC(net_ethernet_info.targetPort),
MG_ESC("targetGateway"), MG_ESC(net_ethernet_info.targetGateway),
MG_ESC("targetDNS"), MG_ESC(net_ethernet_info.targetDNS),
MG_ESC("ethernetStatus"), net_4g_mqtt_info.connect_status);
MG_ESC("ethernetStatus"), net_ethernet_info.connect_status);
} else if (mg_http_match_uri(hm, "/net/setEthernetInfo")) {
struct mg_str json = hm->body;
printf("json: %s\n", json.ptr);
@ -496,10 +633,10 @@ static void fn(struct mg_connection* c, int ev, void* ev_data, void* fn_data)
}
} else if (mg_http_match_uri(hm, "/net/connectEthernet")) {
//enable Ethernet connect function
PrivEvenTrigger(ethernet_event, ETHERNET_CONNECT);
PrivEvenTrigger(wb_event, WB_ETHERNET_CONNECT);
} else if (mg_http_match_uri(hm, "/net/disconnectEthernet")) {
//disable Ethernet connect function
PrivEvenTrigger(ethernet_event, ETHERNET_DISCONNECT);
PrivEvenTrigger(wb_event, WB_ETHERNET_DISCONNECT);
}
/*define plc info*/
else if (mg_http_match_uri(hm, "/control/setPLCInfo")) {
@ -539,7 +676,9 @@ static void* do_webserver(void* args)
Rs485InitConfigure();
#endif
TcpClientSocket();
adapter = AdapterDeviceFindByName(ADAPTER_4G_NAME);
net_lora_info.lora_init_flag = 0;
WbEventInit();
struct mg_mgr mgr; // Event manager
// mg_log_set(MG_LL_INFO); // Set to 3 to enable debug

View File

@ -1,8 +1,16 @@
config ADAPTER_EC200T
bool "Using 4G adapter device EC200T"
default y
default n
if ADAPTER_EC200T
source "$APP_DIR/Framework/connection/4g/ec200t/Kconfig"
endif
config ADAPTER_EC200A
bool "Using 4G adapter device EC200A"
default n
if ADAPTER_EC200A
source "$APP_DIR/Framework/connection/4g/ec200a/Kconfig"
endif

View File

@ -0,0 +1,10 @@
config ADAPTER_4G_EC200A
string "EC200A adapter name"
default "ec200a"
if ADD_XIZI_FEATURES
config ADAPTER_EC200A_DRIVER
string "EC200A device uart driver path"
default "/dev/usart6_dev6"
endif

View File

@ -0,0 +1,3 @@
SRC_FILES := ec200a.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,24 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file ec200a.c
* @brief Implement the connection 4G adapter function, using EC200A device
* @version 3.0
* @author AIIT XUOS Lab
* @date 2023.12.22
*/
#include <adapter.h>
#include <at_agent.h>

View File

@ -36,7 +36,7 @@ menuconfig LIB_USING_LORAWAN
select BSP_USING_SPI
if LIB_USING_LORA_RADIO
source "$APP_DIR/lib/lorawan/lora_radio_driver/Kconfig"
endif
endif

@ -1 +0,0 @@
Subproject commit 2d8abd3eff2a2d5257e17c7f59acb2ba938cb90e

View File

@ -0,0 +1,18 @@
choice
prompt "choose rtos for lora radio driver"
default LORA_RADIO_DRIVER_USING_RTOS_XIUOS
config LORA_RADIO_DRIVER_USING_RTOS_RT_THREAD
bool "rtos select RT-Thread"
config LORA_RADIO_DRIVER_USING_RTOS_XIUOS
bool "rtos select XiUOS"
endchoice
config LORA_RADIO_DRIVER_USING_LORA_RADIO_DEBUG
bool "lora radio driver debug printf"
default y
if LORA_RADIO_DRIVER_USING_RTOS_XIUOS
source "$APP_DIR/lib/lorawan/lora_radio_driver/ports/lora-module/hc32_adapter/Kconfig"
endif

View File

@ -0,0 +1,3 @@
SRC_DIR := lora-radio ports samples
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,5 @@
# LoRa-Radio-Driver软件包 简介
LoRa-Radio-Driver软件包是基于RTOS( RT-Thread、XiUOS ) 实现的LoRa Tranceiver芯片的驱动文件包可用于快速搭建基于LoRa等通信的应用产品。
更多详细信息请查看[LoRa-Radio-Driver/doc](https://github.com/Forest-Rain/lora-radio-driver/tree/master/doc)

View File

@ -0,0 +1,12 @@
import os
from building import *
objs = []
cwd = GetCurrentDir()
list = os.listdir(cwd)
for item in list:
if os.path.isfile(os.path.join(cwd, item, 'SConscript')):
objs = objs + SConscript(os.path.join(item, 'SConscript'))
Return('objs')

View File

@ -0,0 +1,381 @@
# LoRa-Radio-Driver软件包使用说明
# 1 简介
LoRa-Radio-Driver软件包是基于RTOS( RT-Thread ) 实现的LoRa Tranceiver芯片(SX126x、SX127x等)的驱动文件该驱动文件通过SPI访问LoRa Tranceiver芯片可用于快速搭建基于LoRa等通信的应用产品。
LoRa-Radio-Driver软件包在LoRaWAN开源协议栈[LoRaMAC-Node中的radio](https://github.com/Forest-Rain/lora-radio-driver/blob/master/doc)基础上,进一步封装实现。
> LoRaMac\Radio
> [https://github.com/Lora-net/LoRaMac-node/tree/master/src/radio](https://github.com/Lora-net/LoRaMac-node/tree/master/src/radio)
- 主要特点:
- 当前支持LoRa Transceiversx126x\sx127x
- 支持调制方式
- [x] LoRa
- [ ] FSK
- 可通过EVN工具menuconfig直接定义LoRa模块的对外接口降低入门门槛
- 支持使用引脚号来定义GPIO
- 支持使用引脚名来定义GPIO
- 提供常用实例代码,可用于射频性能测试、空口数据包监听、双向通信测试等
- 可作为phy层对接到LoRaWAN End-Device协议栈
- 当前测试的LoRa 模块\芯片
- LoRa Transceiver (SPI)
- SX126X (SX1262\ASR6500S\LLCC68\SX1268..)
- SX1268
- [x] [LSD4RF-2R717N40](http://bbs.lierda.com/forum.php?mod=viewthread&tid=87)
- SX1262
- [x] ASR6500S
- LLCC68
- LR1110
- SX127X (SX1272\SX1276\SX1278..)
- SX1278
- [x] [LSD4RF-2F717N20](http://bbs.lierda.com/forum.php?mod=viewthread&tid=87)
- [x] [Ra-01](http://wiki.ai-thinker.com/lora/man)
- [ ] SX1276
- LoRa SIP\SoC
- 当前测试的MCU平台
- LoRa Radio Driver当前功能主要在STM32L平台测试通过未来计划将适配更多的MCU平台华大MCU、nRF、BK
- [x] STM32L0系列
- [x] STM32L4系列
- 当前支持的RTOS
- [x] RT-Thread
- [ ] RT-Thread Nano
# 2 LoRa Radio Driver 软件包组织结构
![image.png](https://cdn.nlark.com/yuque/0/2020/png/253586/1598742766628-ea39cbc7-119b-4a3f-a323-45ba4cee9bbd.png#align=left&display=inline&height=677&margin=%5Bobject%20Object%5D&name=image.png&originHeight=677&originWidth=1111&size=80753&status=done&style=none&width=1111)
- lora-radio
- sx126x
- lora-radio-sx126x.c
- 对外提供了上层访问接口实现
- lora-spi-sx126x.c
- sx126x芯片的spi读写接口实现独立于MCU平台
- [x] rt_device
- [ ] SPI裸机方式
- sx126x.c
- lora芯片sx126x底层驱动
- sx127x
- lora-radio-sx127x.c
- 对外提供了上层访问接口
- lora-spi-sx127x.c
- sx127x芯片的spi读写接口实现独立于MCU平台
- [x] rt_device
- [ ] SPI裸机方式
- sx127x.c
- lora芯片sx127x底层驱动
- common
- lora-radio-timer.c
- 提供了lora-radio所需的定时服务接口用于发送与接收超时等基于RT-Thread内核rt_timer实现
- 注意这种方式提供的定时最小颗粒度取决于系统tick RT_TICK_PER_SECOND
- 注:如果使能了Multi-Rtimer软件包则优先使用Multi-Rtimer提供定时\超时服务
- include
- lora-radio.h
- 上层服务接口
- lora-radio-debug.h
- 根据需要使能输出lora-radio不同层级的调试信息
- lora-radio-rtos-config.h
- rtos适配层选择当前默认为RT-Thread
- 未来支持RT-Thread-Nano、以及其他RTOS....
- samples
- lora radio driver示例文件
- lora-radio-test-shell
- shell示例主要实现了射频性能测试、空口数据包监听、双向通信测试等shell命令便于日常测试
- port
- 主要包含当前在不同MCU平台下支持的lora模块lora-module文件夹中的xxxx-borad.c包含了与LoRa模块直接相关的主要硬件接口配置
- lora-module
- stm32_adapter
- lora-board-spi.c
- STM32平台的SPI外设初始化等通用接口
- LSD4RF-2F717N20 SX1278 LoRa模块
- LSD4RF-2R717N40 SX1268 LoRa模块
- Ra-01 SX1278 LoRa模块
- xxxx-borad.c
- LoRa模块功率输出方式PA\RFO...
- LoRa模块的RF高频开关控制方式TXE、RXE、无..
- LoRa模块的DIO口DIO0、DIO1、DIO2....
- LoRa模块的工作频率限制等
- xxx_adapter
- 其他mcu平台下的硬件接口实现
# 3 LoRa Radio Driver软件包使用说明
## 3.1 依赖
- SPI外设——用户需根据实际MCU平台自定义LoRa模块实际所需要使用的SPI外设
- 选择SPI外设
```
Hardware Drivers Config --->
On-chip Peripheral Drivers --->
[*] Enable SPI --->
--- Enable SPI
[ ] Enable SPI1
[ ] Enable SPI2
[ ] Enable SPI3
[ ] Enable SPI4
[ ] Enable SPI5
```
- 在bsp\目标板XX\board\Kconfig增加如下定义
```c
menuconfig BSP_USING_SPI
bool "Enable SPI"
select RT_USING_SPI
if BSP_USING_SPI
config BSP_USING_SPI1
bool "Enable SPI1"
default n
if BSP_USING_SPI1
config BSP_SPI1_RX_USING_DMA
bool "Enable SPI1 RX DMA"
default n
config BSP_SPI1_TX_USING_DMA
bool "Enable SPI1 TX DMA"
default n
endif
# 根据实际需要增加其他BSP_USING_SPI2、BSP_USING_SPI3...
endif
```
- 定时服务——用于提供射频通信所需的定时\超时服务,目前支持以下两种方式,二选一
- 内核 SOFT_TIMER
- 若未选用Multi-Rtimer软件包则默认采用内核的rt_timer来提供定时服务(lora-radio-timer.c)
- 注意检测是否**开启RT-Thread内核的SOFT_TIMER**
- M[ulti-Rtimer](https://github.com/Forest-Rain/multi-rtimer)软件包
- 若使能multi-rtimerlora-radio-driver优先使用multi-rtimer提供定时\超时服务。
> 注:如果应用在工业温度范围、时间精度要求高(us\ms级别)的场景建议使用multi-rtimer并设置RTC时钟源为外部32768晶振否则可能会出现下行丢包的情况。
```
RT-Thread online packages --->
peripheral libraries and drivers --->
[*] multi_rtimer: a real-time and low power software timer module. --->
Version (latest) --->
multi_rtimer options --->
[] multi_rtimer demo example
```
- 可选内核组件
- ulog组件——用于打印日志信息
- 使能ulog
- ulog缓存大小设置≥ 128 Byte
- lora-raido-driver内部可看到更多LoRa底层的调试信息
- lora-radio-test-shell.c使用ulog接口用于打印调试信息、原始16进制数据等
- 如果没有使用ulog默认使用rt_kprintf来实现信息输出功能
```
RT-Thread Components --->
Utiliess --->
[*] Enable ulog
[*] Enable ISR log.
```
## 3.2 获取软件包
使用 lora-radio-driver 软件包,需要在 RT-Thread 的包管理中选中它,具体路径如下:
```c
RT-Thread online packages --->
peripheral libraries and drivers --->
[*] lora_radio_driver: lora chipset(sx126x\sx127x.)driver. --->
Select LoRa Radio Object Type (LoRa Radio Single-Instance)
(lora-radio0)Setup LoRa Radio Device Name
(spi3) Setup LoRa Radio Spi Name (Define BSP_USING_SPIx in [Target Platform]\Board\Kconfig)
Select LoRa Chip Type (LoRa Transceiver [SX126X]) --->
Select Supported LoRa Module [SX126X] --->
[ ] Enable LoRa Radio Debug
Select LoRa Radio Driver Sample --->
Version (latest) --->
```
1. Select LoRa Chip \ LoRa Module
1. "Setup LoRa Radio Device Name"
1. 设置LoRa Radio设备名称缺省为"lora-radio0"
2. "Setup LoRa Radio Spi Name"
1. 设置LoRa Radio Spi名称
1. 若在 [Target Platform]\Board\Kconfig提前设定好所使用的BSP_USING_SPIx则会自动配置
3. "Select LoRa Radio Single-Instance"
1. 选择为单实例对象当前只支持单个lora设备
4. "Select LoRa Chip Type"
1. 选择实际使用的LoRa芯片类型
- 当前支持 SX126X、SX127x Transceiver
5. "Select Supported LoRa Module"
1. 选择lora模块根据实际使用的MCU硬件平台与lora模块配置关联的GPIO引脚等功能选项
1. 设定LoRa模块的GPIO口比如 RESET、NSS、BUSY、DIO1、TXE、RXE...
- " Select LoRa Chip GPIO by Pin Number  "
- 支持使用引脚号来定义GPIO比如 输入 10 代表 A10
- "Select LoRa Chip GPIO by Pin Name"
- 支持使用引脚名来定义GPIO比如 输入 A10 代表引脚GPIOA的PIN10脚 (STM32)
2. Select LoRa Radio Driver Sample
1. 根据实际情况,可选择测试示例
## 3.3 新增LoRa模块
在 lora-radio-driver\ports\lora-module文件下参考已有模板根据实际需要增加新的mcu平台适配文件、新的lora模块驱动文件xxxx-board.c
# 4 使用示例
## 4.1 硬件测试平台
当前所使用的硬件测试平台如下所示
| 序号 | 硬件平台 | MCU | LoRa模块 | 主要用户接口 |
| --- | --- | --- | --- | --- |
| 1 | LSD4RF-TEST2002 | STM32L476VG | [LSD4RF-2R717N40](http://bbs.lierda.com/forum.php?mod=viewthread&tid=87)<br />[ ( SX1268 )](http://bbs.lierda.com/forum.php?mod=viewthread&tid=87) | <br />- 用户接口定义<br /> - VCC  - 3.3V<br /> - GND<br /> - SCK    - PC10 (SPI3)<br /> - MISO  - PC11 (SPI3)<br /> - MOSI  - PC12 (SPI3)<br /> - NSS    - PA15<br /> - RESET - PA7<br /> - DIO0  - PB1<br /> - BUSY - PB2<br /> - RFSW1 - PB0<br /> - RFSW2 - PC5<br />- 射频开关TX trace<br /> - TX: RFSW1 = 1 , RFSW2 = 0<br /> - TX: RFSW1 = 0 , RFSW2 = 1<br /> |
| 2 | LSD4RF-TEST2002 | STM32L476VG | [LSD4RF-2F717N20](http://bbs.lierda.com/forum.php?mod=viewthread&tid=87)<br />[ ( SX1278 )](http://bbs.lierda.com/forum.php?mod=viewthread&tid=87) | <br />- 用户接口定义<br /> - VCC   - 3.3V<br /> - GND<br /> - SCK    - PC10 (SPI3)<br /> - MISO  - PC11 (SPI3)<br /> - MOSI  - PC12 (SPI3)<br /> - NSS    - PB6<br /> - RESET - PA7<br /> - DIO0  - PB1<br /> - DIO1  - PC4<br /> - DIO2  - PB2<br /> - DIO3  - NC<br /> - DIO4  - NC<br /> - RFSW1 - PB0<br /> - RFSW2 - PC5<br />- 射频开关TX trace<br /> - TX: RFSW1 = 1 , RFSW2 = 0<br /> - TX: RFSW1 = 0 , RFSW2 = 1<br /> |
| 3 | Nucleo-L476RG | STM32L476RG | [Ra-01](http://wiki.ai-thinker.com/lora/man)<br />(RT-thread LoRa Adruino扩展板V1) | <br />- 用户接口定义<br /> - VCC    - 3.3V<br /> - GND<br /> - SCK    - PA5(SPI1)<br /> - MISO  - PA6(SPI1)<br /> - MOSI  - PA7(SPI1)<br /> - NSS    - PB6<br /> - RESET - PC7<br /> - DIO0  - PA9<br /> - DIO1  - PA8<br /> |
## 4.2 Shell测试命令
若使能 [* ] LoRa Radio Test Shell则可以通过shellfinish命令直接进行LoRa相关测试
```c
[*] Enable LoRa Radio Test Shell │ │
Select the RF frequency (Region CN470) ---> │ │
Select RF Modem (Modem LoRa) --->
```
![image.png](https://cdn.nlark.com/yuque/0/2020/png/253586/1592550763879-ac947241-b072-4db8-89bf-ced6ab168af9.png#align=left&display=inline&height=163&margin=%5Bobject%20Object%5D&name=image.png&originHeight=163&originWidth=858&size=21400&status=done&style=none&width=858)
| 序号 | finish命令 | 说明 |
| --- | --- | --- |
| 1 | lora probe | 测试lora设备(SPI)访问是否正常 |
| 2 | lora cw <para1> <para2> | 输出CW,可用于测试发射功率、频点等<br />\<para1\>:频点单位Hz<br>\<para2\>:功率单位dBm |
| 3 | lora ping <para1> <para2> | 单向\双向通信测试<br />\<para1\> : 主机\从机<br>-m 主机<br>-s 从机<br> \<para2\>: 发送数据包个数 |
| 4 | lora rx  | 接收(监听)数据包同时以16进制格式与ASCII码显示数据内容 |
| 5 | lora config <para1> <para2> | 配置射频参数<br />\<para1\>:radio参数字符表示<br/> freq 表示频率单位Hz<br/> power 表示发射功率单位dbm<br/> sf 表示扩频因子,有效值: 7~12<br/> bw表示带宽有效值: 0 (125kHz)、1 (250KHz)、2 (500KHz)<br/> public表示同步字有效值: 0 sync = 0x12), 1 (sync = 0x34)<br/> iq 表示iq反转有效值: 0 (iq不反转)1 (iq反转)<br/>\<para2\>:radio参数的具体值 |
![image.png](https://cdn.nlark.com/yuque/0/2020/png/253586/1598743470109-a54f4753-4ffd-4c7a-a3bf-30d13b8e15e1.png#align=left&display=inline&height=905&margin=%5Bobject%20Object%5D&name=image.png&originHeight=905&originWidth=1848&size=267690&status=done&style=none&width=1848)
lora ping 双向通信测试示例(SX1278 <-> SX1268)
![image.png](https://cdn.nlark.com/yuque/0/2020/png/253586/1598743657349-9a16556a-35da-4134-8d37-8924ac841578.png#align=left&display=inline&height=871&margin=%5Bobject%20Object%5D&name=image.png&originHeight=871&originWidth=1854&size=269482&status=done&style=none&width=1854)
lora rx 单向接收(监听)lora数据包测试示例 (SX1278 <- 或-> SX1268)
## 4.3 应用层调用说明
用户层调用可以参考如下步骤
1. 定义射频DIO中断服务回调函数
```c
/*!
* \brief Function to be executed on Radio Tx Done event
*/
void OnTxDone( void );
/*!
* \brief Function to be executed on Radio Rx Done event
*/
void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr );
/*!
* \brief Function executed on Radio Tx Timeout event
*/
void OnTxTimeout( void );
/*!
* \brief Function executed on Radio Rx Timeout event
*/
void OnRxTimeout( void );
/*!
* \brief Function executed on Radio Rx Error event
*/
void OnRxError( void );
```
2. 调用lora-radio初始化
```c
void main(void)
{
// Radio initialization
RadioEvents.TxDone = OnTxDone;
RadioEvents.RxDone = OnRxDone;
RadioEvents.TxTimeout = OnTxTimeout;
RadioEvents.RxTimeout = OnRxTimeout;
RadioEvents.RxError = OnRxError;
if(Radio.Init(&RadioEvents))
{
Radio.SetPublicNetwork( false );
lora_chip_initialized = true;
}
//.....
}
```
3. 配置射频通信参数
```c
{
Radio.SetChannel( lora_radio_test_paras.frequency );
if( lora_radio_test_paras.modem == MODEM_LORA )
{
Radio.SetTxConfig( MODEM_LORA, lora_radio_test_paras.txpower, 0, lora_radio_test_paras.bw,
lora_radio_test_paras.sf, lora_radio_test_paras.cr,
LORA_PREAMBLE_LENGTH, LORA_FIX_LENGTH_PAYLOAD_ON_DISABLE,
true, 0, 0, LORA_IQ_INVERSION_ON_DISABLE, 3000 );
Radio.SetRxConfig( MODEM_LORA, lora_radio_test_paras.bw, lora_radio_test_paras.sf,
lora_radio_test_paras.cr, 0, LORA_PREAMBLE_LENGTH,
LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON_DISABLE,
0, true, 0, 0, LORA_IQ_INVERSION_ON_DISABLE, true );
}
}
```
4. 数据发送
```c
Radio.Send( Buffer, len );
```
5. 数据接收
```c
void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr )
{
Radio.Sleep( );
BufferSize = size;
rt_memcpy( Buffer, payload, BufferSize );
rssi_value = rssi;
snr_value = snr;
// .....
}
```
# 5 版本更新历史
- V1.0.0 版本 2020-06-20
- 主体功能实现基于STM32平台
- 支持SX126x、SX127x系列芯片
- 测试LoRa芯片支持LSD4RF-2R717N40(SX1268)、SX1278、ASR6500S @ [**zyk6271**](https://github.com/zyk6271)
- 支持基于RT-Thread内核rt_timer的lora-radio-timer接口@ [**AnswerInTheWind** ](https://github.com/AnswerInTheWind)
- 优化日志换行功能@[**zyk6271**](https://github.com/zyk6271)
- V1.1.0 版本 2020-08-30
- 完善用户使用指南
- .lora-radio-driver软件包
- 新增日志输出选择 lora-radio-debug.h可以按需开启调试日志也可以用于适配不同日志输出方式
- 新增rtos适配选择 lora-radio-rtos-config.h便于未来适配RT-Thread-Nano、不同的RTOS平台
- lora-radio(sx126x\sx127x)
- 同步更新到lorawan4.4.4 release版本的radio
- sx126x更新 SX126xSetLoRaSymbNumTimeout同步到loramac-node-master
- sx126x更新 RadioRandom 与 SX126xGetRandom
- 更新 RadioIrqProcess
- 更新RadioTimeOnAir
- RadioIrqProcess 增加 临界区保护,防止出现硬件异常
- 调整lora-radio-driver软件包架构便于未来适配不同的MCU平台
- port目录下新增mcu平台适配层如stm32_adapter
- lora-radio-test-shell
- 修复 PHY CRC Error后没有重新进入接收问题
- lora ping命令
- 新增发送空口数据包的TOA时间显示
- 新增主机侧接收到数据包后seqno显示
- [Kconfig](https://github.com/Forest-Rain/packages/blob/master/peripherals/lora_radio_driver)
- 更新[lora-radio-driver\Kconfig](https://github.com/Forest-Rain/packages) 软件包配置文件
- 区分单实例(单lora模块)与多实例多lora模块情况目前支持单实例
- 移除了Kconfig中对BSP_USING_SPIx的直接定义BSP_USING_SPIx定义调整到[Target Platform]\Board\Kconfig)
- 重命名宏定义REGION_X为PHY_REGION_X(如REGION_CN470 -> PHY_REGION_CN470)以便与LoRaWAN协议栈中缺省REGION_X共存
- V1.1.2 版本 2020-10-12
- 修复Ra-01未同步与v1.1.1更新导致的问题
- 优化 drv_gpio.h使用兼容RT-Thread Studio
- 优化 lora-radio-test-shell.c 功能
- 新增接收超时时间设置
- V1.2 版本 2020-10-14
- 新增硬件测试平台
- ART-Pi+LSD4RF-2F717N30(SX1268)模块平台 (470~510MHz频段)
- ART-Pi+LSD4RF-2R717N40(SX1268)模块平台 (470~510MHz频段)
- ART-Pi+LSD4RF-2R822N30(SX1262)模块平台 (868/915MHz频段)
- V1.4.0 版本 2021-04-25
- 重设计lora config命令便于快速配置单个radio参数
- ping数据包长度最大支持255Byte可通过shell自定义ping测试数据包长度
- shell新增加iq version、public network参数设置
- 使用LORA_RADIO_DEBUG_LOG代替rt_kprintf
- V1.5.0 版本 2021-11-15
- 新增doxygen支持
# 6 问题和建议
如果有什么问题或者建议欢迎提交 [Issue](https://github.com/Forest-Rain/lora-radio-driver/issues) 进行讨论。

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

View File

@ -0,0 +1,41 @@
/*
* This file is only used for doxygen document generation.
*/
/*!
* @mainpage Introduce
* @author wsn-hxj
* @version v1.5.0
* @date 2021-11-15
*
* lora-radio-driver软件包是基于RTOS( RT-Thread ) LoRa Tranceiver芯片(SX126xSX127x等)SPI读写LoRa Tranceiver芯片LoRa等通信的应用产品
* :
* - 1. LoRa Transceiversx126x\sx127x等
* - Sub-1GHz频段
* - LoRa调制方式(SF5~SF12BW125~BW500)
* - FSK调制方式
* - 2. phy层对接到LoRaWAN End-Device协议栈
* - 3. tester
* - 4. LoRa \
* - LSD4RF-2R717N40 (SX1268 CN470频段)
* - LSD4RF-2R822N300 (SX1262 868/915MHz频段)
* - LSD4RF-2F717N30(SX1278 CN470频段)
* - Ra-01(SX1278 CN470频段)
* @section application_arch 01
*
* lora-radio-driver功能框图:
* @image html lora-radio-driver_func_arch.png "Figure 1: 功能框图"
*
* @section file_arch 02
*
* lora-radio-driver文件结构:
* @image html lora-radio-driver_file_arch.png "Figure 1: 文件结构"
*
* @section lora-radio-driver 03 API
* @ref LORA_RADIO_UPPER_API
*/

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 261 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 263 KiB

View File

@ -0,0 +1,15 @@
SRC_DIR := common
ifeq ($(CONFIG_LORA_RADIO_DRIVER_USING_RTOS_XIUOS),y)
ifeq ($(CONFIG_LORA_RADIO_DRIVER_USING_SX1268_E22400M30S),y)
SRC_DIR += sx126x
endif
ifeq ($(CONFIG_LORA_RADIO_DRIVER_USING_SX1278_RA01),y)
SRC_DIR += sx127x
endif
endif
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,29 @@
from building import *
src = []
cwd = GetCurrentDir()
include_path = [cwd]
include_path += [cwd+'/include']
include_path += [cwd+'/common']
# add lora radio driver.
if GetDepend('LORA_RADIO_DRIVER_USING_LORA_CHIP_SX126X'):
src = Split('''
sx126x/lora-radio-sx126x.c
sx126x/lora-spi-sx126x.c
sx126x/sx126x.c
''')
include_path += [cwd+'/sx126x']
if GetDepend('LORA_RADIO_DRIVER_USING_LORA_CHIP_SX127X'):
src = Split('''
sx127x/lora-radio-sx127x.c
sx127x/lora-spi-sx127x.c
sx127x/sx127x.c
''')
include_path += [cwd+'/sx127x']
src += ['common/lora-radio-timer.c']
group = DefineGroup('lora-radio-driver', src, depend = ['PKG_USING_LORA_RADIO_DRIVER'], CPPPATH = include_path)
Return('group')

View File

@ -0,0 +1,3 @@
SRC_FILES := lora-radio-timer.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,181 @@
/*!
* \file lora-radio-timer.c
*
* \brief lora-radio timer
*
* SPDX-License-Identifier: Apache-2.0
*
* \author DerekChen
*
* \author AIIT XUOS Lab
*/
/**
* @file lora-radio-timer.c
* @brief support lora-radio-driver for XiUOS
* @version 3.0
* @author AIIT XUOS Lab
* @date 2023-03-08
*/
/*************************************************
File name: lora-radio-timer.c
Description: support lora-radio-driver for XiUOS
Others:
History:
1. Date: 2023-03-08
Author: AIIT XUOS Lab
Modification:
1add LORA_RADIO_DRIVER_USING_RTOS_XIUOS to support XiUOS.
*************************************************/
#include <lora-radio-rtos-config.h>
#include <stdint.h>
#include "lora-radio-timer.h"
#if defined ( LORA_RADIO_DRIVER_USING_ON_RTOS_RT_THREAD ) || defined ( LORA_RADIO_DRIVER_USING_ON_RTOS_RT_THREAD_NANO )
#ifndef PKG_USING_MULTI_RTIMER
void rtick_timer_init( rtick_timer_event_t *obj, void ( *callback )( void ) )
{
int count = 0;
char name[RT_NAME_MAX];
rt_snprintf(name,8,"rtk_%d",count++);
rt_timer_init(&(obj->timer),name,(void (*)(void*))callback,RT_NULL,1000,RT_TIMER_FLAG_ONE_SHOT|RT_TIMER_FLAG_SOFT_TIMER);
}
void rtick_timer_start( rtick_timer_event_t *obj )
{
rt_timer_start(&(obj->timer));
}
void rtick_timer_stop( rtick_timer_event_t *obj )
{
rt_timer_stop(&(obj->timer));
}
void rtick_timer_reset( rtick_timer_event_t *obj )
{
rtick_timer_stop(obj);
rtick_timer_start(obj);
}
void rtick_timer_set_value( rtick_timer_event_t *obj, uint32_t value )
{
uint32_t tick = rt_tick_from_millisecond(value);
rt_timer_control(&(obj->timer),RT_TIMER_CTRL_SET_TIME,&tick);
}
TimerTime_t rtick_timer_get_current_time( void )
{
uint32_t now = rt_tick_get();
return now;
}
TimerTime_t rtick_timer_get_elapsed_time( TimerTime_t past )
{
return rt_tick_get() - past;
}
#endif
#endif // End Of ( LORA_RADIO_DRIVER_USING_ON_RTOS_RT_THREAD ) || defined ( LORA_RADIO_DRIVER_USING_ON_RTOS_RT_THREAD_NANO )
#if defined LORA_RADIO_DRIVER_USING_RTOS_XIUOS
#define TIMER_NUM 20
typedef void (*timer_input_callback_entry)(void);
typedef struct {
timer_input_callback_entry callback_entry;
}timer_input_callback_entry_fun;
static timer_input_callback_entry_fun g_timer_input_callback_entry_fun[TIMER_NUM];
static void timer_callback(union sigval sig_val)
{
uint8_t timer_id = *((uint8_t *)sig_val.sival_ptr);
g_timer_input_callback_entry_fun[timer_id].callback_entry();
}
void rtick_timer_init( rtick_timer_event_t *obj, void ( *callback )( void ) )
{
int ret = 0;
int timer_flags;
static int count = 0;
struct sigevent evp;
memset(&evp, 0, sizeof(struct sigevent));
timer_flags = TIMER_TRIGGER_ONCE;
count++;
g_timer_input_callback_entry_fun[count].callback_entry = callback;
evp.sigev_notify = SIGEV_THREAD;
evp.sigev_notify_function = timer_callback;
evp.sigev_notify_attributes = &timer_flags;
ret = PrivTimerCreate(count, &evp, &(obj->timer_id));
if (ret < 0) {
printf("%s create timer failed ret %d\n", __func__, ret);
return;
}
}
void rtick_timer_start( rtick_timer_event_t *obj )
{
PrivTimerStartRun(obj->timer_id);
}
void rtick_timer_stop( rtick_timer_event_t *obj )
{
PrivTimerQuitRun(obj->timer_id);
}
void rtick_timer_reset( rtick_timer_event_t *obj )
{
rtick_timer_stop(obj);
rtick_timer_start(obj);
}
void rtick_timer_set_value( rtick_timer_event_t *obj, uint32_t value )
{
int ret;
uint32_t input_value, ms_value, s_value;
struct itimerspec it_value;
//active time interval
input_value = value;
if (input_value >= 1000) {
ms_value = input_value % 1000;
s_value = (input_value - ms_value) / 1000;
} else {
ms_value = input_value;
s_value = 0;
}
it_value.it_interval.tv_sec = s_value;
it_value.it_interval.tv_nsec = ms_value * 1000000;//1ms = 1000000ns
ret = PrivTimerModify(obj->timer_id, 0, &it_value, NULL);
if (ret < 0) {
printf("%s set timer time failed ret %d\n", __func__, ret);
return;
}
}
TimerTime_t rtick_timer_get_current_time( void )
{
uint32_t now = PRIV_SYSTICK_GET;
return now;
}
TimerTime_t rtick_timer_get_elapsed_time( TimerTime_t past )
{
return PRIV_SYSTICK_GET - past;
}
#endif

View File

@ -0,0 +1,216 @@
#ifndef __LORA_RADIO_TIMER_H__
#define __LORA_RADIO_TIMER_H__
#include <lora-radio-rtos-config.h>
#include <stdint.h>
#ifdef PKG_USING_MULTI_RTIMER
#include "multi_rtimer.h"
#include "hw_rtc_stm32.h"
#define LORA_RADIO_TIMESTAMP_TO_MS(x) (x)
#else
#ifdef LORA_RADIO_DRIVER_USING_RTOS_RT_THREAD
/** @addtogroup LORA_RADIO_TIMER
* @{
*/
#define TimerInit rtick_timer_init
#define TimerStart rtick_timer_start
#define TimerStop rtick_timer_stop
#define TimerReset rtick_timer_reset
#define TimerSetValue rtick_timer_set_value
#define TimerSetTimestamp rtick_timer_set_timestamp
#define TimerGetCurrentTime rtick_timer_get_current_time
#define TimerGetElapsedTime rtick_timer_get_elapsed_time
#define TimerEvent_t rtick_timer_event_t
#define LORA_RADIO_TIMESTAMP_TO_MS(x) ((x) * 1000 / RT_TICK_PER_SECOND)
/*!
* \brief Timer object description
*/
typedef struct TimerEvent_s
{
struct rt_timer timer;
}rtick_timer_event_t;
/*!
* \brief Timer time variable definition
*/
#ifndef TimerTime_t
typedef uint32_t TimerTime_t;
#define TIMERTIME_T_MAX ( ( uint32_t )~0 )
/*!
* \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 rtick_timer_init( rtick_timer_event_t *obj, void ( *callback )( void ) );
/*!
* \brief Starts and adds the timer object to the list of timer events
*
* \param [IN] obj Structure containing the timer object parameters
*/
void rtick_timer_start( rtick_timer_event_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 rtick_timer_stop( rtick_timer_event_t *obj );
/*!
* \brief Resets the timer object
*
* \param [IN] obj Structure containing the timer object parameters
*/
void rtick_timer_reset( rtick_timer_event_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 rtick_timer_set_value( rtick_timer_event_t *obj, uint32_t value );
void rtick_timer_set_timestamp( rtick_timer_event_t *obj, uint32_t value );
/*!
* \brief Read the current time
*
* \retval time returns current time
*/
TimerTime_t rtick_timer_get_current_time( void );
/*!
* \brief Return the Time elapsed since a fix moment in Time
*
* \remark TimerGetElapsedTime will return 0 for argument 0.
*
* \param [IN] past fix moment in Time
* \retval time returns elapsed time
*/
TimerTime_t rtick_timer_get_elapsed_time( TimerTime_t past );
/**
* @}
*/
#endif
#endif
#ifdef LORA_RADIO_DRIVER_USING_RTOS_XIUOS
/** @addtogroup LORA_RADIO_TIMER
* @{
*/
#define TimerInit rtick_timer_init
#define TimerStart rtick_timer_start
#define TimerStop rtick_timer_stop
#define TimerReset rtick_timer_reset
#define TimerSetValue rtick_timer_set_value
#define TimerSetTimestamp rtick_timer_set_timestamp
#define TimerGetCurrentTime rtick_timer_get_current_time
#define TimerGetElapsedTime rtick_timer_get_elapsed_time
#define TimerEvent_t rtick_timer_event_t
#define LORA_RADIO_TIMESTAMP_TO_MS(x) ((x) * 1000 / TICK_PER_SECOND)
/*!
* \brief Timer object description
*/
typedef struct TimerEvent_s
{
timer_t timer_id;
}rtick_timer_event_t;
/*!
* \brief Timer time variable definition
*/
#ifndef TimerTime_t
typedef uint32_t TimerTime_t;
#define TIMERTIME_T_MAX ( ( uint32_t )~0 )
/*!
* \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 rtick_timer_init( rtick_timer_event_t *obj, void ( *callback )( void ) );
/*!
* \brief Starts and adds the timer object to the list of timer events
*
* \param [IN] obj Structure containing the timer object parameters
*/
void rtick_timer_start( rtick_timer_event_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 rtick_timer_stop( rtick_timer_event_t *obj );
/*!
* \brief Resets the timer object
*
* \param [IN] obj Structure containing the timer object parameters
*/
void rtick_timer_reset( rtick_timer_event_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 rtick_timer_set_value( rtick_timer_event_t *obj, uint32_t value );
void rtick_timer_set_timestamp( rtick_timer_event_t *obj, uint32_t value );
/*!
* \brief Read the current time
*
* \retval time returns current time
*/
TimerTime_t rtick_timer_get_current_time( void );
/*!
* \brief Return the Time elapsed since a fix moment in Time
*
* \remark TimerGetElapsedTime will return 0 for argument 0.
*
* \param [IN] past fix moment in Time
* \retval time returns elapsed time
*/
TimerTime_t rtick_timer_get_elapsed_time( TimerTime_t past );
/**
* @}
*/
#endif
#endif
#endif
#endif

View File

@ -0,0 +1,122 @@
/*!
* \file lora-radio-debug.h
*
* \brief control all LoRa Radio Driver debug features.
*
* \copyright SPDX-License-Identifier: Apache-2.0
*
* \author Forest-Rain
*
* \author AIIT XUOS Lab
*/
/**
* @file lora-radio-debug.h
* @brief support lora-radio-driver for XiUOS
* @version 3.0
* @author AIIT XUOS Lab
* @date 2023-03-07
*/
/*************************************************
File name: lora-radio-debug.h
Description: support lora-radio-driver for XiUOS
Others:
History:
1. Date: 2023-03-07
Author: AIIT XUOS Lab
Modification:
1add LORA_RADIO_DRIVER_USING_RTOS_XIUOS to support XiUOS.
*************************************************/
#ifndef __LORA_RADIO_DEBUG_H__
#define __LORA_RADIO_DEBUG_H__
#include "lora-radio-rtos-config.h"
#if ( defined LORA_RADIO_DRIVER_USING_RTOS_RT_THREAD ) || ( defined LORA_RADIO_DRIVER_USING_RTOS_RT_THREAD_NANO )
#include "rtconfig.h"
#ifdef RT_USING_ULOG
#include <rtdbg.h>
#include <ulog.h>
#else
#endif
#endif
//#define LORA_RADIO_DRIVER_USING_LORA_RADIO_DEBUG
/* Using this macro to control all LoRa Radio Driver debug features. */
#ifdef LORA_RADIO_DRIVER_USING_LORA_RADIO_DEBUG
/* Turn on some of these (set to non-zero) to debug LoRa Radio */
/* API interface */
#ifndef LR_DBG_INTERFACE
#define LR_DBG_INTERFACE 1
#endif
/*lora chip driver, eg: sx126x.c\sx27x.c*/
#ifndef LR_DBG_CHIP
#define LR_DBG_CHIP 1
#endif
/* spi driver ,eg: lora-spi-board.c*/
#ifndef LR_DBG_SPI
#define LR_DBG_SPI 1
#endif
/* board driver ,eg: sx1268-board.c*/
#ifndef LR_DBG_BOARD
#define LR_DBG_BOARD 1
#endif
#if ( defined LORA_RADIO_DRIVER_USING_RTOS_RT_THREAD ) || ( defined LORA_RADIO_DRIVER_USING_RTOS_RT_THREAD_NANO )
#if defined RT_USING_ULOG
#define LORA_RADIO_DEBUG_LOG(type, level, ...) \
do \
{ \
if (type) \
{ \
ulog_output(level, LOG_TAG, RT_TRUE, __VA_ARGS__); \
} \
} \
while (0)
#else
#define LORA_RADIO_DEBUG_LOG(type, level, ...) \
do \
{ \
if (type) \
{ \
rt_kprintf(__VA_ARGS__); \
rt_kprintf("\r\n"); \
} \
} \
while (0)
#endif
#elif ( defined LORA_RADIO_DRIVER_USING_RTOS_XIUOS )
#define LORA_RADIO_DEBUG_LOG(type, level, ...) \
do \
{ \
if (type) \
{ \
printf(__VA_ARGS__); \
printf("\r\n"); \
} \
} \
while (0)
#endif
#else /* LORA_RADIO_DEBUG */
#define LORA_RADIO_DEBUG_LOG(type, level, ...)
#endif /* LORA_RADIO_DEBUG */
#endif /* __LORA_RADIO_DEBUG_H__ */

View File

@ -0,0 +1,72 @@
/*!
* \file lora-radio-rtos-config.h
*
* \brief adapter to different RTOS implementation
*
* \copyright SPDX-License-Identifier: Apache-2.0
*
* \author Forest-Rain
*/
/**
* @file lora-radio-rtos-config.h
* @brief support lora-radio-driver for XiUOS
* @version 3.0
* @author AIIT XUOS Lab
* @date 2023-03-07
*/
/*************************************************
File name: lora-radio-rtos-config.h
Description: support lora-radio-driver for XiUOS
Others:
History:
1. Date: 2023-03-07
Author: AIIT XUOS Lab
Modification:
1add LORA_RADIO_DRIVER_USING_RTOS_XIUOS to support XiUOS.
*************************************************/
#ifndef __LORA_RADIO_RTOS_CONFIG_H_
#define __LORA_RADIO_RTOS_CONFIG_H_
#include <transform.h>
// default based on rt-thread
//#define LORA_RADIO_DRIVER_USING_RTOS_RT_THREAD
//#define LORA_RADIO_DRIVER_USING_RTOS_RT_THREAD_NANO
//#define LORA_RADIO_DRIVER_USING_RTOS_XIUOS
#ifdef LORA_RADIO_DRIVER_USING_RTOS_RT_THREAD
#elif defined LORA_RADIO_DRIVER_USING_RTOS_RT_THREAD_NANO
#elif defined LORA_RADIO_DRIVER_USING_RTOS_XIUOS
#else
#error "Please Choose your RTOS setup!"
#endif
#ifdef LORA_RADIO_DRIVER_USING_RTOS_RT_THREAD
#include "rtconfig.h"
#include <rtthread.h>
#include <rtdevice.h>
#include "drv_spi.h"
#define LOG_LVL_ASSERT 0
#define LOG_LVL_ERROR 3
#define LOG_LVL_WARNING 4
#define LOG_LVL_INFO 6
#define LOG_LVL_DBG 7
#elif defined LORA_RADIO_DRIVER_USING_RTOS_RT_THREAD_NANO
#include <rtthread.h>
#elif defined LORA_RADIO_DRIVER_USING_RTOS_XIUOS
#define LOG_LVL_ASSERT 0
#define LOG_LVL_ERROR 3
#define LOG_LVL_WARNING 4
#define LOG_LVL_INFO 6
#define LOG_LVL_DBG 7
#endif
#endif // end of __LORA_RADIO_RTOS_CONFIG_H_

View File

@ -0,0 +1,549 @@
/*!
* \file lora-radio.h
*
* \brief LoRa Radio driver API definition
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
* ______ _
* / _____) _ | |
* ( (____ _____ ____ _| |_ _____ ____| |__
* \____ \| ___ | (_ _) ___ |/ ___) _ \
* _____) ) ____| | | || |_| ____( (___| | | |
* (______/|_____)_|_|_| \__)_____)\____)_| |_|
* (C)2013-2017 Semtech
*
* \endcode
*
* \author Miguel Luis ( Semtech )
*
* \author Gregory Cristian ( Semtech )
*
* \author forest-rain
*
* \author AIIT XUOS Lab
*/
/**
* @file lora-radio.h
* @brief support lora-radio-driver for XiUOS
* @version 3.0
* @author AIIT XUOS Lab
* @date 2023-03-07
*/
/*************************************************
File name: lora-radio.h
Description: support lora-radio-driver for XiUOS
Others:
History:
1. Date: 2023-03-07
Author: AIIT XUOS Lab
Modification:
1add LORA_RADIO_DRIVER_USING_RTOS_XIUOS to support XiUOS.
*************************************************/
#ifndef __LORA_RADIO_H__
#define __LORA_RADIO_H__
#include <stdint.h>
#include <stdbool.h>
#include <transform.h>
/*!
* LoRa Radio software version number
*/
#define LORA_RADIO_SW_VERSION "1.4.5"
#define LORA_RADIO_SW_VERSION_NUM 0x10405
#ifdef LORA_RADIO_DRIVER_USING_RTOS_RT_THREAD
/*!
* Begins critical section
*/
#define LORA_RADIO_CRITICAL_SECTION_BEGIN( ) register rt_base_t level; level = rt_hw_interrupt_disable()
/*!
* Ends critical section
*/
#define LORA_RADIO_CRITICAL_SECTION_END( ) rt_hw_interrupt_enable(level)
#elif defined LORA_RADIO_DRIVER_USING_RTOS_XIUOS
/*!
* Begins critical section
*/
#define LORA_RADIO_CRITICAL_SECTION_BEGIN( )
/*!
* Ends critical section
*/
#define LORA_RADIO_CRITICAL_SECTION_END( )
#else
/*!
* Begins critical section
*/
#define LORA_RADIO_CRITICAL_SECTION_BEGIN(x) register uint32_t level; level = __get_PRIMASK(); __disable_irq();
/*!
* Ends critical section
*/
#define LORA_RADIO_CRITICAL_SECTION_END(x) __set_PRIMASK(level)
#endif
/** @addtogroup LORA_RADIO_UPPER_API
* @{
*/
/*!
* Radio driver supported modems
*/
typedef enum
{
MODEM_FSK = 0,
MODEM_LORA,
MODEM_BPSK, //!<for STM32WL
MODEM_SIGFOX_TX, //!<for STM32WL
MODEM_SIGFOX_RX, //!<for STM32WL
}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;
/*!
* Radio Dio Irq event definition
*/
typedef enum
{
EV_LORA_RADIO_IRQ0_FIRED = 0x0001,
EV_LORA_RADIO_IRQ1_FIRED = 0x0002,
EV_LORA_RADIO_IRQ2_FIRED = 0x0004,
EV_LORA_RADIO_IRQ3_FIRED = 0x0008,
EV_LORA_RADIO_IRQ4_FIRED = 0x0010,
EV_LORA_RADIO_IRQ5_FIRED = 0x0020,
EV_LORA_RADIO_TIMEOUT_FIRED = 0x0040, //!< sx127x tx\rx timeout
}RadioDioIrqEvent_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 SNR value computed while receiving the frame [dB]
* 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 radio
*
* \param [IN] events Structure containing the driver callback functions
*/
bool ( *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] 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] 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] payloadLen Sets payload length when fixed length is used
* \param [IN] crcOn Enables/Disables the CRC [0: OFF, 1: ON]
*
* \retval airTime Computed airTime (ms) for the given packet payload length
*/
uint32_t ( *TimeOnAir )( RadioModems_t modem, uint32_t bandwidth,
uint32_t datarate, uint8_t coderate,
uint16_t preambleLen, bool fixLen, uint8_t payloadLen,
bool crcOn );
/*!
* \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 )( uint16_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 )( uint16_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 )( uint16_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 )( uint16_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 Gets the time required for the board plus radio to get out of sleep.[ms]
*
* \retval time Radio plus board wakeup time in ms.
*/
uint32_t ( *GetWakeupTime )( void );
/*!
* \brief Process radio irq
*/
void ( *IrqProcess )( void );
/*!
* \brief radio spi check
*/
uint8_t ( *Check )( void );
/*
* The next functions are available only on SX126x radios.
*/
/*!
* \brief Sets the radio in reception mode with Max LNA gain for the given time
*
* \remark Available on SX126x radios only.
*
* \param [IN] timeout Reception timeout [ms]
* [0: continuous, others timeout]
*/
void ( *RxBoosted )( uint32_t timeout );
/*!
* \brief Sets the Rx duty cycle management parameters
*
* \remark Available on SX126x radios only.
*
* \param [in] rxTime Structure describing reception timeout value
* \param [in] sleepTime Structure describing sleep timeout value
*/
void ( *SetRxDutyCycle ) ( uint32_t rxTime, uint32_t sleepTime );
/*!
* @brief Sets the Transmitter in continuous PRBS mode for STM32WL
*
* \remark power and datarate shall be configured prior calling TxPrbs
*/
void (*TxPrbs) ( void );
/*!
* @brief Sets the Transmitter in continuous unmodulated Carrier mode for STM32WL
*/
void (*TxCw) ( int8_t power );
/*!
* \brief radio rxdone timestamp
*/
uint32_t ( *GetRxdoneTimestamp )( void );
};
/*!
* \brief Radio Parameter config definition
*/
typedef struct LoRaRadioConfig_s
{
RadioModems_t modem; // LoRa Modem \ FSK modem
uint32_t frequency;
int8_t txpower;
// LoRa
uint8_t sf; // spreadfactor
uint8_t bw; // bandwidth
uint8_t cr; // coderate
uint8_t hop_period;
uint8_t symb_timeout;
union
{
struct
{
uint8_t iq_inverted:1;
//uint8_t public_network:1;
uint8_t fix_len_enable:1;
uint8_t crc_on:1;
uint8_t freq_hop_on:1;
uint8_t rx_continuous:1;
}bits;
uint8_t byte;
}rf_misc;
// FSK
uint32_t fdev;
uint32_t datarate;
uint32_t fsk_bandwidth;
uint32_t fsk_afc_bandwidth;
uint16_t preamble_len;
}LoRaRadioConfig_t;
/*!
* \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__

View File

@ -0,0 +1,3 @@
SRC_FILES := sx126x.c lora-radio-sx126x.c lora-spi-sx126x.c
include $(KERNEL_ROOT)/compiler.mk

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,324 @@
/*!
* \file lora-spi-SX126x.c
*
* \brief spi driver implementation for SX126X
*
* SPDX-License-Identifier: Apache-2.0
*
* \author Forest-Rain
*
* \author AIIT XUOS Lab
*/
/**
* @file lora-spi-SX126x.c
* @brief support lora-radio-driver for XiUOS
* @version 3.0
* @author AIIT XUOS Lab
* @date 2023-03-13
*/
/*************************************************
File name: lora-spi-SX126x.c
Description: support lora-radio-driver for XiUOS
Others:
History:
1. Date: 2023-03-13
Author: AIIT XUOS Lab
Modification:
1add LORA_RADIO_DRIVER_USING_RTOS_XIUOS to support XiUOS.
*************************************************/
#include <sx126x-board.h>
#define LOG_TAG "LoRa.SX126X.SPI"
#define LOG_LEVEL LOG_LVL_DBG
#include <lora-radio-debug.h>
void SX126xWakeup( void )
{
#ifdef LORA_RADIO_DRIVER_USING_RTOS_RT_THREAD
#ifdef RT_USING_SPI
uint8_t msg[2] = { RADIO_GET_STATUS, 0x00 };
rt_spi_transfer(SX126x.spi,msg,RT_NULL,2);
// Wait for chip to be ready.
SX126xWaitOnBusy( );
// Update operating mode context variable
SX126xSetOperatingMode( MODE_STDBY_RC );
#endif
#endif
#ifdef LORA_RADIO_DRIVER_USING_RTOS_XIUOS
int spi_fd;
uint8_t msg[2] = { RADIO_GET_STATUS, 0x00 };
spi_fd = PrivOpen(LORA_SPI_DEV_NAME, O_RDWR);
PrivWrite(spi_fd, msg, 2);
PrivClose(spi_fd);
// Wait for chip to be ready.
SX126xWaitOnBusy( );
// Update operating mode context variable
SX126xSetOperatingMode( MODE_STDBY_RC );
#endif
}
void SX126xWriteCommand( RadioCommands_t command, uint8_t *buffer, uint16_t size )
{
#ifdef LORA_RADIO_DRIVER_USING_RTOS_RT_THREAD
#ifdef RT_USING_SPI
SX126xCheckDeviceReady( );
rt_spi_send_then_send(SX126x.spi,&command,1,buffer,size);
if( command != RADIO_SET_SLEEP )
{
SX126xWaitOnBusy( );
}
#endif
#endif
#ifdef LORA_RADIO_DRIVER_USING_RTOS_XIUOS
int spi_fd;
SX126xCheckDeviceReady( );
spi_fd = PrivOpen(LORA_SPI_DEV_NAME, O_RDWR);
PrivWrite(spi_fd, &command, 1);
PrivWrite(spi_fd, buffer, size);
PrivClose(spi_fd);
if( command != RADIO_SET_SLEEP )
{
SX126xWaitOnBusy( );
}
#endif
}
uint8_t SX126xReadCommand( RadioCommands_t command, uint8_t *buffer, uint16_t size )
{
#ifdef LORA_RADIO_DRIVER_USING_RTOS_RT_THREAD
#ifdef RT_USING_SPI
uint8_t status = 0;
uint8_t buffer_temp[16] = {0}; // command size is 2 size
SX126xCheckDeviceReady( );
rt_spi_send_then_recv(SX126x.spi,&command,1,buffer_temp,size + 1);
status = buffer_temp[0];
rt_memcpy(buffer,buffer_temp+1,size);
SX126xWaitOnBusy( );
return status;
#endif
#endif
#ifdef LORA_RADIO_DRIVER_USING_RTOS_XIUOS
int spi_fd;
uint8_t status = 0;
uint8_t buffer_temp[16] = {0}; // command size is 2 size
SX126xCheckDeviceReady( );
spi_fd = PrivOpen(LORA_SPI_DEV_NAME, O_RDWR);
PrivWrite(spi_fd, &command, 1);
PrivRead(spi_fd, buffer_temp, size + 1);
PrivClose(spi_fd);
status = buffer_temp[0];
memcpy(buffer, buffer_temp + 1, size);
SX126xWaitOnBusy( );
return status;
#endif
}
void SX126xWriteRegisters( uint16_t address, uint8_t *buffer, uint16_t size )
{
#ifdef LORA_RADIO_DRIVER_USING_RTOS_RT_THREAD
#ifdef RT_USING_SPI
uint8_t msg[3] = {0};
msg[0] = RADIO_WRITE_REGISTER;
msg[1] = ( address & 0xFF00 ) >> 8;
msg[2] = address & 0x00FF;
SX126xCheckDeviceReady( );
rt_spi_send_then_send(SX126x.spi,msg,3,buffer,size);
SX126xWaitOnBusy( );
#endif
#endif
#ifdef LORA_RADIO_DRIVER_USING_RTOS_XIUOS
int spi_fd;
uint8_t msg[3] = {0};
msg[0] = RADIO_WRITE_REGISTER;
msg[1] = ( address & 0xFF00 ) >> 8;
msg[2] = address & 0x00FF;
SX126xCheckDeviceReady( );
spi_fd = PrivOpen(LORA_SPI_DEV_NAME, O_RDWR);
PrivWrite(spi_fd, msg, 3);
PrivWrite(spi_fd, buffer, size);
PrivClose(spi_fd);
SX126xWaitOnBusy( );
#endif
}
void SX126xWriteRegister( uint16_t address, uint8_t value )
{
SX126xWriteRegisters( address, &value, 1 );
}
void SX126xReadRegisters( uint16_t address, uint8_t *buffer, uint16_t size )
{
#ifdef LORA_RADIO_DRIVER_USING_RTOS_RT_THREAD
#ifdef RT_USING_SPI
uint8_t msg[4] = {0};
msg[0] = RADIO_READ_REGISTER;
msg[1] = ( address & 0xFF00 ) >> 8;
msg[2] = address & 0x00FF;
msg[3] = 0;
SX126xCheckDeviceReady( );
rt_spi_send_then_recv(SX126x.spi,msg,4,buffer,size);
SX126xWaitOnBusy( );
#endif
#endif
#ifdef LORA_RADIO_DRIVER_USING_RTOS_XIUOS
int spi_fd;
uint8_t msg[4] = {0};
msg[0] = RADIO_READ_REGISTER;
msg[1] = ( address & 0xFF00 ) >> 8;
msg[2] = address & 0x00FF;
msg[3] = 0;
SX126xCheckDeviceReady( );
spi_fd = PrivOpen(LORA_SPI_DEV_NAME, O_RDWR);
PrivWrite(spi_fd, msg, 4);
PrivRead(spi_fd, buffer, size);
PrivClose(spi_fd);
SX126xWaitOnBusy( );
#endif
}
uint8_t SX126xReadRegister( uint16_t address )
{
uint8_t data;
SX126xReadRegisters( address, &data, 1 );
return data;
}
void SX126xWriteBuffer( uint8_t offset, uint8_t *buffer, uint8_t size )
{
#ifdef LORA_RADIO_DRIVER_USING_RTOS_RT_THREAD
#ifdef RT_USING_SPI
uint8_t msg[2] = {0};
msg[0] = RADIO_WRITE_BUFFER;
msg[1] = offset;
SX126xCheckDeviceReady( );
rt_spi_send_then_send(SX126x.spi,msg,2,buffer,size);
SX126xWaitOnBusy( );
#endif
#endif
#ifdef LORA_RADIO_DRIVER_USING_RTOS_XIUOS
int spi_fd;
uint8_t msg[2] = {0};
msg[0] = RADIO_WRITE_BUFFER;
msg[1] = offset;
SX126xCheckDeviceReady( );
spi_fd = PrivOpen(LORA_SPI_DEV_NAME, O_RDWR);
PrivWrite(spi_fd, msg, 2);
PrivWrite(spi_fd, buffer, size);
PrivClose(spi_fd);
SX126xWaitOnBusy( );
#endif
}
void SX126xReadBuffer( uint8_t offset, uint8_t *buffer, uint8_t size )
{
#ifdef LORA_RADIO_DRIVER_USING_RTOS_RT_THREAD
#ifdef RT_USING_SPI
uint8_t msg[3] = {0};
msg[0] = RADIO_READ_BUFFER;
msg[1] = offset;
msg[2] = 0;
SX126xCheckDeviceReady( );
rt_spi_send_then_recv(SX126x.spi,msg,3,buffer,size);
SX126xWaitOnBusy( );
#endif
#endif
#ifdef LORA_RADIO_DRIVER_USING_RTOS_XIUOS
int spi_fd;
uint8_t msg[3] = {0};
msg[0] = RADIO_READ_BUFFER;
msg[1] = offset;
msg[2] = 0;
SX126xCheckDeviceReady( );
spi_fd = PrivOpen(LORA_SPI_DEV_NAME, O_RDWR);
PrivWrite(spi_fd, msg, 3);
PrivRead(spi_fd, buffer, size);
PrivClose(spi_fd);
SX126xWaitOnBusy( );
#endif
}

View File

@ -0,0 +1,111 @@
/*!
* \file lora-spi-sx126x.h
*
* \brief SX126x spi interface
*
* SPDX-License-Identifier: Apache-2.0
*
* \author Forest-Rain
*/
#ifndef __LORA_SPI_SX126X_H__
#define __LORA_SPI_SX126X_H__
#include "sx126x.h"
/** @addtogroup LORA_RADIO_SPI
* @{
*/
/** @addtogroup SX126X_SPI
* @{
*/
/*!
* \brief Wakes up the radio
*/
void SX126xWakeup( void );
/*!
* \brief Send a command that write data to the radio
*
* \param [in] opcode Opcode of the command
* \param [in] buffer Buffer to be send to the radio
* \param [in] size Size of the buffer to send
*/
void SX126xWriteCommand( RadioCommands_t opcode, uint8_t *buffer, uint16_t size );
/*!
* \brief Send a command that read data from the radio
*
* \param [in] opcode Opcode of the command
* \param [out] buffer Buffer holding data from the radio
* \param [in] size Size of the buffer
*
* \retval status Return command radio status
*/
uint8_t SX126xReadCommand( RadioCommands_t opcode, uint8_t *buffer, uint16_t size );
/*!
* \brief Write a single byte of data to the radio memory
*
* \param [in] address The address of the first byte to write in the radio
* \param [in] value The data to be written in radio's memory
*/
void SX126xWriteRegister( uint16_t address, uint8_t value );
/*!
* \brief Read a single byte of data from the radio memory
*
* \param [in] address The address of the first byte to write in the radio
*
* \retval value The value of the byte at the given address in radio's memory
*/
uint8_t SX126xReadRegister( uint16_t address );
/*!
* \brief Write data to the radio memory
*
* \param [in] address The address of the first byte to write in the radio
* \param [in] buffer The data to be written in radio's memory
* \param [in] size The number of bytes to write in radio's memory
*/
void SX126xWriteRegisters( uint16_t address, uint8_t *buffer, uint16_t size );
/*!
* \brief Read data from the radio memory
*
* \param [in] address The address of the first byte to read from the radio
* \param [out] buffer The buffer that holds data read from radio
* \param [in] size The number of bytes to read from radio's memory
*/
void SX126xReadRegisters( uint16_t address, uint8_t *buffer, uint16_t size );
/*!
* \brief Write data to the buffer holding the payload in the radio
*
* \param [in] offset The offset to start writing the payload
* \param [in] buffer The data to be written (the payload)
* \param [in] size The number of byte to be written
*/
void SX126xWriteBuffer( uint8_t offset, uint8_t *buffer, uint8_t size );
/*!
* \brief Read data from the buffer holding the payload in the radio
*
* \param [in] offset The offset to start reading the payload
* \param [out] buffer A pointer to a buffer holding the data from the radio
* \param [in] size The number of byte to be read
*/
void SX126xReadBuffer( uint8_t offset, uint8_t *buffer, uint8_t size );
/**
* @}
*/
/**
* @}
*/
#endif /* __LORA_SPI_SX126X_H__ */

View File

@ -0,0 +1,806 @@
/*!
* \file sx126x.c
*
* \brief SX126x driver implementation
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
* ______ _
* / _____) _ | |
* ( (____ _____ ____ _| |_ _____ ____| |__
* \____ \| ___ | (_ _) ___ |/ ___) _ \
* _____) ) ____| | | || |_| ____( (___| | | |
* (______/|_____)_|_|_| \__)_____)\____)_| |_|
* (C)2013-2017 Semtech
*
* \endcode
*
* \author Miguel Luis ( Semtech )
*
* \author Gregory Cristian ( Semtech )
*/
#include <lora-radio-rtos-config.h>
#include <board.h>
#include <lora-radio-timer.h>
#include <lora-radio.h>
#include <lora-spi-sx126x.h>
#include <sx126x-board.h>
/*!
* \brief Radio registers definition
*/
typedef struct
{
uint16_t Addr; //!< The address of the register
uint8_t Value; //!< The value of the register
}RadioRegisters_t;
/*!
* \brief Holds the internal operating mode of the radio
*/
static RadioOperatingModes_t OperatingMode;
/*!
* \brief Stores the current packet type set in the radio
*/
static RadioPacketTypes_t PacketType;
/*!
* \brief Stores the current packet header type set in the radio
*/
static volatile RadioLoRaPacketLengthsMode_t LoRaHeaderType;
/*!
* \brief Stores the last frequency error measured on LoRa received packet
*/
volatile uint32_t FrequencyError = 0;
/*!
* \brief Hold the status of the Image calibration
*/
static bool ImageCalibrated = false;
/*
* SX126x DIO IRQ callback functions prototype
*/
/*!
* \brief DIO 0 IRQ callback
*/
void SX126xOnDioIrq( void );
/*!
* \brief DIO 0 IRQ callback
*/
void SX126xSetPollingMode( void );
/*!
* \brief DIO 0 IRQ callback
*/
void SX126xSetInterruptMode( void );
/*
* \brief Process the IRQ if handled by the driver
*/
void SX126xProcessIrqs( void );
void SX126xInit( DioIrqHandler dioIrq )
{
SX126xReset( );
SX126xIoIrqInit( dioIrq );
SX126xWakeup( );
SX126xSetStandby( STDBY_RC );
// Initialize TCXO control
SX126xIoTcxoInit( );
#ifdef LORA_RADIO_USE_DIO2_AS_RF_SWITCH_CTRL
SX126xSetDio2AsRfSwitchCtrl( true );
#endif
SX126xSetOperatingMode( MODE_STDBY_RC );
}
RadioOperatingModes_t SX126xGetOperatingMode( void )
{
return OperatingMode;
}
void SX126xSetOperatingMode( RadioOperatingModes_t mode )
{
OperatingMode = mode;
#if defined( LORA_RADIO_RFSW2_PIN ) && defined( LORA_RADIO_RFSW1_PIN )
SX126xSetAntSw( mode );
#endif
#if defined( USE_RADIO_DEBUG )
switch( mode )
{
case MODE_TX:
SX126xDbgPinTxWrite( 1 );
SX126xDbgPinRxWrite( 0 );
break;
case MODE_RX:
case MODE_RX_DC:
SX126xDbgPinTxWrite( 0 );
SX126xDbgPinRxWrite( 1 );
break;
default:
SX126xDbgPinTxWrite( 0 );
SX126xDbgPinRxWrite( 0 );
break;
}
#endif
}
void SX126xCheckDeviceReady( void )
{
if( ( SX126xGetOperatingMode( ) == MODE_SLEEP ) || ( SX126xGetOperatingMode( ) == MODE_RX_DC ) )
{
SX126xWakeup( );
// Switch is turned off when device is in sleep mode and turned on is all other modes
SX126xAntSwOn( );
}
SX126xWaitOnBusy( );
}
void SX126xSetPayload( uint8_t *payload, uint8_t size )
{
SX126xWriteBuffer( 0x00, payload, size );
}
uint8_t SX126xGetPayload( uint8_t *buffer, uint8_t *size, uint8_t maxSize )
{
uint8_t offset = 0;
SX126xGetRxBufferStatus( size, &offset );
if( *size > maxSize )
{
return 1;
}
SX126xReadBuffer( offset, buffer, *size );
return 0;
}
void SX126xSendPayload( uint8_t *payload, uint8_t size, uint32_t timeout )
{
SX126xSetPayload( payload, size );
SX126xSetTx( timeout );
}
uint8_t SX126xSetSyncWord( uint8_t *syncWord )
{
SX126xWriteRegisters( REG_LR_SYNCWORDBASEADDRESS, syncWord, 8 );
return 0;
}
void SX126xSetCrcSeed( uint16_t seed )
{
uint8_t buf[2];
buf[0] = ( uint8_t )( ( seed >> 8 ) & 0xFF );
buf[1] = ( uint8_t )( seed & 0xFF );
switch( SX126xGetPacketType( ) )
{
case PACKET_TYPE_GFSK:
SX126xWriteRegisters( REG_LR_CRCSEEDBASEADDR, buf, 2 );
break;
default:
break;
}
}
void SX126xSetCrcPolynomial( uint16_t polynomial )
{
uint8_t buf[2];
buf[0] = ( uint8_t )( ( polynomial >> 8 ) & 0xFF );
buf[1] = ( uint8_t )( polynomial & 0xFF );
switch( SX126xGetPacketType( ) )
{
case PACKET_TYPE_GFSK:
SX126xWriteRegisters( REG_LR_CRCPOLYBASEADDR, buf, 2 );
break;
default:
break;
}
}
void SX126xSetWhiteningSeed( uint16_t seed )
{
uint8_t regValue = 0;
switch( SX126xGetPacketType( ) )
{
case PACKET_TYPE_GFSK:
regValue = SX126xReadRegister( REG_LR_WHITSEEDBASEADDR_MSB ) & 0xFE;
regValue = ( ( seed >> 8 ) & 0x01 ) | regValue;
SX126xWriteRegister( REG_LR_WHITSEEDBASEADDR_MSB, regValue ); // only 1 bit.
SX126xWriteRegister( REG_LR_WHITSEEDBASEADDR_LSB, ( uint8_t )seed );
break;
default:
break;
}
}
uint32_t SX126xGetRandom( void )
{
uint32_t number = 0;
uint8_t regAnaLna = 0;
uint8_t regAnaMixer = 0;
regAnaLna = SX126xReadRegister( REG_ANA_LNA );
SX126xWriteRegister( REG_ANA_LNA, regAnaLna & ~( 1 << 0 ) );
regAnaMixer = SX126xReadRegister( REG_ANA_MIXER );
SX126xWriteRegister( REG_ANA_MIXER, regAnaMixer & ~( 1 << 7 ) );
// Set radio in continuous reception
SX126xSetRx( 0xFFFFFF ); // Rx Continuous
SX126xReadRegisters( RANDOM_NUMBER_GENERATORBASEADDR, ( uint8_t* )&number, 4 );
SX126xSetStandby( STDBY_RC );
SX126xWriteRegister( REG_ANA_LNA, regAnaLna );
SX126xWriteRegister( REG_ANA_MIXER, regAnaMixer );
return number;
}
void SX126xSetSleep( SleepParams_t sleepConfig )
{
SX126xAntSwOff( );
uint8_t value = ( ( ( uint8_t )sleepConfig.Fields.WarmStart << 2 ) |
( ( uint8_t )sleepConfig.Fields.Reset << 1 ) |
( ( uint8_t )sleepConfig.Fields.WakeUpRTC ) );
SX126xWriteCommand( RADIO_SET_SLEEP, &value, 1 );
SX126xSetOperatingMode( MODE_SLEEP );
}
void SX126xSetStandby( RadioStandbyModes_t standbyConfig )
{
SX126xWriteCommand( RADIO_SET_STANDBY, ( uint8_t* )&standbyConfig, 1 );
if( standbyConfig == STDBY_RC )
{
SX126xSetOperatingMode( MODE_STDBY_RC );
}
else
{
SX126xSetOperatingMode( MODE_STDBY_XOSC );
}
}
void SX126xSetFs( void )
{
SX126xWriteCommand( RADIO_SET_FS, 0, 0 );
SX126xSetOperatingMode( MODE_FS );
}
void SX126xSetTx( uint32_t timeout )
{
uint8_t buf[3];
SX126xSetOperatingMode( MODE_TX );
buf[0] = ( uint8_t )( ( timeout >> 16 ) & 0xFF );
buf[1] = ( uint8_t )( ( timeout >> 8 ) & 0xFF );
buf[2] = ( uint8_t )( timeout & 0xFF );
SX126xWriteCommand( RADIO_SET_TX, buf, 3 );
}
void SX126xSetRx( uint32_t timeout )
{
uint8_t buf[3];
SX126xSetOperatingMode( MODE_RX );
buf[0] = ( uint8_t )( ( timeout >> 16 ) & 0xFF );
buf[1] = ( uint8_t )( ( timeout >> 8 ) & 0xFF );
buf[2] = ( uint8_t )( timeout & 0xFF );
SX126xWriteCommand( RADIO_SET_RX, buf, 3 );
}
void SX126xSetRxBoosted( uint32_t timeout )
{
uint8_t buf[3];
SX126xSetOperatingMode( MODE_RX );
SX126xWriteRegister( REG_RX_GAIN, 0x96 ); // max LNA gain, increase current by ~2mA for around ~3dB in sensivity
buf[0] = ( uint8_t )( ( timeout >> 16 ) & 0xFF );
buf[1] = ( uint8_t )( ( timeout >> 8 ) & 0xFF );
buf[2] = ( uint8_t )( timeout & 0xFF );
SX126xWriteCommand( RADIO_SET_RX, buf, 3 );
}
void SX126xSetRxDutyCycle( uint32_t rxTime, uint32_t sleepTime )
{
uint8_t buf[6];
buf[0] = ( uint8_t )( ( rxTime >> 16 ) & 0xFF );
buf[1] = ( uint8_t )( ( rxTime >> 8 ) & 0xFF );
buf[2] = ( uint8_t )( rxTime & 0xFF );
buf[3] = ( uint8_t )( ( sleepTime >> 16 ) & 0xFF );
buf[4] = ( uint8_t )( ( sleepTime >> 8 ) & 0xFF );
buf[5] = ( uint8_t )( sleepTime & 0xFF );
SX126xWriteCommand( RADIO_SET_RXDUTYCYCLE, buf, 6 );
SX126xSetOperatingMode( MODE_RX_DC );
}
void SX126xSetCad( void )
{
SX126xWriteCommand( RADIO_SET_CAD, 0, 0 );
SX126xSetOperatingMode( MODE_CAD );
}
void SX126xSetTxContinuousWave( void )
{
SX126xSetAntSw(MODE_TX);
SX126xWriteCommand( RADIO_SET_TXCONTINUOUSWAVE, 0, 0 );
}
void SX126xSetTxInfinitePreamble( void )
{
SX126xWriteCommand( RADIO_SET_TXCONTINUOUSPREAMBLE, 0, 0 );
}
void SX126xSetStopRxTimerOnPreambleDetect( bool enable )
{
SX126xWriteCommand( RADIO_SET_STOPRXTIMERONPREAMBLE, ( uint8_t* )&enable, 1 );
}
void SX126xSetLoRaSymbNumTimeout( uint8_t symbNum )
{
SX126xWriteCommand( RADIO_SET_LORASYMBTIMEOUT, &symbNum, 1 );
if( symbNum >= 64 )
{
uint8_t mant = symbNum >> 1;
uint8_t exp = 0;
uint8_t reg = 0;
while( mant > 31 )
{
mant >>= 2;
exp++;
}
reg = exp + ( mant << 3 );
SX126xWriteRegister( REG_LR_SYNCH_TIMEOUT, reg );
}
}
void SX126xSetRegulatorMode( RadioRegulatorMode_t mode )
{
SX126xWriteCommand( RADIO_SET_REGULATORMODE, ( uint8_t* )&mode, 1 );
}
void SX126xCalibrate( CalibrationParams_t calibParam )
{
uint8_t value = ( ( ( uint8_t )calibParam.Fields.ImgEnable << 6 ) |
( ( uint8_t )calibParam.Fields.ADCBulkPEnable << 5 ) |
( ( uint8_t )calibParam.Fields.ADCBulkNEnable << 4 ) |
( ( uint8_t )calibParam.Fields.ADCPulseEnable << 3 ) |
( ( uint8_t )calibParam.Fields.PLLEnable << 2 ) |
( ( uint8_t )calibParam.Fields.RC13MEnable << 1 ) |
( ( uint8_t )calibParam.Fields.RC64KEnable ) );
SX126xWriteCommand( RADIO_CALIBRATE, &value, 1 );
}
void SX126xCalibrateImage( uint32_t freq )
{
uint8_t calFreq[2];
if( freq > 900000000 )
{
calFreq[0] = 0xE1;
calFreq[1] = 0xE9;
}
else if( freq > 850000000 )
{
calFreq[0] = 0xD7;
calFreq[1] = 0xDB;
}
else if( freq > 770000000 )
{
calFreq[0] = 0xC1;
calFreq[1] = 0xC5;
}
else if( freq > 460000000 )
{
calFreq[0] = 0x75;
calFreq[1] = 0x81;
}
else if( freq > 425000000 )
{
calFreq[0] = 0x6B;
calFreq[1] = 0x6F;
}
SX126xWriteCommand( RADIO_CALIBRATEIMAGE, calFreq, 2 );
}
void SX126xSetPaConfig( uint8_t paDutyCycle, uint8_t hpMax, uint8_t deviceSel, uint8_t paLut )
{
uint8_t buf[4];
buf[0] = paDutyCycle;
buf[1] = hpMax;
buf[2] = deviceSel;
buf[3] = paLut;
SX126xWriteCommand( RADIO_SET_PACONFIG, buf, 4 );
}
void SX126xSetRxTxFallbackMode( uint8_t fallbackMode )
{
SX126xWriteCommand( RADIO_SET_TXFALLBACKMODE, &fallbackMode, 1 );
}
void SX126xSetDioIrqParams( uint16_t irqMask, uint16_t dio1Mask, uint16_t dio2Mask, uint16_t dio3Mask )
{
uint8_t buf[8];
buf[0] = ( uint8_t )( ( irqMask >> 8 ) & 0x00FF );
buf[1] = ( uint8_t )( irqMask & 0x00FF );
buf[2] = ( uint8_t )( ( dio1Mask >> 8 ) & 0x00FF );
buf[3] = ( uint8_t )( dio1Mask & 0x00FF );
buf[4] = ( uint8_t )( ( dio2Mask >> 8 ) & 0x00FF );
buf[5] = ( uint8_t )( dio2Mask & 0x00FF );
buf[6] = ( uint8_t )( ( dio3Mask >> 8 ) & 0x00FF );
buf[7] = ( uint8_t )( dio3Mask & 0x00FF );
SX126xWriteCommand( RADIO_CFG_DIOIRQ, buf, 8 );
}
uint16_t SX126xGetIrqStatus( void )
{
uint8_t irqStatus[2];
SX126xReadCommand( RADIO_GET_IRQSTATUS, irqStatus, 2 );
return ( irqStatus[0] << 8 ) | irqStatus[1];
}
void SX126xSetDio2AsRfSwitchCtrl( uint8_t enable )
{
SX126xWriteCommand( RADIO_SET_RFSWITCHMODE, &enable, 1 );
}
void SX126xSetDio3AsTcxoCtrl( RadioTcxoCtrlVoltage_t tcxoVoltage, uint32_t timeout )
{
uint8_t buf[4];
buf[0] = tcxoVoltage & 0x07;
buf[1] = ( uint8_t )( ( timeout >> 16 ) & 0xFF );
buf[2] = ( uint8_t )( ( timeout >> 8 ) & 0xFF );
buf[3] = ( uint8_t )( timeout & 0xFF );
SX126xWriteCommand( RADIO_SET_TCXOMODE, buf, 4 );
}
void SX126xSetRfFrequency( uint32_t frequency )
{
uint8_t buf[4];
uint32_t freq = 0;
if( ImageCalibrated == false )
{
SX126xCalibrateImage( frequency );
ImageCalibrated = true;
}
freq = ( uint32_t )( ( double )frequency / ( double )FREQ_STEP );
buf[0] = ( uint8_t )( ( freq >> 24 ) & 0xFF );
buf[1] = ( uint8_t )( ( freq >> 16 ) & 0xFF );
buf[2] = ( uint8_t )( ( freq >> 8 ) & 0xFF );
buf[3] = ( uint8_t )( freq & 0xFF );
SX126xWriteCommand( RADIO_SET_RFFREQUENCY, buf, 4 );
}
void SX126xSetPacketType( RadioPacketTypes_t packetType )
{
// Save packet type internally to avoid questioning the radio
PacketType = packetType;
SX126xWriteCommand( RADIO_SET_PACKETTYPE, ( uint8_t* )&packetType, 1 );
}
RadioPacketTypes_t SX126xGetPacketType( void )
{
return PacketType;
}
void SX126xSetTxParams( int8_t power, RadioRampTimes_t rampTime )
{
uint8_t buf[2];
//// if( SX126xGetDeviceId( ) == SX1261 )
//// {
//// if( power == 15 )
//// {
//// SX126xSetPaConfig( 0x06, 0x00, 0x01, 0x01 );
//// }
//// else
//// {
//// SX126xSetPaConfig( 0x04, 0x00, 0x01, 0x01 );
//// }
//// if( power >= 14 )
//// {
//// power = 14;
//// }
//// else if( power < -17 )
//// {
//// power = -17;
//// }
//// SX126xWriteRegister( REG_OCP, 0x18 ); // current max is 80 mA for the whole device
//// }
//// else // sx1262
{
// WORKAROUND - Better Resistance of the SX1262 Tx to Antenna Mismatch, see DS_SX1261-2_V1.2 datasheet chapter 15.2
// RegTxClampConfig = @address 0x08D8
SX126xWriteRegister( 0x08D8, SX126xReadRegister( 0x08D8 ) | ( 0x0F << 1 ) );
// WORKAROUND END
SX126xSetPaConfig( 0x04, 0x07, 0x00, 0x01 );
if( power > 22 )
{
power = 22;
}
else if( power < -9 )
{
power = -9;
}
SX126xWriteRegister( REG_OCP, 0x38 ); // current max 160mA for the whole device
}
buf[0] = power;
buf[1] = ( uint8_t )rampTime;
SX126xWriteCommand( RADIO_SET_TXPARAMS, buf, 2 );
}
void SX126xSetRfTxPower( int8_t power )
{
SX126xSetTxParams( power, RADIO_RAMP_40_US );
}
void SX126xSetModulationParams( ModulationParams_t *modulationParams )
{
uint8_t n;
uint32_t tempVal = 0;
uint8_t buf[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
// Check if required configuration corresponds to the stored packet type
// If not, silently update radio packet type
if( PacketType != modulationParams->PacketType )
{
SX126xSetPacketType( modulationParams->PacketType );
}
switch( modulationParams->PacketType )
{
case PACKET_TYPE_GFSK:
n = 8;
tempVal = ( uint32_t )( 32 * ( ( double )XTAL_FREQ / ( double )modulationParams->Params.Gfsk.BitRate ) );
buf[0] = ( tempVal >> 16 ) & 0xFF;
buf[1] = ( tempVal >> 8 ) & 0xFF;
buf[2] = tempVal & 0xFF;
buf[3] = modulationParams->Params.Gfsk.ModulationShaping;
buf[4] = modulationParams->Params.Gfsk.Bandwidth;
tempVal = ( uint32_t )( ( double )modulationParams->Params.Gfsk.Fdev / ( double )FREQ_STEP );
buf[5] = ( tempVal >> 16 ) & 0xFF;
buf[6] = ( tempVal >> 8 ) & 0xFF;
buf[7] = ( tempVal& 0xFF );
SX126xWriteCommand( RADIO_SET_MODULATIONPARAMS, buf, n );
break;
case PACKET_TYPE_LORA:
n = 4;
buf[0] = modulationParams->Params.LoRa.SpreadingFactor;
buf[1] = modulationParams->Params.LoRa.Bandwidth;
buf[2] = modulationParams->Params.LoRa.CodingRate;
buf[3] = modulationParams->Params.LoRa.LowDatarateOptimize;
SX126xWriteCommand( RADIO_SET_MODULATIONPARAMS, buf, n );
break;
default:
case PACKET_TYPE_NONE:
return;
}
}
void SX126xSetPacketParams( PacketParams_t *packetParams )
{
uint8_t n;
uint8_t crcVal = 0;
uint8_t buf[9] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
// Check if required configuration corresponds to the stored packet type
// If not, silently update radio packet type
if( PacketType != packetParams->PacketType )
{
SX126xSetPacketType( packetParams->PacketType );
}
switch( packetParams->PacketType )
{
case PACKET_TYPE_GFSK:
if( packetParams->Params.Gfsk.CrcLength == RADIO_CRC_2_BYTES_IBM )
{
SX126xSetCrcSeed( CRC_IBM_SEED );
SX126xSetCrcPolynomial( CRC_POLYNOMIAL_IBM );
crcVal = RADIO_CRC_2_BYTES;
}
else if( packetParams->Params.Gfsk.CrcLength == RADIO_CRC_2_BYTES_CCIT )
{
SX126xSetCrcSeed( CRC_CCITT_SEED );
SX126xSetCrcPolynomial( CRC_POLYNOMIAL_CCITT );
crcVal = RADIO_CRC_2_BYTES_INV;
}
else
{
crcVal = packetParams->Params.Gfsk.CrcLength;
}
n = 9;
buf[0] = ( packetParams->Params.Gfsk.PreambleLength >> 8 ) & 0xFF;
buf[1] = packetParams->Params.Gfsk.PreambleLength;
buf[2] = packetParams->Params.Gfsk.PreambleMinDetect;
buf[3] = ( packetParams->Params.Gfsk.SyncWordLength /*<< 3*/ ); // convert from byte to bit
buf[4] = packetParams->Params.Gfsk.AddrComp;
buf[5] = packetParams->Params.Gfsk.HeaderType;
buf[6] = packetParams->Params.Gfsk.PayloadLength;
buf[7] = crcVal;
buf[8] = packetParams->Params.Gfsk.DcFree;
break;
case PACKET_TYPE_LORA:
n = 6;
buf[0] = ( packetParams->Params.LoRa.PreambleLength >> 8 ) & 0xFF;
buf[1] = packetParams->Params.LoRa.PreambleLength;
buf[2] = LoRaHeaderType = packetParams->Params.LoRa.HeaderType;
buf[3] = packetParams->Params.LoRa.PayloadLength;
buf[4] = packetParams->Params.LoRa.CrcMode;
buf[5] = packetParams->Params.LoRa.InvertIQ;
break;
default:
case PACKET_TYPE_NONE:
return;
}
SX126xWriteCommand( RADIO_SET_PACKETPARAMS, buf, n );
}
void SX126xSetCadParams( RadioLoRaCadSymbols_t cadSymbolNum, uint8_t cadDetPeak, uint8_t cadDetMin, RadioCadExitModes_t cadExitMode, uint32_t cadTimeout )
{
uint8_t buf[7];
buf[0] = ( uint8_t )cadSymbolNum;
buf[1] = cadDetPeak;
buf[2] = cadDetMin;
buf[3] = ( uint8_t )cadExitMode;
buf[4] = ( uint8_t )( ( cadTimeout >> 16 ) & 0xFF );
buf[5] = ( uint8_t )( ( cadTimeout >> 8 ) & 0xFF );
buf[6] = ( uint8_t )( cadTimeout & 0xFF );
SX126xWriteCommand( RADIO_SET_CADPARAMS, buf, 7 );
SX126xSetOperatingMode( MODE_CAD );
}
void SX126xSetBufferBaseAddress( uint8_t txBaseAddress, uint8_t rxBaseAddress )
{
uint8_t buf[2];
buf[0] = txBaseAddress;
buf[1] = rxBaseAddress;
SX126xWriteCommand( RADIO_SET_BUFFERBASEADDRESS, buf, 2 );
}
RadioStatus_t SX126xGetStatus( void )
{
uint8_t stat = 0;
RadioStatus_t status = { .Value = 0 };
stat = SX126xReadCommand( RADIO_GET_STATUS, NULL, 0 );
status.Fields.CmdStatus = ( stat & ( 0x07 << 1 ) ) >> 1;
status.Fields.ChipMode = ( stat & ( 0x07 << 4 ) ) >> 4;
return status;
}
int8_t SX126xGetRssiInst( void )
{
uint8_t buf[1];
int8_t rssi = 0;
SX126xReadCommand( RADIO_GET_RSSIINST, buf, 1 );
rssi = -buf[0] >> 1;
return rssi;
}
void SX126xGetRxBufferStatus( uint8_t *payloadLength, uint8_t *rxStartBufferPointer )
{
uint8_t status[2];
SX126xReadCommand( RADIO_GET_RXBUFFERSTATUS, status, 2 );
// In case of LORA fixed header, the payloadLength is obtained by reading
// the register REG_LR_PAYLOADLENGTH
if( ( SX126xGetPacketType( ) == PACKET_TYPE_LORA ) && ( LoRaHeaderType == LORA_PACKET_FIXED_LENGTH ) )
{
*payloadLength = SX126xReadRegister( REG_LR_PAYLOADLENGTH );
}
else
{
*payloadLength = status[0];
}
*rxStartBufferPointer = status[1];
}
void SX126xGetPacketStatus( PacketStatus_t *pktStatus )
{
uint8_t status[3];
SX126xReadCommand( RADIO_GET_PACKETSTATUS, status, 3 );
pktStatus->packetType = SX126xGetPacketType( );
switch( pktStatus->packetType )
{
case PACKET_TYPE_GFSK:
pktStatus->Params.Gfsk.RxStatus = status[0];
pktStatus->Params.Gfsk.RssiSync = -status[1] >> 1;
pktStatus->Params.Gfsk.RssiAvg = -status[2] >> 1;
pktStatus->Params.Gfsk.FreqError = 0;
break;
case PACKET_TYPE_LORA:
pktStatus->Params.LoRa.RssiPkt = -status[0] >> 1;
// Returns SNR value [dB] rounded to the nearest integer value
pktStatus->Params.LoRa.SnrPkt = ( ( ( int8_t )status[1] ) + 2 ) >> 2;
pktStatus->Params.LoRa.SignalRssiPkt = -status[2] >> 1;
pktStatus->Params.LoRa.FreqError = FrequencyError;
break;
default:
case PACKET_TYPE_NONE:
// In that specific case, we set everything in the pktStatus to zeros
// and reset the packet type accordingly
memset( pktStatus, 0, sizeof( PacketStatus_t ) );
pktStatus->packetType = PACKET_TYPE_NONE;
break;
}
}
RadioError_t SX126xGetDeviceErrors( void )
{
uint8_t err[] = { 0, 0 };
RadioError_t error = { .Value = 0 };
SX126xReadCommand( RADIO_GET_ERROR, ( uint8_t* )err, 2 );
error.Fields.PaRamp = ( err[0] & ( 1 << 0 ) ) >> 0;
error.Fields.PllLock = ( err[1] & ( 1 << 6 ) ) >> 6;
error.Fields.XoscStart = ( err[1] & ( 1 << 5 ) ) >> 5;
error.Fields.ImgCalib = ( err[1] & ( 1 << 4 ) ) >> 4;
error.Fields.AdcCalib = ( err[1] & ( 1 << 3 ) ) >> 3;
error.Fields.PllCalib = ( err[1] & ( 1 << 2 ) ) >> 2;
error.Fields.Rc13mCalib = ( err[1] & ( 1 << 1 ) ) >> 1;
error.Fields.Rc64kCalib = ( err[1] & ( 1 << 0 ) ) >> 0;
return error;
}
void SX126xClearDeviceErrors( void )
{
uint8_t buf[2] = { 0x00, 0x00 };
SX126xWriteCommand( RADIO_CLR_ERROR, buf, 2 );
}
void SX126xClearIrqStatus( uint16_t irq )
{
uint8_t buf[2];
buf[0] = ( uint8_t )( ( ( uint16_t )irq >> 8 ) & 0x00FF );
buf[1] = ( uint8_t )( ( uint16_t )irq & 0x00FF );
SX126xWriteCommand( RADIO_CLR_IRQSTATUS, buf, 2 );
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,3 @@
SRC_FILES := sx127x.c lora-radio-sx127x.c lora-spi-sx127x.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,300 @@
/*!
* \file lora-radio.c for sx127x
*
* \brief LoRa Radio interface
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
* ______ _
* / _____) _ | |
* ( (____ _____ ____ _| |_ _____ ____| |__
* \____ \| ___ | (_ _) ___ |/ ___) _ \
* _____) ) ____| | | || |_| ____( (___| | | |
* (______/|_____)_|_|_| \__)_____)\____)_| |_|
* (C)2013-2017 Semtech
*
* \endcode
*
* \author Miguel Luis ( Semtech )
*
* \author Gregory Cristian ( Semtech )
*
* \author Forest-Rain
*
* \author AIIT XUOS Lab
*/
/**
* @file lora-radio-sx127x.c
* @brief support lora-radio-driver for XiUOS
* @version 3.0
* @author AIIT XUOS Lab
* @date 2023-03-13
*/
/*************************************************
File name: lora-radio-sx127x.c
Description: support lora-radio-driver for XiUOS
Others:
History:
1. Date: 2023-03-13
Author: AIIT XUOS Lab
Modification:
1add LORA_RADIO_DRIVER_USING_RTOS_XIUOS to support XiUOS.
*************************************************/
#include <lora-radio-rtos-config.h>
#include <stdlib.h>
#include <lora-radio.h>
#include "sx127x.h"
#include <sx127x-board.h>
#ifdef RT_USING_PM
#include "drivers/pm.h"
#ifndef PM_RADIO_ID
#define PM_RADIO_ID ( PM_MODULE_MAX_ID - 3 )
#endif
#endif
#define LOG_TAG "PHY.LoRa.SX127X"
#define LOG_LEVEL LOG_LVL_DBG
#include <lora-radio-debug.h>
#ifdef LORA_RADIO_DRIVER_USING_RTOS_RT_THREAD
#define EV_LORA_RADIO_IRQ_MASK 0x0007 // DIO0 | DIO1 | DIO2 depend on board
#ifdef LORA_RADIO_DRIVER_USING_RTOS_RT_THREAD
static struct rt_event lora_radio_event;
static struct rt_thread lora_radio_thread;
static rt_uint8_t rt_lora_radio_thread_stack[4096];
extern struct rt_spi_device *lora_radio_spi_init(const char *bus_name, const char *lora_device_name, rt_uint8_t param);
#endif
#endif // end of LORA_RADIO_DRIVER_USING_RTOS_RT_THREAD
#ifdef LORA_RADIO_DRIVER_USING_RTOS_XIUOS
static pthread_t lora_radio_task;
extern int lora_radio_spi_init(void);
#endif
bool SX127xRadioInit( RadioEvents_t *events );
/*!
* Radio driver structure initialization
*/
const struct Radio_s Radio =
{
SX127xRadioInit,
SX127xGetStatus,
SX127xSetModem,
SX127xSetChannel,
SX127xIsChannelFree,
SX127xRandom,
SX127xSetRxConfig,
SX127xSetTxConfig,
SX127xCheckRfFrequency,
SX127xGetTimeOnAir,
SX127xSend,
SX127xSetSleep,
SX127xSetStby,
SX127xSetRx,
SX127xStartCad,
SX127xSetTxContinuousWave,
SX127xReadRssi,
SX127xWrite,
SX127xRead,
//SX127xWriteBuffer,
//SX127xReadBuffer,
SX127xSetMaxPayloadLength,
SX127xSetPublicNetwork,
SX127xGetWakeupTime,
NULL, // void ( *IrqProcess )( void )
SX127xCheck,
//SX126x Only
NULL, // void ( *RxBoosted )( uint32_t timeout )
NULL, // void ( *SetRxDutyCycle )( uint32_t rxTime, uint32_t sleepTime )
};
static bool lora_radio_init = false;
#ifdef LORA_RADIO_DRIVER_USING_RTOS_RT_THREAD
static uint8_t get_irq_index(uint32_t ev)
{
uint32_t i = 0;
for(i = 0; i < 32; i++)
{
if(ev & 0x01)
{
break;
}
ev >>= 1;
}
return i;
}
#ifdef LORA_RADIO_DRIVER_USING_RTOS_RT_THREAD
/**
* @brief lora_radio_thread_entry
* @param None
* @retval None
*/
void lora_radio_thread_entry(void* parameter)
{
rt_uint32_t ev;
while(1)
{
if (rt_event_recv(&lora_radio_event, EV_LORA_RADIO_IRQ_MASK | EV_LORA_RADIO_TIMEOUT_FIRED,
(RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR),
RT_WAITING_FOREVER, &ev) == RT_EOK)
{
#ifdef RT_USING_PM
rt_pm_module_request(PM_RADIO_ID, PM_SLEEP_MODE_NONE);
RadioIrqProcess(get_irq_index(ev));
rt_pm_module_release(PM_RADIO_ID, PM_SLEEP_MODE_NONE);
#else
RadioIrqProcess(get_irq_index(ev));
#endif
}
}
}
#endif
bool SX127xRadioInit( RadioEvents_t *events )
{
#ifdef LORA_RADIO_DRIVER_USING_RTOS_RT_THREAD
if( lora_radio_init == false )
{
// Initialize spi bus
SX127x.spi = lora_radio_spi_init(LORA_RADIO0_SPI_BUS_NAME, LORA_RADIO0_DEVICE_NAME, RT_NULL);
if (SX127x.spi == RT_NULL)
{
LORA_RADIO_DEBUG_LOG(LR_DBG_INTERFACE, LOG_LEVEL, "SX127x SPI Init Failed\n");
return false;
}
LORA_RADIO_DEBUG_LOG(LR_DBG_INTERFACE, LOG_LEVEL, "SX127x SPI Init Succeed\n");
rt_event_init(&lora_radio_event, "ev_lora_phy", RT_IPC_FLAG_PRIO);//RT_IPC_FLAG_FIFO);
rt_thread_init(&lora_radio_thread,
"lora-phy",
lora_radio_thread_entry,
RT_NULL,
&rt_lora_radio_thread_stack[0],
sizeof(rt_lora_radio_thread_stack),
1, // highest priority
20);
rt_thread_startup(&lora_radio_thread);
lora_radio_init = true;
}
#endif /* LORA_RADIO_DRIVER_USING_RTOS_RT_THREAD */
SX127xIoInit();
SX127xInit(events);
return true;
}
void SX127xOnDio0IrqEvent( void *args )
{
#ifdef LORA_RADIO_DRIVER_USING_RTOS_RT_THREAD
rt_event_send(&lora_radio_event, EV_LORA_RADIO_IRQ0_FIRED);
#endif
}
void SX127xOnDio1IrqEvent( void *args )
{
#ifdef LORA_RADIO_DRIVER_USING_RTOS_RT_THREAD
rt_event_send(&lora_radio_event, EV_LORA_RADIO_IRQ1_FIRED);
#endif
}
void SX127xOnDio2IrqEvent( void *args )
{
#ifdef LORA_RADIO_DRIVER_USING_RTOS_RT_THREAD
rt_event_send(&lora_radio_event, EV_LORA_RADIO_IRQ2_FIRED);
#endif
}
void SX127xOnDio3IrqEvent( void *args )
{
#ifdef LORA_RADIO_DRIVER_USING_RTOS_RT_THREAD
rt_event_send(&lora_radio_event, EV_LORA_RADIO_IRQ3_FIRED);
#endif
}
void SX127xOnDio4IrqEvent( void *args )
{
#ifdef LORA_RADIO_DRIVER_USING_RTOS_RT_THREAD
rt_event_send(&lora_radio_event, EV_LORA_RADIO_IRQ4_FIRED);
#endif
}
void SX127xOnDio5IrqEvent( void *args )
{
#ifdef LORA_RADIO_DRIVER_USING_RTOS_RT_THREAD
rt_event_send(&lora_radio_event, EV_LORA_RADIO_IRQ5_FIRED);
#endif
}
void SX127xOnTimeoutIrqEvent( void )
{
#ifdef LORA_RADIO_DRIVER_USING_RTOS_RT_THREAD
rt_event_send(&lora_radio_event, EV_LORA_RADIO_TIMEOUT_FIRED);
#endif
}
#endif
#ifdef LORA_RADIO_DRIVER_USING_RTOS_XIUOS
/**
* @brief lora_radio_thread_entry
* @param None
* @retval None
*/
static void *lora_radio_thread_entry(void* parameter)
{
int ret;
while(1) {
RadioIrqProcess(ret);
}
}
bool SX127xRadioInit( RadioEvents_t *events )
{
int ret;
if( lora_radio_init == false ) {
// Initialize spi bus
ret = lora_radio_spi_init();
if (ret < 0) {
LORA_RADIO_DEBUG_LOG(LR_DBG_INTERFACE, LOG_LEVEL, "SX127x SPI Init Failed\n");
return false;
}
LORA_RADIO_DEBUG_LOG(LR_DBG_INTERFACE, LOG_LEVEL, "SX127x SPI Init Succeed\n");
}
SX127xInit(events);
if ( lora_radio_init == false ) {
pthread_attr_t attr;
attr.schedparam.sched_priority = 20;
attr.stacksize = 4096;
char task_name[] = "lora_radio_task";
pthread_args_t args;
args.pthread_name = task_name;
PrivTaskCreate(&lora_radio_task, &attr, &lora_radio_thread_entry, (void *)&args);
PrivTaskStartup(&lora_radio_task);
lora_radio_init = true;
}
return true;
}
#endif

View File

@ -0,0 +1,120 @@
/*!
* \file lora-radio-spi-sx127x.c
*
* \brief sx127x spi driver implementation
*
* SPDX-License-Identifier: Apache-2.0
*
* \author Forest-Rain
*
* \author AIIT XUOS Lab
*/
/**
* @file lora-radio-spi-sx127x.c
* @brief support lora-radio-driver for XiUOS
* @version 3.0
* @author AIIT XUOS Lab
* @date 2023-03-17
*/
/*************************************************
File name: lora-radio-spi-sx127x.c
Description: support lora-radio-driver for XiUOS
Others:
History:
1. Date: 2023-03-17
Author: AIIT XUOS Lab
Modification:
1add LORA_RADIO_DRIVER_USING_RTOS_XIUOS to support XiUOS.
*************************************************/
#include "sx127x.h"
#include <sx127x-board.h>
void SX127xWriteBuffer( uint16_t addr, uint8_t *buffer, uint8_t size )
{
#ifdef LORA_RADIO_DRIVER_USING_RTOS_RT_THREAD
#ifdef RT_USING_SPI
uint8_t msg[1] = {0};
msg[0] = (addr | 0x80);
rt_spi_send_then_send(SX127x.spi,msg,1,buffer,size);
#else
// uint8_t i;
// //NSS = 0;
// GpioWrite( &SX127x.Spi.Nss, 0 );
// SpiInOut( &SX127x.Spi, addr | 0x80 );
// for( i = 0; i < size; i++ )
// {
// SpiInOut( &SX127x.Spi, buffer[i] );
// }
// //NSS = 1;
// GpioWrite( &SX127x.Spi.Nss, 1 );
#endif
#endif
#ifdef LORA_RADIO_DRIVER_USING_RTOS_XIUOS
int spi_fd;
uint8_t msg[1] = {0};
msg[0] = (addr | 0x80);
spi_fd = PrivOpen(LORA_SPI_DEV_NAME, O_RDWR);
PrivWrite(spi_fd, msg, 1);
PrivWrite(spi_fd, buffer, size);
PrivClose(spi_fd);
#endif
}
void SX127xReadBuffer( uint16_t addr, uint8_t *buffer, uint8_t size )
{
#ifdef LORA_RADIO_DRIVER_USING_RTOS_RT_THREAD
#ifdef RT_USING_SPI
uint8_t msg[1] = {0};
msg[0] = (addr & 0x7F);
rt_spi_send_then_recv(SX127x.spi,msg,1,buffer,size);
#else
// uint8_t i;
// //NSS = 0;
// GpioWrite( &SX127x.Spi.Nss, 0 );
// SpiInOut( &SX127x.Spi, addr & 0x7F );
// for( i = 0; i < size; i++ )
// {
// buffer[i] = SpiInOut( &SX127x.Spi, 0 );
// }
// //NSS = 1;
// GpioWrite( &SX127x.Spi.Nss, 1 );
#endif
#endif
#ifdef LORA_RADIO_DRIVER_USING_RTOS_XIUOS
int spi_fd;
uint8_t msg[1] = {0};
msg[0] = (addr & 0x7F);
spi_fd = PrivOpen(LORA_SPI_DEV_NAME, O_RDWR);
PrivWrite(spi_fd, msg, 1);
PrivRead(spi_fd, buffer, size);
PrivClose(spi_fd);
#endif
}

View File

@ -0,0 +1,64 @@
/*!
* \file lora-spi-sx127x.h
*
* \brief SX127x spi interface
*
* SPDX-License-Identifier: Apache-2.0
*
* \author Forest-Rain
*/
#ifndef __LORA_SPI_SX127x_H__
#define __LORA_SPI_SX127x_H__
/** @addtogroup LORA_RADIO_SPI
* @{
*/
/** @addtogroup SX127X_SPI
* @{
*/
/*!
* \brief Writes the radio register at the specified address
*
* \param [IN]: addr Register address
* \param [IN]: data New register value
*/
void SX127xWrite( uint16_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 SX127xRead( uint16_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 SX127xWriteBuffer( uint16_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 SX127xReadBuffer( uint16_t addr, uint8_t *buffer, uint8_t size );
/**
* @}
*/
/**
* @}
*/
#endif // __LORA_SPI_SX127x_H__

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,530 @@
/*!
* \file SX127x.h
*
* \brief SX127x driver implementation
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
* ______ _
* / _____) _ | |
* ( (____ _____ ____ _| |_ _____ ____| |__
* \____ \| ___ | (_ _) ___ |/ ___) _ \
* _____) ) ____| | | || |_| ____( (___| | | |
* (______/|_____)_|_|_| \__)_____)\____)_| |_|
* (C)2013-2017 Semtech
*
* \endcode
*
* \author Miguel Luis ( Semtech )
*
* \author Gregory Cristian ( Semtech )
*
* \author Forest-Rain
*/
#ifndef __SX127x_H__
#define __SX127x_H__
#include <stdint.h>
#include <stdbool.h>
#include <lora-radio.h>
#include <lora-radio-rtos-config.h>
#include "sx127xRegs-Fsk.h"
#include "sx127xRegs-LoRa.h"
/*!
* Radio wake-up time from sleep
*/
#define RADIO_WAKEUP_TIME 1 // [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;
#if defined( LORA_RADIO_DRIVER_USING_RF_MODEM_FSK )
RadioFskSettings_t Fsk;
RadioFskPacketHandler_t FskPacketHandler;
#endif
RadioLoRaSettings_t LoRa;
RadioLoRaPacketHandler_t LoRaPacketHandler;
}RadioSettings_t;
/*!
* Radio hardware and global parameters
*/
typedef struct SX127x_s
{
// Gpio_t Reset;
// Gpio_t DIO0;
// Gpio_t DIO1;
// Gpio_t DIO2;
// Gpio_t DIO3;
// Gpio_t DIO4;
// Gpio_t DIO5;
// Spi_t Spi;
/*!
* Radio Spi bus
*/
#ifdef LORA_RADIO_DRIVER_USING_ON_RTOS_RT_THREAD
struct rt_spi_device *spi;
#endif
RadioSettings_t Settings;
}SX127x_t;
/*!
* Hardware IO IRQ callback function definition
*/
typedef void ( DioIrqHandler )( void );
/*!
* SX127x definitions
*/
#define XTAL_FREQ 32000000
#define FREQ_STEP 61.03515625
#define RX_BUFFER_SIZE 256
/*!
* \brief Radio hardware registers initialization definition
*
* \remark Can be automatically generated by the SX127x 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_PAYLOADMAXLENGTH, 0x40 },\
} \
#define RF_MID_BAND_THRESH 525000000
/** @addtogroup LORA_RADIO_CHIP_DRIVER
* @{
*/
/** @addtogroup SX127X_DRIVER
* @{
*/
/*!
* ============================================================================
* Public functions prototypes
* ============================================================================
*/
/*!
* \brief Initializes the radio
*
* \param [IN] events Structure containing the driver callback functions
*/
void SX127xInit( RadioEvents_t *events );
/*!
* Return current radio status
*
* \param status Radio status.[RF_IDLE, RF_RX_RUNNING, RF_TX_RUNNING]
*/
RadioState_t SX127xGetStatus( void );
/*!
* \brief Configures the radio with the given modem
*
* \param [IN] modem Modem to be used [0: FSK, 1: LoRa]
*/
void SX127xSetModem( RadioModems_t modem );
/*!
* \brief Sets the channel configuration
*
* \param [IN] freq Channel RF frequency
*/
void SX127xSetChannel( uint32_t freq );
/*!
* \brief Sets the radio output power.
*
* \param [IN] power Sets the RF output power
*/
void SX127xSetRfTxPower( int8_t power );
/*!
* \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 SX127xIsChannelFree( 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 SX127xSetRxConfig or
* SX127xSetTxConfig functions must be called.
*
* \retval randomValue 32 bits random value
*/
uint32_t SX127xRandom( void );
/*!
* \brief Sets the reception parameters
*
* \remark When using LoRa modem only bandwidths 125, 250 and 500 kHz are supported
*
* \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 SX127xSetRxConfig( 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
*
* \remark When using LoRa modem only bandwidths 125, 250 and 500 kHz are supported
*
* \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 SX127xSetTxConfig( 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] 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] 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] payloadLen Sets payload length when fixed length is used
* \param [IN] crcOn Enables/Disables the CRC [0: OFF, 1: ON]
*
* \retval airTime Computed airTime (ms) for the given packet payload length
*/
uint32_t SX127xGetTimeOnAir( RadioModems_t modem, uint32_t bandwidth,
uint32_t datarate, uint8_t coderate,
uint16_t preambleLen, bool fixLen, uint8_t payloadLen,
bool crcOn );
/*!
* \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 SX127xSend( uint8_t *buffer, uint8_t size );
/*!
* \brief Sets the radio in sleep mode
*/
void SX127xSetSleep( void );
/*!
* \brief Sets the radio in standby mode
*/
void SX127xSetStby( void );
/*!
* \brief Sets the radio in reception mode for the given time
* \param [IN] timeout Reception timeout [ms] [0: continuous, others timeout]
*/
void SX127xSetRx( uint32_t timeout );
/*!
* \brief Start a Channel Activity Detection
*/
void SX127xStartCad( 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 SX127xSetTxContinuousWave( uint32_t freq, int8_t power, uint16_t time );
/*!
* \brief Reads the current RSSI value
*
* \retval rssiValue Current RSSI value in [dBm]
*/
int16_t SX127xReadRssi( RadioModems_t modem );
/*!
* \brief Writes the radio register at the specified address
*
* \param [IN]: addr Register address
* \param [IN]: data New register value
*/
void SX127xWrite( uint16_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 SX127xRead( uint16_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 SX127xWriteBuffer( uint16_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 SX127xReadBuffer( uint16_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 SX127xSetMaxPayloadLength( 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 SX127xSetPublicNetwork( bool enable );
/*!
* \brief Gets the time required for the board plus radio to get out of sleep.[ms]
*
* \retval time Radio plus board wakeup time in ms.
*/
uint32_t SX127xGetWakeupTime( void );
/*!
* \brief Check spi access
*
* \retval the .
*/
uint8_t SX127xCheck( void );
/*!
* \brief Initializes DIO IRQ handlers
*
* \param [IN] irqHandlers Array containing the IRQ callback functions
*/
void SX127xIoIrqInit( DioIrqHandler **irqHandlers );
/*!
* \brief Process radio irq
*/
void RadioIrqProcess( uint8_t irq_index );
/*!
* Radio hardware and global parameters
*/
extern SX127x_t SX127x;
/**
* @}
*/
/**
* @}
*/
#endif // __SX127x_H__

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,573 @@
/*!
* \file sx1276Regs-LoRa.h
*
* \brief SX1276 LoRa modem registers and bits definitions
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
* ______ _
* / _____) _ | |
* ( (____ _____ ____ _| |_ _____ ____| |__
* \____ \| ___ | (_ _) ___ |/ ___) _ \
* _____) ) ____| | | || |_| ____( (___| | | |
* (______/|_____)_|_|_| \__)_____)\____)_| |_|
* (C)2013-2017 Semtech
*
* \endcode
*
* \author Miguel Luis ( Semtech )
*
* \author Gregory Cristian ( Semtech )
*/
#ifndef __SX1276_REGS_LORA_H__
#define __SX1276_REGS_LORA_H__
/*!
* ============================================================================
* SX1276 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_MODEMCONFIG3 0x26
#define REG_LR_FEIMSB 0x28
#define REG_LR_FEIMID 0x29
#define REG_LR_FEILSB 0x2A
#define REG_LR_RSSIWIDEBAND 0x2C
#define REG_LR_IFFREQ1 0x2F
#define REG_LR_IFFREQ2 0x30
#define REG_LR_DETECTOPTIMIZE 0x31
#define REG_LR_INVERTIQ 0x33
#define REG_LR_HIGHBWOPTIMIZE1 0x36
#define REG_LR_DETECTIONTHRESHOLD 0x37
#define REG_LR_SYNCWORD 0x39
#define REG_LR_HIGHBWOPTIMIZE2 0x3A
#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_PLLHOP 0x44
#define REG_LR_TCXO 0x4B
#define REG_LR_PADAC 0x4D
#define REG_LR_FORMERTEMP 0x5B
#define REG_LR_BITRATEFRAC 0x5D
#define REG_LR_AGCREF 0x61
#define REG_LR_AGCTHRESH1 0x62
#define REG_LR_AGCTHRESH2 0x63
#define REG_LR_AGCTHRESH3 0x64
#define REG_LR_PLL 0x70
/*!
* ============================================================================
* SX1276 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_FREQMODE_ACCESS_MASK 0xF7
#define RFLR_OPMODE_FREQMODE_ACCESS_LF 0x08 // Default
#define RFLR_OPMODE_FREQMODE_ACCESS_HF 0x00
#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_434_MHZ 0x6C // Default
#define RFLR_FRFMID_434_MHZ 0x80 // Default
#define RFLR_FRFLSB_434_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_MAX_POWER_MASK 0x8F
#define RFLR_PACONFIG_OUTPUTPOWER_MASK 0xF0
/*!
* RegPaRamp
*/
#define RFLR_PARAMP_TXBANDFORCE_MASK 0xEF
#define RFLR_PARAMP_TXBANDFORCE_BAND_SEL 0x10
#define RFLR_PARAMP_TXBANDFORCE_AUTO 0x00 // Default
#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_LF_MASK 0xE7
#define RFLR_LNA_BOOST_LF_DEFAULT 0x00 // Default
#define RFLR_LNA_BOOST_HF_MASK 0xFC
#define RFLR_LNA_BOOST_HF_OFF 0x00 // Default
#define RFLR_LNA_BOOST_HF_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 0x0F
#define RFLR_MODEMCONFIG1_BW_7_81_KHZ 0x00
#define RFLR_MODEMCONFIG1_BW_10_41_KHZ 0x10
#define RFLR_MODEMCONFIG1_BW_15_62_KHZ 0x20
#define RFLR_MODEMCONFIG1_BW_20_83_KHZ 0x30
#define RFLR_MODEMCONFIG1_BW_31_25_KHZ 0x40
#define RFLR_MODEMCONFIG1_BW_41_66_KHZ 0x50
#define RFLR_MODEMCONFIG1_BW_62_50_KHZ 0x60
#define RFLR_MODEMCONFIG1_BW_125_KHZ 0x70 // Default
#define RFLR_MODEMCONFIG1_BW_250_KHZ 0x80
#define RFLR_MODEMCONFIG1_BW_500_KHZ 0x90
#define RFLR_MODEMCONFIG1_CODINGRATE_MASK 0xF1
#define RFLR_MODEMCONFIG1_CODINGRATE_4_5 0x02
#define RFLR_MODEMCONFIG1_CODINGRATE_4_6 0x04 // Default
#define RFLR_MODEMCONFIG1_CODINGRATE_4_7 0x06
#define RFLR_MODEMCONFIG1_CODINGRATE_4_8 0x08
#define RFLR_MODEMCONFIG1_IMPLICITHEADER_MASK 0xFE
#define RFLR_MODEMCONFIG1_IMPLICITHEADER_ON 0x01
#define RFLR_MODEMCONFIG1_IMPLICITHEADER_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_RXPAYLOADCRC_MASK 0xFB
#define RFLR_MODEMCONFIG2_RXPAYLOADCRC_ON 0x04
#define RFLR_MODEMCONFIG2_RXPAYLOADCRC_OFF 0x00 // Default
#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)
*/
/*!
* RegModemConfig3
*/
#define RFLR_MODEMCONFIG3_LOWDATARATEOPTIMIZE_MASK 0xF7
#define RFLR_MODEMCONFIG3_LOWDATARATEOPTIMIZE_ON 0x08
#define RFLR_MODEMCONFIG3_LOWDATARATEOPTIMIZE_OFF 0x00 // Default
#define RFLR_MODEMCONFIG3_AGCAUTO_MASK 0xFB
#define RFLR_MODEMCONFIG3_AGCAUTO_ON 0x04 // Default
#define RFLR_MODEMCONFIG3_AGCAUTO_OFF 0x00
/*!
* 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)
*/
/*!
* 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
/*!
* RegFormerTemp
*/
/*!
* RegBitrateFrac
*/
#define RF_BITRATEFRAC_MASK 0xF0
/*!
* RegAgcRef
*/
/*!
* RegAgcThresh1
*/
/*!
* RegAgcThresh2
*/
/*!
* RegAgcThresh3
*/
/*!
* RegPll
*/
#define RF_PLL_BANDWIDTH_MASK 0x3F
#define RF_PLL_BANDWIDTH_75 0x00
#define RF_PLL_BANDWIDTH_150 0x40
#define RF_PLL_BANDWIDTH_225 0x80
#define RF_PLL_BANDWIDTH_300 0xC0 // Default
#endif // __SX1276_REGS_LORA_H__

View File

@ -0,0 +1,3 @@
SRC_DIR := lora-module
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,41 @@
from building import *
src = []
cwd = GetCurrentDir()
include_path = [cwd]
include_path += [cwd+'/lora-module/inc']
# add lora radio driver.
if GetDepend('LORA_RADIO_DRIVER_USING_LORA_MODULE_LSD4RF_2F717N30'):
src += Split('''
lora-module/stm32_adapter/lora-spi-board.c
lora-module/stm32_adapter/SX1278_LSD4RF-2F717N30/sx1278-board.c
''')
if GetDepend('LORA_RADIO_DRIVER_USING_LORA_MODULE_LSD4RF_2R822N30'):
src += Split('''
lora-module/stm32_adapter/lora-spi-board.c
lora-module/stm32_adapter/SX1262_LSD4RF-2R822N30/sx1262-board.c
''')
if GetDepend('LORA_RADIO_DRIVER_USING_LORA_MODULE_LSD4RF_2R717N40'):
src += Split('''
lora-module/stm32_adapter/lora-spi-board.c
lora-module/stm32_adapter/SX1268_LSD4RF-2R717N40/sx1268-board.c
''')
if GetDepend('LORA_RADIO_DRIVER_USING_LORA_MODULE_RA_01'):
src += Split('''
lora-module/stm32_adapter/lora-spi-board.c
lora-module/stm32_adapter/SX1278_Ra-01/sx1278-board.c
''')
if GetDepend('LORA_RADIO_DRIVER_USING_LORA_MODULE_ASR6500S'):
src += Split('''
lora-module/stm32_adapter/lora-spi-board.c
lora-module/stm32_adapter/SX1262_ASR6500S/sx126x-board.c
''')
group = DefineGroup('lora-radio-driver/board', src, depend = ['PKG_USING_LORA_RADIO_DRIVER'], CPPPATH = include_path)
Return('group')

View File

@ -0,0 +1,5 @@
ifeq ($(CONFIG_LORA_RADIO_DRIVER_USING_RTOS_XIUOS),y)
SRC_DIR := hc32_adapter
endif
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,18 @@
choice
prompt "choose lora device module"
default LORA_RADIO_DRIVER_USING_SX1268_E22400M30S
config LORA_RADIO_DRIVER_USING_SX1268_E22400M30S
bool "lora device module select E22-400M30S(SX1268)"
config LORA_RADIO_DRIVER_USING_SX1278_RA01
bool "lora device module select RA01(SX1278)"
endchoice
if LORA_RADIO_DRIVER_USING_SX1268_E22400M30S
source "$APP_DIR/lib/lorawan/lora_radio_driver/ports/lora-module/hc32_adapter/SX1268_E22-400M30S/Kconfig"
endif
if LORA_RADIO_DRIVER_USING_SX1278_RA01
source "$APP_DIR/lib/lorawan/lora_radio_driver/ports/lora-module/hc32_adapter/SX1278_Ra-01/Kconfig"
endif

View File

@ -0,0 +1,11 @@
ifeq ($(CONFIG_LORA_RADIO_DRIVER_USING_SX1268_E22400M30S),y)
SRC_DIR := SX1268_E22-400M30S
endif
ifeq ($(CONFIG_LORA_RADIO_DRIVER_USING_SX1278_RA01),y)
SRC_DIR := SX1278_Ra-01
endif
SRC_FILES := lora-spi-board.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,45 @@
choice
prompt "choose board for lora radio driver"
default LORA_RADIO_DRIVER_USING_XISHUTONG_ARM32
config LORA_RADIO_DRIVER_USING_EDU_ARM32
bool "board select edu-arm32 bsp"
config LORA_RADIO_DRIVER_USING_XISHUTONG_ARM32
bool "board select xishutong-arm32 bsp"
endchoice
if LORA_RADIO_DRIVER_USING_EDU_ARM32
config LORA_SPI_DEV_NAME
string "lora device pin driver path"
default "/dev/spi1_dev0"
config LORA_RADIO_RESET_PIN
int "hc32 board lora chip reset pin[PI02]"
default "133"
config LORA_RADIO_BUSY_PIN
int "hc32 board lora chip busy pin[PE03]"
default "2"
endif
if LORA_RADIO_DRIVER_USING_XISHUTONG_ARM32
config LORA_SPI_DEV_NAME
string "lora device pin driver path"
default "/dev/spi2_dev0"
config LORA_RADIO_RESET_PIN
int "xishutong-arm32 board lora chip reset pin[PD02]"
default "144"
endif
config LORA_RADIO_DRIVER_USING_LORA_CHIP_SX126X
bool "hc32 board using lora chip sx126x"
default y
if LORA_RADIO_DRIVER_USING_LORA_CHIP_SX126X
config LORA_RADIO_DRIVER_USING_LORA_CHIP_SX1268
bool "hc32 board using lora chip sx1268"
default y
endif

View File

@ -0,0 +1,3 @@
SRC_FILES := sx1268-board.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,394 @@
/*!
* \file sx1268-board.c
*
* \brief Target board SX126x shield driver implementation
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
* ______ _
* / _____) _ | |
* ( (____ _____ ____ _| |_ _____ ____| |__
* \____ \| ___ | (_ _) ___ |/ ___) _ \
* _____) ) ____| | | || |_| ____( (___| | | |
* (______/|_____)_|_|_| \__)_____)\____)_| |_|
* (C)2013-2017 Semtech
*
* \endcode
*
* \author Miguel Luis ( Semtech )
*
* \author Gregory Cristian ( Semtech )
*
* \author Forest-Rain
*/
/**
* @file sx126x-board.c
* @brief support lora-radio-driver for XiUOS
* @version 3.0
* @author AIIT XUOS Lab
* @date 2023-06-06
*/
/*************************************************
File name: sx126x-board.c
Description: support lora-radio-driver for XiUOS
Others:
History:
1. Date: 2023-06-06
Author: AIIT XUOS Lab
Modification:
1add LORA_RADIO_DRIVER_USING_RTOS_XIUOS to support XiUOS.
*************************************************/
#include <lora-radio-rtos-config.h>
#include <lora-radio.h>
#include <sx126x-board.h>
#define LOG_TAG "LoRa.Board.E22-400M30S(SX1268)" // E22-400M30S
#define LOG_LEVEL LOG_LVL_DBG
#include <lora-radio-debug.h>
/*!
* Debug GPIO pins objects
*/
#if defined( USE_RADIO_DEBUG )
Gpio_t DbgPinTx;
Gpio_t DbgPinRx;
#endif
#ifdef LORA_RADIO_GPIO_SETUP_BY_PIN_NAME
#if ( RT_VER_NUM <= 0x40004 )
int stm32_pin_get(char *pin_name)
{
/* eg: pin_name : "PA.4" ( GPIOA, GPIO_PIN_4 )--> drv_gpio.c pin */
char pin_index = strtol(&pin_name[3],0,10);
if(pin_name[1] < 'A' || pin_name[1] > 'Z')
{
return -1;
}
return (16 * (pin_name[1]-'A') + pin_index);
}
#endif
#endif /* LORA_RADIO_GPIO_SETUP_BY_PIN_NAME */
#ifdef LORA_RADIO_DRIVER_USING_RTOS_RT_THREAD
void SX126xIoInit( void )
{
rt_pin_mode(LORA_RADIO_NSS_PIN, PIN_MODE_OUTPUT);
rt_pin_mode(LORA_RADIO_BUSY_PIN, PIN_MODE_INPUT);
rt_pin_mode(LORA_RADIO_DIO1_PIN, PIN_MODE_INPUT_PULLDOWN);
#if defined( LORA_RADIO_DIO2_PIN )
rt_pin_mode(LORA_RADIO_DIO2_PIN, PIN_MODE_INPUT_PULLDOWN);
#endif
#if defined( LORA_RADIO_RFSW1_PIN ) && defined ( LORA_RADIO_RFSW2_PIN )
rt_pin_mode(LORA_RADIO_RFSW1_PIN, PIN_MODE_OUTPUT);
rt_pin_mode(LORA_RADIO_RFSW2_PIN, PIN_MODE_OUTPUT);
#endif
}
void SX126xIoIrqInit( DioIrqHandler dioIrq )
{
rt_pin_mode(LORA_RADIO_DIO1_PIN, PIN_MODE_INPUT_PULLDOWN);
rt_pin_attach_irq(LORA_RADIO_DIO1_PIN, PIN_IRQ_MODE_RISING, dioIrq,(void*)"rf-dio1");
rt_pin_irq_enable(LORA_RADIO_DIO1_PIN, PIN_IRQ_ENABLE);
}
void SX126xIoDeInit( void )
{
//// GpioInit( &SX126x.Spi.Nss, RADIO_NSS, PIN_ANALOGIC, PIN_PUSH_PULL, PIN_PULL_UP, 1 );
//// GpioInit( &SX126x.BUSY, RADIO_BUSY, PIN_ANALOGIC, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
//// GpioInit( &SX126x.DIO1, RADIO_DIO_1, PIN_ANALOGIC, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
SX126xAntSwOff();
}
void SX126xIoDbgInit( void )
{
#if defined( USE_RADIO_DEBUG )
GpioInit( &DbgPinTx, RADIO_DBG_PIN_TX, PIN_OUTPUT, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
GpioInit( &DbgPinRx, RADIO_DBG_PIN_RX, PIN_OUTPUT, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
#endif
}
void SX126xIoTcxoInit( void )
{
// Initialize TCXO control
CalibrationParams_t calibParam;
// +clear OSC_START_ERR for reboot or cold-start from sleep
SX126xClearDeviceErrors();
// TCXO_CTRL_1_7V -> TCXO_CTRL_2_7V 64*15.0625US
SX126xSetDio3AsTcxoCtrl( TCXO_CTRL_2_7V, 320);//SX126xGetBoardTcxoWakeupTime( ) << 6 ); // convert from ms to SX126x time base
calibParam.Value = 0x7F;
SX126xCalibrate( calibParam );
}
uint32_t SX126xGetBoardTcxoWakeupTime( void )
{
return BOARD_TCXO_WAKEUP_TIME;
}
void SX126xReset( void )
{
SX126X_DELAY_MS( 10 );
rt_pin_mode(LORA_RADIO_RESET_PIN, PIN_MODE_OUTPUT);
rt_pin_write(LORA_RADIO_RESET_PIN, PIN_LOW);
SX126X_DELAY_MS( 20 );
// internal pull-up
rt_pin_mode(LORA_RADIO_RESET_PIN, PIN_MODE_INPUT);
SX126X_DELAY_MS( 10 );
}
void SX126xWaitOnBusy( void )
{
while( rt_pin_read( LORA_RADIO_BUSY_PIN ) == PIN_HIGH );
}
void SX126xAntSwOn( void )
{
// No need
}
void SX126xAntSwOff( void )
{
////GpioInit( &AntPow, RADIO_ANT_SWITCH_POWER, PIN_ANALOGIC, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
#if defined( LORA_RADIO_RFSW1_PIN ) && defined ( LORA_RADIO_RFSW2_PIN )
rt_pin_write(LORA_RADIO_RFSW1_PIN, PIN_LOW);
rt_pin_write(LORA_RADIO_RFSW2_PIN, PIN_LOW);
#endif
}
void SX126xSetAntSw( RadioOperatingModes_t mode )
{
if( mode == MODE_TX )
{ // Transmit
rt_pin_write(LORA_RADIO_RFSW1_PIN, PIN_HIGH);
rt_pin_write(LORA_RADIO_RFSW2_PIN, PIN_LOW);
}
else
{
rt_pin_write(LORA_RADIO_RFSW1_PIN, PIN_LOW);
rt_pin_write(LORA_RADIO_RFSW2_PIN, PIN_HIGH);
}
}
#endif
#ifdef LORA_RADIO_DRIVER_USING_RTOS_XIUOS
static int pin_fd = -1;
void SX126xIoInit( void )
{
if (pin_fd < 0) {
pin_fd = PrivOpen("/dev/pin_dev", O_RDWR);
if (pin_fd < 0) {
printf("open %s error\n", "/dev/pin_dev");
return;
}
}
#ifdef LORA_RADIO_DRIVER_USING_EDU_ARM32
struct PinParam pin_param;
pin_param.cmd = GPIO_CONFIG_MODE;
pin_param.mode = GPIO_CFG_OUTPUT;
pin_param.pin = LORA_RADIO_RFSW1_PIN;
struct PrivIoctlCfg ioctl_cfg;
ioctl_cfg.ioctl_driver_type = PIN_TYPE;
ioctl_cfg.args = &pin_param;
PrivIoctl(pin_fd, OPE_CFG, &ioctl_cfg);
struct PinStat pin_stat;
pin_stat.pin = LORA_RADIO_RFSW1_PIN;
pin_stat.val = GPIO_LOW;
PrivWrite(pin_fd, &pin_stat, 1);
pin_param.cmd = GPIO_CONFIG_MODE;
pin_param.mode = GPIO_CFG_OUTPUT;
pin_param.pin = LORA_RADIO_RFSW2_PIN;
ioctl_cfg.ioctl_driver_type = PIN_TYPE;
ioctl_cfg.args = &pin_param;
PrivIoctl(pin_fd, OPE_CFG, &ioctl_cfg);
pin_stat.pin = LORA_RADIO_RFSW2_PIN;
pin_stat.val = GPIO_LOW;
PrivWrite(pin_fd, &pin_stat, 1);
pin_param.cmd = GPIO_CONFIG_MODE;
pin_param.mode = GPIO_CFG_INPUT;
pin_param.pin = LORA_RADIO_BUSY_PIN;
ioctl_cfg.ioctl_driver_type = PIN_TYPE;
ioctl_cfg.args = &pin_param;
PrivIoctl(pin_fd, OPE_CFG, &ioctl_cfg);
pin_stat.pin = LORA_RADIO_BUSY_PIN;
pin_stat.val = GPIO_LOW;
PrivWrite(pin_fd, &pin_stat, 1);
#endif
}
void SX126xIoIrqInit( DioIrqHandler dioIrq )
{
}
void SX126xIoDeInit( void )
{
SX126xAntSwOff();
}
void SX126xIoDbgInit( void )
{
}
void SX126xIoTcxoInit( void )
{
// Initialize TCXO control
CalibrationParams_t calibParam;
// +clear OSC_START_ERR for reboot or cold-start from sleep
SX126xClearDeviceErrors();
// TCXO_CTRL_1_7V -> TCXO_CTRL_2_7V 64*15.0625US
SX126xSetDio3AsTcxoCtrl( TCXO_CTRL_2_7V, 320);//SX126xGetBoardTcxoWakeupTime( ) << 6 ); // convert from ms to SX126x time base
calibParam.Value = 0x7F;
SX126xCalibrate( calibParam );
}
uint32_t SX126xGetBoardTcxoWakeupTime( void )
{
return BOARD_TCXO_WAKEUP_TIME;
}
void SX126xReset( void )
{
SX126X_DELAY_MS( 10 );
if (pin_fd < 0) {
pin_fd = PrivOpen("/dev/pin_dev", O_RDWR);
if (pin_fd < 0) {
printf("open %s error\n", "/dev/pin_dev");
return;
}
}
struct PinParam pin_param;
pin_param.cmd = GPIO_CONFIG_MODE;
pin_param.mode = GPIO_CFG_OUTPUT;
pin_param.pin = LORA_RADIO_RESET_PIN;
struct PrivIoctlCfg ioctl_cfg;
ioctl_cfg.ioctl_driver_type = PIN_TYPE;
ioctl_cfg.args = &pin_param;
PrivIoctl(pin_fd, OPE_CFG, &ioctl_cfg);
struct PinStat pin_stat;
pin_stat.pin = LORA_RADIO_RESET_PIN;
pin_stat.val = GPIO_LOW;
PrivWrite(pin_fd, &pin_stat, 1);
// Wait 20 ms
SX126X_DELAY_MS( 20 );
// Configure RESET as input
pin_param.cmd = GPIO_CONFIG_MODE;
pin_param.mode = GPIO_CFG_INPUT;
pin_param.pin = LORA_RADIO_RESET_PIN;
ioctl_cfg.ioctl_driver_type = PIN_TYPE;
ioctl_cfg.args = &pin_param;
PrivIoctl(pin_fd, OPE_CFG, &ioctl_cfg);
// Wait 10 ms
SX126X_DELAY_MS( 10 );
}
void SX126xWaitOnBusy( void )
{
if (pin_fd < 0) {
pin_fd = PrivOpen("/dev/pin_dev", O_RDWR);
if (pin_fd < 0) {
printf("open %s error\n", "/dev/pin_dev");
return;
}
}
#ifdef LORA_RADIO_DRIVER_USING_EDU_ARM32
struct PinStat pin_stat;
pin_stat.pin = LORA_RADIO_BUSY_PIN;
PrivRead(pin_fd, &pin_stat, 1);
while (GPIO_HIGH == pin_stat.val) {
PrivRead(pin_fd, &pin_stat, 1);
}
#endif
}
void SX126xAntSwOn( void )
{
// No need
}
void SX126xAntSwOff( void )
{
#ifdef LORA_RADIO_DRIVER_USING_EDU_ARM32
struct PinStat pin_stat;
pin_stat.pin = LORA_RADIO_RFSW1_PIN;
pin_stat.val = GPIO_LOW;
PrivWrite(pin_fd, &pin_stat, 1);
pin_stat.pin = LORA_RADIO_RFSW2_PIN;
pin_stat.val = GPIO_LOW;
PrivWrite(pin_fd, &pin_stat, 1);
#endif
}
void SX126xSetAntSw( RadioOperatingModes_t mode )
{
#ifdef LORA_RADIO_DRIVER_USING_EDU_ARM32
struct PinStat pin_stat;
if( mode == MODE_TX ) { // Transmit
pin_stat.pin = LORA_RADIO_RFSW1_PIN;
pin_stat.val = GPIO_HIGH;
PrivWrite(pin_fd, &pin_stat, 1);
pin_stat.pin = LORA_RADIO_RFSW2_PIN;
pin_stat.val = GPIO_LOW;
PrivWrite(pin_fd, &pin_stat, 1);
} else {
pin_stat.pin = LORA_RADIO_RFSW1_PIN;
pin_stat.val = GPIO_LOW;
PrivWrite(pin_fd, &pin_stat, 1);
pin_stat.pin = LORA_RADIO_RFSW2_PIN;
pin_stat.val = GPIO_HIGH;
PrivWrite(pin_fd, &pin_stat, 1);
}
#endif
}
#endif
bool SX126xCheckRfFrequency( uint32_t frequency )
{
// Implement check. Currently all frequencies are supported
return true;
}
#if defined( USE_RADIO_DEBUG )
void SX126xDbgPinTxWrite( uint8_t state )
{
GpioWrite( &DbgPinTx, state );
}
void SX126xDbgPinRxWrite( uint8_t state )
{
GpioWrite( &DbgPinRx, state );
}
#endif

View File

@ -0,0 +1,18 @@
config LORA_SPI_DEV_NAME
string "lora device pin driver path"
default "/dev/spi1_dev0"
config LORA_RADIO_RESET_PIN
int "hc32 board lora chip reset pin[PI02]"
default "133"
config LORA_RADIO_DRIVER_USING_LORA_CHIP_SX127X
bool "hc32 board using lora chip sx127x"
default y
if LORA_RADIO_DRIVER_USING_LORA_CHIP_SX127X
config LORA_RADIO_DRIVER_USING_LORA_CHIP_SX1278
bool "hc32 board using lora chip sx1278"
default y
endif

View File

@ -0,0 +1,3 @@
SRC_FILES := sx1278-board.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,283 @@
/*!
* \file sx1278-board.c
*
* \brief Target board SX127x driver implementation
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
* ______ _
* / _____) _ | |
* ( (____ _____ ____ _| |_ _____ ____| |__
* \____ \| ___ | (_ _) ___ |/ ___) _ \
* _____) ) ____| | | || |_| ____( (___| | | |
* (______/|_____)_|_|_| \__)_____)\____)_| |_|
* (C)2013-2017 Semtech
*
* \endcode
*
* \author Miguel Luis ( Semtech )
*
* \author Gregory Cristian ( Semtech )
*
* \author Forest-Rain
*
* \author AIIT XUOS Lab
*/
/**
* @file sx127x-board.c
* @brief support lora-radio-driver for XiUOS
* @version 3.0
* @author AIIT XUOS Lab
* @date 2023-03-13
*/
/*************************************************
File name: sx127x-board.c
Description: support lora-radio-driver for XiUOS
Others:
History:
1. Date: 2023-03-13
Author: AIIT XUOS Lab
Modification:
1add LORA_RADIO_DRIVER_USING_RTOS_XIUOS to support XiUOS.
*************************************************/
#include <lora-radio-rtos-config.h>
#include <lora-radio.h>
#include <sx127x.h>
#include <sx127x-board.h>
#define LOG_TAG "LoRa.Board.Ra-01(SX1278)"
#define LOG_LEVEL LOG_LVL_DBG
#include <lora-radio-debug.h>
/*!
* Flag used to set the RF switch control pins in low power mode when the radio is not active.
*/
static bool RadioIsActive = false;
#ifdef LORA_RADIO_DRIVER_USING_RTOS_XIUOS
static int pin_fd = -1;
#endif
#ifdef LORA_RADIO_DRIVER_USING_ON_RTOS_RT_THREAD
/*!
* \brief DIO 0 IRQ callback
*/
void SX127xOnDio0IrqEvent( void *args );
/*!
* \brief DIO 1 IRQ callback
*/
void SX127xOnDio1IrqEvent( void *args );
/*!
* \brief DIO 2 IRQ callback
*/
void SX127xOnDio2IrqEvent( void *args );
/*!
* \brief DIO 3 IRQ callback
*/
void SX127xOnDio3IrqEvent( void *args );
/*!
* \brief DIO 4 IRQ callback
*/
void SX127xOnDio4IrqEvent( void *args );
/*!
* \brief DIO 5 IRQ callback
*/
void SX127xOnDio5IrqEvent( void *args );
#endif
/*!
* Debug GPIO pins objects
*/
#if defined( USE_RADIO_DEBUG )
Gpio_t DbgPinTx;
Gpio_t DbgPinRx;
#endif
#ifdef LORA_RADIO_GPIO_SETUP_BY_PIN_NAME
#if ( RT_VER_NUM <= 0x40004 )
int stm32_pin_get(char *pin_name)
{
/* eg: pin_name : "PA.4" ( GPIOA, GPIO_PIN_4 )--> drv_gpio.c pin */
char pin_index = strtol(&pin_name[3],0,10);
if(pin_name[1] < 'A' || pin_name[1] > 'Z')
{
return -1;
}
return (16 * (pin_name[1]-'A') + pin_index);
}
#endif
#endif /* LORA_RADIO_GPIO_SETUP_BY_PIN_NAME */
void SX127xIoInit( void )
{
#ifdef LORA_RADIO_DRIVER_USING_ON_RTOS_RT_THREAD
// RT-Thread
rt_pin_mode(LORA_RADIO_NSS_PIN, PIN_MODE_OUTPUT);
rt_pin_mode(LORA_RADIO_DIO0_PIN, PIN_MODE_INPUT_PULLDOWN);
#ifdef LORA_RADIO_DIO1_PIN
rt_pin_mode(LORA_RADIO_DIO1_PIN, PIN_MODE_INPUT_PULLDOWN);
#endif
#ifdef LORA_RADIO_DIO2_PIN
rt_pin_mode(LORA_RADIO_DIO2_PIN, PIN_MODE_INPUT_PULLDOWN);
#endif
#else
#endif
}
void SX127xIoIrqInit( DioIrqHandler **irqHandlers )
{
#ifdef LORA_RADIO_DRIVER_USING_ON_RTOS_RT_THREAD
#ifdef LORA_RADIO_DIO0_PIN
rt_pin_attach_irq(LORA_RADIO_DIO0_PIN, PIN_IRQ_MODE_RISING,SX127xOnDio0IrqEvent,(void*)"rf-dio0");
rt_pin_irq_enable(LORA_RADIO_DIO0_PIN, PIN_IRQ_ENABLE);
#endif
#ifdef LORA_RADIO_DIO1_PIN
rt_pin_attach_irq(LORA_RADIO_DIO1_PIN, PIN_IRQ_MODE_RISING,SX127xOnDio1IrqEvent,(void*)"rf-dio1");
rt_pin_irq_enable(LORA_RADIO_DIO1_PIN, PIN_IRQ_ENABLE);
#endif
#ifdef LORA_RADIO_DIO2_PIN
rt_pin_attach_irq(LORA_RADIO_DIO2_PIN, PIN_IRQ_MODE_RISING,SX127xOnDio2IrqEvent,(void*)"rf-dio2");
rt_pin_irq_enable(LORA_RADIO_DIO2_PIN, PIN_IRQ_ENABLE);
#endif
#endif
}
void SX127xIoDeInit( void )
{
}
void SX127xIoDbgInit( void )
{
}
void SX127xReset( void )
{
#ifdef LORA_RADIO_DRIVER_USING_ON_RTOS_RT_THREAD
// Set RESET pin to 0
rt_pin_mode(LORA_RADIO_RESET_PIN, PIN_MODE_OUTPUT);
rt_pin_write(LORA_RADIO_RESET_PIN, PIN_LOW);
// Wait 1 ms
SX127X_DELAY_MS( 1 );
// Configure RESET as input
rt_pin_mode(LORA_RADIO_RESET_PIN, PIN_MODE_INPUT);
// Wait 6 ms
SX127X_DELAY_MS( 6 );
#endif
#ifdef LORA_RADIO_DRIVER_USING_RTOS_XIUOS
if (pin_fd < 0) {
pin_fd = PrivOpen("/dev/pin_dev", O_RDWR);
if (pin_fd < 0) {
printf("open %s error\n", "/dev/pin_dev");
return;
}
}
struct PinParam pin_param;
pin_param.cmd = GPIO_CONFIG_MODE;
pin_param.mode = GPIO_CFG_OUTPUT;
pin_param.pin = LORA_RADIO_RESET_PIN;
struct PrivIoctlCfg ioctl_cfg;
ioctl_cfg.ioctl_driver_type = PIN_TYPE;
ioctl_cfg.args = &pin_param;
PrivIoctl(pin_fd, OPE_CFG, &ioctl_cfg);
struct PinStat pin_stat;
pin_stat.pin = LORA_RADIO_RESET_PIN;
pin_stat.val = GPIO_LOW;
PrivWrite(pin_fd, &pin_stat, 1);
// Wait 1 ms
SX127X_DELAY_MS( 1 );
// Configure RESET as input
pin_param.cmd = GPIO_CONFIG_MODE;
pin_param.mode = GPIO_CFG_INPUT;
pin_param.pin = LORA_RADIO_RESET_PIN;
ioctl_cfg.ioctl_driver_type = PIN_TYPE;
ioctl_cfg.args = &pin_param;
PrivIoctl(pin_fd, OPE_CFG, &ioctl_cfg);
// Wait 6 ms
SX127X_DELAY_MS( 6 );
#endif
}
void SX127xSetAntSwLowPower( bool status )
{
if( RadioIsActive != status )
{
RadioIsActive = status;
if( status == false )
{
SX127xAntSwInit( );
}
else
{
SX127xAntSwDeInit( );
}
}
}
void SX127xAntSwInit( void )
{
}
void SX127xAntSwDeInit( void )
{
}
/* TX and RX ANT switch */
void SX127xSetAntSw( uint8_t opMode )
{
}
#if defined( USE_RADIO_DEBUG )
void SX127xDbgPinTxWrite( uint8_t state )
{
GpioWrite( &DbgPinTx, state );
}
void SX127xDbgPinRxWrite( uint8_t state )
{
GpioWrite( &DbgPinRx, state );
}
#endif
uint8_t SX127xGetPaSelect( int8_t power )
{
return RF_PACONFIG_PASELECT_PABOOST;
}
bool SX127xCheckRfFrequency( uint32_t frequency )
{
// Implement check. Currently all frequencies are supported,todo depend on board
return true;
}

View File

@ -0,0 +1,158 @@
/*!
* \file lora-spi-board.c
*
* \brief spi peripheral initlize,it depend on mcu platform.
*
* SPDX-License-Identifier: Apache-2.0
*
* \author Forest-Rain
*
* \author AIIT XUOS Lab
*/
/**
* @file lora-spi-board.c
* @brief support lora-radio-driver for XiUOS
* @version 3.0
* @author AIIT XUOS Lab
* @date 2023-03-13
*/
/*************************************************
File name: lora-spi-board.c
Description: support lora-radio-driver for XiUOS
Others:
History:
1. Date: 2023-03-13
Author: AIIT XUOS Lab
Modification:
1add LORA_RADIO_DRIVER_USING_RTOS_XIUOS to support XiUOS.
*************************************************/
#include <lora-radio-rtos-config.h>
#ifdef LORA_RADIO_DRIVER_USING_LORA_CHIP_SX126X
#include <sx126x-board.h>
#elif defined LORA_RADIO_DRIVER_USING_LORA_CHIP_SX127X
#include <sx127x-board.h>
#endif
#define LOG_TAG "LoRa.HC32.SPI"
#define LOG_LEVEL LOG_LVL_DBG
#include <lora-radio-debug.h>
#ifdef LORA_RADIO_DRIVER_USING_ON_RTOS_RT_THREAD
/* for get GPIO fort,eg GPIOA */
#ifndef GET_GPIO_PORT
#define GET_GPIO_PORT(pin) (GPIO_TypeDef *)( GPIOA_BASE + (uint32_t) ( pin >> 4 ) * 0x0400UL )
#endif
#ifndef GET_GPIO_PIN
#define GET_GPIO_PIN(pin) (rt_uint16_t)( 1 << ( pin & 0x0F ) ) // for get GPIO_PIN, eg: GPIO_PIN_6
#endif
#ifdef LORA_RADIO_GPIO_SETUP_BY_PIN_NAME
#if ( RT_VER_NUM <= 0x40002 )
extern int stm32_pin_get(char *pin_name);
#endif
#endif
struct rt_spi_device *lora_radio_spi_init(const char *bus_name, const char *lora_device_name, rt_uint8_t param)
{
rt_err_t res;
struct rt_spi_device *lora_radio_spi_device;
RT_ASSERT(bus_name);
{
res = rt_hw_spi_device_attach( bus_name, lora_device_name, LORA_RADIO_NSS_PIN);
if (res != RT_EOK)
{
LORA_RADIO_DEBUG_LOG(LR_DBG_SPI, LOG_LEVEL,"rt_spi_bus_attach_device failed!\r\n");
return RT_NULL;
}
lora_radio_spi_device = (struct rt_spi_device *)rt_device_find(lora_device_name);
if (!lora_radio_spi_device)
{
LORA_RADIO_DEBUG_LOG(LR_DBG_SPI, LOG_LEVEL,"spi sample run failed! cant't find %s device!\n", lora_device_name);
return RT_NULL;
}
}
LORA_RADIO_DEBUG_LOG(LR_DBG_SPI, LOG_LEVEL,"find %s device!\n", lora_device_name);
/* config spi */
{
struct rt_spi_configuration cfg;
cfg.data_width = 8;
cfg.mode = RT_SPI_MASTER | RT_SPI_MODE_0 | RT_SPI_MSB; /* SPI Compatible: Mode 0. */
cfg.max_hz = 8 * 1000000; /* max 10M */
res = rt_spi_configure(lora_radio_spi_device, &cfg);
if (res != RT_EOK)
{
LORA_RADIO_DEBUG_LOG(LR_DBG_SPI, LOG_LEVEL,"rt_spi_configure failed!\r\n");
}
res = rt_spi_take_bus(lora_radio_spi_device);
if (res != RT_EOK)
{
LORA_RADIO_DEBUG_LOG(LR_DBG_SPI, LOG_LEVEL,"rt_spi_take_bus failed!\r\n");
}
res = rt_spi_release_bus(lora_radio_spi_device);
if(res != RT_EOK)
{
LORA_RADIO_DEBUG_LOG(LR_DBG_SPI, LOG_LEVEL,"rt_spi_release_bus failed!\r\n");
}
}
return lora_radio_spi_device;
}
/**
* This function releases memory
*
* @param dev the pointer of device driver structure
*/
void lora_radio_spi_deinit(struct rt_spi_device *dev)
{
RT_ASSERT(dev);
rt_spi_release_bus(dev);
}
#endif
#ifdef LORA_RADIO_DRIVER_USING_RTOS_XIUOS
int lora_radio_spi_init(void)
{
int spi_fd;
spi_fd = PrivOpen(LORA_SPI_DEV_NAME, O_RDWR);
if (spi_fd < 0) {
printf("open %s error\n", LORA_SPI_DEV_NAME);
return -1;
}
struct SpiMasterParam spi_master_param;
spi_master_param.spi_data_bit_width = 8;
spi_master_param.spi_work_mode = SPI_MODE_0 | SPI_MSB;
struct PrivIoctlCfg ioctl_cfg;
ioctl_cfg.ioctl_driver_type = SPI_TYPE;
ioctl_cfg.args = &spi_master_param;
PrivIoctl(spi_fd, OPE_CFG, &ioctl_cfg);
ioctl_cfg.args = NULL;
PrivIoctl(spi_fd, OPE_INT, &ioctl_cfg);
PrivClose(spi_fd);
return 0;
}
void lora_radio_spi_deinit(int spi_fd)
{
PrivClose(spi_fd);
}
#endif

View File

@ -0,0 +1,256 @@
/*!
* \file sx126x-board.h
*
* \brief Target board SX126x driver implementation
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
* ______ _
* / _____) _ | |
* ( (____ _____ ____ _| |_ _____ ____| |__
* \____ \| ___ | (_ _) ___ |/ ___) _ \
* _____) ) ____| | | || |_| ____( (___| | | |
* (______/|_____)_|_|_| \__)_____)\____)_| |_|
* (C)2013-2017 Semtech
*
* \endcode
*
* \author Miguel Luis ( Semtech )
*
* \author Gregory Cristian ( Semtech )
*
* \author Forest-Rain
*
* \author AIIT XUOS Lab
*/
/**
* @file sx126x-board.h
* @brief support lora-radio-driver for XiUOS
* @version 3.0
* @author AIIT XUOS Lab
* @date 2023-03-13
*/
/*************************************************
File name: sx126x-board.h
Description: support lora-radio-driver for XiUOS
Others:
History:
1. Date: 2023-03-13
Author: AIIT XUOS Lab
Modification:
1add LORA_RADIO_DRIVER_USING_RTOS_XIUOS to support XiUOS.
*************************************************/
#ifndef __SX126x_BOARD_H__
#define __SX126x_BOARD_H__
#include <lora-radio-rtos-config.h>
#include <stdint.h>
#include <stdbool.h>
#include <sx126x.h>
#ifdef LORA_RADIO_DRIVER_USING_RTOS_RT_THREAD
#ifdef LORA_RADIO_GPIO_SETUP_BY_PIN_NAME
#if ( RT_VER_NUM <= 0x40002 )
#define LORA_RADIO_NSS_PIN stm32_pin_get(LORA_RADIO_NSS_PIN_NAME)
#define LORA_RADIO_BUSY_PIN stm32_pin_get(LORA_RADIO_BUSY_PIN_NAME)
#define LORA_RADIO_DIO1_PIN stm32_pin_get(LORA_RADIO_DIO1_PIN_NAME)
#define LORA_RADIO_RESET_PIN stm32_pin_get(LORA_RADIO_RESET_PIN_NAME)
#if defined( LORA_RADIO_DIO2_PIN_NAME )
#define LORA_RADIO_DIO2_PIN stm32_pin_get(LORA_RADIO_DIO2_PIN_NAME)
#endif
#if defined( LORA_RADIO_RFSW1_PIN_NAME ) && defined ( LORA_RADIO_RFSW2_PIN_NAME )
#define LORA_RADIO_RFSW1_PIN stm32_pin_get(LORA_RADIO_RFSW1_PIN_NAME)
#define LORA_RADIO_RFSW2_PIN stm32_pin_get(LORA_RADIO_RFSW2_PIN_NAME)
#endif
#else
#define LORA_RADIO_NSS_PIN rt_pin_get(LORA_RADIO_NSS_PIN_NAME)
#define LORA_RADIO_BUSY_PIN rt_pin_get(LORA_RADIO_BUSY_PIN_NAME)
#define LORA_RADIO_DIO1_PIN rt_pin_get(LORA_RADIO_DIO1_PIN_NAME)
#define LORA_RADIO_RESET_PIN rt_pin_get(LORA_RADIO_RESET_PIN_NAME)
#if defined( LORA_RADIO_DIO2_PIN_NAME )
#define LORA_RADIO_DIO2_PIN rt_pin_get(LORA_RADIO_DIO2_PIN_NAME)
#endif
#if defined( LORA_RADIO_RFSW1_PIN_NAME ) && defined ( LORA_RADIO_RFSW2_PIN_NAME )
#define LORA_RADIO_RFSW1_PIN rt_pin_get(LORA_RADIO_RFSW1_PIN_NAME)
#define LORA_RADIO_RFSW2_PIN rt_pin_get(LORA_RADIO_RFSW2_PIN_NAME)
#endif
#endif/* ( RT_VER_NUM <= 0x40002) */
#else
/* if not use env\menuconfig,define Radio GPIO directly.*/
#ifndef LORA_RADIO_NSS_PIN
#define LORA_RADIO_NSS_PIN GET_PIN(A,15)
#endif
#ifndef LORA_RADIO_RESET_PIN
#define LORA_RADIO_RESET_PIN GET_PIN(A,7)
#endif
#ifndef LORA_RADIO_DIO1_PIN
#define LORA_RADIO_DIO1_PIN GET_PIN(B,1)
#endif
#ifndef LORA_RADIO_BUSY_PIN
#define LORA_RADIO_BUSY_PIN GET_PIN(B,2)
#endif
#ifndef LORA_RADIO_RFSW1_PIN
#define LORA_RADIO_RFSW1_PIN GET_PIN(B,0)
#endif
#ifndef LORA_RADIO_RFSW2_PIN
#define LORA_RADIO_RFSW2_PIN GET_PIN(C,5)
#endif
#endif // end of LORA_RADIO_GPIO_SETUP_BY_PIN_NAME
#endif
#ifdef LORA_RADIO_DRIVER_USING_RTOS_XIUOS
#ifdef LORA_RADIO_DRIVER_USING_EDU_ARM32
#ifndef LORA_RADIO_RESET_PIN
#define LORA_RADIO_RESET_PIN 133//PI02 on HC32F4A0_I
#endif
#ifndef LORA_RADIO_BUSY_PIN
#define LORA_RADIO_BUSY_PIN 2//PE03 on HC32F4A0_I
#endif
#ifndef LORA_RADIO_RFSW1_PIN
#define LORA_RADIO_RFSW1_PIN 140//PC11 on HC32F4A0_I TX_EN
#endif
#ifndef LORA_RADIO_RFSW2_PIN
#define LORA_RADIO_RFSW2_PIN 143//PD01 on HC32F4A0_I RX_EN
#endif
#ifndef LORA_SPI_DEV_NAME
#define LORA_SPI_DEV_NAME "/dev/spi1_dev0"
#endif
#endif
#ifdef LORA_RADIO_DRIVER_USING_XISHUTONG_ARM32
#ifndef LORA_RADIO_RESET_PIN
#define LORA_RADIO_RESET_PIN 144//PD02 on xishutong-arm32
#endif
#ifndef LORA_SPI_DEV_NAME
#define LORA_SPI_DEV_NAME "/dev/spi2_dev0"
#endif
#endif
#endif
/** @addtogroup LORA_RADIO_BOARD
* @{
*/
/** @addtogroup LORA_RADIO_BOARD_SX126X
* @{
*/
/*!
* Defines the time required for the TCXO to wakeup [ms].
*/
#define BOARD_TCXO_WAKEUP_TIME 2
#ifdef LORA_RADIO_DRIVER_USING_RTOS_RT_THREAD
#define SX126X_DELAY_MS( ms ) rt_thread_mdelay(ms)
#define SX126X_BLOCK_DELAY_1MS() rt_hw_us_delay(999)
#endif
#ifdef LORA_RADIO_DRIVER_USING_RTOS_XIUOS
#define SX126X_DELAY_MS( ms ) PrivTaskDelay(ms)
#define SX126X_BLOCK_DELAY_1MS() PrivTaskDelay(1)
#endif
/*!
* \brief Initializes the radio I/Os pins interface
*/
void SX126xIoInit( void );
/*!
* \brief Initializes DIO IRQ handlers
*
* \param [IN] irqHandlers Array containing the IRQ callback functions
*/
void SX126xIoIrqInit( DioIrqHandler dioIrq );
/*!
* \brief De-initializes the radio I/Os pins interface.
*
* \remark Useful when going in MCU low power modes
*/
void SX126xIoDeInit( void );
/*!
* \brief Initializes the TCXO power pin.
*/
void SX126xIoTcxoInit( void );
/*!
* \brief Initializes the radio debug pins.
*/
void SX126xIoDbgInit( void );
/*!
* \brief HW Reset of the radio
*/
void SX126xReset( void );
/*!
* \brief Blocking loop to wait while the Busy pin in high
*/
void SX126xWaitOnBusy( void );
/*!
* \brief Initializes the RF Switch I/Os pins interface
*/
void SX126xAntSwOn( void );
/*!
* \brief De-initializes the RF Switch I/Os pins interface
*
* \remark Needed to decrease the power consumption in MCU low power modes
*/
void SX126xAntSwOff( void );
/*!
* \brief Set the RF Switch I/Os pins interface
*/
void SX126xSetAntSw( RadioOperatingModes_t mode );
/*!
* \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 SX126xCheckRfFrequency( uint32_t frequency );
/*!
* \brief Gets the Defines the time required for the TCXO to wakeup [ms].
*
* \retval time Board TCXO wakeup time in ms.
*/
uint32_t SX126xGetBoardTcxoWakeupTime( void );
/*!
* \brief Writes new Tx debug pin state
*
* \param [IN] state Debug pin state
*/
void SX126xDbgPinTxWrite( uint8_t state );
/*!
* \brief Writes new Rx debug pin state
*
* \param [IN] state Debug pin state
*/
void SX126xDbgPinRxWrite( uint8_t state );
/**
* @}
*/
/**
* @}
*/
#endif // __SX126x_BOARD_H__

View File

@ -0,0 +1,261 @@
/*!
* \file sx127x-board.h
*
* \brief Target board SX127x driver implementation
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
* ______ _
* / _____) _ | |
* ( (____ _____ ____ _| |_ _____ ____| |__
* \____ \| ___ | (_ _) ___ |/ ___) _ \
* _____) ) ____| | | || |_| ____( (___| | | |
* (______/|_____)_|_|_| \__)_____)\____)_| |_|
* (C)2013-2017 Semtech
*
* \endcode
*
* \author Miguel Luis ( Semtech )
*
* \author Gregory Cristian ( Semtech )
*
* \author Forest-Rain
*
* \author AIIT XUOS Lab
*/
/**
* @file sx127x-board.h
* @brief support lora-radio-driver for XiUOS
* @version 3.0
* @author AIIT XUOS Lab
* @date 2023-03-13
*/
/*************************************************
File name: sx127x-board.h
Description: support lora-radio-driver for XiUOS
Others:
History:
1. Date: 2023-03-13
Author: AIIT XUOS Lab
Modification:
1add LORA_RADIO_DRIVER_USING_RTOS_XIUOS to support XiUOS.
*************************************************/
#ifndef __SX127x_BOARD_H__
#define __SX127x_BOARD_H__
#include <lora-radio-rtos-config.h>
#include <stdint.h>
#include <stdbool.h>
#include <sx127x.h>
#ifdef LORA_RADIO_DRIVER_USING_RTOS_RT_THREAD
#ifdef LORA_RADIO_GPIO_SETUP_BY_PIN_NAME
#if ( RT_VER_NUM <= 0x40002 )
#define LORA_RADIO_NSS_PIN stm32_pin_get(LORA_RADIO_NSS_PIN_NAME)
#define LORA_RADIO_RESET_PIN stm32_pin_get(LORA_RADIO_RESET_PIN_NAME)
#define LORA_RADIO_DIO0_PIN stm32_pin_get(LORA_RADIO_DIO0_PIN_NAME)
#if defined( LORA_RADIO_DIO1_PIN_NAME )
#define LORA_RADIO_DIO1_PIN stm32_pin_get(LORA_RADIO_DIO1_PIN_NAME)
#endif
#if defined( LORA_RADIO_DIO2_PIN_NAME )
#define LORA_RADIO_DIO2_PIN stm32_pin_get(LORA_RADIO_DIO2_PIN_NAME)
#endif
#if defined( LORA_RADIO_DIO3_PIN_NAME )
#define LORA_RADIO_DIO1_PIN stm32_pin_get(LORA_RADIO_DIO3_PIN_NAME)
#endif
#if defined( LORA_RADIO_DIO4_PIN_NAME )
#define LORA_RADIO_DIO2_PIN stm32_pin_get(LORA_RADIO_DIO4_PIN_NAME)
#endif
#if defined( LORA_RADIO_DIO5_PIN_NAME )
#define LORA_RADIO_DIO1_PIN stm32_pin_get(LORA_RADIO_DIO5_PIN_NAME)
#endif
#if defined( LORA_RADIO_RFSW1_PIN_NAME ) && defined ( LORA_RADIO_RFSW2_PIN_NAME )
#define LORA_RADIO_RFSW1_PIN stm32_pin_get(LORA_RADIO_RFSW1_PIN_NAME)
#define LORA_RADIO_RFSW2_PIN stm32_pin_get(LORA_RADIO_RFSW2_PIN_NAME)
#endif
#else
#define LORA_RADIO_NSS_PIN rt_pin_get(LORA_RADIO_NSS_PIN_NAME)
#define LORA_RADIO_RESET_PIN rt_pin_get(LORA_RADIO_RESET_PIN_NAME)
#define LORA_RADIO_DIO0_PIN rt_pin_get(LORA_RADIO_DIO0_PIN_NAME)
#if defined( LORA_RADIO_DIO1_PIN_NAME )
#define LORA_RADIO_DIO1_PIN rt_pin_get(LORA_RADIO_DIO1_PIN_NAME)
#endif
#if defined( LORA_RADIO_DIO2_PIN_NAME )
#define LORA_RADIO_DIO2_PIN rt_pin_get(LORA_RADIO_DIO2_PIN_NAME)
#endif
#if defined( LORA_RADIO_DIO3_PIN_NAME )
#define LORA_RADIO_DIO1_PIN rt_pin_get(LORA_RADIO_DIO3_PIN_NAME)
#endif
#if defined( LORA_RADIO_DIO4_PIN_NAME )
#define LORA_RADIO_DIO2_PIN rt_pin_get(LORA_RADIO_DIO4_PIN_NAME)
#endif
#if defined( LORA_RADIO_DIO5_PIN_NAME )
#define LORA_RADIO_DIO1_PIN rt_pin_get(LORA_RADIO_DIO5_PIN_NAME)
#endif
#if defined( LORA_RADIO_RFSW1_PIN_NAME ) && defined ( LORA_RADIO_RFSW2_PIN_NAME )
#define LORA_RADIO_RFSW1_PIN rt_pin_get(LORA_RADIO_RFSW1_PIN_NAME)
#define LORA_RADIO_RFSW2_PIN rt_pin_get(LORA_RADIO_RFSW2_PIN_NAME)
#endif
#endif /* ( RT_VER_NUM <= 0x40002) */
#else
/* if not use env\menuconfig,define Radio GPIO directly.*/
#ifndef LORA_RADIO_NSS_PIN
#define LORA_RADIO_NSS_PIN GET_PIN(A,15)
#endif
#ifndef LORA_RADIO_RESET_PIN
#define LORA_RADIO_RESET_PIN GET_PIN(A,7)
#endif
#ifndef LORA_RADIO_DIO0_PIN
#define LORA_RADIO_DIO0_PIN GET_PIN(B,1)
#endif
#endif // end of LORA_RADIO_GPIO_SETUP_BY_PIN_NAME
#endif
#ifdef LORA_RADIO_DRIVER_USING_RTOS_XIUOS
#ifdef LORA_RADIO_DRIVER_USING_EDU_ARM32
#ifndef LORA_RADIO_RESET_PIN
#define LORA_RADIO_RESET_PIN 133//PI02 on HC32F4A0
#endif
#ifndef LORA_SPI_DEV_NAME
#define LORA_SPI_DEV_NAME "/dev/spi1_dev0"
#endif
#endif
#endif
/** @addtogroup LORA_RADIO_BOARD_SX127X
* @{
*/
#ifdef LORA_RADIO_DRIVER_USING_RTOS_RT_THREAD
/*!
* \brief delayms for radio access
*/
#define SX127X_DELAY_MS(ms) rt_thread_mdelay(ms)
#endif
#ifdef LORA_RADIO_DRIVER_USING_RTOS_XIUOS
#define SX127X_DELAY_MS(ms) PrivTaskDelay(ms)
#endif
/*!
* \brief Initializes the radio I/Os pins interface
*/
void SX127xIoInit( void );
/*!
* \brief De-initializes the radio I/Os pins interface.
*
* \remark Useful when going in MCU low power modes
*/
void SX127xIoDeInit( void );
/*!
* \brief Initializes the TCXO power pin.
*/
void SX127xIoTcxoInit( void );
/*!
* \brief Initializes the radio debug pins.
*/
void SX127xIoDbgInit( void );
/*!
* \brief Resets the radio
*/
void SX127xReset( void );
/*!
* \brief Gets the board PA selection configuration
*
* \param [IN] power Selects the right PA according to the wanted power.
* \retval PaSelect RegPaConfig PaSelect value
*/
uint8_t SX127xGetPaSelect( int8_t power );
/*!
* \brief Set the RF Switch I/Os pins in low power mode
*
* \param [IN] status enable or disable
*/
void SX127xSetAntSwLowPower( bool status );
/*!
* \brief Initializes the RF Switch I/Os pins interface
*/
void SX127xAntSwInit( void );
/*!
* \brief De-initializes the RF Switch I/Os pins interface
*
* \remark Needed to decrease the power consumption in MCU low power modes
*/
void SX127xAntSwDeInit( void );
/*!
* \brief Controls the antenna switch if necessary.
*
* \remark see errata note
*
* \param [IN] opMode Current radio operating mode
*/
void SX127xSetAntSw( uint8_t opMode );
/*!
* \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 SX127xCheckRfFrequency( uint32_t frequency );
/*!
* \brief Enables/disables the TCXO if available on board design.
*
* \param [IN] state TCXO enabled when true and disabled when false.
*/
void SX127xSetBoardTcxo( uint8_t state );
/*!
* \brief Gets the Defines the time required for the TCXO to wakeup [ms].
*
* \retval time Board TCXO wakeup time in ms.
*/
uint32_t SX127xGetBoardTcxoWakeupTime( void );
/*!
* \brief Writes new Tx debug pin state
*
* \param [IN] state Debug pin state
*/
void SX127xDbgPinTxWrite( uint8_t state );
/*!
* \brief Writes new Rx debug pin state
*
* \param [IN] state Debug pin state
*/
void SX127xDbgPinRxWrite( uint8_t state );
#ifdef LORA_RADIO_GPIO_SETUP_BY_PIN_NAME
// todo PR to drv_gpio.c
int stm32_pin_get(char *pin_name);
#endif
/*!
* Radio hardware and global parameters
*/
extern SX127x_t SX127x;
/**
* @}
*/
#endif // __SX127x_BOARD_H__

View File

@ -0,0 +1,79 @@
/*
* author Rick Zhang
* date 2020.07.20
*/
#include "lora-radio-rtos-config.h"
#include "lora-radio.h"
#include "sx126x-board.h"
#define DRV_DEBUG
#define LOG_TAG "LoRa.Board.ASR6500S(SX1262)" // ASR6500S
#include <drv_log.h>
extern void RadioOnDioIrq( void* context );
void SX126xIoInit( void )
{
rt_pin_mode(LORA_RADIO_NSS_PIN, PIN_MODE_OUTPUT);
rt_pin_mode(LORA_RADIO_BUSY_PIN, PIN_MODE_INPUT);
rt_pin_mode(LORA_RADIO_DIO1_PIN, PIN_MODE_INPUT);
}
void SX126xIoIrqInit( DioIrqHandler dioIrq )
{
rt_pin_mode(LORA_RADIO_DIO1_PIN, PIN_MODE_INPUT);
rt_pin_attach_irq(LORA_RADIO_DIO1_PIN, PIN_IRQ_MODE_RISING, RadioOnDioIrq,(void*)"callback args");
rt_pin_irq_enable(LORA_RADIO_DIO1_PIN, PIN_IRQ_ENABLE);
}
void SX126xIoDeInit( void )
{
}
void SX126xIoDbgInit( void )
{
}
void SX126xIoTcxoInit( void )
{
CalibrationParams_t calibParam;
SX126xSetDio3AsTcxoCtrl( TCXO_CTRL_1_8V, SX126xGetBoardTcxoWakeupTime( ) << 6 ); // convert from ms to SX126x time base
calibParam.Value = 0x7F;
SX126xCalibrate( calibParam );
}
uint32_t SX126xGetBoardTcxoWakeupTime( void )
{
return BOARD_TCXO_WAKEUP_TIME;
}
void SX126xReset( void )
{
SX126X_DELAY_MS( 20 );
rt_pin_mode(LORA_RADIO_RESET_PIN, PIN_MODE_OUTPUT);
rt_pin_write(LORA_RADIO_RESET_PIN, PIN_LOW);
SX126X_DELAY_MS( 40 );
rt_pin_mode(LORA_RADIO_RESET_PIN, PIN_MODE_INPUT);
SX126X_DELAY_MS( 20 );
}
void SX126xWaitOnBusy( void )
{
while( rt_pin_read( LORA_RADIO_BUSY_PIN ) == PIN_HIGH );
}
void SX126xAntSwOn( void )
{
}
void SX126xAntSwOff( void )
{
}
bool SX126xCheckRfFrequency( uint32_t frequency )
{
return true;
}
void SX126xSetAntSw( RadioOperatingModes_t mode )
{
}

View File

@ -0,0 +1,174 @@
/*!
* \file sx1262-board.c
*
* \brief Target board SX126x shield driver implementation
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
* ______ _
* / _____) _ | |
* ( (____ _____ ____ _| |_ _____ ____| |__
* \____ \| ___ | (_ _) ___ |/ ___) _ \
* _____) ) ____| | | || |_| ____( (___| | | |
* (______/|_____)_|_|_| \__)_____)\____)_| |_|
* (C)2013-2017 Semtech
*
* \endcode
*
* \author Miguel Luis ( Semtech )
*
* \author Gregory Cristian ( Semtech )
*
* \author Forest-Rain
*/
#include "lora-radio-rtos-config.h"
#include "lora-radio.h"
#include "sx126x-board.h"
#define LOG_TAG "LoRa.Board.LSD4RF-2R822N30(SX1262)"
#define LOG_LEVEL LOG_LVL_DBG
#include "lora-radio-debug.h"
/*!
* Debug GPIO pins objects
*/
#if defined( USE_RADIO_DEBUG )
Gpio_t DbgPinTx;
Gpio_t DbgPinRx;
#endif
#ifdef LORA_RADIO_GPIO_SETUP_BY_PIN_NAME
#if ( RT_VER_NUM <= 0x40004 )
int stm32_pin_get(char *pin_name)
{
/* eg: pin_name : "PA.4" ( GPIOA, GPIO_PIN_4 )--> drv_gpio.c pin */
char pin_index = strtol(&pin_name[3],0,10);
if(pin_name[1] < 'A' || pin_name[1] > 'Z')
{
return -1;
}
return (16 * (pin_name[1]-'A') + pin_index);
}
#endif
#endif /* LORA_RADIO_GPIO_SETUP_BY_PIN_NAME */
void SX126xIoInit( void )
{
rt_pin_mode(LORA_RADIO_NSS_PIN, PIN_MODE_OUTPUT);
rt_pin_mode(LORA_RADIO_BUSY_PIN, PIN_MODE_INPUT);
rt_pin_mode(LORA_RADIO_DIO1_PIN, PIN_MODE_INPUT_PULLDOWN);
#if defined( LORA_RADIO_DIO2_PIN )
rt_pin_mode(LORA_RADIO_DIO2_PIN, PIN_MODE_INPUT_PULLDOWN);
#endif
#if defined( LORA_RADIO_RFSW1_PIN ) && defined ( LORA_RADIO_RFSW2_PIN )
rt_pin_mode(LORA_RADIO_RFSW1_PIN, PIN_MODE_OUTPUT);
rt_pin_mode(LORA_RADIO_RFSW2_PIN, PIN_MODE_OUTPUT);
#endif
}
void SX126xIoIrqInit( DioIrqHandler dioIrq )
{
rt_pin_mode(LORA_RADIO_DIO1_PIN, PIN_MODE_INPUT_PULLDOWN);
rt_pin_attach_irq(LORA_RADIO_DIO1_PIN, PIN_IRQ_MODE_RISING, dioIrq,(void*)"rf-dio1");
rt_pin_irq_enable(LORA_RADIO_DIO1_PIN, PIN_IRQ_ENABLE);
}
void SX126xIoDeInit( void )
{
SX126xAntSwOff();
}
void SX126xIoDbgInit( void )
{
#if defined( USE_RADIO_DEBUG )
GpioInit( &DbgPinTx, RADIO_DBG_PIN_TX, PIN_OUTPUT, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
GpioInit( &DbgPinRx, RADIO_DBG_PIN_RX, PIN_OUTPUT, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
#endif
}
void SX126xIoTcxoInit( void )
{
// Initialize TCXO control
CalibrationParams_t calibParam;
// +clear OSC_START_ERR for reboot or cold-start from sleep
SX126xClearDeviceErrors();
// TCXO_CTRL_2_7V 64*15.0625US
SX126xSetDio3AsTcxoCtrl( TCXO_CTRL_2_7V, 320);//SX126xGetBoardTcxoWakeupTime( ) << 6 ); // convert from ms to SX126x time base
calibParam.Value = 0x7F;
SX126xCalibrate( calibParam );
}
uint32_t SX126xGetBoardTcxoWakeupTime( void )
{
return BOARD_TCXO_WAKEUP_TIME;
}
void SX126xReset( void )
{
SX126X_DELAY_MS( 10 );
rt_pin_mode(LORA_RADIO_RESET_PIN, PIN_MODE_OUTPUT);
rt_pin_write(LORA_RADIO_RESET_PIN, PIN_LOW);
SX126X_DELAY_MS( 20 );
// internal pull-up
rt_pin_mode(LORA_RADIO_RESET_PIN, PIN_MODE_INPUT);
SX126X_DELAY_MS( 10 );
}
void SX126xWaitOnBusy( void )
{
while( rt_pin_read( LORA_RADIO_BUSY_PIN ) == PIN_HIGH );
}
void SX126xAntSwOn( void )
{
// No need
}
void SX126xAntSwOff( void )
{
////GpioInit( &AntPow, RADIO_ANT_SWITCH_POWER, PIN_ANALOGIC, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
#if defined( LORA_RADIO_RFSW1_PIN ) && defined ( LORA_RADIO_RFSW2_PIN )
rt_pin_write(LORA_RADIO_RFSW1_PIN, PIN_LOW);
rt_pin_write(LORA_RADIO_RFSW2_PIN, PIN_LOW);
#endif
}
void SX126xSetAntSw( RadioOperatingModes_t mode )
{
if( mode == MODE_TX )
{ // Transmit
rt_pin_write(LORA_RADIO_RFSW1_PIN, PIN_HIGH);
rt_pin_write(LORA_RADIO_RFSW2_PIN, PIN_LOW);
}
else
{
rt_pin_write(LORA_RADIO_RFSW1_PIN, PIN_LOW);
rt_pin_write(LORA_RADIO_RFSW2_PIN, PIN_HIGH);
}
}
bool SX126xCheckRfFrequency( uint32_t frequency )
{
// Implement check. Currently all frequencies are supported
return true;
}
#if defined( USE_RADIO_DEBUG )
void SX126xDbgPinTxWrite( uint8_t state )
{
GpioWrite( &DbgPinTx, state );
}
void SX126xDbgPinRxWrite( uint8_t state )
{
GpioWrite( &DbgPinRx, state );
}
#endif

View File

@ -0,0 +1,177 @@
/*!
* \file sx1268-board.c
*
* \brief Target board SX126x shield driver implementation
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
* ______ _
* / _____) _ | |
* ( (____ _____ ____ _| |_ _____ ____| |__
* \____ \| ___ | (_ _) ___ |/ ___) _ \
* _____) ) ____| | | || |_| ____( (___| | | |
* (______/|_____)_|_|_| \__)_____)\____)_| |_|
* (C)2013-2017 Semtech
*
* \endcode
*
* \author Miguel Luis ( Semtech )
*
* \author Gregory Cristian ( Semtech )
*
* \author Forest-Rain
*/
#include "lora-radio-rtos-config.h"
#include "lora-radio.h"
#include "sx126x-board.h"
#define LOG_TAG "LoRa.Board.LSD4RF-2R717N40(SX1268)" // LSD4RF-2R717N40
#define LOG_LEVEL LOG_LVL_DBG
#include "lora-radio-debug.h"
/*!
* Debug GPIO pins objects
*/
#if defined( USE_RADIO_DEBUG )
Gpio_t DbgPinTx;
Gpio_t DbgPinRx;
#endif
#ifdef LORA_RADIO_GPIO_SETUP_BY_PIN_NAME
#if ( RT_VER_NUM <= 0x40004 )
int stm32_pin_get(char *pin_name)
{
/* eg: pin_name : "PA.4" ( GPIOA, GPIO_PIN_4 )--> drv_gpio.c pin */
char pin_index = strtol(&pin_name[3],0,10);
if(pin_name[1] < 'A' || pin_name[1] > 'Z')
{
return -1;
}
return (16 * (pin_name[1]-'A') + pin_index);
}
#endif
#endif /* LORA_RADIO_GPIO_SETUP_BY_PIN_NAME */
void SX126xIoInit( void )
{
rt_pin_mode(LORA_RADIO_NSS_PIN, PIN_MODE_OUTPUT);
rt_pin_mode(LORA_RADIO_BUSY_PIN, PIN_MODE_INPUT);
rt_pin_mode(LORA_RADIO_DIO1_PIN, PIN_MODE_INPUT_PULLDOWN);
#if defined( LORA_RADIO_DIO2_PIN )
rt_pin_mode(LORA_RADIO_DIO2_PIN, PIN_MODE_INPUT_PULLDOWN);
#endif
#if defined( LORA_RADIO_RFSW1_PIN ) && defined ( LORA_RADIO_RFSW2_PIN )
rt_pin_mode(LORA_RADIO_RFSW1_PIN, PIN_MODE_OUTPUT);
rt_pin_mode(LORA_RADIO_RFSW2_PIN, PIN_MODE_OUTPUT);
#endif
}
void SX126xIoIrqInit( DioIrqHandler dioIrq )
{
rt_pin_mode(LORA_RADIO_DIO1_PIN, PIN_MODE_INPUT_PULLDOWN);
rt_pin_attach_irq(LORA_RADIO_DIO1_PIN, PIN_IRQ_MODE_RISING, dioIrq,(void*)"rf-dio1");
rt_pin_irq_enable(LORA_RADIO_DIO1_PIN, PIN_IRQ_ENABLE);
}
void SX126xIoDeInit( void )
{
//// GpioInit( &SX126x.Spi.Nss, RADIO_NSS, PIN_ANALOGIC, PIN_PUSH_PULL, PIN_PULL_UP, 1 );
//// GpioInit( &SX126x.BUSY, RADIO_BUSY, PIN_ANALOGIC, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
//// GpioInit( &SX126x.DIO1, RADIO_DIO_1, PIN_ANALOGIC, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
SX126xAntSwOff();
}
void SX126xIoDbgInit( void )
{
#if defined( USE_RADIO_DEBUG )
GpioInit( &DbgPinTx, RADIO_DBG_PIN_TX, PIN_OUTPUT, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
GpioInit( &DbgPinRx, RADIO_DBG_PIN_RX, PIN_OUTPUT, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
#endif
}
void SX126xIoTcxoInit( void )
{
// Initialize TCXO control
CalibrationParams_t calibParam;
// +clear OSC_START_ERR for reboot or cold-start from sleep
SX126xClearDeviceErrors();
// TCXO_CTRL_1_7V -> TCXO_CTRL_2_7V 64*15.0625US
SX126xSetDio3AsTcxoCtrl( TCXO_CTRL_2_7V, 320);//SX126xGetBoardTcxoWakeupTime( ) << 6 ); // convert from ms to SX126x time base
calibParam.Value = 0x7F;
SX126xCalibrate( calibParam );
}
uint32_t SX126xGetBoardTcxoWakeupTime( void )
{
return BOARD_TCXO_WAKEUP_TIME;
}
void SX126xReset( void )
{
SX126X_DELAY_MS( 10 );
rt_pin_mode(LORA_RADIO_RESET_PIN, PIN_MODE_OUTPUT);
rt_pin_write(LORA_RADIO_RESET_PIN, PIN_LOW);
SX126X_DELAY_MS( 20 );
// internal pull-up
rt_pin_mode(LORA_RADIO_RESET_PIN, PIN_MODE_INPUT);
SX126X_DELAY_MS( 10 );
}
void SX126xWaitOnBusy( void )
{
while( rt_pin_read( LORA_RADIO_BUSY_PIN ) == PIN_HIGH );
}
void SX126xAntSwOn( void )
{
// No need
}
void SX126xAntSwOff( void )
{
////GpioInit( &AntPow, RADIO_ANT_SWITCH_POWER, PIN_ANALOGIC, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
#if defined( LORA_RADIO_RFSW1_PIN ) && defined ( LORA_RADIO_RFSW2_PIN )
rt_pin_write(LORA_RADIO_RFSW1_PIN, PIN_LOW);
rt_pin_write(LORA_RADIO_RFSW2_PIN, PIN_LOW);
#endif
}
void SX126xSetAntSw( RadioOperatingModes_t mode )
{
if( mode == MODE_TX )
{ // Transmit
rt_pin_write(LORA_RADIO_RFSW1_PIN, PIN_HIGH);
rt_pin_write(LORA_RADIO_RFSW2_PIN, PIN_LOW);
}
else
{
rt_pin_write(LORA_RADIO_RFSW1_PIN, PIN_LOW);
rt_pin_write(LORA_RADIO_RFSW2_PIN, PIN_HIGH);
}
}
bool SX126xCheckRfFrequency( uint32_t frequency )
{
// Implement check. Currently all frequencies are supported
return true;
}
#if defined( USE_RADIO_DEBUG )
void SX126xDbgPinTxWrite( uint8_t state )
{
GpioWrite( &DbgPinTx, state );
}
void SX126xDbgPinRxWrite( uint8_t state )
{
GpioWrite( &DbgPinRx, state );
}
#endif

View File

@ -0,0 +1,292 @@
/*!
* \file sx1278-board.c
*
* \brief Target board SX127x driver implementation
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
* ______ _
* / _____) _ | |
* ( (____ _____ ____ _| |_ _____ ____| |__
* \____ \| ___ | (_ _) ___ |/ ___) _ \
* _____) ) ____| | | || |_| ____( (___| | | |
* (______/|_____)_|_|_| \__)_____)\____)_| |_|
* (C)2013-2017 Semtech
*
* \endcode
*
* \author Miguel Luis ( Semtech )
*
* \author Gregory Cristian ( Semtech )
*
* \author Forest-Rain
*/
#include "lora-radio-rtos-config.h"
#include "lora-radio.h"
#include "sx127x\sx127x.h"
#include "sx127x-board.h"
#define LOG_TAG "LoRa.Board.LSD4RF-2F717N30(SX1278)"
#define LOG_LEVEL LOG_LVL_DBG
#include "lora-radio-debug.h"
/*!
* Flag used to set the RF switch control pins in low power mode when the radio is not active.
*/
static bool RadioIsActive = false;
#ifdef LORA_RADIO_DRIVER_USING_ON_RTOS_RT_THREAD
/*!
* \brief DIO 0 IRQ callback
*/
void SX127xOnDio0IrqEvent( void *args );
/*!
* \brief DIO 1 IRQ callback
*/
void SX127xOnDio1IrqEvent( void *args );
/*!
* \brief DIO 2 IRQ callback
*/
void SX127xOnDio2IrqEvent( void *args );
/*!
* \brief DIO 3 IRQ callback
*/
void SX127xOnDio3IrqEvent( void *args );
/*!
* \brief DIO 4 IRQ callback
*/
void SX127xOnDio4IrqEvent( void *args );
/*!
* \brief DIO 5 IRQ callback
*/
void SX127xOnDio5IrqEvent( void *args );
#endif
/*!
* Debug GPIO pins objects
*/
#if defined( USE_RADIO_DEBUG )
Gpio_t DbgPinTx;
Gpio_t DbgPinRx;
#endif
#ifdef LORA_RADIO_GPIO_SETUP_BY_PIN_NAME
#if ( RT_VER_NUM <= 0x40004 )
int stm32_pin_get(char *pin_name)
{
/* eg: pin_name : "PA.4" ( GPIOA, GPIO_PIN_4 )--> drv_gpio.c pin */
char pin_index = strtol(&pin_name[3],0,10);
if(pin_name[1] < 'A' || pin_name[1] > 'Z')
{
return -1;
}
return (16 * (pin_name[1]-'A') + pin_index);
}
#endif
#endif /* LORA_RADIO_GPIO_SETUP_BY_PIN_NAME */
void SX127xIoInit( void )
{
#ifdef LORA_RADIO_DRIVER_USING_ON_RTOS_RT_THREAD
rt_pin_mode(LORA_RADIO_NSS_PIN, PIN_MODE_OUTPUT);
rt_pin_mode(LORA_RADIO_DIO0_PIN, PIN_MODE_INPUT_PULLDOWN);
rt_pin_mode(LORA_RADIO_DIO1_PIN, PIN_MODE_INPUT_PULLDOWN);
rt_pin_mode(LORA_RADIO_DIO2_PIN, PIN_MODE_INPUT_PULLDOWN);
#else
// GpioInit( &SX127x.Spi.Nss, RADIO_NSS, PIN_OUTPUT, PIN_PUSH_PULL, PIN_PULL_UP, 1 );
// GpioInit( &SX127x.DIO0, RADIO_DIO_0, PIN_INPUT, PIN_PUSH_PULL, PIN_PULL_UP, 0 );
// GpioInit( &SX127x.DIO1, RADIO_DIO_1, PIN_INPUT, PIN_PUSH_PULL, PIN_PULL_UP, 0 );
// GpioInit( &SX127x.DIO2, RADIO_DIO_2, PIN_INPUT, PIN_PUSH_PULL, PIN_PULL_UP, 0 );
// GpioInit( &SX127x.DIO3, RADIO_DIO_3, PIN_INPUT, PIN_PUSH_PULL, PIN_PULL_UP, 0 );
// GpioInit( &SX127x.DIO4, RADIO_DIO_4, PIN_INPUT, PIN_PUSH_PULL, PIN_PULL_UP, 0 );
// GpioInit( &SX127x.DIO5, RADIO_DIO_5, PIN_INPUT, PIN_PUSH_PULL, PIN_PULL_UP, 0 );
#endif
}
void SX127xIoIrqInit( DioIrqHandler **irqHandlers )
{
#ifdef LORA_RADIO_DRIVER_USING_ON_RTOS_RT_THREAD
#ifdef LORA_RADIO_DIO0_PIN
rt_pin_attach_irq(LORA_RADIO_DIO0_PIN, PIN_IRQ_MODE_RISING,SX127xOnDio0IrqEvent,(void*)"rf-dio0");
rt_pin_irq_enable(LORA_RADIO_DIO0_PIN, PIN_IRQ_ENABLE);
#endif
#ifdef LORA_RADIO_DIO1_PIN
rt_pin_attach_irq(LORA_RADIO_DIO1_PIN, PIN_IRQ_MODE_RISING,SX127xOnDio1IrqEvent,(void*)"rf-dio1");
rt_pin_irq_enable(LORA_RADIO_DIO1_PIN, PIN_IRQ_ENABLE);
#endif
#ifdef LORA_RADIO_DIO2_PIN
rt_pin_attach_irq(LORA_RADIO_DIO2_PIN, PIN_IRQ_MODE_RISING,SX127xOnDio2IrqEvent,(void*)"rf-dio2");
rt_pin_irq_enable(LORA_RADIO_DIO2_PIN, PIN_IRQ_ENABLE);
#endif
#else
#ifdef LORA_RADIO_DIO0_PIN
rt_pin_attach_irq(LORA_RADIO_DIO0_PIN, PIN_IRQ_MODE_RISING,irqHandlers[0],(void*)"rf-dio0");
rt_pin_irq_enable(LORA_RADIO_DIO0_PIN, PIN_IRQ_ENABLE);
#endif
#ifdef LORA_RADIO_DIO1_PIN
rt_pin_attach_irq(LORA_RADIO_DIO1_PIN, PIN_IRQ_MODE_RISING,irqHandlers[1],(void*)"rf-dio1");
rt_pin_irq_enable(LORA_RADIO_DIO1_PIN, PIN_IRQ_ENABLE);
#endif
#ifdef LORA_RADIO_DIO2_PIN
rt_pin_attach_irq(LORA_RADIO_DIO2_PIN, PIN_IRQ_MODE_RISING,irqHandlers[2],(void*)"rf-dio2");
rt_pin_irq_enable(LORA_RADIO_DIO2_PIN, PIN_IRQ_ENABLE);
#endif
// GpioSetInterrupt( &SX127x.DIO0, IRQ_RISING_EDGE, IRQ_HIGH_PRIORITY, irqHandlers[0] );
// GpioSetInterrupt( &SX127x.DIO1, IRQ_RISING_EDGE, IRQ_HIGH_PRIORITY, irqHandlers[1] );
// GpioSetInterrupt( &SX127x.DIO2, IRQ_RISING_EDGE, IRQ_HIGH_PRIORITY, irqHandlers[2] );
// GpioSetInterrupt( &SX127x.DIO3, IRQ_RISING_EDGE, IRQ_HIGH_PRIORITY, irqHandlers[3] );
// GpioSetInterrupt( &SX127x.DIO4, IRQ_RISING_EDGE, IRQ_HIGH_PRIORITY, irqHandlers[4] );
// GpioSetInterrupt( &SX127x.DIO5, IRQ_RISING_EDGE, IRQ_HIGH_PRIORITY, irqHandlers[5] );
#endif /*end of USING_LORA_RADIO_DRIVER_RTOS_SUPPORT */
}
void SX127xIoDeInit( void )
{
#ifdef LORA_RADIO_DRIVER_USING_ON_RTOS_RT_THREAD
// rt_pin_mode(LORA_RADIO_DIO0_PIN, PIN_MODE_INPUT);
// rt_pin_mode(LORA_RADIO_DIO1_PIN, PIN_MODE_INPUT);
// rt_pin_mode(LORA_RADIO_DIO2_PIN, PIN_MODE_INPUT);
#else
// GpioInit( &SX127x.Spi.Nss, RADIO_NSS, PIN_OUTPUT, PIN_PUSH_PULL, PIN_NO_PULL, 1 );
// GpioInit( &SX127x.DIO0, RADIO_DIO_0, PIN_INPUT, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
// GpioInit( &SX127x.DIO1, RADIO_DIO_1, PIN_INPUT, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
// GpioInit( &SX127x.DIO2, RADIO_DIO_2, PIN_INPUT, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
// GpioInit( &SX127x.DIO3, RADIO_DIO_3, PIN_INPUT, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
// GpioInit( &SX127x.DIO4, RADIO_DIO_4, PIN_INPUT, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
// GpioInit( &SX127x.DIO5, RADIO_DIO_5, PIN_INPUT, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
#endif /*end of USING_LORA_RADIO_DRIVER_RTOS_SUPPORT */
SX127xAntSwDeInit();
}
void SX127xIoDbgInit( void )
{
#if defined( USE_RADIO_DEBUG )
GpioInit( &DbgPinTx, RADIO_DBG_PIN_TX, PIN_OUTPUT, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
GpioInit( &DbgPinRx, RADIO_DBG_PIN_RX, PIN_OUTPUT, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
#endif
}
void SX127xReset( void )
{
// Set RESET pin to 0
rt_pin_mode(LORA_RADIO_RESET_PIN, PIN_MODE_OUTPUT);
rt_pin_write(LORA_RADIO_RESET_PIN, PIN_LOW);
// Wait 1 ms
SX127X_DELAY_MS( 1 );
// Configure RESET as input
rt_pin_mode(LORA_RADIO_RESET_PIN, PIN_MODE_INPUT);
// Wait 6 ms
SX127X_DELAY_MS( 6 );
}
void SX127xSetAntSwLowPower( bool status )
{
if( RadioIsActive != status )
{
RadioIsActive = status;
if( status == false )
{
SX127xAntSwInit( );
}
else
{
SX127xAntSwDeInit( );
}
}
}
void SX127xAntSwInit( void )
{
//// GpioInit( &AntSwitchRx, RADIO_ANT_SWITCH_RX, PIN_OUTPUT, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
//// GpioInit( &AntSwitchTxBoost, RADIO_ANT_SWITCH_TX_BOOST, PIN_OUTPUT, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
//// GpioInit( &AntSwitchTxRfo, RADIO_ANT_SWITCH_TX_RFO, PIN_OUTPUT, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
rt_pin_mode(LORA_RADIO_RFSW1_PIN, PIN_MODE_OUTPUT);
rt_pin_mode(LORA_RADIO_RFSW2_PIN, PIN_MODE_OUTPUT);
rt_pin_write(LORA_RADIO_RFSW1_PIN, PIN_LOW);
rt_pin_write(LORA_RADIO_RFSW2_PIN, PIN_LOW);
}
void SX127xAntSwDeInit( void )
{
//// GpioInit( &AntSwitchRx, RADIO_ANT_SWITCH_RX, PIN_ANALOGIC, PIN_OPEN_DRAIN, PIN_NO_PULL, 0 );
//// GpioInit( &AntSwitchTxBoost, RADIO_ANT_SWITCH_TX_BOOST, PIN_ANALOGIC, PIN_OPEN_DRAIN, PIN_NO_PULL, 0 );
//// GpioInit( &AntSwitchTxRfo, RADIO_ANT_SWITCH_TX_RFO, PIN_ANALOGIC, PIN_OPEN_DRAIN, PIN_NO_PULL, 0 );
rt_pin_write(LORA_RADIO_RFSW1_PIN, PIN_LOW);
rt_pin_write(LORA_RADIO_RFSW2_PIN, PIN_LOW);
}
/* TX/RX ANT Swich */
void SX127xSetAntSw( uint8_t opMode )
{
uint8_t paConfig = SX127xRead( REG_PACONFIG );
switch( opMode )
{
case RFLR_OPMODE_TRANSMITTER:
if( ( paConfig & RF_PACONFIG_PASELECT_PABOOST ) == RF_PACONFIG_PASELECT_PABOOST )
{
///GpioWrite( &AntSwitchTxBoost, 1 );
rt_pin_write(LORA_RADIO_RFSW1_PIN, PIN_HIGH);
rt_pin_write(LORA_RADIO_RFSW2_PIN, PIN_LOW);
}
break;
case RFLR_OPMODE_RECEIVER:
case RFLR_OPMODE_RECEIVER_SINGLE:
case RFLR_OPMODE_CAD:
default:
////GpioWrite( &AntSwitchRx, 1 );
rt_pin_write(LORA_RADIO_RFSW1_PIN, PIN_LOW);
rt_pin_write(LORA_RADIO_RFSW2_PIN, PIN_HIGH);
break;
}
}
#if defined( USE_RADIO_DEBUG )
void SX127xDbgPinTxWrite( uint8_t state )
{
GpioWrite( &DbgPinTx, state );
}
void SX127xDbgPinRxWrite( uint8_t state )
{
GpioWrite( &DbgPinRx, state );
}
#endif
uint8_t SX127xGetPaSelect( int8_t power )
{
return RF_PACONFIG_PASELECT_PABOOST;
}
bool SX127xCheckRfFrequency( uint32_t frequency )
{
// Implement check. Currently all frequencies are supported,todo depend on board
return true;
}

View File

@ -0,0 +1,225 @@
/*!
* \file sx1278-board.c
*
* \brief Target board SX127x driver implementation
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
* ______ _
* / _____) _ | |
* ( (____ _____ ____ _| |_ _____ ____| |__
* \____ \| ___ | (_ _) ___ |/ ___) _ \
* _____) ) ____| | | || |_| ____( (___| | | |
* (______/|_____)_|_|_| \__)_____)\____)_| |_|
* (C)2013-2017 Semtech
*
* \endcode
*
* \author Miguel Luis ( Semtech )
*
* \author Gregory Cristian ( Semtech )
*
* \author Forest-Rain
*/
#include "lora-radio-rtos-config.h"
#include "lora-radio.h"
#include "sx127x.h"
#include "sx127x-board.h"
#define LOG_TAG "LoRa.Board.Ra-01(SX1278)"
#define LOG_LEVEL LOG_LVL_DBG
#include "lora-radio-debug.h"
/*!
* Flag used to set the RF switch control pins in low power mode when the radio is not active.
*/
static bool RadioIsActive = false;
#ifdef LORA_RADIO_DRIVER_USING_ON_RTOS_RT_THREAD
/*!
* \brief DIO 0 IRQ callback
*/
void SX127xOnDio0IrqEvent( void *args );
/*!
* \brief DIO 1 IRQ callback
*/
void SX127xOnDio1IrqEvent( void *args );
/*!
* \brief DIO 2 IRQ callback
*/
void SX127xOnDio2IrqEvent( void *args );
/*!
* \brief DIO 3 IRQ callback
*/
void SX127xOnDio3IrqEvent( void *args );
/*!
* \brief DIO 4 IRQ callback
*/
void SX127xOnDio4IrqEvent( void *args );
/*!
* \brief DIO 5 IRQ callback
*/
void SX127xOnDio5IrqEvent( void *args );
#endif
/*!
* Debug GPIO pins objects
*/
#if defined( USE_RADIO_DEBUG )
Gpio_t DbgPinTx;
Gpio_t DbgPinRx;
#endif
#ifdef LORA_RADIO_GPIO_SETUP_BY_PIN_NAME
#if ( RT_VER_NUM <= 0x40004 )
int stm32_pin_get(char *pin_name)
{
/* eg: pin_name : "PA.4" ( GPIOA, GPIO_PIN_4 )--> drv_gpio.c pin */
char pin_index = strtol(&pin_name[3],0,10);
if(pin_name[1] < 'A' || pin_name[1] > 'Z')
{
return -1;
}
return (16 * (pin_name[1]-'A') + pin_index);
}
#endif
#endif /* LORA_RADIO_GPIO_SETUP_BY_PIN_NAME */
void SX127xIoInit( void )
{
#ifdef LORA_RADIO_DRIVER_USING_ON_RTOS_RT_THREAD
// RT-Thread
rt_pin_mode(LORA_RADIO_NSS_PIN, PIN_MODE_OUTPUT);
rt_pin_mode(LORA_RADIO_DIO0_PIN, PIN_MODE_INPUT_PULLDOWN);
#ifdef LORA_RADIO_DIO1_PIN
rt_pin_mode(LORA_RADIO_DIO1_PIN, PIN_MODE_INPUT_PULLDOWN);
#endif
#ifdef LORA_RADIO_DIO2_PIN
rt_pin_mode(LORA_RADIO_DIO2_PIN, PIN_MODE_INPUT_PULLDOWN);
#endif
#else
#endif
}
void SX127xIoIrqInit( DioIrqHandler **irqHandlers )
{
#ifdef LORA_RADIO_DRIVER_USING_ON_RTOS_RT_THREAD
#ifdef LORA_RADIO_DIO0_PIN
rt_pin_attach_irq(LORA_RADIO_DIO0_PIN, PIN_IRQ_MODE_RISING,SX127xOnDio0IrqEvent,(void*)"rf-dio0");
rt_pin_irq_enable(LORA_RADIO_DIO0_PIN, PIN_IRQ_ENABLE);
#endif
#ifdef LORA_RADIO_DIO1_PIN
rt_pin_attach_irq(LORA_RADIO_DIO1_PIN, PIN_IRQ_MODE_RISING,SX127xOnDio1IrqEvent,(void*)"rf-dio1");
rt_pin_irq_enable(LORA_RADIO_DIO1_PIN, PIN_IRQ_ENABLE);
#endif
#ifdef LORA_RADIO_DIO2_PIN
rt_pin_attach_irq(LORA_RADIO_DIO2_PIN, PIN_IRQ_MODE_RISING,SX127xOnDio2IrqEvent,(void*)"rf-dio2");
rt_pin_irq_enable(LORA_RADIO_DIO2_PIN, PIN_IRQ_ENABLE);
#endif
#else
#ifdef LORA_RADIO_DIO0_PIN
rt_pin_attach_irq(LORA_RADIO_DIO0_PIN, PIN_IRQ_MODE_RISING,irqHandlers[0],(void*)"rf-dio0");
rt_pin_irq_enable(LORA_RADIO_DIO0_PIN, PIN_IRQ_ENABLE);
#endif
#ifdef LORA_RADIO_DIO1_PIN
rt_pin_attach_irq(LORA_RADIO_DIO1_PIN, PIN_IRQ_MODE_RISING,irqHandlers[1],(void*)"rf-dio1");
rt_pin_irq_enable(LORA_RADIO_DIO1_PIN, PIN_IRQ_ENABLE);
#endif
#ifdef LORA_RADIO_DIO2_PIN
rt_pin_attach_irq(LORA_RADIO_DIO2_PIN, PIN_IRQ_MODE_RISING,irqHandlers[2],(void*)"rf-dio2");
rt_pin_irq_enable(LORA_RADIO_DIO2_PIN, PIN_IRQ_ENABLE);
#endif
#endif
}
void SX127xIoDeInit( void )
{
}
void SX127xIoDbgInit( void )
{
}
void SX127xReset( void )
{
// Set RESET pin to 0
rt_pin_mode(LORA_RADIO_RESET_PIN, PIN_MODE_OUTPUT);
rt_pin_write(LORA_RADIO_RESET_PIN, PIN_LOW);
// Wait 1 ms
SX127X_DELAY_MS( 1 );
// Configure RESET as input
rt_pin_mode(LORA_RADIO_RESET_PIN, PIN_MODE_INPUT);
// Wait 6 ms
SX127X_DELAY_MS( 6 );
}
void SX127xSetAntSwLowPower( bool status )
{
if( RadioIsActive != status )
{
RadioIsActive = status;
if( status == false )
{
SX127xAntSwInit( );
}
else
{
SX127xAntSwDeInit( );
}
}
}
void SX127xAntSwInit( void )
{
}
void SX127xAntSwDeInit( void )
{
}
/* TX and RX ANT switch */
void SX127xSetAntSw( uint8_t opMode )
{
}
#if defined( USE_RADIO_DEBUG )
void SX127xDbgPinTxWrite( uint8_t state )
{
GpioWrite( &DbgPinTx, state );
}
void SX127xDbgPinRxWrite( uint8_t state )
{
GpioWrite( &DbgPinRx, state );
}
#endif
uint8_t SX127xGetPaSelect( int8_t power )
{
return RF_PACONFIG_PASELECT_PABOOST;
}
bool SX127xCheckRfFrequency( uint32_t frequency )
{
// Implement check. Currently all frequencies are supported,todo depend on board
return true;
}

View File

@ -0,0 +1,100 @@
/*!
* \file lora-spi-board.c
*
* \brief spi peripheral initlize,it depend on mcu platform.
*
* SPDX-License-Identifier: Apache-2.0
*
* \author Forest-Rain
*/
#include "lora-radio-rtos-config.h"
#ifdef LORA_RADIO_DRIVER_USING_LORA_CHIP_SX126X
#include "sx126x-board.h"
#elif defined LORA_RADIO_DRIVER_USING_LORA_CHIP_SX127X
#include "sx127x-board.h"
#endif
#define LOG_TAG "LoRa.STM32.SPI"
#define LOG_LEVEL LOG_LVL_DBG
#include "lora-radio-debug.h"
/* for get GPIO fort,eg GPIOA */
#ifndef GET_GPIO_PORT
#define GET_GPIO_PORT(pin) (GPIO_TypeDef *)( GPIOA_BASE + (uint32_t) ( pin >> 4 ) * 0x0400UL )
#endif
#ifndef GET_GPIO_PIN
#define GET_GPIO_PIN(pin) (rt_uint16_t)( 1 << ( pin & 0x0F ) ) // for get GPIO_PIN, eg: GPIO_PIN_6
#endif
#ifdef LORA_RADIO_GPIO_SETUP_BY_PIN_NAME
#if ( RT_VER_NUM <= 0x40002 )
extern int stm32_pin_get(char *pin_name);
#endif
#endif
struct rt_spi_device *lora_radio_spi_init(const char *bus_name, const char *lora_device_name, rt_uint8_t param)
{
rt_err_t res;
struct rt_spi_device *lora_radio_spi_device;
RT_ASSERT(bus_name);
{
res = rt_hw_spi_device_attach( bus_name, lora_device_name, LORA_RADIO_NSS_PIN);
if (res != RT_EOK)
{
LORA_RADIO_DEBUG_LOG(LR_DBG_SPI, LOG_LEVEL,"rt_spi_bus_attach_device failed!\r\n");
return RT_NULL;
}
lora_radio_spi_device = (struct rt_spi_device *)rt_device_find(lora_device_name);
if (!lora_radio_spi_device)
{
LORA_RADIO_DEBUG_LOG(LR_DBG_SPI, LOG_LEVEL,"spi sample run failed! cant't find %s device!\n", lora_device_name);
return RT_NULL;
}
}
LORA_RADIO_DEBUG_LOG(LR_DBG_SPI, LOG_LEVEL,"find %s device!\n", lora_device_name);
/* config spi */
{
struct rt_spi_configuration cfg;
cfg.data_width = 8;
cfg.mode = RT_SPI_MASTER | RT_SPI_MODE_0 | RT_SPI_MSB; /* SPI Compatible: Mode 0. */
cfg.max_hz = 8 * 1000000; /* max 10M */
res = rt_spi_configure(lora_radio_spi_device, &cfg);
if (res != RT_EOK)
{
LORA_RADIO_DEBUG_LOG(LR_DBG_SPI, LOG_LEVEL,"rt_spi_configure failed!\r\n");
}
res = rt_spi_take_bus(lora_radio_spi_device);
if (res != RT_EOK)
{
LORA_RADIO_DEBUG_LOG(LR_DBG_SPI, LOG_LEVEL,"rt_spi_take_bus failed!\r\n");
}
res = rt_spi_release_bus(lora_radio_spi_device);
if(res != RT_EOK)
{
LORA_RADIO_DEBUG_LOG(LR_DBG_SPI, LOG_LEVEL,"rt_spi_release_bus failed!\r\n");
}
}
return lora_radio_spi_device;
}
/**
* This function releases memory
*
* @param dev the pointer of device driver structure
*/
void lora_radio_spi_deinit(struct rt_spi_device *dev)
{
RT_ASSERT(dev);
rt_spi_release_bus(dev);
}

View File

@ -0,0 +1,3 @@
SRC_DIR := lora-radio-tester
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,14 @@
from building import *
src = []
cwd = GetCurrentDir()
include_path = [cwd]
if GetDepend('LORA_RADIO_DRIVER_USING_LORA_RADIO_TESTER'):
src += Glob('lora-radio-tester/lora-radio-tester.c')
group = DefineGroup('lora-radio-driver/sample', src, depend = ['PKG_USING_LORA_RADIO_DRIVER'], CPPPATH = include_path)
Return('group')

View File

@ -0,0 +1,3 @@
SRC_FILES := lora-radio-tester.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,158 @@
/*!
* \file lora-radio-tester.h
*
* \brief lora radio test implementation
*
* \copyright SPDX-License-Identifier: Apache-2.0
*
* \author Forest-Rain
*/
#ifndef __LORA_RADIO_TESTER_H__
#define __LORA_RADIO_TESTER_H__
#include <lora-radio-rtos-config.h>
/* application debug */
#ifndef LR_DBG_SHELL
#define LR_DBG_SHELL 1
#endif
#define PHY_REGION_EU433
#if defined( PHY_REGION_AS923 )
#define RF_FREQUENCY 923000000 // Hz
#elif defined( PHY_REGION_AU915 )
#define RF_FREQUENCY 915000000 // Hz
#elif defined( PHY_REGION_CN470 ) || defined ( PHY_REGION_CN470S )
#define RF_FREQUENCY 470300000 // Hz
#elif defined( PHY_REGION_CN779 )
#define RF_FREQUENCY 779000000 // Hz
#elif defined( PHY_REGION_EU433 )
#define RF_FREQUENCY 433000000 // Hz
#elif defined( PHY_REGION_EU868 )
#define RF_FREQUENCY 868000000 // Hz
#elif defined( PHY_REGION_KR920 )
#define RF_FREQUENCY 920000000 // Hz
#elif defined( PHY_REGION_IN865 )
#define RF_FREQUENCY 865000000 // Hz
#elif defined( PHY_REGION_US915 )
#define RF_FREQUENCY 915000000 // Hz
#elif defined( PHY_REGION_RU864 )
#define RF_FREQUENCY 864000000 // Hz
#else
#error "Please define a frequency band in the compiler options."
#endif
#define TX_RX_FREQUENCE_OFFSET 0 // 0 TX = RX
// 1800000 RX = TX+1.8M
#define TX_OUTPUT_POWER 20//14 // dBm
#define LORA_BANDWIDTH 2 // [0: 125 kHz,
// 1: 250 kHz,
// 2: 500 kHz,
// 3: Reserved]
#define LORA_SPREADING_FACTOR 12 // [SF7..SF12]
#define LORA_CODINGRATE 2 // [1: 4/5,
// 2: 4/6,
// 3: 4/7,
// 4: 4/8]
#define LORA_PREAMBLE_LENGTH 8 // Same for Tx and Rx
#define LORA_SYMBOL_TIMEOUT 0 // Symbols
#define LORA_FIX_LENGTH_PAYLOAD_ON_DISABLE false
#define LORA_IQ_INVERSION_ON_DISABLE false
#define FSK_FDEV 25000 // Hz
#define FSK_DATARATE 50000 // bps
#if defined( LORA_RADIO_DRIVER_USING_LORA_CHIP_SX127X )
#define FSK_BANDWIDTH 50000 // Hz >> SSB in sx127x
#define FSK_AFC_BANDWIDTH 83333 // Hz
#elif defined( LORA_RADIO_DRIVER_USING_LORA_CHIP_SX126X) || defined( LORA_RADIO_DRIVER_USING_LORA_CHIP_LLCC68 )
#define FSK_BANDWIDTH 100000 // Hz >> DSB in sx126x
#define FSK_AFC_BANDWIDTH 166666 // Hz >> Unused in sx126x
#elif defined( LORA_RADIO_DRIVER_USING_LORA_SOC_STM32WL )
#define FSK_BANDWIDTH 100000 // Hz >> DSB in sx126x
#define FSK_AFC_BANDWIDTH 166666 // Hz >> Unused in sx126x
#elif defined( LORA_RADIO_DRIVER_USING_LORA_CHIP_SX128X )
#define FSK_BANDWIDTH 100000 // Hz >> DSB in sx126x
#define FSK_AFC_BANDWIDTH 166666 // Hz >> Unused in sx126x
#else
#error "Please define a lora-shield in the compiler options."
#endif
#define FSK_PREAMBLE_LENGTH 5 // Same for Tx and Rx
#define FSK_FIX_LENGTH_PAYLOAD_ON false
#define TX_TIMEOUT_VALUE 1000
#define RX_TIMEOUT_VALUE 1000
#define BUFFER_SIZE 256 // Define the payload size here
#define MIN_TETS_APP_DATA_SIZE 17 // for PING protocol
#define LORA_MASTER_DEVADDR 0x11223344
#define LORA_SLAVER_DEVADDR 0x01020304
#define MAC_HEADER_OVERHEAD 13
// Ping pong event
#define EV_RADIO_INIT 0x0001
#define EV_RADIO_TX_START 0x0002
#define EV_RADIO_TX_DONE 0x0004
#define EV_RADIO_TX_TIMEOUT 0x0008
#define EV_RADIO_RX_DONE 0x0010
#define EV_RADIO_RX_TIMEOUT 0x0020
#define EV_RADIO_RX_ERROR 0x0040
#define EV_RADIO_ALL (EV_RADIO_INIT | EV_RADIO_TX_START | EV_RADIO_TX_DONE | EV_RADIO_TX_TIMEOUT | EV_RADIO_RX_DONE | EV_RADIO_RX_TIMEOUT | EV_RADIO_RX_ERROR)
typedef struct
{
RadioModems_t modem; // LoRa Modem \ FSK modem
uint32_t tx_frequency;
uint32_t rx_frequency;
int32_t trx_frequency_offset;
int8_t txpower;
// LoRa
uint8_t sf; // spreadfactor
uint8_t bw; // bandwidth
uint8_t cr; // coderate
uint8_t iq_inversion;
bool public_network;
// FSK
uint32_t fdev;
uint32_t datarate;
uint32_t fsk_bandwidth;
uint32_t fsk_afc_bandwidth;
uint16_t preamble_len;
}lora_radio_test_t;
#endif

View File

@ -15,19 +15,27 @@ if BSP_USING_SPI
default "spi1_drv"
endif
config BSP_USING_SPI6
bool "Using spi6"
default n
config BSP_USING_SPI2
bool "Using spi2 for E22 LoRa"
default y
if BSP_USING_SPI6
config SPI_BUS_NAME_6
string "spi bus 6 name"
default "spi6"
config SPI_6_DEVICE_NAME_0
string "spi bus 6 device 0 name"
default "spi6_dev0"
config SPI_6_DRV_NAME
string "spi bus 6 driver name"
default "spi6_drv"
if BSP_USING_SPI2
config SPI_BUS_NAME_2
string "spi bus 2 name"
default "spi2"
config SPI_2_DEVICE_NAME_0
string "spi bus 2 device 0 name"
default "spi2_dev0"
config SPI_2_DRV_NAME
string "spi bus 2 driver name"
default "spi2_drv"
menuconfig RESOURCES_SPI_LORA
bool "Using spi lora function"
default n
if RESOURCES_SPI_LORA
config SX12XX_DEVICE_NAME
string "SX1276 lora device name"
default "spi2_lora"
endif
endif
endif

View File

@ -1,3 +1,8 @@
SRC_FILES := connect_spi.c
ifeq ($(CONFIG_RESOURCES_SPI_LORA),y)
SRC_DIR := third_party_spi_lora
SRC_FILES += connect_lora_spi.c
endif
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,457 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file connect_lora_spi.c
* @brief support to register spi lora pointer and function for xishutong-arm32
* @version 3.0
* @author AIIT XUOS Lab
* @date 2023-12-21
*/
#include <connect_spi_lora.h>
/* RST = PD02 */
#define LORA_RST_PORT (GPIO_PORT_D)
#define LORA_RST_PIN (GPIO_PIN_02)
static struct HardwareDev *g_spi_lora_dev;
static tRadioDriver *Radio = NONE;
void SX1276InitIo(void)
{
stc_gpio_init_t stcGpioInit;
(void)GPIO_StructInit(&stcGpioInit);
stcGpioInit.u16PinState = PIN_STAT_RST;
stcGpioInit.u16PinDir = PIN_DIR_OUT;
(void)GPIO_Init(LORA_RST_PORT, LORA_RST_PIN, &stcGpioInit);
}
inline void SX1276WriteRxTx(uint8_t txEnable)
{
if (txEnable != 0) {
/*to do*/
} else {
/*to do*/
}
}
void SX1276SetReset(uint8_t state)
{
if (state == RADIO_RESET_ON) {
GPIO_ResetPins(LORA_RST_PORT, LORA_RST_PIN);
} else {
stc_gpio_init_t stcGpioInit;
(void)GPIO_StructInit(&stcGpioInit);
stcGpioInit.u16PinDir = PIN_DIR_IN;
(void)GPIO_Init(LORA_RST_PORT, LORA_RST_PIN, &stcGpioInit);
}
}
//Not-necessary Function
uint8_t SX1276ReadDio0(void)
{
return 1;
}
uint8_t SX1276ReadDio1(void)
{
return 1;
}
uint8_t SX1276ReadDio2(void)
{
return 1;
}
uint8_t SX1276ReadDio3(void)
{
return 1;
}
uint8_t SX1276ReadDio4(void)
{
return 1;
}
uint8_t SX1276ReadDio5(void)
{
return 1;
}
void SX1276WriteBuffer(uint8_t addr, uint8_t *buffer, uint8_t size)
{
struct BusBlockWriteParam write_param;
uint8 write_addr = addr | 0x80;
BusDevOpen(g_spi_lora_dev);
write_param.buffer = (void *)&write_addr;
write_param.size = 1;
BusDevWriteData(g_spi_lora_dev, &write_param);
write_param.buffer = (void *)buffer;
write_param.size = size;
BusDevWriteData(g_spi_lora_dev, &write_param);
BusDevClose(g_spi_lora_dev);
}
void SX1276ReadBuffer(uint8_t addr, uint8_t *buffer, uint8_t size)
{
struct BusBlockWriteParam write_param;
struct BusBlockReadParam read_param;
uint8 write_addr = addr & 0x7F;
BusDevOpen(g_spi_lora_dev);
write_param.buffer = (void *)&write_addr;
write_param.size = 1;
BusDevWriteData(g_spi_lora_dev, &write_param);
read_param.buffer = (void *)buffer;
read_param.size = size;
BusDevReadData(g_spi_lora_dev, &read_param);
BusDevClose(g_spi_lora_dev);
}
void SX1276WriteFifo(uint8_t *buffer, uint8_t size)
{
SX1276WriteBuffer(0, buffer, size);
}
void SX1276ReadFifo(uint8_t *buffer, uint8_t size)
{
SX1276ReadBuffer(0, buffer, size);
}
void SX1276Write(uint8_t addr, uint8_t data)
{
SX1276WriteBuffer(addr, &data, 1);
}
void SX1276Read(uint8_t addr, uint8_t *data)
{
SX1276ReadBuffer(addr, data, 1);
}
uint8_t Sx1276SpiCheck(void)
{
uint8_t test = 0;
tLoRaSettings settings;
SX1276Read(REG_LR_VERSION, &test);
KPrintf("version code of the chip is 0x%x\n", test);
settings.RFFrequency = SX1276LoRaGetRFFrequency();
KPrintf("SX1278 Lora parameters are :\nRFFrequency is %d\n", settings.RFFrequency);
settings.Power = SX1276LoRaGetRFPower();
KPrintf("RFPower is %d\n",settings.Power);
settings.SignalBw = SX1276LoRaGetSignalBandwidth();
KPrintf("SignalBw is %d\n",settings.SignalBw);
settings.SpreadingFactor = SX1276LoRaGetSpreadingFactor();
KPrintf("SpreadingFactor is %d\n",settings.SpreadingFactor);
/*SPI confirm*/
SX1276Write(REG_LR_HOPPERIOD, 0x91);
SX1276Read(REG_LR_HOPPERIOD, &test);
if (test != 0x91) {
return 0;
}
return test;
}
/**
* This function supports to write data to the lora.
*
* @param dev lora dev descriptor
* @param write_param lora dev write datacfg param
*/
static uint32 SpiLoraWrite(void *dev, struct BusBlockWriteParam *write_param)
{
NULL_PARAM_CHECK(dev);
NULL_PARAM_CHECK(write_param);
if (write_param->size > 256) {
KPrintf("SpiLoraWrite ERROR:The message is too long!\n");
return ERROR;
} else {
SX1276SetTx(write_param->buffer, write_param->size);
KPrintf("SpiLoraWrite success!\n");
}
return EOK;
}
/**
* This function supports to read data from the lora.
*
* @param dev lora dev descriptor
* @param read_param lora dev read datacfg param
*/
static uint32 SpiLoraRead(void *dev, struct BusBlockReadParam *read_param)
{
NULL_PARAM_CHECK(dev);
NULL_PARAM_CHECK(read_param);
KPrintf("SpiLoraRead Ready!\n");
int ret = SX1276GetRx(read_param->buffer, (uint16 *)&read_param->read_length);
if (ret < 0) {
return 0;
}
return read_param->read_length;
}
static uint32 SpiLoraOpen(void *dev)
{
NULL_PARAM_CHECK(dev);
KPrintf("SpiLoraOpen start\n");
x_err_t ret = EOK;
static x_bool lora_init_status = RET_FALSE;
if (RET_TRUE == lora_init_status) {
return EOK;
}
struct HardwareDev *haldev = (struct HardwareDev *)dev;
struct SpiHardwareDevice *lora_dev = CONTAINER_OF(haldev, struct SpiHardwareDevice, haldev);
NULL_PARAM_CHECK(lora_dev);
SpiLoraDeviceType spi_lora_dev = CONTAINER_OF(lora_dev, struct SpiLoraDevice, lora_dev);
NULL_PARAM_CHECK(spi_lora_dev);
struct Driver *spi_drv = spi_lora_dev->spi_dev->haldev.owner_bus->owner_driver;
struct BusConfigureInfo configure_info;
struct SpiMasterParam spi_master_param;
spi_master_param.spi_data_bit_width = 8;
spi_master_param.spi_work_mode = SPI_MODE_0 | SPI_MSB;
configure_info.configure_cmd = OPE_CFG;
configure_info.private_data = (void *)&spi_master_param;
ret = BusDrvConfigure(spi_drv, &configure_info);
if (ret) {
KPrintf("spi drv OPE_CFG error drv %8p cfg %8p\n", spi_drv, &spi_master_param);
return ERROR;
}
configure_info.configure_cmd = OPE_INT;
ret = BusDrvConfigure(spi_drv, &configure_info);
if (ret) {
KPrintf("spi drv OPE_INT error drv %8p\n", spi_drv);
return ERROR;
}
SX1276Init();
if (0x91 != Sx1276SpiCheck()) {
KPrintf("LoRa check failed!\n!");
} else {
Radio = RadioDriverInit();
KPrintf("LoRa check ok!\nNote: The length of the message that can be sent in a single time is 256 characters\n");
}
lora_init_status = RET_TRUE;
return ret;
}
static uint32 SpiLoraClose(void *dev)
{
NULL_PARAM_CHECK(dev);
return EOK;
}
static const struct LoraDevDone lora_done =
{
.open = SpiLoraOpen,
.close = SpiLoraClose,
.write = SpiLoraWrite,
.read = SpiLoraRead,
};
/**
* This function supports to init spi_lora_dev
*
* @param bus_name spi bus name
* @param dev_name spi dev name
* @param drv_name spi drv name
* @param lora_name lora dev name
*/
SpiLoraDeviceType SpiLoraInit(char *bus_name, char *dev_name, char *drv_name, char *lora_name)
{
NULL_PARAM_CHECK(dev_name);
NULL_PARAM_CHECK(drv_name);
NULL_PARAM_CHECK(lora_name);
NULL_PARAM_CHECK(bus_name);
x_err_t ret;
static HardwareDevType haldev;
haldev = SpiDeviceFind(dev_name, TYPE_SPI_DEV);
if (NONE == haldev) {
KPrintf("SpiLoraInit find spi haldev %s error! \n", dev_name);
return NONE;
}
SpiLoraDeviceType spi_lora_dev = (SpiLoraDeviceType)malloc(sizeof(struct SpiLoraDevice));
if (NONE == spi_lora_dev) {
KPrintf("SpiLoraInit malloc spi_lora_dev failed\n");
free(spi_lora_dev);
return NONE;
}
memset(spi_lora_dev, 0, sizeof(struct SpiLoraDevice));
spi_lora_dev->spi_dev = CONTAINER_OF(haldev, struct SpiHardwareDevice, haldev);
spi_lora_dev->lora_dev.spi_dev_flag = RET_TRUE;
spi_lora_dev->lora_dev.haldev.dev_done = (struct HalDevDone *)&lora_done;
struct Driver *spi_driver = SpiDriverFind(drv_name, TYPE_SPI_DRV);
if (NONE == spi_driver) {
KPrintf("SpiLoraInit find spi driver %s error! \n", drv_name);
free(spi_lora_dev);
return NONE;
}
//spi drv get spi dev param (SpiDeviceParam)
spi_driver->private_data = spi_lora_dev->spi_dev->haldev.private_data;
spi_lora_dev->spi_dev->haldev.owner_bus->owner_driver = spi_driver;
ret = SpiDeviceRegister(&spi_lora_dev->lora_dev, spi_lora_dev->spi_dev->haldev.private_data, lora_name);
if (EOK != ret) {
KPrintf("SpiLoraInit SpiDeviceRegister device %s error %d\n", lora_name, ret);
free(spi_lora_dev);
return NONE;
}
ret = SpiDeviceAttachToBus(lora_name, bus_name);
if (EOK != ret) {
KPrintf("SpiLoraInit SpiDeviceAttachToBus device %s error %d\n", lora_name, ret);
free(spi_lora_dev);
return NONE;
}
g_spi_lora_dev = &spi_lora_dev->spi_dev->haldev;
return spi_lora_dev;
}
/**
* This function supports to release spi_lora_dev
*
* @param spi_lora_dev spi lora descriptor
*/
uint32 SpiLoraRelease(SpiLoraDeviceType spi_lora_dev)
{
NULL_PARAM_CHECK(spi_lora_dev);
x_err_t ret;
DeviceDeleteFromBus(spi_lora_dev->lora_dev.haldev.owner_bus, &spi_lora_dev->lora_dev.haldev);
free(spi_lora_dev);
return EOK;
}
int LoraSx12xxSpiDeviceInit(void)
{
#ifdef BSP_USING_SPI2
if (NONE == SpiLoraInit(SPI_BUS_NAME_2, SPI_2_DEVICE_NAME_0, SPI_2_DRV_NAME, SX12XX_DEVICE_NAME)) {
return ERROR;
}
#endif
return EOK;
}
#define LORA_TEST
#ifdef LORA_TEST
/*Just for lora test*/
static struct Bus *bus;
static struct HardwareDev *dev;
void LoraOpen(void)
{
x_err_t ret = EOK;
bus = BusFind(SPI_BUS_NAME_1);
dev = BusFindDevice(bus, SX12XX_DEVICE_NAME);
ret = SpiLoraOpen(dev);
if (EOK != ret) {
KPrintf("LoRa init failed\n");
return;
}
KPrintf("LoRa init succeed\n");
return;
}
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN),
LoraOpen, LoraOpen, open lora device and read parameters );
static void LoraReceive(void)
{
uint32 read_length = 0;
struct BusBlockReadParam read_param;
memset(&read_param, 0, sizeof(struct BusBlockReadParam));
read_param.buffer = malloc(SPI_LORA_BUFFER_SIZE);
read_length = SpiLoraRead(dev, &read_param);
KPrintf("LoraReceive length %d\n", read_length);
for (int i = 0; i < read_length; i ++) {
KPrintf("i %d data 0x%x\n", i, ((uint8 *)read_param.buffer)[i]);
}
free(read_param.buffer);
}
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_PARAM_NUM(0),
LoraReceive, LoraReceive, lora wait message );
static void LoraSend(int argc, char *argv[])
{
char Msg[SPI_LORA_BUFFER_SIZE] = {0};
struct BusBlockWriteParam write_param;
memset(&write_param, 0, sizeof(struct BusBlockWriteParam));
if (argc == 2) {
strncpy(Msg, argv[1], SPI_LORA_BUFFER_SIZE);
write_param.buffer = Msg;
write_param.size = strlen(Msg);
KPrintf("LoraSend data %s length %d\n", Msg, strlen(Msg));
SpiLoraWrite(dev, &write_param);
}
}
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN),
LoraSend, LoraSend, lora send message );
#endif

View File

@ -28,7 +28,7 @@ Author: AIIT XUOS Lab
Modification:
1. support xishutong-arm32-board spi configure, write and read
2. support xishutong-arm32-board spi bus device and driver register
3. SPI1 for W5500, SPI6 using J12-pin-header to connect
3. SPI1 for W5500, SPI2 using J12-pin-header to connect
*************************************************/
#include <connect_spi.h>
@ -36,48 +36,48 @@ Modification:
#define SPI1_MASTER_SLAVE_MODE (SPI_MASTER)
/* SPI1 definition */
#define SPI1_UNIT (CM_SPI1)
#define SPI1_CLK (FCG1_PERIPH_SPI1)
#define SPI1_UNIT (CM_SPI1)
#define SPI1_CLK (FCG1_PERIPH_SPI1)
/* CS = PG3 */
#define SPI1_SS_PORT (GPIO_PORT_G)
#define SPI1_SS_PIN (GPIO_PIN_03)
#define SPI1_SS_PORT (GPIO_PORT_G)
#define SPI1_SS_PIN (GPIO_PIN_03)
/* SCLK = PG5 */
#define SPI1_SCK_PORT (GPIO_PORT_G)
#define SPI1_SCK_PIN (GPIO_PIN_05)
#define SPI1_SCK_FUNC (GPIO_FUNC_40)
#define SPI1_SCK_PORT (GPIO_PORT_G)
#define SPI1_SCK_PIN (GPIO_PIN_05)
#define SPI1_SCK_FUNC (GPIO_FUNC_40)
/* MOSI = PG4 */
#define SPI1_MOSI_PORT (GPIO_PORT_G)
#define SPI1_MOSI_PIN (GPIO_PIN_04)
#define SPI1_MOSI_FUNC (GPIO_FUNC_41)
#define SPI1_MOSI_PORT (GPIO_PORT_G)
#define SPI1_MOSI_PIN (GPIO_PIN_04)
#define SPI1_MOSI_FUNC (GPIO_FUNC_41)
/* MISO = PG6 */
#define SPI1_MISO_PORT (GPIO_PORT_G)
#define SPI1_MISO_PIN (GPIO_PIN_06)
#define SPI1_MISO_FUNC (GPIO_FUNC_42)
#define SPI1_MISO_PORT (GPIO_PORT_G)
#define SPI1_MISO_PIN (GPIO_PIN_06)
#define SPI1_MISO_FUNC (GPIO_FUNC_42)
#define SPI1_DEVICE_SLAVE_ID_0 0
#define SPI1_DEVICE_SLAVE_ID_0 0
/* SPI6 definition */
#define SPI6_UNIT (CM_SPI6)
#define SPI6_CLK (FCG1_PERIPH_SPI6)
/* SPI2 definition */
#define SPI2_UNIT (CM_SPI2)
#define SPI2_CLK (FCG1_PERIPH_SPI2)
/* SS = PE02 */
#define SPI6_SS_PORT (GPIO_PORT_E)
#define SPI6_SS_PIN (GPIO_PIN_02)
/* SCK = PE03 */
#define SPI6_SCK_PORT (GPIO_PORT_E)
#define SPI6_SCK_PIN (GPIO_PIN_03)
#define SPI6_SCK_FUNC (GPIO_FUNC_46)
/* MOSI = PE04 */
#define SPI6_MOSI_PORT (GPIO_PORT_E)
#define SPI6_MOSI_PIN (GPIO_PIN_04)
#define SPI6_MOSI_FUNC (GPIO_FUNC_47)
/* MISO = PE05 */
#define SPI6_MISO_PORT (GPIO_PORT_E)
#define SPI6_MISO_PIN (GPIO_PIN_05)
#define SPI6_MISO_FUNC (GPIO_FUNC_48)
/* SS = PI01 */
#define SPI2_SS_PORT (GPIO_PORT_I)
#define SPI2_SS_PIN (GPIO_PIN_01)
/* SCK = PH14 */
#define SPI2_SCK_PORT (GPIO_PORT_H)
#define SPI2_SCK_PIN (GPIO_PIN_14)
#define SPI2_SCK_FUNC (GPIO_FUNC_43)
/* MOSI = PH15 */
#define SPI2_MOSI_PORT (GPIO_PORT_H)
#define SPI2_MOSI_PIN (GPIO_PIN_15)
#define SPI2_MOSI_FUNC (GPIO_FUNC_44)
/* MISO = PI0 */
#define SPI2_MISO_PORT (GPIO_PORT_I)
#define SPI2_MISO_PIN (GPIO_PIN_00)
#define SPI2_MISO_FUNC (GPIO_FUNC_45)
#define SPI6_DEVICE_SLAVE_ID_0 0
#define SPI2_DEVICE_SLAVE_ID_0 0
static void HwSpiEnable(CM_SPI_TypeDef* SPIx)
{
@ -148,20 +148,20 @@ static uint32 SpiSdkInit(struct SpiDriver* spi_drv)
SPI_Cmd(SPI1_UNIT, ENABLE);
#endif
#ifdef BSP_USING_SPI6
#ifdef BSP_USING_SPI2
/* Configure Port */
(void)GPIO_StructInit(&stcGpioInit);
stcGpioInit.u16PinState = PIN_STAT_RST;
stcGpioInit.u16PinDir = PIN_DIR_OUT;
(void)GPIO_Init(SPI6_SS_PORT, SPI6_SS_PIN, &stcGpioInit);
GPIO_SetPins(SPI6_SS_PORT, SPI6_SS_PIN);
(void)GPIO_Init(SPI2_SS_PORT, SPI2_SS_PIN, &stcGpioInit);
GPIO_SetPins(SPI2_SS_PORT, SPI2_SS_PIN);
GPIO_SetFunc(SPI6_SCK_PORT, SPI6_SCK_PIN, SPI6_SCK_FUNC);
GPIO_SetFunc(SPI6_MOSI_PORT, SPI6_MOSI_PIN, SPI6_MOSI_FUNC);
GPIO_SetFunc(SPI6_MISO_PORT, SPI6_MISO_PIN, SPI6_MISO_FUNC);
GPIO_SetFunc(SPI2_SCK_PORT, SPI2_SCK_PIN, SPI2_SCK_FUNC);
GPIO_SetFunc(SPI2_MOSI_PORT, SPI2_MOSI_PIN, SPI2_MOSI_FUNC);
GPIO_SetFunc(SPI2_MISO_PORT, SPI2_MISO_PIN, SPI2_MISO_FUNC);
/* Configuration SPI */
FCG_Fcg1PeriphClockCmd(SPI6_CLK, ENABLE);
FCG_Fcg1PeriphClockCmd(SPI2_CLK, ENABLE);
SPI_StructInit(&stcSpiInit);
stcSpiInit.u32WireMode = SPI_4_WIRE;
@ -195,8 +195,8 @@ static uint32 SpiSdkInit(struct SpiDriver* spi_drv)
stcSpiInit.u32FrameLevel = SPI_1_FRAME;
(void)SPI_Init(SPI6_UNIT, &stcSpiInit);
SPI_Cmd(SPI6_UNIT, ENABLE);
(void)SPI_Init(SPI2_UNIT, &stcSpiInit);
SPI_Cmd(SPI2_UNIT, ENABLE);
#endif
return EOK;
@ -414,30 +414,30 @@ static int BoardSpiDevBend(void)
}
#endif
#ifdef SPI_6_DEVICE_NAME_0
static struct SpiHardwareDevice spi6_device0;
memset(&spi6_device0, 0, sizeof(struct SpiHardwareDevice));
#ifdef SPI_2_DEVICE_NAME_0
static struct SpiHardwareDevice spi2_device0;
memset(&spi2_device0, 0, sizeof(struct SpiHardwareDevice));
static struct SpiSlaveParam spi6_slaveparam0;
memset(&spi6_slaveparam0, 0, sizeof(struct SpiSlaveParam));
static struct SpiSlaveParam spi2_slaveparam0;
memset(&spi2_slaveparam0, 0, sizeof(struct SpiSlaveParam));
spi6_slaveparam0.spi_slave_id = SPI1_DEVICE_SLAVE_ID_0;
spi6_slaveparam0.spi_cs_gpio_pin = SPI6_SS_PIN;
spi6_slaveparam0.spi_cs_gpio_port = SPI6_SS_PORT;
spi2_slaveparam0.spi_slave_id = SPI1_DEVICE_SLAVE_ID_0;
spi2_slaveparam0.spi_cs_gpio_pin = SPI2_SS_PIN;
spi2_slaveparam0.spi_cs_gpio_port = SPI2_SS_PORT;
spi6_device0.spi_param.spi_slave_param = &spi6_slaveparam0;
spi2_device0.spi_param.spi_slave_param = &spi2_slaveparam0;
spi6_device0.spi_dev_done = &(spi_dev_done);
spi2_device0.spi_dev_done = &(spi_dev_done);
ret = SpiDeviceRegister(&spi6_device0, (void*)(&spi6_device0.spi_param), SPI_6_DEVICE_NAME_0);
ret = SpiDeviceRegister(&spi2_device0, (void*)(&spi2_device0.spi_param), SPI_2_DEVICE_NAME_0);
if (EOK != ret) {
KPrintf("BoardSpiDevBend SpiDeviceRegister device %s error %d\n", SPI_6_DEVICE_NAME_0, ret);
KPrintf("BoardSpiDevBend SpiDeviceRegister device %s error %d\n", SPI_2_DEVICE_NAME_0, ret);
return ERROR;
}
ret = SpiDeviceAttachToBus(SPI_6_DEVICE_NAME_0, SPI_BUS_NAME_6);
ret = SpiDeviceAttachToBus(SPI_2_DEVICE_NAME_0, SPI_BUS_NAME_2);
if (EOK != ret) {
KPrintf("BoardSpiDevBend SpiDeviceAttachToBus device %s error %d\n", SPI_6_DEVICE_NAME_0, ret);
KPrintf("BoardSpiDevBend SpiDeviceAttachToBus device %s error %d\n", SPI_2_DEVICE_NAME_0, ret);
return ERROR;
}
#endif
@ -467,17 +467,17 @@ int HwSpiInit(void)
#endif
#ifdef BSP_USING_SPI6
static struct SpiBus spi6_bus;
memset(&spi6_bus, 0, sizeof(struct SpiBus));
#ifdef BSP_USING_SPI2
static struct SpiBus spi2_bus;
memset(&spi2_bus, 0, sizeof(struct SpiBus));
static struct SpiDriver spi6_driver;
memset(&spi6_driver, 0, sizeof(struct SpiDriver));
static struct SpiDriver spi2_driver;
memset(&spi2_driver, 0, sizeof(struct SpiDriver));
spi6_bus.private_data = SPI6_UNIT;
spi6_driver.configure = SpiDrvConfigure;
spi2_bus.private_data = SPI2_UNIT;
spi2_driver.configure = SpiDrvConfigure;
ret = BoardSpiBusInit(&spi6_bus, &spi6_driver, SPI_BUS_NAME_6, SPI_6_DRV_NAME);
ret = BoardSpiBusInit(&spi2_bus, &spi2_driver, SPI_BUS_NAME_2, SPI_2_DRV_NAME);
if (EOK != ret) {
KPrintf("BoardSpiBusInit error ret %u\n", ret);
return ERROR;

View File

@ -0,0 +1,5 @@
ifeq ($(CONFIG_RESOURCES_SPI_LORA),y)
SRC_DIR := sx12xx
endif
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,3 @@
SRC_DIR := src
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,51 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file spi_lora_sx12xx.h
* @brief define spi lora driver function
* @version 2.0
* @author AIIT XUOS Lab
* @date 2022-10-31
*/
#ifndef SPI_LORA_SX12XX_H
#define SPI_LORA_SX12XX_H
#include <connect_spi_lora.h>
#ifdef __cplusplus
extern "C" {
#endif
uint8_t SX1276ReadDio0(void);
uint8_t SX1276ReadDio1(void);
uint8_t SX1276ReadDio2(void);
uint8_t SX1276ReadDio3(void);
uint8_t SX1276ReadDio4(void);
uint8_t SX1276ReadDio5(void);
void SX1276Write(uint8_t addr, uint8_t data);
void SX1276Read(uint8_t addr, uint8_t *data);
void SX1276WriteBuffer(uint8_t addr, uint8_t *buffer, uint8_t size);
void SX1276ReadBuffer(uint8_t addr, uint8_t *buffer, uint8_t size);
void SX1276WriteFifo(uint8_t *buffer, uint8_t size);
void SX1276ReadFifo(uint8_t *buffer, uint8_t size);
void SX1276SetReset(uint8_t state);
uint8_t Sx1276SpiCheck(void);
void SX1276WriteRxTx(uint8_t txEnable);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,3 @@
SRC_DIR := radio
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,3 @@
SRC_FILES := radio.c sx1276-Fsk.c sx1276-FskMisc.c sx1276-LoRa.c sx1276-LoRaMisc.c sx1276.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,96 @@
/*
* THE FOLLOWING FIRMWARE IS PROVIDED: (1) "AS IS" WITH NO WARRANTY; AND
* (2)TO ENABLE ACCESS TO CODING INFORMATION TO GUIDE AND FACILITATE CUSTOMER.
* CONSEQUENTLY, SEMTECH SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR
* CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
* OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION
* CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* Copyright (C) SEMTECH S.A.
*/
/*!
* \file platform.h
* \brief
*
* \version 1.0
* \date Nov 21 2012
* \author Miguel Luis
*/
/*************************************************
File name: platform.h
Description: support aiit board configure and register function
History:
1. Date: 2021-04-25
Author: AIIT XUOS Lab
Modification:
1. replace original macro and basic date type with AIIT XUOS Lab's own defination
*************************************************/
#ifndef __PLATFORM_H__
#define __PLATFORM_H__
#ifndef __GNUC__
#define inline
#endif
/*!
* Platform definition
*/
#define Bleeper 3
#define SX1243ska 2
#define SX12xxEiger 1
#define SX12000DVK 0
/*!
* Platform choice. Please uncoment the PLATFORM define and choose your platform
* or add/change the PLATFORM definition on the compiler Defines option
*/
#define PLATFORM SX12xxEiger
#if( PLATFORM == SX12xxEiger )
/*!
* Radio choice. Please uncomment the wanted radio and comment the others
* or add/change wanted radio definition on the compiler Defines option
*/
//#define USE_SX1232_RADIO
//#define USE_SX1272_RADIO
#define USE_SX1276_RADIO
//#define USE_SX1243_RADIO
/*!
* Module choice. There are three existing module with the SX1276.
* Please set the connected module to the value 1 and set the others to 0
*/
#ifdef USE_SX1276_RADIO
#define MODULE_SX1276RF1IAS 0
#define MODULE_SX1276RF1JAS 0
#define MODULE_SX1276RF1KAS 1
#endif
#include <spi_lora_sx12xx.h>
#define USE_UART 0
#elif( PLATFORM == SX12000DVK )
/*!
* Radio choice. Please uncomment the wanted radio and comment the others
* or add/change wanted radio definition on the compiler Defines option
*/
//#define USE_SX1232_RADIO
#define USE_SX1272_RADIO
//#define USE_SX1276_RADIO
//#define USE_SX1243_RADIO
#include "sx1200dvk/sx1200dvk.h"
#elif( PLATFORM == SX1243ska )
#elif( PLATFORM == Bleeper )
#define USE_SX1272_RADIO
#include "bleeper/bleeper.h"
#define USE_UART 0
#else
#error "Missing define: Platform (ie. SX12xxEiger)"
#endif
#endif // __PLATFORM_H__

View File

@ -0,0 +1,75 @@
/*
* THE FOLLOWING FIRMWARE IS PROVIDED: (1) "AS IS" WITH NO WARRANTY; AND
* (2)TO ENABLE ACCESS TO CODING INFORMATION TO GUIDE AND FACILITATE CUSTOMER.
* CONSEQUENTLY, SEMTECH SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR
* CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
* OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION
* CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* Copyright (C) SEMTECH S.A.
*/
/*!
* \file radio.c
* \brief Generic radio driver ( radio abstraction )
*
* \version 2.0.0
* \date Nov 21 2012
* \author Miguel Luis
*
* Last modified by Gregory Cristian on Apr 25 2013
*/
/*************************************************
File name: radio.c
Description: support aiit board configure and register function
History:
1. Date: 2021-04-25
Author: AIIT XUOS Lab
Modification:
1. replace original macro and basic date type with AIIT XUOS Lab's own defination
*************************************************/
#include <stdint.h>
#include "platform.h"
#include "radio.h"
#if defined( USE_SX1232_RADIO )
#include "sx1232.h"
#elif defined( USE_SX1272_RADIO )
#include "sx1272.h"
#elif defined( USE_SX1276_RADIO )
#include "sx1276.h"
#else
#error "Missing define: USE_XXXXXX_RADIO (ie. USE_SX1272_RADIO)"
#endif
tRadioDriver RadioDriver;
tRadioDriver* RadioDriverInit( void )
{
#if defined( USE_SX1232_RADIO )
RadioDriver.Init = SX1232Init;
RadioDriver.Reset = SX1232Reset;
RadioDriver.StartRx = SX1232StartRx;
RadioDriver.GetRxPacket = SX1232GetRxPacket;
RadioDriver.SetTxPacket = SX1232SetTxPacket;
RadioDriver.Process = SX1232Process;
#elif defined( USE_SX1272_RADIO )
RadioDriver.Init = SX1272Init;
RadioDriver.Reset = SX1272Reset;
RadioDriver.StartRx = SX1272StartRx;
RadioDriver.GetRxPacket = SX1272GetRxPacket;
RadioDriver.SetTxPacket = SX1272SetTxPacket;
RadioDriver.Process = SX1272Process;
#elif defined( USE_SX1276_RADIO )
RadioDriver.Init = SX1276Init;
RadioDriver.Reset = SX1276Reset;
RadioDriver.StartRx = SX1276StartRx;
RadioDriver.GetRxPacket = SX1276GetRxPacket;
RadioDriver.SetTxPacket = SX1276SetTxPacket;
RadioDriver.Process = SX1276Process;
RadioDriver.ChannelEmpty = SX1276ChannelEmpty;
#else
#error "Missing define: USE_XXXXXX_RADIO (ie. USE_SX1272_RADIO)"
#endif
return &RadioDriver;
}

View File

@ -0,0 +1,77 @@
/*
* THE FOLLOWING FIRMWARE IS PROVIDED: (1) "AS IS" WITH NO WARRANTY; AND
* (2)TO ENABLE ACCESS TO CODING INFORMATION TO GUIDE AND FACILITATE CUSTOMER.
* CONSEQUENTLY, SEMTECH SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR
* CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
* OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION
* CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* Copyright (C) SEMTECH S.A.
*/
/*!
* \file radio.h
* \brief Generic radio driver ( radio abstraction )
*
* \version 2.0.B2
* \date Nov 21 2012
* \author Miguel Luis
*
* Last modified by Gregory Cristian on Apr 25 2013
*/
/*************************************************
File name: radio.h
Description: support aiit board configure and register function
History:
1. Date: 2021-04-25
Author: AIIT XUOS Lab
Modification:
1. replace original macro and basic date type with AIIT XUOS Lab's own defination
*************************************************/
#ifndef __RADIO_H__
#define __RADIO_H__
/*!
* SX1272 and SX1276 General parameters definition
*/
#define LORA 1 // [0: OFF, 1: ON]
/*!
* RF process function return codes
*/
typedef enum
{
RF_IDLE,
RF_BUSY,
RF_RX_DONE,
RF_RX_TIMEOUT,
RF_TX_DONE,
RF_TX_TIMEOUT,
RF_LEN_ERROR,
RF_CHANNEL_EMPTY,
RF_CHANNEL_ACTIVITY_DETECTED,
}tRFProcessReturnCodes;
/*!
* Radio driver structure defining the different function pointers
*/
typedef struct sRadioDriver
{
void ( *Init )( void );
void ( *Reset )( void );
void ( *StartRx )( void );
void ( *GetRxPacket )( void *buffer, uint16_t *size );
void ( *SetTxPacket )( const void *buffer, uint16_t size );
uint32_t ( *Process )( void );
uint32_t ( *ChannelEmpty )(void );
}tRadioDriver;
/*!
* \brief Initializes the RadioDriver structure with specific radio
* functions.
*
* \retval radioDriver Pointer to the radio driver variable
*/
tRadioDriver* RadioDriverInit( void );
#endif // __RADIO_H__

View File

@ -0,0 +1,616 @@
/*
* THE FOLLOWING FIRMWARE IS PROVIDED: (1) "AS IS" WITH NO WARRANTY; AND
* (2)TO ENABLE ACCESS TO CODING INFORMATION TO GUIDE AND FACILITATE CUSTOMER.
* CONSEQUENTLY, SEMTECH SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR
* CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
* OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION
* CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* Copyright (C) SEMTECH S.A.
*/
/*!
* \file sx1276.c
* \brief SX1276 RF chip driver
*
* \version 2.0.0
* \date May 6 2013
* \author Gregory Cristian
*
* Last modified by Miguel Luis on Jun 19 2013
*/
/*************************************************
File name: sx1276-Fsk.c
Description: support aiit board configure and register function
History:
1. Date: 2021-04-25
Author: AIIT XUOS Lab
Modification:
1. replace original macro and basic date type with AIIT XUOS Lab's own defination
*************************************************/
#include <string.h>
#include <math.h>
#include "platform.h"
#if defined( USE_SX1276_RADIO )
#include "radio.h"
#include "sx1276-Hal.h"
#include "sx1276.h"
#include "sx1276-FskMisc.h"
#include "sx1276-Fsk.h"
// Default settings
tFskSettings FskSettings =
{
870000000, // RFFrequency
9600, // Bitrate
50000, // Fdev
20, // Power
100000, // RxBw
150000, // RxBwAfc
true, // CrcOn
true, // AfcOn
255 // PayloadLength (set payload size to the maximum for variable mode, else set the exact payload length)
};
/*!
* SX1276 FSK registers variable
*/
tSX1276* SX1276;
/*!
* Local RF buffer for communication support
*/
static uint8_t RFBuffer[RF_BUFFER_SIZE];
/*!
* Chunk size of data write in buffer
*/
static uint8_t DataChunkSize = 32;
/*!
* RF state machine variable
*/
static uint8_t RFState = RF_STATE_IDLE;
/*!
* Rx management support variables
*/
/*!
* PacketTimeout holds the RF packet timeout
* SyncSize = [0..8]
* VariableSize = [0;1]
* AddressSize = [0;1]
* PayloadSize = [0..RF_BUFFER_SIZE]
* CrcSize = [0;2]
* PacketTimeout = ( ( 8 * ( VariableSize + AddressSize + PayloadSize + CrcSize ) / BR ) * 1000.0 ) + 1
* Computed timeout is in miliseconds
*/
static uint32_t PacketTimeout;
/*!
* Preamble2SyncTimeout
* Preamble2SyncTimeout = ( ( 8 * ( PremableSize + SyncSize ) / RFBitrate ) * 1000.0 ) + 1
* Computed timeout is in miliseconds
*/
static uint32_t Preamble2SyncTimeout;
static bool PreambleDetected = false;
static bool SyncWordDetected = false;
static bool PacketDetected = false;
static uint16_t RxPacketSize = 0;
static uint8_t RxBytesRead = 0;
static uint8_t TxBytesSent = 0;
static double RxPacketRssiValue;
static uint32_t RxPacketAfcValue;
static uint8_t RxGain = 1;
static uint32_t RxTimeoutTimer = 0;
static uint32_t Preamble2SyncTimer = 0;
/*!
* Tx management support variables
*/
static uint16_t TxPacketSize = 0;
static uint32_t TxTimeoutTimer = 0;
void SX1276FskInit( void )
{
RFState = RF_STATE_IDLE;
SX1276FskSetDefaults( );
SX1276ReadBuffer( REG_OPMODE, SX1276Regs + 1, 0x70 - 1 );
// Set the device in FSK mode and Sleep Mode
SX1276->RegOpMode = RF_OPMODE_MODULATIONTYPE_FSK | RF_OPMODE_SLEEP;
SX1276Write( REG_OPMODE, SX1276->RegOpMode );
SX1276->RegPaRamp = RF_PARAMP_MODULATIONSHAPING_01;
SX1276Write( REG_PARAMP, SX1276->RegPaRamp );
SX1276->RegLna = RF_LNA_GAIN_G1;
SX1276Write( REG_LNA, SX1276->RegLna );
if( FskSettings.AfcOn == true )
{
SX1276->RegRxConfig = RF_RXCONFIG_RESTARTRXONCOLLISION_OFF | RF_RXCONFIG_AFCAUTO_ON |
RF_RXCONFIG_AGCAUTO_ON | RF_RXCONFIG_RXTRIGER_PREAMBLEDETECT;
}
else
{
SX1276->RegRxConfig = RF_RXCONFIG_RESTARTRXONCOLLISION_OFF | RF_RXCONFIG_AFCAUTO_OFF |
RF_RXCONFIG_AGCAUTO_ON | RF_RXCONFIG_RXTRIGER_PREAMBLEDETECT;
}
SX1276->RegPreambleLsb = 8;
SX1276->RegPreambleDetect = RF_PREAMBLEDETECT_DETECTOR_ON | RF_PREAMBLEDETECT_DETECTORSIZE_2 |
RF_PREAMBLEDETECT_DETECTORTOL_10;
SX1276->RegRssiThresh = 0xFF;
SX1276->RegSyncConfig = RF_SYNCCONFIG_AUTORESTARTRXMODE_WAITPLL_ON | RF_SYNCCONFIG_PREAMBLEPOLARITY_AA |
RF_SYNCCONFIG_SYNC_ON |
RF_SYNCCONFIG_SYNCSIZE_4;
SX1276->RegSyncValue1 = 0x69;
SX1276->RegSyncValue2 = 0x81;
SX1276->RegSyncValue3 = 0x7E;
SX1276->RegSyncValue4 = 0x96;
SX1276->RegPacketConfig1 = RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE | RF_PACKETCONFIG1_DCFREE_OFF |
( FskSettings.CrcOn << 4 ) | RF_PACKETCONFIG1_CRCAUTOCLEAR_ON |
RF_PACKETCONFIG1_ADDRSFILTERING_OFF | RF_PACKETCONFIG1_CRCWHITENINGTYPE_CCITT;
SX1276FskGetPacketCrcOn( ); // Update CrcOn on FskSettings
SX1276->RegPayloadLength = FskSettings.PayloadLength;
// we can now update the registers with our configuration
SX1276WriteBuffer( REG_OPMODE, SX1276Regs + 1, 0x70 - 1 );
// then we need to set the RF settings
SX1276FskSetRFFrequency( FskSettings.RFFrequency );
SX1276FskSetBitrate( FskSettings.Bitrate );
SX1276FskSetFdev( FskSettings.Fdev );
SX1276FskSetDccBw( &SX1276->RegRxBw, 0, FskSettings.RxBw );
SX1276FskSetDccBw( &SX1276->RegAfcBw, 0, FskSettings.RxBwAfc );
SX1276FskSetRssiOffset( 0 );
#if( ( MODULE_SX1276RF1IAS == 1 ) || ( MODULE_SX1276RF1KAS == 1 ) )
if( FskSettings.RFFrequency > 860000000 )
{
SX1276FskSetPAOutput( RF_PACONFIG_PASELECT_RFO );
SX1276FskSetPa20dBm( false );
FskSettings.Power = 14;
SX1276FskSetRFPower( FskSettings.Power );
}
else
{
SX1276FskSetPAOutput( RF_PACONFIG_PASELECT_PABOOST );
SX1276FskSetPa20dBm( true );
FskSettings.Power = 20;
SX1276FskSetRFPower( FskSettings.Power );
}
#elif( MODULE_SX1276RF1JAS == 1 )
if( FskSettings.RFFrequency > 860000000 )
{
SX1276FskSetPAOutput( RF_PACONFIG_PASELECT_PABOOST );
SX1276FskSetPa20dBm( true );
FskSettings.Power = 20;
SX1276FskSetRFPower( FskSettings.Power );
}
else
{
SX1276FskSetPAOutput( RF_PACONFIG_PASELECT_RFO );
SX1276FskSetPa20dBm( false );
FskSettings.Power = 14;
SX1276FskSetRFPower( FskSettings.Power );
}
#endif
SX1276FskSetOpMode( RF_OPMODE_STANDBY );
// Calibrate the HF
SX1276FskRxCalibrate( );
}
void SX1276FskSetDefaults( void )
{
// REMARK: See SX1276 datasheet for modified default values.
SX1276Read( REG_VERSION, &SX1276->RegVersion );
}
void SX1276FskSetOpMode( uint8_t opMode )
{
static uint8_t opModePrev = RF_OPMODE_STANDBY;
static bool antennaSwitchTxOnPrev = true;
bool antennaSwitchTxOn = false;
opModePrev = SX1276->RegOpMode & ~RF_OPMODE_MASK;
if( opMode != opModePrev )
{
if( opMode == RF_OPMODE_TRANSMITTER )
{
antennaSwitchTxOn = true;
}
else
{
antennaSwitchTxOn = false;
}
if( antennaSwitchTxOn != antennaSwitchTxOnPrev )
{
antennaSwitchTxOnPrev = antennaSwitchTxOn;
RXTX( antennaSwitchTxOn ); // Antenna switch control
}
SX1276->RegOpMode = ( SX1276->RegOpMode & RF_OPMODE_MASK ) | opMode;
SX1276Write( REG_OPMODE, SX1276->RegOpMode );
}
}
uint8_t SX1276FskGetOpMode( void )
{
SX1276Read( REG_OPMODE, &SX1276->RegOpMode );
return SX1276->RegOpMode & ~RF_OPMODE_MASK;
}
int32_t SX1276FskReadFei( void )
{
SX1276ReadBuffer( REG_FEIMSB, &SX1276->RegFeiMsb, 2 ); // Reads the FEI value
return ( int32_t )( double )( ( ( uint16_t )SX1276->RegFeiMsb << 8 ) | ( uint16_t )SX1276->RegFeiLsb ) * ( double )FREQ_STEP;
}
int32_t SX1276FskReadAfc( void )
{
SX1276ReadBuffer( REG_AFCMSB, &SX1276->RegAfcMsb, 2 ); // Reads the AFC value
return ( int32_t )( double )( ( ( uint16_t )SX1276->RegAfcMsb << 8 ) | ( uint16_t )SX1276->RegAfcLsb ) * ( double )FREQ_STEP;
}
uint8_t SX1276FskReadRxGain( void )
{
SX1276Read( REG_LNA, &SX1276->RegLna );
return( SX1276->RegLna >> 5 ) & 0x07;
}
double SX1276FskReadRssi( void )
{
SX1276Read( REG_RSSIVALUE, &SX1276->RegRssiValue ); // Reads the RSSI value
return -( double )( ( double )SX1276->RegRssiValue / 2.0 );
}
uint8_t SX1276FskGetPacketRxGain( void )
{
return RxGain;
}
double SX1276FskGetPacketRssi( void )
{
return RxPacketRssiValue;
}
uint32_t SX1276FskGetPacketAfc( void )
{
return RxPacketAfcValue;
}
void SX1276FskStartRx( void )
{
SX1276FskSetRFState( RF_STATE_RX_INIT );
}
void SX1276FskGetRxPacket( void *buffer, uint16_t *size )
{
*size = RxPacketSize;
RxPacketSize = 0;
memcpy( ( void * )buffer, ( void * )RFBuffer, ( size_t )*size );
}
void SX1276FskSetTxPacket( const void *buffer, uint16_t size )
{
TxPacketSize = size;
memcpy( ( void * )RFBuffer, buffer, ( size_t )TxPacketSize );
RFState = RF_STATE_TX_INIT;
}
// Remark: SX1276 must be fully initialized before calling this function
uint16_t SX1276FskGetPacketPayloadSize( void )
{
uint16_t syncSize;
uint16_t variableSize;
uint16_t addressSize;
uint16_t payloadSize;
uint16_t crcSize;
syncSize = ( SX1276->RegSyncConfig & 0x07 ) + 1;
variableSize = ( ( SX1276->RegPacketConfig1 & 0x80 ) == 0x80 ) ? 1 : 0;
addressSize = ( ( SX1276->RegPacketConfig1 & 0x06 ) != 0x00 ) ? 1 : 0;
payloadSize = SX1276->RegPayloadLength;
crcSize = ( ( SX1276->RegPacketConfig1 & 0x10 ) == 0x10 ) ? 2 : 0;
return syncSize + variableSize + addressSize + payloadSize + crcSize;
}
// Remark: SX1276 must be fully initialized before calling this function
uint16_t SX1276FskGetPacketHeaderSize( void )
{
uint16_t preambleSize;
uint16_t syncSize;
preambleSize = ( ( uint16_t )SX1276->RegPreambleMsb << 8 ) | ( uint16_t )SX1276->RegPreambleLsb;
syncSize = ( SX1276->RegSyncConfig & 0x07 ) + 1;
return preambleSize + syncSize;
}
uint8_t SX1276FskGetRFState( void )
{
return RFState;
}
void SX1276FskSetRFState( uint8_t state )
{
RFState = state;
}
uint32_t SX1276FskProcess( void )
{
uint32_t result = RF_BUSY;
switch( RFState )
{
case RF_STATE_IDLE:
break;
// Rx management
case RF_STATE_RX_INIT:
// DIO mapping setup
if( ( SX1276->RegPacketConfig1 & RF_PACKETCONFIG1_CRC_ON ) == RF_PACKETCONFIG1_CRC_ON )
{
// CrcOk, FifoLevel, SyncAddr, FifoEmpty
SX1276->RegDioMapping1 = RF_DIOMAPPING1_DIO0_01 | RF_DIOMAPPING1_DIO1_00 | RF_DIOMAPPING1_DIO2_11 | RF_DIOMAPPING1_DIO3_00;
}
else
{
// PayloadReady, FifoLevel, SyncAddr, FifoEmpty
SX1276->RegDioMapping1 = RF_DIOMAPPING1_DIO0_00 | RF_DIOMAPPING1_DIO1_00 | RF_DIOMAPPING1_DIO2_11 | RF_DIOMAPPING1_DIO3_00;
}
// Preamble, Data
SX1276->RegDioMapping2 = RF_DIOMAPPING2_DIO4_11 | RF_DIOMAPPING2_DIO5_10 | RF_DIOMAPPING2_MAP_PREAMBLEDETECT;
SX1276WriteBuffer( REG_DIOMAPPING1, &SX1276->RegDioMapping1, 2 );
SX1276FskSetOpMode( RF_OPMODE_RECEIVER );
memset( RFBuffer, 0, ( size_t )RF_BUFFER_SIZE );
PacketTimeout = ( uint16_t )( round( ( 8.0 * ( ( double )SX1276FskGetPacketPayloadSize( ) ) / ( double )FskSettings.Bitrate ) * 1000.0 ) + 1.0 );
PacketTimeout = PacketTimeout + ( PacketTimeout >> 1 ); // Set the Packet timeout as 1.5 times the full payload transmission time
Preamble2SyncTimeout = PacketTimeout;
Preamble2SyncTimer = RxTimeoutTimer = GET_TICK_COUNT( );
SX1276->RegFifoThresh = RF_FIFOTHRESH_TXSTARTCONDITION_FIFONOTEMPTY | 0x20; // 32 bytes of data
SX1276Write( REG_FIFOTHRESH, SX1276->RegFifoThresh );
PreambleDetected = false;
SyncWordDetected = false;
PacketDetected = false;
RxBytesRead = 0;
RxPacketSize = 0;
RFState = RF_STATE_RX_SYNC;
break;
case RF_STATE_RX_SYNC:
if( ( DIO4 == 1 ) && ( PreambleDetected == false ) )// Preamble
{
PreambleDetected = true;
Preamble2SyncTimer = GET_TICK_COUNT( );
}
if( ( DIO2 == 1 ) && ( PreambleDetected == true ) && ( SyncWordDetected == false ) ) // SyncAddr
{
SyncWordDetected = true;
RxPacketRssiValue = SX1276FskReadRssi( );
RxPacketAfcValue = SX1276FskReadAfc( );
RxGain = SX1276FskReadRxGain( );
Preamble2SyncTimer = RxTimeoutTimer = GET_TICK_COUNT( );
RFState = RF_STATE_RX_RUNNING;
}
// Preamble 2 SyncAddr timeout
if( ( SyncWordDetected == false ) && ( PreambleDetected == true ) && ( ( GET_TICK_COUNT( ) - Preamble2SyncTimer ) > Preamble2SyncTimeout ) )
{
RFState = RF_STATE_RX_INIT;
SX1276Write( REG_RXCONFIG, SX1276->RegRxConfig | RF_RXCONFIG_RESTARTRXWITHPLLLOCK );
}
if( ( SyncWordDetected == false ) &&
( PreambleDetected == false ) &&
( PacketDetected == false ) &&
( ( GET_TICK_COUNT( ) - RxTimeoutTimer ) > PacketTimeout ) )
{
RFState = RF_STATE_RX_TIMEOUT;
}
break;
case RF_STATE_RX_RUNNING:
if( RxPacketSize > RF_BUFFER_SIZE_MAX )
{
RFState = RF_STATE_RX_LEN_ERROR;
break;
}
#if 1
if( DIO1 == 1 ) // FifoLevel
{
if( ( RxPacketSize == 0 ) && ( RxBytesRead == 0 ) ) // Read received packet size
{
if( ( SX1276->RegPacketConfig1 & RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE ) == RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE )
{
SX1276ReadFifo( ( uint8_t* )&RxPacketSize, 1 );
}
else
{
RxPacketSize = SX1276->RegPayloadLength;
}
}
if( ( RxPacketSize - RxBytesRead ) > ( SX1276->RegFifoThresh & 0x3F ) )
{
SX1276ReadFifo( ( RFBuffer + RxBytesRead ), ( SX1276->RegFifoThresh & 0x3F ) );
RxBytesRead += ( SX1276->RegFifoThresh & 0x3F );
}
else
{
SX1276ReadFifo( ( RFBuffer + RxBytesRead ), RxPacketSize - RxBytesRead );
RxBytesRead += ( RxPacketSize - RxBytesRead );
}
}
#endif
if( DIO0 == 1 ) // PayloadReady/CrcOk
{
RxTimeoutTimer = GET_TICK_COUNT( );
if( ( RxPacketSize == 0 ) && ( RxBytesRead == 0 ) ) // Read received packet size
{
if( ( SX1276->RegPacketConfig1 & RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE ) == RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE )
{
SX1276ReadFifo( ( uint8_t* )&RxPacketSize, 1 );
}
else
{
RxPacketSize = SX1276->RegPayloadLength;
}
SX1276ReadFifo( RFBuffer + RxBytesRead, RxPacketSize - RxBytesRead );
RxBytesRead += ( RxPacketSize - RxBytesRead );
PacketDetected = true;
RFState = RF_STATE_RX_DONE;
}
else
{
SX1276ReadFifo( RFBuffer + RxBytesRead, RxPacketSize - RxBytesRead );
RxBytesRead += ( RxPacketSize - RxBytesRead );
PacketDetected = true;
RFState = RF_STATE_RX_DONE;
}
}
// Packet timeout
if( ( PacketDetected == false ) && ( ( GET_TICK_COUNT( ) - RxTimeoutTimer ) > PacketTimeout ) )
{
RFState = RF_STATE_RX_TIMEOUT;
}
break;
case RF_STATE_RX_DONE:
RxBytesRead = 0;
RFState = RF_STATE_RX_INIT;
result = RF_RX_DONE;
break;
case RF_STATE_RX_TIMEOUT:
RxBytesRead = 0;
RxPacketSize = 0;
SX1276Write( REG_RXCONFIG, SX1276->RegRxConfig | RF_RXCONFIG_RESTARTRXWITHPLLLOCK );
RFState = RF_STATE_RX_INIT;
result = RF_RX_TIMEOUT;
break;
case RF_STATE_RX_LEN_ERROR:
RxBytesRead = 0;
RxPacketSize = 0;
SX1276Write( REG_RXCONFIG, SX1276->RegRxConfig | RF_RXCONFIG_RESTARTRXWITHPLLLOCK );
RFState = RF_STATE_RX_INIT;
result = RF_LEN_ERROR;
break;
// Tx management
case RF_STATE_TX_INIT:
// Packet DIO mapping setup
// PacketSent, FifoLevel, FifoFull, TxReady
SX1276->RegDioMapping1 = RF_DIOMAPPING1_DIO0_00 | RF_DIOMAPPING1_DIO1_00 | RF_DIOMAPPING1_DIO2_00 | RF_DIOMAPPING1_DIO3_01;
// LowBat, Data
SX1276->RegDioMapping2 = RF_DIOMAPPING2_DIO4_00 | RF_DIOMAPPING2_DIO5_10;
SX1276WriteBuffer( REG_DIOMAPPING1, &SX1276->RegDioMapping1, 2 );
SX1276->RegFifoThresh = RF_FIFOTHRESH_TXSTARTCONDITION_FIFONOTEMPTY | 0x18; // 24 bytes of data
SX1276Write( REG_FIFOTHRESH, SX1276->RegFifoThresh );
SX1276FskSetOpMode( RF_OPMODE_TRANSMITTER );
RFState = RF_STATE_TX_READY_WAIT;
TxBytesSent = 0;
break;
case RF_STATE_TX_READY_WAIT:
if( DIO3 == 1 ) // TxReady
{
if( ( SX1276->RegPacketConfig1 & RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE ) == RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE )
{
SX1276WriteFifo( ( uint8_t* )&TxPacketSize, 1 );
}
if( ( TxPacketSize > 0 ) && ( TxPacketSize <= 64 ) )
{
DataChunkSize = TxPacketSize;
}
else
{
DataChunkSize = 32;
}
SX1276WriteFifo( RFBuffer, DataChunkSize );
TxBytesSent += DataChunkSize;
TxTimeoutTimer = GET_TICK_COUNT( );
RFState = RF_STATE_TX_RUNNING;
}
break;
case RF_STATE_TX_RUNNING:
if( DIO1 == 0 ) // FifoLevel below thresold
{
if( ( TxPacketSize - TxBytesSent ) > DataChunkSize )
{
SX1276WriteFifo( ( RFBuffer + TxBytesSent ), DataChunkSize );
TxBytesSent += DataChunkSize;
}
else
{
// we write the last chunk of data
SX1276WriteFifo( RFBuffer + TxBytesSent, TxPacketSize - TxBytesSent );
TxBytesSent += TxPacketSize - TxBytesSent;
}
}
if( DIO0 == 1 ) // PacketSent
{
TxTimeoutTimer = GET_TICK_COUNT( );
RFState = RF_STATE_TX_DONE;
SX1276FskSetOpMode( RF_OPMODE_STANDBY );
}
// Packet timeout
if( ( GET_TICK_COUNT( ) - TxTimeoutTimer ) > TICK_RATE_MS( 1000 ) )
{
RFState = RF_STATE_TX_TIMEOUT;
}
break;
case RF_STATE_TX_DONE:
RFState = RF_STATE_IDLE;
result = RF_TX_DONE;
break;
case RF_STATE_TX_TIMEOUT:
RFState = RF_STATE_IDLE;
result = RF_TX_TIMEOUT;
break;
default:
break;
}
return result;
}
#endif // USE_SX1276_RADIO

View File

@ -0,0 +1,532 @@
/*
* THE FOLLOWING FIRMWARE IS PROVIDED: (1) "AS IS" WITH NO WARRANTY; AND
* (2)TO ENABLE ACCESS TO CODING INFORMATION TO GUIDE AND FACILITATE CUSTOMER.
* CONSEQUENTLY, SEMTECH SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR
* CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
* OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION
* CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* Copyright (C) SEMTECH S.A.
*/
/*!
* \file sx1276-FskMisc.c
* \brief SX1276 RF chip high level functions driver
*
* \remark Optional support functions.
* These functions are defined only to easy the change of the
* parameters.
* For a final firmware the radio parameters will be known so
* there is no need to support all possible parameters.
* Removing these functions will greatly reduce the final firmware
* size.
*
* \version 2.0.0
* \date May 6 2013
* \author Gregory Cristian
*
* Last modified by Miguel Luis on Jun 19 2013
*/
/*************************************************
File name: sx1276-FskMisc.c
Description: support aiit board configure and register function
History:
1. Date: 2021-04-25
Author: AIIT XUOS Lab
Modification:
1. replace original macro and basic date type with AIIT XUOS Lab's own defination
*************************************************/
#include <math.h>
#include "platform.h"
#if defined( USE_SX1276_RADIO )
#include "sx1276-Hal.h"
#include "sx1276.h"
#include "sx1276-Fsk.h"
#include "sx1276-FskMisc.h"
extern tFskSettings FskSettings;
void SX1276FskSetRFFrequency( uint32_t freq )
{
FskSettings.RFFrequency = freq;
freq = ( uint32_t )( ( double )freq / ( double )FREQ_STEP );
SX1276->RegFrfMsb = ( uint8_t )( ( freq >> 16 ) & 0xFF );
SX1276->RegFrfMid = ( uint8_t )( ( freq >> 8 ) & 0xFF );
SX1276->RegFrfLsb = ( uint8_t )( freq & 0xFF );
SX1276WriteBuffer( REG_FRFMSB, &SX1276->RegFrfMsb, 3 );
}
uint32_t SX1276FskGetRFFrequency( void )
{
SX1276ReadBuffer( REG_FRFMSB, &SX1276->RegFrfMsb, 3 );
FskSettings.RFFrequency = ( ( uint32_t )SX1276->RegFrfMsb << 16 ) | ( ( uint32_t )SX1276->RegFrfMid << 8 ) | ( ( uint32_t )SX1276->RegFrfLsb );
FskSettings.RFFrequency = ( uint32_t )( ( double )FskSettings.RFFrequency * ( double )FREQ_STEP );
return FskSettings.RFFrequency;
}
void SX1276FskRxCalibrate( void )
{
// the function RadioRxCalibrate is called just after the reset so all register are at their default values
uint8_t regPaConfigInitVal;
uint32_t initialFreq;
// save register values;
SX1276Read( REG_PACONFIG, &regPaConfigInitVal );
initialFreq = SX1276FskGetRFFrequency( );
// Cut the PA just in case
SX1276->RegPaConfig = 0x00; // RFO output, power = -1 dBm
SX1276Write( REG_PACONFIG, SX1276->RegPaConfig );
// Set Frequency in HF band
SX1276FskSetRFFrequency( 860000000 );
// Rx chain re-calibration workaround
SX1276Read( REG_IMAGECAL, &SX1276->RegImageCal );
SX1276->RegImageCal = ( SX1276->RegImageCal & RF_IMAGECAL_IMAGECAL_MASK ) | RF_IMAGECAL_IMAGECAL_START;
SX1276Write( REG_IMAGECAL, SX1276->RegImageCal );
SX1276Read( REG_IMAGECAL, &SX1276->RegImageCal );
// rx_cal_run goes low when calibration in finished
while( ( SX1276->RegImageCal & RF_IMAGECAL_IMAGECAL_RUNNING ) == RF_IMAGECAL_IMAGECAL_RUNNING )
{
SX1276Read( REG_IMAGECAL, &SX1276->RegImageCal );
}
// reload saved values into the registers
SX1276->RegPaConfig = regPaConfigInitVal;
SX1276Write( REG_PACONFIG, SX1276->RegPaConfig );
SX1276FskSetRFFrequency( initialFreq );
}
void SX1276FskSetBitrate( uint32_t bitrate )
{
FskSettings.Bitrate = bitrate;
bitrate = ( uint16_t )( ( double )XTAL_FREQ / ( double )bitrate );
SX1276->RegBitrateMsb = ( uint8_t )( bitrate >> 8 );
SX1276->RegBitrateLsb = ( uint8_t )( bitrate & 0xFF );
SX1276WriteBuffer( REG_BITRATEMSB, &SX1276->RegBitrateMsb, 2 );
}
uint32_t SX1276FskGetBitrate( void )
{
SX1276ReadBuffer( REG_BITRATEMSB, &SX1276->RegBitrateMsb, 2 );
FskSettings.Bitrate = ( ( ( uint32_t )SX1276->RegBitrateMsb << 8 ) | ( ( uint32_t )SX1276->RegBitrateLsb ) );
FskSettings.Bitrate = ( uint16_t )( ( double )XTAL_FREQ / ( double )FskSettings.Bitrate );
return FskSettings.Bitrate;
}
void SX1276FskSetFdev( uint32_t fdev )
{
FskSettings.Fdev = fdev;
SX1276Read( REG_FDEVMSB, &SX1276->RegFdevMsb );
fdev = ( uint16_t )( ( double )fdev / ( double )FREQ_STEP );
SX1276->RegFdevMsb = ( ( SX1276->RegFdevMsb & RF_FDEVMSB_FDEV_MASK ) | ( ( ( uint8_t )( fdev >> 8 ) ) & ~RF_FDEVMSB_FDEV_MASK ) );
SX1276->RegFdevLsb = ( uint8_t )( fdev & 0xFF );
SX1276WriteBuffer( REG_FDEVMSB, &SX1276->RegFdevMsb, 2 );
}
uint32_t SX1276FskGetFdev( void )
{
SX1276ReadBuffer( REG_FDEVMSB, &SX1276->RegFdevMsb, 2 );
FskSettings.Fdev = ( ( ( uint32_t )( ( SX1276->RegFdevMsb << 8 ) & ~RF_FDEVMSB_FDEV_MASK ) ) | ( ( uint32_t )SX1276->RegFdevLsb ) );
FskSettings.Fdev = ( uint16_t )( ( double )FskSettings.Fdev * ( double )FREQ_STEP );
return FskSettings.Fdev;
}
void SX1276FskSetRFPower( int8_t power )
{
SX1276Read( REG_PACONFIG, &SX1276->RegPaConfig );
SX1276Read( REG_PADAC, &SX1276->RegPaDac );
if( ( SX1276->RegPaConfig & RF_PACONFIG_PASELECT_PABOOST ) == RF_PACONFIG_PASELECT_PABOOST )
{
if( ( SX1276->RegPaDac & 0x87 ) == 0x87 )
{
if( power < 5 )
{
power = 5;
}
if( power > 20 )
{
power = 20;
}
SX1276->RegPaConfig = ( SX1276->RegPaConfig & RF_PACONFIG_MAX_POWER_MASK ) | 0x70;
SX1276->RegPaConfig = ( SX1276->RegPaConfig & RF_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power - 5 ) & 0x0F );
}
else
{
if( power < 2 )
{
power = 2;
}
if( power > 17 )
{
power = 17;
}
SX1276->RegPaConfig = ( SX1276->RegPaConfig & RF_PACONFIG_MAX_POWER_MASK ) | 0x70;
SX1276->RegPaConfig = ( SX1276->RegPaConfig & RF_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power - 2 ) & 0x0F );
}
}
else
{
if( power < -1 )
{
power = -1;
}
if( power > 14 )
{
power = 14;
}
SX1276->RegPaConfig = ( SX1276->RegPaConfig & RF_PACONFIG_MAX_POWER_MASK ) | 0x70;
SX1276->RegPaConfig = ( SX1276->RegPaConfig & RF_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power + 1 ) & 0x0F );
}
SX1276Write( REG_PACONFIG, SX1276->RegPaConfig );
FskSettings.Power = power;
}
int8_t SX1276FskGetRFPower( void )
{
SX1276Read( REG_PACONFIG, &SX1276->RegPaConfig );
SX1276Read( REG_PADAC, &SX1276->RegPaDac );
if( ( SX1276->RegPaConfig & RF_PACONFIG_PASELECT_PABOOST ) == RF_PACONFIG_PASELECT_PABOOST )
{
if( ( SX1276->RegPaDac & 0x07 ) == 0x07 )
{
FskSettings.Power = 5 + ( SX1276->RegPaConfig & ~RF_PACONFIG_OUTPUTPOWER_MASK );
}
else
{
FskSettings.Power = 2 + ( SX1276->RegPaConfig & ~RF_PACONFIG_OUTPUTPOWER_MASK );
}
}
else
{
FskSettings.Power = -1 + ( SX1276->RegPaConfig & ~RF_PACONFIG_OUTPUTPOWER_MASK );
}
return FskSettings.Power;
}
/*!
* \brief Computes the Rx bandwidth with the mantisse and exponent
*
* \param [IN] mantisse Mantisse of the bandwidth value
* \param [IN] exponent Exponent of the bandwidth value
* \retval bandwidth Computed bandwidth
*/
static uint32_t SX1276FskComputeRxBw( uint8_t mantisse, uint8_t exponent )
{
// rxBw
if( ( SX1276->RegOpMode & RF_OPMODE_MODULATIONTYPE_FSK ) == RF_OPMODE_MODULATIONTYPE_FSK )
{
return ( uint32_t )( ( double )XTAL_FREQ / ( mantisse * ( double )pow( 2, exponent + 2 ) ) );
}
else
{
return ( uint32_t )( ( double )XTAL_FREQ / ( mantisse * ( double )pow( 2, exponent + 3 ) ) );
}
}
/*!
* \brief Computes the mantisse and exponent from the bandwitdh value
*
* \param [IN] rxBwValue Bandwidth value
* \param [OUT] mantisse Mantisse of the bandwidth value
* \param [OUT] exponent Exponent of the bandwidth value
*/
static void SX1276FskComputeRxBwMantExp( uint32_t rxBwValue, uint8_t* mantisse, uint8_t* exponent )
{
uint8_t tmpExp = 0;
uint8_t tmpMant = 0;
double tmpRxBw = 0;
double rxBwMin = 10e6;
for( tmpExp = 0; tmpExp < 8; tmpExp++ )
{
for( tmpMant = 16; tmpMant <= 24; tmpMant += 4 )
{
if( ( SX1276->RegOpMode & RF_OPMODE_MODULATIONTYPE_FSK ) == RF_OPMODE_MODULATIONTYPE_FSK )
{
tmpRxBw = ( double )XTAL_FREQ / ( tmpMant * ( double )pow( 2, tmpExp + 2 ) );
}
else
{
tmpRxBw = ( double )XTAL_FREQ / ( tmpMant * ( double )pow( 2, tmpExp + 3 ) );
}
if( fabs( tmpRxBw - rxBwValue ) < rxBwMin )
{
rxBwMin = fabs( tmpRxBw - rxBwValue );
*mantisse = tmpMant;
*exponent = tmpExp;
}
}
}
}
void SX1276FskSetDccBw( uint8_t* reg, uint32_t dccValue, uint32_t rxBwValue )
{
uint8_t mantisse = 0;
uint8_t exponent = 0;
if( reg == &SX1276->RegRxBw )
{
*reg = ( uint8_t )dccValue & 0x60;
}
else
{
*reg = 0;
}
SX1276FskComputeRxBwMantExp( rxBwValue, &mantisse, &exponent );
switch( mantisse )
{
case 16:
*reg |= ( uint8_t )( 0x00 | ( exponent & 0x07 ) );
break;
case 20:
*reg |= ( uint8_t )( 0x08 | ( exponent & 0x07 ) );
break;
case 24:
*reg |= ( uint8_t )( 0x10 | ( exponent & 0x07 ) );
break;
default:
// Something went terribely wrong
break;
}
if( reg == &SX1276->RegRxBw )
{
SX1276Write( REG_RXBW, *reg );
FskSettings.RxBw = rxBwValue;
}
else
{
SX1276Write( REG_AFCBW, *reg );
FskSettings.RxBwAfc = rxBwValue;
}
}
uint32_t SX1276FskGetBw( uint8_t* reg )
{
uint32_t rxBwValue = 0;
uint8_t mantisse = 0;
switch( ( *reg & 0x18 ) >> 3 )
{
case 0:
mantisse = 16;
break;
case 1:
mantisse = 20;
break;
case 2:
mantisse = 24;
break;
default:
break;
}
rxBwValue = SX1276FskComputeRxBw( mantisse, ( uint8_t )*reg & 0x07 );
if( reg == &SX1276->RegRxBw )
{
return FskSettings.RxBw = rxBwValue;
}
else
{
return FskSettings.RxBwAfc = rxBwValue;
}
}
void SX1276FskSetPacketCrcOn( bool enable )
{
SX1276Read( REG_PACKETCONFIG1, &SX1276->RegPacketConfig1 );
SX1276->RegPacketConfig1 = ( SX1276->RegPacketConfig1 & RF_PACKETCONFIG1_CRC_MASK ) | ( enable << 4 );
SX1276Write( REG_PACKETCONFIG1, SX1276->RegPacketConfig1 );
FskSettings.CrcOn = enable;
}
bool SX1276FskGetPacketCrcOn( void )
{
SX1276Read( REG_PACKETCONFIG1, &SX1276->RegPacketConfig1 );
FskSettings.CrcOn = ( SX1276->RegPacketConfig1 & RF_PACKETCONFIG1_CRC_ON ) >> 4;
return FskSettings.CrcOn;
}
void SX1276FskSetAfcOn( bool enable )
{
SX1276Read( REG_RXCONFIG, &SX1276->RegRxConfig );
SX1276->RegRxConfig = ( SX1276->RegRxConfig & RF_RXCONFIG_AFCAUTO_MASK ) | ( enable << 4 );
SX1276Write( REG_RXCONFIG, SX1276->RegRxConfig );
FskSettings.AfcOn = enable;
}
bool SX1276FskGetAfcOn( void )
{
SX1276Read( REG_RXCONFIG, &SX1276->RegRxConfig );
FskSettings.AfcOn = ( SX1276->RegRxConfig & RF_RXCONFIG_AFCAUTO_ON ) >> 4;
return FskSettings.AfcOn;
}
void SX1276FskSetPayloadLength( uint8_t value )
{
SX1276->RegPayloadLength = value;
SX1276Write( REG_PAYLOADLENGTH, SX1276->RegPayloadLength );
FskSettings.PayloadLength = value;
}
uint8_t SX1276FskGetPayloadLength( void )
{
SX1276Read( REG_PAYLOADLENGTH, &SX1276->RegPayloadLength );
FskSettings.PayloadLength = SX1276->RegPayloadLength;
return FskSettings.PayloadLength;
}
void SX1276FskSetPa20dBm( bool enale )
{
SX1276Read( REG_PADAC, &SX1276->RegPaDac );
SX1276Read( REG_PACONFIG, &SX1276->RegPaConfig );
if( ( SX1276->RegPaConfig & RF_PACONFIG_PASELECT_PABOOST ) == RF_PACONFIG_PASELECT_PABOOST )
{
if( enale == true )
{
SX1276->RegPaDac = 0x87;
}
}
else
{
SX1276->RegPaDac = 0x84;
}
SX1276Write( REG_PADAC, SX1276->RegPaDac );
}
bool SX1276FskGetPa20dBm( void )
{
SX1276Read( REG_PADAC, &SX1276->RegPaDac );
return ( ( SX1276->RegPaDac & 0x07 ) == 0x07 ) ? true : false;
}
void SX1276FskSetPAOutput( uint8_t outputPin )
{
SX1276Read( REG_PACONFIG, &SX1276->RegPaConfig );
SX1276->RegPaConfig = (SX1276->RegPaConfig & RF_PACONFIG_PASELECT_MASK ) | outputPin;
SX1276Write( REG_PACONFIG, SX1276->RegPaConfig );
}
uint8_t SX1276FskGetPAOutput( void )
{
SX1276Read( REG_PACONFIG, &SX1276->RegPaConfig );
return SX1276->RegPaConfig & ~RF_PACONFIG_PASELECT_MASK;
}
void SX1276FskSetPaRamp( uint8_t value )
{
SX1276Read( REG_PARAMP, &SX1276->RegPaRamp );
SX1276->RegPaRamp = ( SX1276->RegPaRamp & RF_PARAMP_MASK ) | ( value & ~RF_PARAMP_MASK );
SX1276Write( REG_PARAMP, SX1276->RegPaRamp );
}
uint8_t SX1276FskGetPaRamp( void )
{
SX1276Read( REG_PARAMP, &SX1276->RegPaRamp );
return SX1276->RegPaRamp & ~RF_PARAMP_MASK;
}
void SX1276FskSetRssiOffset( int8_t offset )
{
SX1276Read( REG_RSSICONFIG, &SX1276->RegRssiConfig );
if( offset < 0 )
{
offset = ( ~offset & 0x1F );
offset += 1;
offset = -offset;
}
SX1276->RegRssiConfig |= ( uint8_t )( ( offset & 0x1F ) << 3 );
SX1276Write( REG_RSSICONFIG, SX1276->RegRssiConfig );
}
int8_t SX1276FskGetRssiOffset( void )
{
int8_t offset;
SX1276Read( REG_RSSICONFIG, &SX1276->RegRssiConfig );
offset = SX1276->RegRssiConfig >> 3;
if( ( offset & 0x10 ) == 0x10 )
{
offset = ( ~offset & 0x1F );
offset += 1;
offset = -offset;
}
return offset;
}
int8_t SX1276FskGetRawTemp( void )
{
int8_t temp = 0;
uint8_t previousOpMode;
uint32_t startTick;
// Enable Temperature reading
SX1276Read( REG_IMAGECAL, &SX1276->RegImageCal );
SX1276->RegImageCal = ( SX1276->RegImageCal & RF_IMAGECAL_TEMPMONITOR_MASK ) | RF_IMAGECAL_TEMPMONITOR_ON;
SX1276Write( REG_IMAGECAL, SX1276->RegImageCal );
// save current Op Mode
SX1276Read( REG_OPMODE, &SX1276->RegOpMode );
previousOpMode = SX1276->RegOpMode;
// put device in FSK RxSynth
SX1276->RegOpMode = RF_OPMODE_SYNTHESIZER_RX;
SX1276Write( REG_OPMODE, SX1276->RegOpMode );
// Wait 1ms
startTick = GET_TICK_COUNT( );
while( ( GET_TICK_COUNT( ) - startTick ) < TICK_RATE_MS( 1 ) );
// Disable Temperature reading
SX1276Read( REG_IMAGECAL, &SX1276->RegImageCal );
SX1276->RegImageCal = ( SX1276->RegImageCal & RF_IMAGECAL_TEMPMONITOR_MASK ) | RF_IMAGECAL_TEMPMONITOR_OFF;
SX1276Write( REG_IMAGECAL, SX1276->RegImageCal );
// Read temperature
SX1276Read( REG_TEMP, &SX1276->RegTemp );
temp = SX1276->RegTemp & 0x7F;
if( ( SX1276->RegTemp & 0x80 ) == 0x80 )
{
temp *= -1;
}
// Reload previous Op Mode
SX1276Write( REG_OPMODE, previousOpMode );
return temp;
}
int8_t SX1276FskCalibreateTemp( int8_t actualTemp )
{
return actualTemp - SX1276FskGetRawTemp( );
}
int8_t SX1276FskGetTemp( int8_t compensationFactor )
{
return SX1276FskGetRawTemp( ) + compensationFactor;
}
#endif // USE_SX1276_RADIO

View File

@ -0,0 +1,251 @@
/*
* THE FOLLOWING FIRMWARE IS PROVIDED: (1) "AS IS" WITH NO WARRANTY; AND
* (2)TO ENABLE ACCESS TO CODING INFORMATION TO GUIDE AND FACILITATE CUSTOMER.
* CONSEQUENTLY, SEMTECH SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR
* CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
* OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION
* CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* Copyright (C) SEMTECH S.A.
*/
/*!
* \file sx1276-FskMisc.h
* \brief SX1276 RF chip high level functions driver
*
* \remark Optional support functions.
* These functions are defined only to easy the change of the
* parameters.
* For a final firmware the radio parameters will be known so
* there is no need to support all possible parameters.
* Removing these functions will greatly reduce the final firmware
* size.
*
* \version 2.0.B2
* \date May 6 2013
* \author Gregory Cristian
*
* Last modified by Miguel Luis on Jun 19 2013
*/
/*************************************************
File name: sx1276-FskMisc.h
Description: support aiit board configure and register function
History:
1. Date: 2021-04-25
Author: AIIT XUOS Lab
Modification:
1. replace original macro and basic date type with AIIT XUOS Lab's own defination
*************************************************/
#ifndef __SX1276_FSK_MISC_H__
#define __SX1276_FSK_MISC_H__
/*!
* \brief Writes the new RF frequency value
*
* \param [IN] freq New RF frequency value in [Hz]
*/
void SX1276FskSetRFFrequency( uint32_t freq );
/*!
* \brief Reads the current RF frequency value
*
* \retval freq Current RF frequency value in [Hz]
*/
uint32_t SX1276FskGetRFFrequency( void );
/*!
* \brief Calibrate RSSI and I/Q mismatch for HF
*
* \retval none
*/
void SX1276FskRxCalibrate( void );
/*!
* \brief Writes the new bitrate value
*
* \param [IN] bitrate New bitrate value in [bps]
*/
void SX1276FskSetBitrate( uint32_t bitrate );
/*!
* \brief Reads the current bitrate value
*
* \retval bitrate Current bitrate value in [bps]
*/
uint32_t SX1276FskGetBitrate( void );
/*!
* \brief Writes the new frequency deviation value
*
* \param [IN] fdev New frequency deviation value in [Hz]
*/
void SX1276FskSetFdev( uint32_t fdev );
/*!
* \brief Reads the current frequency deviation value
*
* \retval fdev Current frequency deviation value in [Hz]
*/
uint32_t SX1276FskGetFdev( void );
/*!
* \brief Writes the new RF output power value
*
* \param [IN] power New output power value in [dBm]
*/
void SX1276FskSetRFPower( int8_t power );
/*!
* \brief Reads the current RF output power value
*
* \retval power Current output power value in [dBm]
*/
int8_t SX1276FskGetRFPower( void );
/*!
* \brief Writes the DC offset canceller and Rx bandwidth values
*
* \remark For SX1276 there is no DCC setting. dccValue should be 0
* ie: SX1276SetDccBw( &SX1276.RegRxBw, 0, 62500 );
*
* \param [IN] reg Register pointer to either SX1231.RegRxBw or SX1231.RegAfcBw
* \param [IN] dccValue New DC offset canceller value in [Hz] ( SX1231 only )
* \param [IN] rxBwValue New Rx bandwidth value in [Hz]
*/
void SX1276FskSetDccBw( uint8_t* reg, uint32_t dccValue, uint32_t rxBwValue );
/*!
* \brief Reads the current bandwidth setting
*
* \param [IN] reg Register pointer to either SX1231.RegRxBw or SX1231.RegAfcBw
*
* \retval bandwidth Bandwidth value
*/
uint32_t SX1276FskGetBw( uint8_t* reg );
/*!
* \brief Enables/Disables CRC
*
* \param [IN] enable CRC enable/disable
*/
void SX1276FskSetPacketCrcOn( bool enable );
/*!
* \brief Reads the current CRC Enable/Disbale value
*
* \retval enable Current CRC Enable/Disbale value
*/
bool SX1276FskGetPacketCrcOn( void );
/*!
* \brief Enables/Disables AFC
*
* \param [IN] enable AFC enable/disable
*/
void SX1276FskSetAfcOn( bool enable );
/*!
* \brief Reads the current AFC Enable/Disbale value
*
* \retval enable Current AFC Enable/Disbale value
*/
bool SX1276FskGetAfcOn( void );
/*!
* \brief Writes the new payload length value
*
* \param [IN] value New payload length value
*/
void SX1276FskSetPayloadLength( uint8_t value );
/*!
* \brief Reads the current payload length value
*
* \retval value Current payload length value
*/
uint8_t SX1276FskGetPayloadLength( void );
/*!
* \brief Enables/Disables the 20 dBm PA
*
* \param [IN] enable [true, false]
*/
void SX1276FskSetPa20dBm( bool enale );
/*!
* \brief Gets the current 20 dBm PA status
*
* \retval enable [true, false]
*/
bool SX1276FskGetPa20dBm( void );
/*!
* \brief Set the RF Output pin
*
* \param [IN] RF_PACONFIG_PASELECT_PABOOST or RF_PACONFIG_PASELECT_RFO
*/
void SX1276FskSetPAOutput( uint8_t outputPin );
/*!
* \brief Gets the used RF Ouptu pin
*
* \retval RF_PACONFIG_PASELECT_PABOOST or RF_PACONFIG_PASELECT_RFO
*/
uint8_t SX1276FskGetPAOutput( void );
/*!
* \brief Writes the new PA rise/fall time of ramp up/down value
*
* \param [IN] value New PaRamp value
*/
void SX1276FskSetPaRamp( uint8_t value );
/*!
* \brief Reads the current PA rise/fall time of ramp up/down value
*
* \retval value Current PaRamp value
*/
uint8_t SX1276FskGetPaRamp( void );
/*!
* \brief Applies an offset to the RSSI. Compensates board components
*
* \param [IN] offset Offset to be applied (+/-)
*/
void SX1276FskSetRssiOffset( int8_t offset );
/*!
* \brief Gets the current RSSI offset.
*
* \retval offset Current offset (+/-)
*/
int8_t SX1276FskGetRssiOffset( void );
/*!
* \brief Writes the new value for the preamble size
*
* \param [IN] size New value of pramble size
*/
void SX1276FskSetPreambleSize( uint16_t size );
/*!
* Reads the raw temperature
* \retval temperature New raw temperature reading in 2's complement format
*/
int8_t SX1276FskGetRawTemp( void );
/*!
* Computes the temperature compensation factor
* \param [IN] actualTemp Actual temperature measured by an external device
* \retval compensationFactor Computed compensation factor
*/
int8_t SX1276FskCalibreateTemp( int8_t actualTemp );
/*!
* Gets the actual compensated temperature
* \param [IN] compensationFactor Return value of the calibration function
* \retval New compensated temperature value
*/
int8_t SX1276FskGetTemp( int8_t compensationFactor );
#endif //__SX1276_FSK_MISC_H__

View File

@ -0,0 +1,170 @@
/*
* THE FOLLOWING FIRMWARE IS PROVIDED: (1) "AS IS" WITH NO WARRANTY; AND
* (2)TO ENABLE ACCESS TO CODING INFORMATION TO GUIDE AND FACILITATE CUSTOMER.
* CONSEQUENTLY, SEMTECH SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR
* CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
* OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION
* CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* Copyright (C) SEMTECH S.A.
*/
/*!
* \file sx1276-Hal.h
* \brief SX1276 Hardware Abstraction Layer
*
* \version 2.0.B2
* \date Nov 21 2012
* \author Miguel Luis
*
* Last modified by Miguel Luis on Jun 19 2013
*/
/*************************************************
File name: sx1276-Hal.h
Description: support aiit board configure and register function
History:
1. Date: 2021-04-25
Author: AIIT XUOS Lab
Modification:
1. replace original macro and basic date type with AIIT XUOS Lab's own defination
*************************************************/
#ifndef __SX1276_HAL_H__
#define __SX1276_HAL_H__
#include "platform.h"
/*!
* DIO state read functions mapping
*/
#define DIO0 SX1276ReadDio0( )
#define DIO1 SX1276ReadDio1( )
#define DIO2 SX1276ReadDio2( )
#define DIO3 SX1276ReadDio3( )
#define DIO4 SX1276ReadDio4( )
#define DIO5 SX1276ReadDio5( )
// RXTX pin control see errata note
#define RXTX( txEnable ) SX1276WriteRxTx( txEnable );
#define GET_TICK_COUNT( ) CurrentTicksGain()
#define TICK_RATE_MS( ms ) ( ms )
typedef enum
{
RADIO_RESET_OFF,
RADIO_RESET_ON,
}tRadioResetState;
/*!
* \brief Initializes the radio interface I/Os
*/
void SX1276InitIo( void );
/*!
* \brief Set the radio reset pin state
*
* \param state New reset pin state
*/
void SX1276SetReset( uint8_t state );
/*!
* \brief Writes the radio register at the specified address
*
* \param [IN]: addr Register address
* \param [IN]: data New register value
*/
void SX1276Write( uint8_t addr, uint8_t data );
/*!
* \brief Reads the radio register at the specified address
*
* \param [IN]: addr Register address
* \param [OUT]: data Register value
*/
void SX1276Read( uint8_t addr, uint8_t *data );
/*!
* \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 SX1276WriteBuffer( 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 SX1276ReadBuffer( uint8_t addr, uint8_t *buffer, uint8_t size );
/*!
* \brief Writes the buffer contents to the radio FIFO
*
* \param [IN] buffer Buffer containing data to be put on the FIFO.
* \param [IN] size Number of bytes to be written to the FIFO
*/
void SX1276WriteFifo( uint8_t *buffer, uint8_t size );
/*!
* \brief Reads the contents of the radio FIFO
*
* \param [OUT] buffer Buffer where to copy the FIFO read data.
* \param [IN] size Number of bytes to be read from the FIFO
*/
void SX1276ReadFifo( uint8_t *buffer, uint8_t size );
/*!
* \brief Gets the SX1276 DIO0 hardware pin status
*
* \retval status Current hardware pin status [1, 0]
*/
inline uint8_t SX1276ReadDio0( void );
/*!
* \brief Ge// USE_SX1276_RADIOts the SX1276 DIO1 hardware pin status
*
* \retval status Current hardware pin status [1, 0]
*/
inline uint8_t SX1276ReadDio1( void );
/*!
* \brief Gets the SX1276 DIO2 hardware pin status
*
* \retval status Current hardware pin status [1, 0]
*/
inline uint8_t SX1276ReadDio2( void );
/*!
* \brief Gets the SX1276 DIO3 hardware pin status
*
* \retval status Current hardware pin status [1, 0]
*/
inline uint8_t SX1276ReadDio3( void );
/*!
* \brief Gets the SX1276 DIO4 hardware pin status
*
* \retval status Current hardware pin status [1, 0]
*/
inline uint8_t SX1276ReadDio4( void );
/*!
* \brief Gets the SX1276 DIO5 hardware pin status
*
* \retval status Current hardware pin status [1, 0]
*/
inline uint8_t SX1276ReadDio5( void );
/*!
* \brief Writes the external RxTx pin value
*
* \remark see errata note
*
* \param [IN] txEnable [1: Tx, 0: Rx]
*/
inline void SX1276WriteRxTx( uint8_t txEnable );
#endif //__SX1276_HAL_H__

View File

@ -0,0 +1,723 @@
/*
* THE FOLLOWING FIRMWARE IS PROVIDED: (1) "AS IS" WITH NO WARRANTY; AND
* (2)TO ENABLE ACCESS TO CODING INFORMATION TO GUIDE AND FACILITATE CUSTOMER.
* CONSEQUENTLY, SEMTECH SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR
* CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
* OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION
* CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* Original Copyright (C) SEMTECH S.A.
* Modified Copyright (C) 2020 AIIT XUOS Lab
*/
/*!
* \file sx1276-LoRa.c
* \brief SX1276 RF chip driver mode LoRa
*
* \version 2.0.0
* \date Nov 21 2012
* \author Miguel Luis
*
* Last modified by Miguel Luis on Jun 19 2013
*/
/*************************************************
File name: sx1276-LoRa.c
Description: support aiit board configure and register function
History:
1. Date: 2021-04-25
Author: AIIT XUOS Lab
Modification:
1. replace original macro and basic date type with AIIT XUOS Lab's own defination
*************************************************/
#include <string.h>
#include "platform.h"
#if defined( USE_SX1276_RADIO )
#include "radio.h"
#include "sx1276-Hal.h"
#include "sx1276.h"
#include "sx1276-LoRaMisc.h"
#include "sx1276-LoRa.h"
#define LoRa_FREQENCY 433000000
#define RSSI_OFFSET_LF -155.0
#define RSSI_OFFSET_HF -150.0
#define NOISE_ABSOLUTE_ZERO -174.0
#define NOISE_FIGURE_LF 4.0
#define NOISE_FIGURE_HF 6.0
volatile uint32 TickCounter = 0;
uint32 Tx_Time_Start,Tx_Time_End;
uint32 Rx_Time_Start,Rx_Time_End;
//Signal bandwidth, used to calculate RSSI
const double SignalBwLog[] =
{
3.8927900303521316335038277369285, // 7.8 kHz
4.0177301567005500940384239336392, // 10.4 kHz
4.193820026016112828717566631653, // 15.6 kHz
4.31875866931372901183597627752391, // 20.8 kHz
4.4948500216800940239313055263775, // 31.2 kHz
4.6197891057238405255051280399961, // 41.6 kHz
4.795880017344075219145044421102, // 62.5 kHz
5.0969100130080564143587833158265, // 125 kHz
5.397940008672037609572522210551, // 250 kHz
5.6989700043360188047862611052755 // 500 kHz
};
//These values need testing
const double RssiOffsetLF[] =
{
-155.0,
-155.0,
-155.0,
-155.0,
-155.0,
-155.0,
-155.0,
-155.0,
-155.0,
-155.0,
};
//These values need testing
const double RssiOffsetHF[] =
{
-150.0,
-150.0,
-150.0,
-150.0,
-150.0,
-150.0,
-150.0,
-150.0,
-150.0,
-150.0,
};
/*!
* Frequency hopping frequencies table
*/
const int32_t HoppingFrequencies[] =
{
916500000,
923500000,
906500000,
917500000,
917500000,
909000000,
903000000,
916000000,
912500000,
926000000,
925000000,
909500000,
913000000,
918500000,
918500000,
902500000,
911500000,
926500000,
902500000,
922000000,
924000000,
903500000,
913000000,
922000000,
926000000,
910000000,
920000000,
922500000,
911000000,
922000000,
909500000,
926000000,
922000000,
918000000,
925500000,
908000000,
917500000,
926500000,
908500000,
916000000,
905500000,
916000000,
903000000,
905000000,
915000000,
913000000,
907000000,
910000000,
926500000,
925500000,
911000000,
};
// Default settings
tLoRaSettings LoRaSettings =
{
LoRa_FREQENCY , // RFFrequency
20, // Power
9, // SignalBw [0: 125 kHz, 1: 250 kHz, 2: 500 kHz, 3: Reserved]
12, // SpreadingFactor [6: 64, 7: 128, 8: 256, 9: 512, 10: 1024, 11: 2048, 12: 4096 chips]
2, // ErrorCoding [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8]
true, // CrcOn [0: OFF, 1: ON]
false, // ImplicitHeaderOn [0: OFF, 1: ON]
0, // RxSingleOn [0: Continuous, 1 Single]
0, // FreqHopOn [0: OFF, 1: ON]
4, // HopPeriod Hops every frequency hopping period symbols
1000, // TxPacketTimeout
1000, // RxPacketTimeout
128, // PayloadLength (used for implicit header mode)
};
/*!
* SX1276 LoRa registers variable
*/
tSX1276LR* SX1276LR;
/*!
* Local RF buffer for communication support
*/
static uint8_t RFBuffer[RF_BUFFER_SIZE];
static uint8_t TFBuffer[RF_BUFFER_SIZE];
/*!
* RF state machine variable
*/
static uint8_t RFLRState = RFLR_STATE_IDLE;
/*!
* Rx management support variables
*/
static uint16_t RxPacketSize = 0;
static int8_t RxPacketSnrEstimate;
static double RxPacketRssiValue;
static uint8_t RxGain = 1;
static uint32_t RxTimeoutTimer = 0;
/*!
* PacketTimeout Stores the Rx window time value for packet reception
*/
static uint32_t PacketTimeout;
/*!
* Tx management support variables
*/
static uint16_t TxPacketSize = 0;
void SX1276LoRaInit( void )
{
RFLRState = RFLR_STATE_IDLE;
SX1276LoRaSetDefaults();
SX1276ReadBuffer( REG_LR_OPMODE, SX1276Regs + 1, 0x70 - 1 );
//SX1276LoRaSetOpMode( RFLR_OPMODE_SLEEP );
SX1276LR->RegLna = RFLR_LNA_GAIN_G1;
SX1276WriteBuffer( REG_LR_OPMODE, SX1276Regs + 1, 0x70 - 1 );
// set the RF settings
SX1276LoRaSetRFFrequency( LoRaSettings.RFFrequency );
SX1276LoRaSetSpreadingFactor( LoRaSettings.SpreadingFactor );
SX1276LoRaSetErrorCoding( LoRaSettings.ErrorCoding );
SX1276LoRaSetPacketCrcOn( LoRaSettings.CrcOn );
SX1276LoRaSetSignalBandwidth( LoRaSettings.SignalBw );
SX1276LoRaSetImplicitHeaderOn( LoRaSettings.ImplicitHeaderOn );
SX1276LoRaSetSymbTimeout(0x3FF);
SX1276LoRaSetPayloadLength( LoRaSettings.PayloadLength );
SX1276LoRaSetLowDatarateOptimize( true );
#if( ( MODULE_SX1276RF1IAS == 1 ) || ( MODULE_SX1276RF1KAS == 1 ) )
if( LoRaSettings.RFFrequency > 860000000 )
{
SX1276LoRaSetPAOutput( RFLR_PACONFIG_PASELECT_RFO );
SX1276LoRaSetPa20dBm( false );
LoRaSettings.Power = 14;
SX1276LoRaSetRFPower( LoRaSettings.Power );
}
else
{
//SX1276Write( REG_LR_OCP, 0x3f );
SX1276LoRaSetPAOutput( RFLR_PACONFIG_PASELECT_PABOOST );
SX1276LoRaSetPa20dBm( true );
LoRaSettings.Power = 20;
SX1276LoRaSetRFPower( LoRaSettings.Power );
}
#elif( MODULE_SX1276RF1JAS == 1 )
if( LoRaSettings.RFFrequency > 380000000 )
{
SX1276LoRaSetPAOutput( RFLR_PACONFIG_PASELECT_PABOOST );
SX1276LoRaSetPa20dBm( true );
LoRaSettings.Power = 20;
SX1276LoRaSetRFPower( LoRaSettings.Power );
}
else
{
SX1276LoRaSetPAOutput( RFLR_PACONFIG_PASELECT_RFO );
SX1276LoRaSetPa20dBm( false );
LoRaSettings.Power = 14;
SX1276LoRaSetRFPower( LoRaSettings.Power );
}
#endif
SX1276LoRaSetOpMode( RFLR_OPMODE_STANDBY );
SX1276ReadBuffer( REG_LR_OPMODE, SX1276Regs + 1, 0x70 - 1 );
}
void SX1276LoRaSetDefaults( void )
{
// REMARK: See SX1276 datasheet for modified default values.
// Sets IF frequency selection manual
SX1276Read( REG_LR_VERSION, &SX1276LR->RegVersion );
}
void SX1276LoRaReset( void )
{
uint32_t startTick;
SX1276SetReset( RADIO_RESET_ON );
// Wait 1ms
startTick = GET_TICK_COUNT( );
while( ( GET_TICK_COUNT( ) - startTick ) < TICK_RATE_MS( 1 ) );
SX1276SetReset( RADIO_RESET_OFF );
// Wait 6ms
startTick = GET_TICK_COUNT( );
while( ( GET_TICK_COUNT( ) - startTick ) < TICK_RATE_MS( 6 ) );
}
void SX1276LoRaSetOpMode( uint8_t opMode )
{
static uint8_t opModePrev = RFLR_OPMODE_STANDBY;
static bool antennaSwitchTxOnPrev = true;
bool antennaSwitchTxOn = false;
opModePrev = SX1276LR->RegOpMode & ~RFLR_OPMODE_MASK;
if( opMode != opModePrev )
{
if( opMode == RFLR_OPMODE_TRANSMITTER )
{
antennaSwitchTxOn = true;
}
else
{
antennaSwitchTxOn = false;
}
if( antennaSwitchTxOn != antennaSwitchTxOnPrev )
{
antennaSwitchTxOnPrev = antennaSwitchTxOn; // Antenna switch control
RXTX( antennaSwitchTxOn );
}
SX1276LR->RegOpMode = ( SX1276LR->RegOpMode & RFLR_OPMODE_MASK ) | opMode | RFLR_OPMODE_FREQMODE_ACCESS_LF;
SX1276Write( REG_LR_OPMODE, SX1276LR->RegOpMode );
}
}
uint8_t SX1276LoRaGetOpMode( void )
{
SX1276Read( REG_LR_OPMODE, &SX1276LR->RegOpMode );
return SX1276LR->RegOpMode & ~RFLR_OPMODE_MASK;
}
uint8_t SX1276LoRaReadRxGain( void )
{
SX1276Read( REG_LR_LNA, &SX1276LR->RegLna );
return( SX1276LR->RegLna >> 5 ) & 0x07;
}
double SX1276LoRaReadRssi( void )
{
// Reads the RSSI value
SX1276Read( REG_LR_RSSIVALUE, &SX1276LR->RegRssiValue );
if( LoRaSettings.RFFrequency < 860000000 )
{
return RssiOffsetLF[LoRaSettings.SignalBw] + ( double )SX1276LR->RegRssiValue;
}
else
{
return RssiOffsetHF[LoRaSettings.SignalBw] + ( double )SX1276LR->RegRssiValue;
}
}
uint8_t SX1276LoRaGetPacketRxGain( void )
{
return RxGain;
}
int8_t SX1276LoRaGetPacketSnr( void )
{
return RxPacketSnrEstimate;
}
double SX1276LoRaGetPacketRssi( void )
{
return RxPacketRssiValue;
}
void SX1276LoRaStartRx( void )
{
SX1276LoRaSetRFState( RFLR_STATE_RX_INIT );
}
void SX1276LoRaGetRxPacket( void *buffer, uint16_t *size )
{
*size = RxPacketSize;
RxPacketSize = 0;
memcpy( (void*)buffer, (void*)RFBuffer, (size_t)*size );
}
void SX1276LoRaSetTxPacket( const void *buffer, uint16_t size )
{
if( LoRaSettings.FreqHopOn == false )
{
TxPacketSize = size;
}
else
{
TxPacketSize = 255;
}
memcpy( ( void * )TFBuffer, buffer, ( size_t )TxPacketSize );
RFLRState = RFLR_STATE_TX_INIT;
}
uint8_t SX1276LoRaGetRFState( void )
{
return RFLRState;
}
void SX1276LoRaSetRFState( uint8_t state )
{
RFLRState = state;
}
/*!
* \brief Process the LoRa modem Rx and Tx state machines depending on the
* SX1276 operating mode.
*
* \retval rfState Current RF state [RF_IDLE, RF_BUSY,
* RF_RX_DONE, RF_RX_TIMEOUT,
* RF_TX_DONE, RF_TX_TIMEOUT]
*/
uint32_t SX1276LoRaProcess( void )
{
uint32_t result = RF_BUSY;
uint8_t regValue = 0;
switch( RFLRState )
{
case RFLR_STATE_IDLE:
break;
case RFLR_STATE_RX_INIT:
SX1276LoRaSetOpMode(RFLR_OPMODE_STANDBY);
SX1276LR->RegIrqFlagsMask = RFLR_IRQFLAGS_RXTIMEOUT |
//RFLR_IRQFLAGS_RXDONE |
RFLR_IRQFLAGS_PAYLOADCRCERROR |
RFLR_IRQFLAGS_VALIDHEADER |
RFLR_IRQFLAGS_TXDONE |
RFLR_IRQFLAGS_CADDONE |
RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL |
RFLR_IRQFLAGS_CADDETECTED;
SX1276Write( REG_LR_IRQFLAGSMASK, SX1276LR->RegIrqFlagsMask );
if(LoRaSettings.FreqHopOn == true )
{
SX1276LR->RegHopPeriod = LoRaSettings.HopPeriod;
SX1276Read( REG_LR_HOPCHANNEL, &SX1276LR->RegHopChannel );
SX1276LoRaSetRFFrequency( HoppingFrequencies[SX1276LR->RegHopChannel & RFLR_HOPCHANNEL_CHANNEL_MASK] );
}
else
{
SX1276LR->RegHopPeriod = 255;
}
SX1276Write( REG_LR_HOPPERIOD, SX1276LR->RegHopPeriod );
if( LoRaSettings.RxSingleOn == true ) // Rx single mode
{
SX1276LoRaSetOpMode( RFLR_OPMODE_RECEIVER_SINGLE );
}
else // Rx continuous mode
{
SX1276LR->RegFifoAddrPtr = SX1276LR->RegFifoRxBaseAddr;
SX1276Write( REG_LR_FIFOADDRPTR, SX1276LR->RegFifoAddrPtr );
SX1276LoRaSetOpMode( RFLR_OPMODE_RECEIVER );
}
memset( RFBuffer, 0, ( size_t )RF_BUFFER_SIZE );
Rx_Time_Start=TickCounter;
PacketTimeout = LoRaSettings.RxPacketTimeout;
RxTimeoutTimer = GET_TICK_COUNT( );
RFLRState = RFLR_STATE_RX_RUNNING;
break;
case RFLR_STATE_RX_RUNNING:
SX1276Read(0x12, &regValue);
// RxDone
if(regValue & (1<<6))
{
RxTimeoutTimer = GET_TICK_COUNT( );
if( LoRaSettings.FreqHopOn == true )
{
SX1276Read( REG_LR_HOPCHANNEL, &SX1276LR->RegHopChannel );
SX1276LoRaSetRFFrequency( HoppingFrequencies[SX1276LR->RegHopChannel & RFLR_HOPCHANNEL_CHANNEL_MASK] );
}
// Clear Irq
SX1276Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_RXDONE );
RFLRState = RFLR_STATE_RX_DONE;
}
// FHSS Changed Channel
if(regValue & (1<<1))
{
RxTimeoutTimer = GET_TICK_COUNT( );
if( LoRaSettings.FreqHopOn == true )
{
SX1276Read( REG_LR_HOPCHANNEL, &SX1276LR->RegHopChannel );
SX1276LoRaSetRFFrequency( HoppingFrequencies[SX1276LR->RegHopChannel & RFLR_HOPCHANNEL_CHANNEL_MASK] );
}
// Clear Irq
SX1276Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL );
//RxGain = SX1276LoRaReadRxGain( );
}
if( LoRaSettings.RxSingleOn == true ) // Rx single mode
{
if( ( GET_TICK_COUNT( ) - RxTimeoutTimer ) > PacketTimeout )
{
RFLRState = RFLR_STATE_RX_TIMEOUT;
}
}
break;
case RFLR_STATE_RX_DONE:
SX1276Read( REG_LR_IRQFLAGS, &SX1276LR->RegIrqFlags );
if( ( SX1276LR->RegIrqFlags & RFLR_IRQFLAGS_PAYLOADCRCERROR ) == RFLR_IRQFLAGS_PAYLOADCRCERROR )
{
// Clear Irq
SX1276Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_PAYLOADCRCERROR );
if( LoRaSettings.RxSingleOn == true ) // Rx single mode
{
RFLRState = RFLR_STATE_RX_INIT;
}
else
{
RFLRState = RFLR_STATE_RX_RUNNING;
}
break;
}
if( LoRaSettings.RxSingleOn == true ) // Rx single mode
{
SX1276LR->RegFifoAddrPtr = SX1276LR->RegFifoRxBaseAddr;
SX1276Write( REG_LR_FIFOADDRPTR, SX1276LR->RegFifoAddrPtr );
if( LoRaSettings.ImplicitHeaderOn == true )
{
RxPacketSize = SX1276LR->RegPayloadLength;
SX1276ReadFifo( RFBuffer, SX1276LR->RegPayloadLength );
}
else
{
SX1276Read( REG_LR_NBRXBYTES, &SX1276LR->RegNbRxBytes );
RxPacketSize = SX1276LR->RegNbRxBytes;
SX1276ReadFifo( RFBuffer, SX1276LR->RegNbRxBytes );
}
}
else // Rx continuous mode
{
SX1276Read( REG_LR_FIFORXCURRENTADDR, &SX1276LR->RegFifoRxCurrentAddr );
if( LoRaSettings.ImplicitHeaderOn == true )
{
RxPacketSize = SX1276LR->RegPayloadLength;
SX1276LR->RegFifoAddrPtr = SX1276LR->RegFifoRxCurrentAddr;
SX1276Write( REG_LR_FIFOADDRPTR, SX1276LR->RegFifoAddrPtr );
SX1276ReadFifo( RFBuffer, SX1276LR->RegPayloadLength );
}
else
{
SX1276Read( REG_LR_NBRXBYTES, &SX1276LR->RegNbRxBytes );
RxPacketSize = SX1276LR->RegNbRxBytes;
SX1276LR->RegFifoAddrPtr = SX1276LR->RegFifoRxCurrentAddr;
SX1276Write( REG_LR_FIFOADDRPTR, SX1276LR->RegFifoAddrPtr );
SX1276ReadFifo( RFBuffer, SX1276LR->RegNbRxBytes );
}
}
if( LoRaSettings.RxSingleOn == true ) // Rx single mode
{
RFLRState = RFLR_STATE_RX_INIT;
}
else // Rx continuous mode
{
RFLRState = RFLR_STATE_RX_RUNNING;
}
Rx_Time_End=TickCounter;
result = RF_RX_DONE;
break;
case RFLR_STATE_RX_TIMEOUT:
RFLRState = RFLR_STATE_RX_INIT;
result = RF_RX_TIMEOUT;
break;
case RFLR_STATE_TX_INIT:
Tx_Time_Start = TickCounter;
// Initializes the payload size
SX1276LR->RegPayloadLength = TxPacketSize;
SX1276Write( REG_LR_PAYLOADLENGTH, SX1276LR->RegPayloadLength );
SX1276LR->RegFifoTxBaseAddr = 0x00; // Full buffer used for Tx
SX1276Write( REG_LR_FIFOTXBASEADDR, SX1276LR->RegFifoTxBaseAddr );
SX1276LR->RegFifoAddrPtr = SX1276LR->RegFifoTxBaseAddr;
SX1276Write( REG_LR_FIFOADDRPTR, SX1276LR->RegFifoAddrPtr );
SX1276LoRaSetOpMode( RFLR_OPMODE_STANDBY );
// Write payload buffer to LORA modem
SX1276WriteFifo( TFBuffer, SX1276LR->RegPayloadLength );
if( LoRaSettings.FreqHopOn == true )
{
SX1276LR->RegIrqFlagsMask = RFLR_IRQFLAGS_RXTIMEOUT |
RFLR_IRQFLAGS_RXDONE |
RFLR_IRQFLAGS_PAYLOADCRCERROR |
RFLR_IRQFLAGS_VALIDHEADER |
//RFLR_IRQFLAGS_TXDONE |
RFLR_IRQFLAGS_CADDONE |
RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL |
RFLR_IRQFLAGS_CADDETECTED;
SX1276LR->RegHopPeriod = LoRaSettings.HopPeriod;
SX1276Read( REG_LR_HOPCHANNEL, &SX1276LR->RegHopChannel );
SX1276LoRaSetRFFrequency( HoppingFrequencies[SX1276LR->RegHopChannel & RFLR_HOPCHANNEL_CHANNEL_MASK] );
}
else
{
SX1276LR->RegIrqFlagsMask = RFLR_IRQFLAGS_RXTIMEOUT |
RFLR_IRQFLAGS_RXDONE |
RFLR_IRQFLAGS_PAYLOADCRCERROR |
RFLR_IRQFLAGS_VALIDHEADER |
//RFLR_IRQFLAGS_TXDONE |
RFLR_IRQFLAGS_CADDONE |
RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL |
RFLR_IRQFLAGS_CADDETECTED;
SX1276LR->RegHopPeriod = 0;
}
SX1276Write( REG_LR_HOPPERIOD, SX1276LR->RegHopPeriod );
SX1276Write( REG_LR_IRQFLAGSMASK, SX1276LR->RegIrqFlagsMask );
SX1276Write( REG_LR_DIOMAPPING1, ( regValue & RFLR_DIOMAPPING1_DIO0_MASK ) | RFLR_DIOMAPPING1_DIO0_01 );//DIO0设置为TXdone中断
SX1276LoRaSetOpMode( RFLR_OPMODE_TRANSMITTER );
RFLRState = RFLR_STATE_TX_RUNNING;
break;
case RFLR_STATE_TX_RUNNING:
SX1276Read(0x12, &regValue);
if(regValue & (1<<3))
{
// Clear Irq
SX1276Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_TXDONE );
RFLRState = RFLR_STATE_TX_DONE;
}
// FHSS Changed Channel
if(regValue & (1<<3))
{
if( LoRaSettings.FreqHopOn == true )
{
SX1276Read( REG_LR_HOPCHANNEL, &SX1276LR->RegHopChannel );
SX1276LoRaSetRFFrequency( HoppingFrequencies[SX1276LR->RegHopChannel & RFLR_HOPCHANNEL_CHANNEL_MASK] );
}
// Clear Irq
SX1276Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL );
}
break;
case RFLR_STATE_TX_DONE:
Tx_Time_End=TickCounter;
SX1276LoRaSetOpMode( RFLR_OPMODE_STANDBY );
RFLRState = RFLR_STATE_IDLE;
result = RF_TX_DONE;
break;
case RFLR_STATE_CAD_INIT:
// optimize the power consumption by switching off the transmitter as soon as the packet has been sent
SX1276LoRaSetOpMode( RFLR_OPMODE_STANDBY );
SX1276LR->RegIrqFlagsMask = RFLR_IRQFLAGS_RXTIMEOUT |
RFLR_IRQFLAGS_RXDONE |
RFLR_IRQFLAGS_PAYLOADCRCERROR |
RFLR_IRQFLAGS_VALIDHEADER |
RFLR_IRQFLAGS_TXDONE |
//RFLR_IRQFLAGS_CADDONE |
RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL;
//RFLR_IRQFLAGS_CADDETECTED;
SX1276Write( REG_LR_IRQFLAGSMASK, SX1276LR->RegIrqFlagsMask );
SX1276LoRaSetOpMode( RFLR_OPMODE_CAD );
RFLRState = RFLR_STATE_CAD_RUNNING;
break;
case RFLR_STATE_CAD_RUNNING:
SX1276Read(0x12,&regValue);
int cad_done = regValue & (1<<2);
int cad_detected = regValue & (1<<0);
if( cad_done ) //CAD Done interrupt
{
SX1276Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_CADDONE );
if( cad_detected ) // CAD Detected interrupt
{
SX1276Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_CADDETECTED );
//CAD detected, we have a LoRa preamble
RFLRState = RFLR_STATE_RX_INIT;
result = RF_CHANNEL_ACTIVITY_DETECTED;
}
else
{
// The device goes in Standby Mode automatically
RFLRState = RFLR_STATE_IDLE;
result = RF_CHANNEL_EMPTY;
}
}
break;
default:
break;
}
return result;
}
uint32_t SX1276LoraChannelEmpty( void )
{
uint32_t result = 0;
RFLRState = RFLR_STATE_CAD_INIT;
SX1276LoRaProcess();
while(RFLRState == RFLR_STATE_CAD_RUNNING)
{
//KPrintf("\nLora--SX1276LoRaProcess()");
result = SX1276LoRaProcess();
}
if(result == RF_CHANNEL_EMPTY)
{
KPrintf("\nLora--RF_CHANNEL_EMPTY\n");
return 0;
}
else if(result == RF_CHANNEL_ACTIVITY_DETECTED)
{
KPrintf("\nLora--RF_CHANNEL_ACTIVITY_DETECTED\n");
return 1;
}
else
{
return 2;
}
}
#endif // USE_SX1276_RADIO

View File

@ -0,0 +1,820 @@
/*
* THE FOLLOWING FIRMWARE IS PROVIDED: (1) "AS IS" WITH NO WARRANTY; AND
* (2)TO ENABLE ACCESS TO CODING INFORMATION TO GUIDE AND FACILITATE CUSTOMER.
* CONSEQUENTLY, SEMTECH SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR
* CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
* OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION
* CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* Original Copyright (C) SEMTECH S.A.
* Modified Copyright (C) 2020 AIIT XUOS Lab
*/
/*!
* \file sx1276-LoRa.h
* \brief SX1276 RF chip driver mode LoRa
*
* \version 2.0.0
* \date Nov 21 2012
* \author Miguel Luis
*
* Last modified by Miguel Luis on Jun 19 2013
*/
/*************************************************
File name: sx1276-LoRa.h
Description: support aiit board configure and register function
History:
1. Date: 2021-04-25
Author: AIIT XUOS Lab
Modification:
1. replace original macro and basic date type with AIIT XUOS Lab's own defination
*************************************************/
#ifndef __SX1276_LORA_H__
#define __SX1276_LORA_H__
#include "stdint.h"
#include "stdbool.h"
//SX1276一些配置参数设置
typedef struct sLoRaSettings
{
uint32_t RFFrequency; //无线通信频率
int8_t Power; //功率
uint8_t SignalBw; //LORA 带宽[0: 7.8 kHz, 1: 10.4 kHz, 2: 15.6 kHz, 3: 20.8 kHz, 4: 31.2 kHz,
//5: 41.6 kHz, 6: 62.5 kHz, 7: 125 kHz, 8: 250 kHz, 9: 500 kHz, other: Reserved]
uint8_t SpreadingFactor; //扩频因子 LORA [6: 64, 7: 128, 8: 256, 9: 512, 10: 1024, 11: 2048, 12: 4096 chips]
uint8_t ErrorCoding; //LORA 纠错码 [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8]
bool CrcOn; //CRC效验开关 [0: OFF, 1: ON]
bool ImplicitHeaderOn; //隐藏头部信息开关 [0: OFF, 1: ON]
bool RxSingleOn; //接收单次模式\连续模式配置[0: Continuous, 1 Single]
bool FreqHopOn; //跳频模式开关 [0: OFF, 1: ON]
uint8_t HopPeriod; //跳频之间的周期长度 Hops every frequency hopping period symbols
uint32_t TxPacketTimeout; //最大发送时间
uint32_t RxPacketTimeout; //最大接收时间
uint8_t PayloadLength; //数据长度
}tLoRaSettings;
//RF数据包大小(模块配备了256Byte的RAM缓存该缓存仅能通过LoRa模式访问)
#define RF_BUFFER_SIZE_MAX 256
#define RF_BUFFER_SIZE 256
//LoRa的返回值
typedef enum
{
RFLR_STATE_IDLE,
RFLR_STATE_RX_INIT,
RFLR_STATE_RX_RUNNING,
RFLR_STATE_RX_DONE,
RFLR_STATE_RX_TIMEOUT,
RFLR_STATE_TX_INIT,
RFLR_STATE_TX_RUNNING,
RFLR_STATE_TX_DONE,
RFLR_STATE_TX_TIMEOUT,
RFLR_STATE_CAD_INIT,
RFLR_STATE_CAD_RUNNING,
}tRFLRStates;
//SX1276 definitions
#define XTAL_FREQ 32000000
#define FREQ_STEP 61.03515625
/*LoRa模式寄存器映射*/
//SX1276内部寄存器地址
#define REG_LR_FIFO 0x00 //FIFO 数据输入/输出。当器件处于睡眠模式时FIFO被清零无法访问。
//通用寄存器
#define REG_LR_OPMODE 0x01 //关于模式选择相关的寄存器
#define REG_LR_BANDSETTING 0x04
#define REG_LR_FRFMSB 0x06 //RF 载波频率最高有效位
#define REG_LR_FRFMID 0x07 //RF 载波频率中间有效位
#define REG_LR_FRFLSB 0x08 //RF 载波频率最低有效位
//RF模块寄存器
#define REG_LR_PACONFIG 0x09
#define REG_LR_PARAMP 0x0A
#define REG_LR_OCP 0x0B
#define REG_LR_LNA 0x0C
//LoRa页面寄存器
#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 //IAQ标志屏蔽
#define REG_LR_IRQFLAGS 0x12
#define REG_LR_NBRXBYTES 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_MODEMCONFIG3 0x26
/*以上是LoRa模式寄存器映射*/
//IO控制寄存器关于DI00-DI05的映射设置
#define REG_LR_DIOMAPPING1 0x40
#define REG_LR_DIOMAPPING2 0x41
//版本寄存器
#define REG_LR_VERSION 0x42
//附加寄存器
#define REG_LR_PLLHOP 0x44
#define REG_LR_TCXO 0x4B
#define REG_LR_PADAC 0x4D
#define REG_LR_FORMERTEMP 0x5B
#define REG_LR_BITRATEFRAC 0x5D
#define REG_LR_AGCREF 0x61
#define REG_LR_AGCTHRESH1 0x62
#define REG_LR_AGCTHRESH2 0x63
#define REG_LR_AGCTHRESH3 0x64
//与模式选择相关的宏定义 RegOpMode(寄存器地址0X01)
#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_FREQMODE_ACCESS_MASK 0xF7
#define RFLR_OPMODE_FREQMODE_ACCESS_LF 0x08 // Default
#define RFLR_OPMODE_FREQMODE_ACCESS_HF 0x00
#define RFLR_OPMODE_MASK 0xF8
#define RFLR_OPMODE_SLEEP 0x00 //睡眠模式
#define RFLR_OPMODE_STANDBY 0x01 //待机模式
#define RFLR_OPMODE_SYNTHESIZER_TX 0x02 //频率合成器转换至Tx频率
#define RFLR_OPMODE_TRANSMITTER 0x03 //发送模式
#define RFLR_OPMODE_SYNTHESIZER_RX 0x04 //频率合成器转换至Rx频率
#define RFLR_OPMODE_RECEIVER 0x05 //接收模式
#define RFLR_OPMODE_RECEIVER_SINGLE 0x06 //单次接收模式
#define RFLR_OPMODE_CAD 0x07 //CAD模式
//与位带操作相关的宏定义
#define RFLR_BANDSETTING_MASK 0x3F
#define RFLR_BANDSETTING_AUTO 0x00 // Default
#define RFLR_BANDSETTING_DIV_BY_1 0x40
#define RFLR_BANDSETTING_DIV_BY_2 0x80
#define RFLR_BANDSETTING_DIV_BY_6 0xC0
//射频载波频率设置相关宏定义 RegFrf (MHz)(寄存器地址0x060x07,0x08)
#define RFLR_FRFMSB_434_MHZ 0x6C // Default
#define RFLR_FRFMID_434_MHZ 0x80 // Default
#define RFLR_FRFLSB_434_MHZ 0x00 // Default
#define RFLR_FRFMSB_470_MHZ 0x73 // Default
#define RFLR_FRFMID_470_MHZ 0xBB // Default
#define RFLR_FRFLSB_470_MHZ 0xBB // Default
#define RFLR_FRFMSB_863_MHZ 0xD7
#define RFLR_FRFMID_863_MHZ 0xC0
#define RFLR_FRFLSB_863_MHZ 0x00
#define RFLR_FRFMSB_864_MHZ 0xD8
#define RFLR_FRFMID_864_MHZ 0x00
#define RFLR_FRFLSB_864_MHZ 0x00
#define RFLR_FRFMSB_865_MHZ 0xD8
#define RFLR_FRFMID_865_MHZ 0x40
#define RFLR_FRFLSB_865_MHZ 0x00
#define RFLR_FRFMSB_866_MHZ 0xD8
#define RFLR_FRFMID_866_MHZ 0x80
#define RFLR_FRFLSB_866_MHZ 0x00
#define RFLR_FRFMSB_867_MHZ 0xD8
#define RFLR_FRFMID_867_MHZ 0xC0
#define RFLR_FRFLSB_867_MHZ 0x00
#define RFLR_FRFMSB_868_MHZ 0xD9
#define RFLR_FRFMID_868_MHZ 0x00
#define RFLR_FRFLSB_868_MHZ 0x00
#define RFLR_FRFMSB_869_MHZ 0xD9
#define RFLR_FRFMID_869_MHZ 0x40
#define RFLR_FRFLSB_869_MHZ 0x00
#define RFLR_FRFMSB_870_MHZ 0xD9
#define RFLR_FRFMID_870_MHZ 0x80
#define RFLR_FRFLSB_870_MHZ 0x00
#define RFLR_FRFMSB_902_MHZ 0xE1
#define RFLR_FRFMID_902_MHZ 0x80
#define RFLR_FRFLSB_902_MHZ 0x00
#define RFLR_FRFMSB_903_MHZ 0xE1
#define RFLR_FRFMID_903_MHZ 0xC0
#define RFLR_FRFLSB_903_MHZ 0x00
#define RFLR_FRFMSB_904_MHZ 0xE2
#define RFLR_FRFMID_904_MHZ 0x00
#define RFLR_FRFLSB_904_MHZ 0x00
#define RFLR_FRFMSB_905_MHZ 0xE2
#define RFLR_FRFMID_905_MHZ 0x40
#define RFLR_FRFLSB_905_MHZ 0x00
#define RFLR_FRFMSB_906_MHZ 0xE2
#define RFLR_FRFMID_906_MHZ 0x80
#define RFLR_FRFLSB_906_MHZ 0x00
#define RFLR_FRFMSB_907_MHZ 0xE2
#define RFLR_FRFMID_907_MHZ 0xC0
#define RFLR_FRFLSB_907_MHZ 0x00
#define RFLR_FRFMSB_908_MHZ 0xE3
#define RFLR_FRFMID_908_MHZ 0x00
#define RFLR_FRFLSB_908_MHZ 0x00
#define RFLR_FRFMSB_909_MHZ 0xE3
#define RFLR_FRFMID_909_MHZ 0x40
#define RFLR_FRFLSB_909_MHZ 0x00
#define RFLR_FRFMSB_910_MHZ 0xE3
#define RFLR_FRFMID_910_MHZ 0x80
#define RFLR_FRFLSB_910_MHZ 0x00
#define RFLR_FRFMSB_911_MHZ 0xE3
#define RFLR_FRFMID_911_MHZ 0xC0
#define RFLR_FRFLSB_911_MHZ 0x00
#define RFLR_FRFMSB_912_MHZ 0xE4
#define RFLR_FRFMID_912_MHZ 0x00
#define RFLR_FRFLSB_912_MHZ 0x00
#define RFLR_FRFMSB_913_MHZ 0xE4
#define RFLR_FRFMID_913_MHZ 0x40
#define RFLR_FRFLSB_913_MHZ 0x00
#define RFLR_FRFMSB_914_MHZ 0xE4
#define RFLR_FRFMID_914_MHZ 0x80
#define RFLR_FRFLSB_914_MHZ 0x00
#define RFLR_FRFMSB_915_MHZ 0xE4 // Default
#define RFLR_FRFMID_915_MHZ 0xC0 // Default
#define RFLR_FRFLSB_915_MHZ 0x00 // Default
#define RFLR_FRFMSB_916_MHZ 0xE5
#define RFLR_FRFMID_916_MHZ 0x00
#define RFLR_FRFLSB_916_MHZ 0x00
#define RFLR_FRFMSB_917_MHZ 0xE5
#define RFLR_FRFMID_917_MHZ 0x40
#define RFLR_FRFLSB_917_MHZ 0x00
#define RFLR_FRFMSB_918_MHZ 0xE5
#define RFLR_FRFMID_918_MHZ 0x80
#define RFLR_FRFLSB_918_MHZ 0x00
#define RFLR_FRFMSB_919_MHZ 0xE5
#define RFLR_FRFMID_919_MHZ 0xC0
#define RFLR_FRFLSB_919_MHZ 0x00
#define RFLR_FRFMSB_920_MHZ 0xE6
#define RFLR_FRFMID_920_MHZ 0x00
#define RFLR_FRFLSB_920_MHZ 0x00
#define RFLR_FRFMSB_921_MHZ 0xE6
#define RFLR_FRFMID_921_MHZ 0x40
#define RFLR_FRFLSB_921_MHZ 0x00
#define RFLR_FRFMSB_922_MHZ 0xE6
#define RFLR_FRFMID_922_MHZ 0x80
#define RFLR_FRFLSB_922_MHZ 0x00
#define RFLR_FRFMSB_923_MHZ 0xE6
#define RFLR_FRFMID_923_MHZ 0xC0
#define RFLR_FRFLSB_923_MHZ 0x00
#define RFLR_FRFMSB_924_MHZ 0xE7
#define RFLR_FRFMID_924_MHZ 0x00
#define RFLR_FRFLSB_924_MHZ 0x00
#define RFLR_FRFMSB_925_MHZ 0xE7
#define RFLR_FRFMID_925_MHZ 0x40
#define RFLR_FRFLSB_925_MHZ 0x00
#define RFLR_FRFMSB_926_MHZ 0xE7
#define RFLR_FRFMID_926_MHZ 0x80
#define RFLR_FRFLSB_926_MHZ 0x00
#define RFLR_FRFMSB_927_MHZ 0xE7
#define RFLR_FRFMID_927_MHZ 0xC0
#define RFLR_FRFLSB_927_MHZ 0x00
#define RFLR_FRFMSB_928_MHZ 0xE8
#define RFLR_FRFMID_928_MHZ 0x00
#define RFLR_FRFLSB_928_MHZ 0x00
//PA功率放大器 选择和输出功率控制设置相关宏定义 RegPaConfig寄存器地址0X09
#define RFLR_PACONFIG_PASELECT_MASK 0x7F
#define RFLR_PACONFIG_PASELECT_PABOOST 0x80
#define RFLR_PACONFIG_PASELECT_RFO 0x00 // Default
#define RFLR_PACONFIG_MAX_POWER_MASK 0x8F
#define RFLR_PACONFIG_OUTPUTPOWER_MASK 0xF0
//PA功率放大器 斜升/斜降时间和低相噪设置相关定义 RegPaRamp寄存器地址0X0A
#define RFLR_PARAMP_TXBANDFORCE_MASK 0xEF
#define RFLR_PARAMP_TXBANDFORCE_BAND_SEL 0x10
#define RFLR_PARAMP_TXBANDFORCE_AUTO 0x00 // Default
#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寄存器地址0X0B
#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
//LNA低噪声放大器 )设置相关宏定义 RegLna寄存器地址0X0C
#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_LF_MASK 0xE7
#define RFLR_LNA_BOOST_LF_DEFAULT 0x00 // Default
#define RFLR_LNA_BOOST_LF_GAIN 0x08
#define RFLR_LNA_BOOST_LF_IP3 0x10
#define RFLR_LNA_BOOST_LF_BOOST 0x18
#define RFLR_LNA_RXBANDFORCE_MASK 0xFB
#define RFLR_LNA_RXBANDFORCE_BAND_SEL 0x04
#define RFLR_LNA_RXBANDFORCE_AUTO 0x00 // Default
#define RFLR_LNA_BOOST_HF_MASK 0xFC
#define RFLR_LNA_BOOST_HF_OFF 0x00 // Default
#define RFLR_LNA_BOOST_HF_ON 0x03
//FIFO 数据缓冲区中 SPI 接口地址指针寄存器地址0X0D
#define RFLR_FIFOADDRPTR 0x00 // Default
//发送信息的起始位置
#define RFLR_FIFOTXBASEADDR 0x80 // Default
//接收信息的起始位置
#define RFLR_FIFORXBASEADDR 0x00 // Default
/*!
* RegFifoRxCurrentAddr (Read Only)
*/
//关于中断屏蔽相关的宏定义
#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
//关于中断打开相关的宏定义
#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) //
*/
//与信号宽度纠错编码率是否显示报头有关宏定义寄存器位置0X1D
#define RFLR_MODEMCONFIG1_BW_MASK 0x0F
#define RFLR_MODEMCONFIG1_BW_7_81_KHZ 0x00
#define RFLR_MODEMCONFIG1_BW_10_41_KHZ 0x10
#define RFLR_MODEMCONFIG1_BW_15_62_KHZ 0x20
#define RFLR_MODEMCONFIG1_BW_20_83_KHZ 0x30
#define RFLR_MODEMCONFIG1_BW_31_25_KHZ 0x40
#define RFLR_MODEMCONFIG1_BW_41_66_KHZ 0x50
#define RFLR_MODEMCONFIG1_BW_62_50_KHZ 0x60
#define RFLR_MODEMCONFIG1_BW_125_KHZ 0x70 // Default
#define RFLR_MODEMCONFIG1_BW_250_KHZ 0x80
#define RFLR_MODEMCONFIG1_BW_500_KHZ 0x90
#define RFLR_MODEMCONFIG1_CODINGRATE_MASK 0xF1
#define RFLR_MODEMCONFIG1_CODINGRATE_4_5 0x02
#define RFLR_MODEMCONFIG1_CODINGRATE_4_6 0x04 // Default
#define RFLR_MODEMCONFIG1_CODINGRATE_4_7 0x06
#define RFLR_MODEMCONFIG1_CODINGRATE_4_8 0x08
#define RFLR_MODEMCONFIG1_IMPLICITHEADER_MASK 0xFE
#define RFLR_MODEMCONFIG1_IMPLICITHEADER_ON 0x01
#define RFLR_MODEMCONFIG1_IMPLICITHEADER_OFF 0x00 // Default
//与扩频因子接收模式发送CRC开启RX超时相关宏定义
#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_RXPAYLOADCRC_MASK 0xFB
#define RFLR_MODEMCONFIG2_RXPAYLOADCRC_ON 0x04
#define RFLR_MODEMCONFIG2_RXPAYLOADCRC_OFF 0x00 // Default
#define RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB_MASK 0xFC
#define RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB 0x00 // Default
/*!
* 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_PAYLOAD_CRC16_MASK 0xBF
#define RFLR_HOPCHANNEL_PAYLOAD_CRC16_ON 0x40
#define RFLR_HOPCHANNEL_PAYLOAD_CRC16_OFF 0x00 // Default
#define RFLR_HOPCHANNEL_CHANNEL_MASK 0x3F
/*!
* 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
/*!
* 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
*/
/*!
* RegFifoRxByteAddr (Read Only)
*/
/*!
* 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
/*!
* RegModemConfig3
*/
#define RFLR_MODEMCONFIG3_LOWDATARATEOPTIMIZE_MASK 0xF7
#define RFLR_MODEMCONFIG3_LOWDATARATEOPTIMIZE_ON 0x08
#define RFLR_MODEMCONFIG3_LOWDATARATEOPTIMIZE_OFF 0x00 // Default
#define RFLR_MODEMCONFIG3_AGCAUTO_MASK 0xFB
#define RFLR_MODEMCONFIG3_AGCAUTO_ON 0x04 // Default
#define RFLR_MODEMCONFIG3_AGCAUTO_OFF 0x00
/*!
* RegFormerTemp
*/
typedef struct sSX1276LR
{
uint8_t RegFifo; // 0x00
// Common settings
uint8_t RegOpMode; // 0x01
uint8_t RegRes02; // 0x02
uint8_t RegRes03; // 0x03
uint8_t RegBandSetting; // 0x04
uint8_t RegRes05; // 0x05
uint8_t RegFrfMsb; // 0x06
uint8_t RegFrfMid; // 0x07
uint8_t RegFrfLsb; // 0x08
// Tx settings
uint8_t RegPaConfig; // 0x09
uint8_t RegPaRamp; // 0x0A
uint8_t RegOcp; // 0x0B
// Rx settings
uint8_t RegLna; // 0x0C
// LoRa registers
uint8_t RegFifoAddrPtr; // 0x0D
uint8_t RegFifoTxBaseAddr; // 0x0E
uint8_t RegFifoRxBaseAddr; // 0x0F
uint8_t RegFifoRxCurrentAddr; // 0x10
uint8_t RegIrqFlagsMask; // 0x11
uint8_t RegIrqFlags; // 0x12
uint8_t RegNbRxBytes; // 0x13
uint8_t RegRxHeaderCntValueMsb; // 0x14
uint8_t RegRxHeaderCntValueLsb; // 0x15
uint8_t RegRxPacketCntValueMsb; // 0x16
uint8_t RegRxPacketCntValueLsb; // 0x17
uint8_t RegModemStat; // 0x18
uint8_t RegPktSnrValue; // 0x19
uint8_t RegPktRssiValue; // 0x1A
uint8_t RegRssiValue; // 0x1B
uint8_t RegHopChannel; // 0x1C
uint8_t RegModemConfig1; // 0x1D
uint8_t RegModemConfig2; // 0x1E
uint8_t RegSymbTimeoutLsb; // 0x1F
uint8_t RegPreambleMsb; // 0x20
uint8_t RegPreambleLsb; // 0x21
uint8_t RegPayloadLength; // 0x22
uint8_t RegMaxPayloadLength; // 0x23
uint8_t RegHopPeriod; // 0x24 跳频周期
uint8_t RegFifoRxByteAddr; // 0x25
uint8_t RegModemConfig3; // 0x26
uint8_t RegTestReserved27[0x30 - 0x27]; // 0x27-0x30
uint8_t RegTestReserved31; // 0x31
uint8_t RegTestReserved32[0x40 - 0x32]; // 0x32-0x40
// I/O settings
uint8_t RegDioMapping1; // 0x40
uint8_t RegDioMapping2; // 0x41
// Version
uint8_t RegVersion; // 0x42
// Additional settings
uint8_t RegAgcRef; // 0x43
uint8_t RegAgcThresh1; // 0x44
uint8_t RegAgcThresh2; // 0x45
uint8_t RegAgcThresh3; // 0x46
// Test
uint8_t RegTestReserved47[0x4B - 0x47]; // 0x47-0x4A
// Additional settings
uint8_t RegPllHop; // 0x4B
uint8_t RegTestReserved4C; // 0x4C
uint8_t RegPaDac; // 0x4D
// Test
uint8_t RegTestReserved4E[0x58-0x4E]; // 0x4E-0x57
// Additional settings
uint8_t RegTcxo; // 0x58
// Test
uint8_t RegTestReserved59; // 0x59
// Test
uint8_t RegTestReserved5B; // 0x5B
// Additional settings
uint8_t RegPll; // 0x5C
// Test
uint8_t RegTestReserved5D; // 0x5D
// Additional settings
uint8_t RegPllLowPn; // 0x5E
// Test
uint8_t RegTestReserved5F[0x6C - 0x5F]; // 0x5F-0x6B
// Additional settings
uint8_t RegFormerTemp; // 0x6C
// Test
uint8_t RegTestReserved6D[0x71 - 0x6D]; // 0x6D-0x70
}tSX1276LR;
extern tSX1276LR* SX1276LR;
//初始化SX1276LoRa模式
void SX1276LoRaInit( void );
//读SX1276的版本号
void SX1276LoRaSetDefaults( void );
//启用/禁用LoRa模式
void SX1276LoRaSetLoRaOn( bool enable );
//设置SX1276操作模式
void SX1276LoRaSetOpMode( uint8_t opMode );
//获取SX1276操作模式
uint8_t SX1276LoRaGetOpMode( void );
//读取SX1276低噪声放大器信号放大的增益
uint8_t SX1276LoRaReadRxGain( void );
//读取lora模式下无线信号强度
double SX1276LoRaReadRssi( void );
//获取数据时的增益值
uint8_t SX1276LoRaGetPacketRxGain( void );
//获取数据时的信噪比值,信号和噪声的比值,信噪比越高,说明信号干扰越小。
int8_t SX1276LoRaGetPacketSnr( void );
//获取数据时的无线信号强度
double SX1276LoRaGetPacketRssi( void );
//开始接收
void SX1276LoRaStartRx( void );
//接收数据
void SX1276LoRaGetRxPacket( void *buffer, uint16_t *size );
//发送数据
void SX1276LoRaSetTxPacket( const void *buffer, uint16_t size );
//得到RFLRState状态
uint8_t SX1276LoRaGetRFState( void );
//设置RFLRState状态RFLRState的值决定了下面的函数处理哪一步的代码
void SX1276LoRaSetRFState( uint8_t state );
//SX1276模块接发收数据的处理函数
uint32_t SX1276LoRaProcess( void );
uint32_t SX1276LoraChannelEmpty( void );
#endif

View File

@ -0,0 +1,420 @@
/*
* THE FOLLOWING FIRMWARE IS PROVIDED: (1) "AS IS" WITH NO WARRANTY; AND
* (2)TO ENABLE ACCESS TO CODING INFORMATION TO GUIDE AND FACILITATE CUSTOMER.
* CONSEQUENTLY, SEMTECH SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR
* CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
* OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION
* CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* Copyright (C) SEMTECH S.A.
*/
/*!
* \file sx1276-LoRaMisc.c
* \brief SX1276 RF chip high level functions driver
*
* \remark Optional support functions.
* These functions are defined only to easy the change of the
* parameters.
* For a final firmware the radio parameters will be known so
* there is no need to support all possible parameters.
* Removing these functions will greatly reduce the final firmware
* size.
*
* \version 2.0.0
* \date May 6 2013
* \author Gregory Cristian
*
* Last modified by Miguel Luis on Jun 19 2013
*/
/*************************************************
File name: sx1276-LoRaMisc.c
Description: support aiit board configure and register function
History:
1. Date: 2021-04-25
Author: AIIT XUOS Lab
Modification:
1. replace original macro and basic date type with AIIT XUOS Lab's own defination
*************************************************/
#include "platform.h"
#if defined( USE_SX1276_RADIO )
#include "sx1276-Hal.h"
#include "sx1276.h"
#include "sx1276-LoRa.h"
#include "sx1276-LoRaMisc.h"
/*!
* SX1276 definitions
*/
#define XTAL_FREQ 32000000
#define FREQ_STEP 61.03515625
extern tLoRaSettings LoRaSettings;
void SX1276LoRaSetRFFrequency( uint32_t freq )
{
LoRaSettings.RFFrequency = freq;
freq = ( uint32_t )( ( double )freq / ( double )FREQ_STEP );
SX1276LR->RegFrfMsb = ( uint8_t )( ( freq >> 16 ) & 0xFF );
SX1276LR->RegFrfMid = ( uint8_t )( ( freq >> 8 ) & 0xFF );
SX1276LR->RegFrfLsb = ( uint8_t )( freq & 0xFF );
SX1276WriteBuffer( REG_LR_FRFMSB, &SX1276LR->RegFrfMsb, 3 );
}
uint32_t SX1276LoRaGetRFFrequency( void )
{
SX1276ReadBuffer( REG_LR_FRFMSB, &SX1276LR->RegFrfMsb, 3 );
LoRaSettings.RFFrequency = ( ( uint32_t )SX1276LR->RegFrfMsb << 16 ) | ( ( uint32_t )SX1276LR->RegFrfMid << 8 ) | ( ( uint32_t )SX1276LR->RegFrfLsb );
LoRaSettings.RFFrequency = ( uint32_t )( ( double )LoRaSettings.RFFrequency * ( double )FREQ_STEP );
return LoRaSettings.RFFrequency;
}
void SX1276LoRaSetRFPower( int8_t power )
{
SX1276Read( REG_LR_PACONFIG, &SX1276LR->RegPaConfig );
SX1276Read( REG_LR_PADAC, &SX1276LR->RegPaDac );
if( ( SX1276LR->RegPaConfig & RFLR_PACONFIG_PASELECT_PABOOST ) == RFLR_PACONFIG_PASELECT_PABOOST )
{
if( ( SX1276LR->RegPaDac & 0x87 ) == 0x87 )
{
if( power < 5 )
{
power = 5;
}
if( power > 20 )
{
power = 20;
}
SX1276LR->RegPaConfig = ( SX1276LR->RegPaConfig & RFLR_PACONFIG_MAX_POWER_MASK ) | 0x70;
SX1276LR->RegPaConfig = ( SX1276LR->RegPaConfig & RFLR_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power - 5 ) & 0x0F );
}
else
{
if( power < 2 )
{
power = 2;
}
if( power > 17 )
{
power = 17;
}
SX1276LR->RegPaConfig = ( SX1276LR->RegPaConfig & RFLR_PACONFIG_MAX_POWER_MASK ) | 0x70;
SX1276LR->RegPaConfig = ( SX1276LR->RegPaConfig & RFLR_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power - 2 ) & 0x0F );
}
}
else
{
if( power < -1 )
{
power = -1;
}
if( power > 14 )
{
power = 14;
}
SX1276LR->RegPaConfig = ( SX1276LR->RegPaConfig & RFLR_PACONFIG_MAX_POWER_MASK ) | 0x70;
SX1276LR->RegPaConfig = ( SX1276LR->RegPaConfig & RFLR_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power + 1 ) & 0x0F );
}
SX1276Write( REG_LR_PACONFIG, SX1276LR->RegPaConfig );
LoRaSettings.Power = power;
}
int8_t SX1276LoRaGetRFPower( void )
{
SX1276Read( REG_LR_PACONFIG, &SX1276LR->RegPaConfig );
SX1276Read( REG_LR_PADAC, &SX1276LR->RegPaDac );
if( ( SX1276LR->RegPaConfig & RFLR_PACONFIG_PASELECT_PABOOST ) == RFLR_PACONFIG_PASELECT_PABOOST )
{
if( ( SX1276LR->RegPaDac & 0x07 ) == 0x07 )
{
LoRaSettings.Power = 5 + ( SX1276LR->RegPaConfig & ~RFLR_PACONFIG_OUTPUTPOWER_MASK );
}
else
{
LoRaSettings.Power = 2 + ( SX1276LR->RegPaConfig & ~RFLR_PACONFIG_OUTPUTPOWER_MASK );
}
}
else
{
LoRaSettings.Power = -1 + ( SX1276LR->RegPaConfig & ~RFLR_PACONFIG_OUTPUTPOWER_MASK );
}
return LoRaSettings.Power;
}
void SX1276LoRaSetSignalBandwidth( uint8_t bw )
{
SX1276Read( REG_LR_MODEMCONFIG1, &SX1276LR->RegModemConfig1 );
SX1276LR->RegModemConfig1 = ( SX1276LR->RegModemConfig1 & RFLR_MODEMCONFIG1_BW_MASK ) | ( bw << 4 );
SX1276Write( REG_LR_MODEMCONFIG1, SX1276LR->RegModemConfig1 );
LoRaSettings.SignalBw = bw;
}
uint8_t SX1276LoRaGetSignalBandwidth( void )
{
SX1276Read( REG_LR_MODEMCONFIG1, &SX1276LR->RegModemConfig1 );
LoRaSettings.SignalBw = ( SX1276LR->RegModemConfig1 & ~RFLR_MODEMCONFIG1_BW_MASK ) >> 4;
return LoRaSettings.SignalBw;
}
void SX1276LoRaSetSpreadingFactor( uint8_t factor )
{
if( factor > 12 )
{
factor = 12;
}
else if( factor < 6 )
{
factor = 6;
}
if( factor == 6 )
{
SX1276LoRaSetNbTrigPeaks( 5 );
}
else
{
SX1276LoRaSetNbTrigPeaks( 3 );
}
SX1276Read( REG_LR_MODEMCONFIG2, &SX1276LR->RegModemConfig2 );
SX1276LR->RegModemConfig2 = ( SX1276LR->RegModemConfig2 & RFLR_MODEMCONFIG2_SF_MASK ) | ( factor << 4 );
SX1276Write( REG_LR_MODEMCONFIG2, SX1276LR->RegModemConfig2 );
LoRaSettings.SpreadingFactor = factor;
}
uint8_t SX1276LoRaGetSpreadingFactor( void )
{
SX1276Read( REG_LR_MODEMCONFIG2, &SX1276LR->RegModemConfig2 );
LoRaSettings.SpreadingFactor = ( SX1276LR->RegModemConfig2 & ~RFLR_MODEMCONFIG2_SF_MASK ) >> 4;
return LoRaSettings.SpreadingFactor;
}
void SX1276LoRaSetErrorCoding( uint8_t value )
{
SX1276Read( REG_LR_MODEMCONFIG1, &SX1276LR->RegModemConfig1 );
SX1276LR->RegModemConfig1 = ( SX1276LR->RegModemConfig1 & RFLR_MODEMCONFIG1_CODINGRATE_MASK ) | ( value << 1 );
SX1276Write( REG_LR_MODEMCONFIG1, SX1276LR->RegModemConfig1 );
LoRaSettings.ErrorCoding = value;
}
uint8_t SX1276LoRaGetErrorCoding( void )
{
SX1276Read( REG_LR_MODEMCONFIG1, &SX1276LR->RegModemConfig1 );
LoRaSettings.ErrorCoding = ( SX1276LR->RegModemConfig1 & ~RFLR_MODEMCONFIG1_CODINGRATE_MASK ) >> 1;
return LoRaSettings.ErrorCoding;
}
void SX1276LoRaSetPacketCrcOn( bool enable )
{
SX1276Read( REG_LR_MODEMCONFIG2, &SX1276LR->RegModemConfig2 );
SX1276LR->RegModemConfig2 = ( SX1276LR->RegModemConfig2 & RFLR_MODEMCONFIG2_RXPAYLOADCRC_MASK ) | ( enable << 2 );
SX1276Write( REG_LR_MODEMCONFIG2, SX1276LR->RegModemConfig2 );
LoRaSettings.CrcOn = enable;
}
void SX1276LoRaSetPreambleLength( uint16_t value )
{
SX1276ReadBuffer( REG_LR_PREAMBLEMSB, &SX1276LR->RegPreambleMsb, 2 );
SX1276LR->RegPreambleMsb = ( value >> 8 ) & 0x00FF;
SX1276LR->RegPreambleLsb = value & 0xFF;
SX1276WriteBuffer( REG_LR_PREAMBLEMSB, &SX1276LR->RegPreambleMsb, 2 );
}
uint16_t SX1276LoRaGetPreambleLength( void )
{
SX1276ReadBuffer( REG_LR_PREAMBLEMSB, &SX1276LR->RegPreambleMsb, 2 );
return ( ( SX1276LR->RegPreambleMsb & 0x00FF ) << 8 ) | SX1276LR->RegPreambleLsb;
}
bool SX1276LoRaGetPacketCrcOn( void )
{
SX1276Read( REG_LR_MODEMCONFIG2, &SX1276LR->RegModemConfig2 );
LoRaSettings.CrcOn = ( SX1276LR->RegModemConfig2 & RFLR_MODEMCONFIG2_RXPAYLOADCRC_ON ) >> 1;
return LoRaSettings.CrcOn;
}
void SX1276LoRaSetImplicitHeaderOn( bool enable )
{
SX1276Read( REG_LR_MODEMCONFIG1, &SX1276LR->RegModemConfig1 );
SX1276LR->RegModemConfig1 = ( SX1276LR->RegModemConfig1 & RFLR_MODEMCONFIG1_IMPLICITHEADER_MASK ) | ( enable );
SX1276Write( REG_LR_MODEMCONFIG1, SX1276LR->RegModemConfig1 );
LoRaSettings.ImplicitHeaderOn = enable;
}
bool SX1276LoRaGetImplicitHeaderOn( void )
{
SX1276Read( REG_LR_MODEMCONFIG1, &SX1276LR->RegModemConfig1 );
LoRaSettings.ImplicitHeaderOn = ( SX1276LR->RegModemConfig1 & RFLR_MODEMCONFIG1_IMPLICITHEADER_ON );
return LoRaSettings.ImplicitHeaderOn;
}
void SX1276LoRaSetRxSingleOn( bool enable )
{
LoRaSettings.RxSingleOn = enable;
}
bool SX1276LoRaGetRxSingleOn( void )
{
return LoRaSettings.RxSingleOn;
}
void SX1276LoRaSetFreqHopOn( bool enable )
{
LoRaSettings.FreqHopOn = enable;
}
bool SX1276LoRaGetFreqHopOn( void )
{
return LoRaSettings.FreqHopOn;
}
void SX1276LoRaSetHopPeriod( uint8_t value )
{
SX1276LR->RegHopPeriod = value;
SX1276Write( REG_LR_HOPPERIOD, SX1276LR->RegHopPeriod );
LoRaSettings.HopPeriod = value;
}
uint8_t SX1276LoRaGetHopPeriod( void )
{
SX1276Read( REG_LR_HOPPERIOD, &SX1276LR->RegHopPeriod );
LoRaSettings.HopPeriod = SX1276LR->RegHopPeriod;
return LoRaSettings.HopPeriod;
}
void SX1276LoRaSetTxPacketTimeout( uint32_t value )
{
LoRaSettings.TxPacketTimeout = value;
}
uint32_t SX1276LoRaGetTxPacketTimeout( void )
{
return LoRaSettings.TxPacketTimeout;
}
void SX1276LoRaSetRxPacketTimeout( uint32_t value )
{
LoRaSettings.RxPacketTimeout = value;
}
uint32_t SX1276LoRaGetRxPacketTimeout( void )
{
return LoRaSettings.RxPacketTimeout;
}
void SX1276LoRaSetPayloadLength( uint8_t value )
{
SX1276LR->RegPayloadLength = value;
SX1276Write( REG_LR_PAYLOADLENGTH, SX1276LR->RegPayloadLength );
LoRaSettings.PayloadLength = value;
}
uint8_t SX1276LoRaGetPayloadLength( void )
{
SX1276Read( REG_LR_PAYLOADLENGTH, &SX1276LR->RegPayloadLength );
LoRaSettings.PayloadLength = SX1276LR->RegPayloadLength;
return LoRaSettings.PayloadLength;
}
void SX1276LoRaSetPa20dBm( bool enale )
{
SX1276Read( REG_LR_PADAC, &SX1276LR->RegPaDac );
SX1276Read( REG_LR_PACONFIG, &SX1276LR->RegPaConfig );
if( ( SX1276LR->RegPaConfig & RFLR_PACONFIG_PASELECT_PABOOST ) == RFLR_PACONFIG_PASELECT_PABOOST )
{
if( enale == true )
{
SX1276LR->RegPaDac = 0x87;
}
}
else
{
SX1276LR->RegPaDac = 0x84;
}
SX1276Write( REG_LR_PADAC, SX1276LR->RegPaDac );
}
bool SX1276LoRaGetPa20dBm( void )
{
SX1276Read( REG_LR_PADAC, &SX1276LR->RegPaDac );
return ( ( SX1276LR->RegPaDac & 0x07 ) == 0x07 ) ? true : false;
}
void SX1276LoRaSetPAOutput( uint8_t outputPin )
{
SX1276Read( REG_LR_PACONFIG, &SX1276LR->RegPaConfig );
SX1276LR->RegPaConfig = (SX1276LR->RegPaConfig & RFLR_PACONFIG_PASELECT_MASK ) | outputPin;
SX1276Write( REG_LR_PACONFIG, SX1276LR->RegPaConfig );
}
uint8_t SX1276LoRaGetPAOutput( void )
{
SX1276Read( REG_LR_PACONFIG, &SX1276LR->RegPaConfig );
return SX1276LR->RegPaConfig & ~RFLR_PACONFIG_PASELECT_MASK;
}
void SX1276LoRaSetPaRamp( uint8_t value )
{
SX1276Read( REG_LR_PARAMP, &SX1276LR->RegPaRamp );
SX1276LR->RegPaRamp = ( SX1276LR->RegPaRamp & RFLR_PARAMP_MASK ) | ( value & ~RFLR_PARAMP_MASK );
SX1276Write( REG_LR_PARAMP, SX1276LR->RegPaRamp );
}
uint8_t SX1276LoRaGetPaRamp( void )
{
SX1276Read( REG_LR_PARAMP, &SX1276LR->RegPaRamp );
return SX1276LR->RegPaRamp & ~RFLR_PARAMP_MASK;
}
void SX1276LoRaSetSymbTimeout( uint16_t value )
{
SX1276ReadBuffer( REG_LR_MODEMCONFIG2, &SX1276LR->RegModemConfig2, 2 );
SX1276LR->RegModemConfig2 = ( SX1276LR->RegModemConfig2 & RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB_MASK ) | ( ( value >> 8 ) & ~RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB_MASK );
SX1276LR->RegSymbTimeoutLsb = value & 0xFF;
SX1276WriteBuffer( REG_LR_MODEMCONFIG2, &SX1276LR->RegModemConfig2, 2 );
}
uint16_t SX1276LoRaGetSymbTimeout( void )
{
SX1276ReadBuffer( REG_LR_MODEMCONFIG2, &SX1276LR->RegModemConfig2, 2 );
return ( ( SX1276LR->RegModemConfig2 & ~RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB_MASK ) << 8 ) | SX1276LR->RegSymbTimeoutLsb;
}
void SX1276LoRaSetLowDatarateOptimize( bool enable )
{
SX1276Read( REG_LR_MODEMCONFIG3, &SX1276LR->RegModemConfig3 );
SX1276LR->RegModemConfig3 = ( SX1276LR->RegModemConfig3 & RFLR_MODEMCONFIG3_LOWDATARATEOPTIMIZE_MASK ) | ( enable << 3 );
SX1276Write( REG_LR_MODEMCONFIG3, SX1276LR->RegModemConfig3 );
}
bool SX1276LoRaGetLowDatarateOptimize( void )
{
SX1276Read( REG_LR_MODEMCONFIG3, &SX1276LR->RegModemConfig3 );
return ( ( SX1276LR->RegModemConfig3 & RFLR_MODEMCONFIG3_LOWDATARATEOPTIMIZE_ON ) >> 3 );
}
void SX1276LoRaSetNbTrigPeaks( uint8_t value )
{
SX1276Read( 0x31, &SX1276LR->RegTestReserved31 );
SX1276LR->RegTestReserved31 = ( SX1276LR->RegTestReserved31 & 0xF8 ) | value;//数据包长度最高有效位 0x31 bit2 1 0
SX1276Write( 0x31, SX1276LR->RegTestReserved31 );
}
uint8_t SX1276LoRaGetNbTrigPeaks( void )
{
SX1276Read( 0x31, &SX1276LR->RegTestReserved31 );
return ( SX1276LR->RegTestReserved31 & 0x07 );
}
#endif // USE_SX1276_RADIO

View File

@ -0,0 +1,324 @@
/*
* THE FOLLOWING FIRMWARE IS PROVIDED: (1) "AS IS" WITH NO WARRANTY; AND
* (2)TO ENABLE ACCESS TO CODING INFORMATION TO GUIDE AND FACILITATE CUSTOMER.
* CONSEQUENTLY, SEMTECH SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR
* CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
* OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION
* CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* Copyright (C) SEMTECH S.A.
*/
/*!
* \file sx1276-LoRaMisc.h
* \brief SX1276 RF chip high level functions driver
*
* \remark Optional support functions.
* These functions are defined only to easy the change of the
* parameters.
* For a final firmware the radio parameters will be known so
* there is no need to support all possible parameters.
* Removing these functions will greatly reduce the final firmware
* size.
*
* \version 2.0.0
* \date May 6 2013
* \author Gregory Cristian
*
* Last modified by Miguel Luis on Jun 19 2013
*/
/*************************************************
File name: sx1276-LoRaMisc.h
Description: support aiit board configure and register function
History:
1. Date: 2021-04-25
Author: AIIT XUOS Lab
Modification:
1. replace original macro and basic date type with AIIT XUOS Lab's own defination
*************************************************/
#ifndef __SX1276_LORA_MISC_H__
#define __SX1276_LORA_MISC_H__
#include "stdint.h"
#include "stdbool.h"
/*!
* \brief Writes the new RF frequency value
*
* \param [IN] freq New RF frequency value in [Hz]
*/
void SX1276LoRaSetRFFrequency( uint32_t freq );
/*!
* \brief Reads the current RF frequency value
*
* \retval freq Current RF frequency value in [Hz]
*/
uint32_t SX1276LoRaGetRFFrequency( void );
/*!
* \brief Writes the new RF output power value
*
* \param [IN] power New output power value in [dBm]
*/
void SX1276LoRaSetRFPower( int8_t power );
/*!
* \brief Reads the current RF output power value
*
* \retval power Current output power value in [dBm]
*/
int8_t SX1276LoRaGetRFPower( void );
/*!
* \brief Writes the new Signal Bandwidth value
*
* \remark This function sets the IF frequency according to the datasheet
*
* \param [IN] factor New Signal Bandwidth value [0: 125 kHz, 1: 250 kHz, 2: 500 kHz]
*/
void SX1276LoRaSetSignalBandwidth( uint8_t bw );
/*!
* \brief Reads the current Signal Bandwidth value
*
* \retval factor Current Signal Bandwidth value [0: 125 kHz, 1: 250 kHz, 2: 500 kHz]
*/
uint8_t SX1276LoRaGetSignalBandwidth( void );
/*!
* \brief Writes the new Spreading Factor value
*
* \param [IN] factor New Spreading Factor value [7, 8, 9, 10, 11, 12]
*/
void SX1276LoRaSetSpreadingFactor( uint8_t factor );
/*!
* \brief Reads the current Spreading Factor value
*
* \retval factor Current Spreading Factor value [7, 8, 9, 10, 11, 12]
*/
uint8_t SX1276LoRaGetSpreadingFactor( void );
/*!
* \brief Writes the new Error Coding value
*
* \param [IN] value New Error Coding value [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8]
*/
void SX1276LoRaSetErrorCoding( uint8_t value );
/*!
* \brief Reads the current Error Coding value
*
* \retval value Current Error Coding value [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8]
*/
uint8_t SX1276LoRaGetErrorCoding( void );
/*!
* \brief Enables/Disables the packet CRC generation
*
* \param [IN] enaable [true, false]
*/
void SX1276LoRaSetPacketCrcOn( bool enable );
/*!
* \brief Reads the current packet CRC generation status
*
* \retval enable [true, false]
*/
bool SX1276LoRaGetPacketCrcOn( void );
/*!
* \brief Enables/Disables the Implicit Header mode in LoRa
*
* \param [IN] enable [true, false]
*/
void SX1276LoRaSetImplicitHeaderOn( bool enable );
/*!
* \brief Check if implicit header mode in LoRa in enabled or disabled
*
* \retval enable [true, false]
*/
bool SX1276LoRaGetImplicitHeaderOn( void );
/*!
* \brief Enables/Disables Rx single instead of Rx continuous
*
* \param [IN] enable [true, false]
*/
void SX1276LoRaSetRxSingleOn( bool enable );
/*!
* \brief Check if LoRa is in Rx Single mode
*
* \retval enable [true, false]
*/
bool SX1276LoRaGetRxSingleOn( void );
/*!
* \brief Enables/Disables the frequency hopping
*
* \param [IN] enable [true, false]
*/
void SX1276LoRaSetFreqHopOn( bool enable );
/*!
* \brief Get the frequency hopping status
*
* \param [IN] enable [true, false]
*/
bool SX1276LoRaGetFreqHopOn( void );
/*!
* \brief Set symbol period between frequency hops
*
* \param [IN] value
*/
void SX1276LoRaSetHopPeriod( uint8_t value );
/*!
* \brief Get symbol period between frequency hops
*
* \retval value symbol period between frequency hops
*/
uint8_t SX1276LoRaGetHopPeriod( void );
/*!
* \brief Set timeout Tx packet (based on MCU timer, timeout between Tx Mode entry Tx Done IRQ)
*
* \param [IN] value timeout (ms)
*/
void SX1276LoRaSetTxPacketTimeout( uint32_t value );
/*!
* \brief Get timeout between Tx packet (based on MCU timer, timeout between Tx Mode entry Tx Done IRQ)
*
* \retval value timeout (ms)
*/
uint32_t SX1276LoRaGetTxPacketTimeout( void );
/*!
* \brief Set timeout Rx packet (based on MCU timer, timeout between Rx Mode entry and Rx Done IRQ)
*
* \param [IN] value timeout (ms)
*/
void SX1276LoRaSetRxPacketTimeout( uint32_t value );
/*!
* \brief Get timeout Rx packet (based on MCU timer, timeout between Rx Mode entry and Rx Done IRQ)
*
* \retval value timeout (ms)
*/
uint32_t SX1276LoRaGetRxPacketTimeout( void );
/*!
* \brief Set payload length
*
* \param [IN] value payload length
*/
void SX1276LoRaSetPayloadLength( uint8_t value );
/*!
* \brief Get payload length
*
* \retval value payload length
*/
uint8_t SX1276LoRaGetPayloadLength( void );
/*!
* \brief Enables/Disables the 20 dBm PA
*
* \param [IN] enable [true, false]
*/
void SX1276LoRaSetPa20dBm( bool enale );
/*!
* \brief Gets the current 20 dBm PA status
*
* \retval enable [true, false]
*/
bool SX1276LoRaGetPa20dBm( void );
/*!
* \brief Set the RF Output pin
*
* \param [IN] RF_PACONFIG_PASELECT_PABOOST or RF_PACONFIG_PASELECT_RFO
*/
void SX1276LoRaSetPAOutput( uint8_t outputPin );
/*!
* \brief Gets the used RF Ouptut pin
*
* \retval RF_PACONFIG_PASELECT_PABOOST or RF_PACONFIG_PASELECT_RFO
*/
uint8_t SX1276LoRaGetPAOutput( void );
/*!
* \brief Writes the new PA rise/fall time of ramp up/down value
*
* \param [IN] value New PaRamp value
*/
void SX1276LoRaSetPaRamp( uint8_t value );
/*!
* \brief Reads the current PA rise/fall time of ramp up/down value
*
* \retval freq Current PaRamp value
*/
uint8_t SX1276LoRaGetPaRamp( void );
/*!
* \brief Set Symbol Timeout based on symbol length
*
* \param [IN] value number of symbol
*/
void SX1276LoRaSetSymbTimeout( uint16_t value );
/*!
* \brief Get Symbol Timeout based on symbol length
*
* \retval value number of symbol
*/
uint16_t SX1276LoRaGetSymbTimeout( void );
/*!
* \brief Configure the device to optimize low datarate transfers
*
* \param [IN] enable Enables/Disables the low datarate optimization
*/
void SX1276LoRaSetLowDatarateOptimize( bool enable );
/*!
* \brief Get the status of optimize low datarate transfers
*
* \retval LowDatarateOptimize enable or disable
*/
bool SX1276LoRaGetLowDatarateOptimize( void );
/*!
* \brief Get the preamble length
*
* \retval value preamble length
*/
uint16_t SX1276LoRaGetPreambleLength( void );
/*!
* \brief Set the preamble length
*
* \param [IN] value preamble length
*/
void SX1276LoRaSetPreambleLength( uint16_t value );
/*!
* \brief Set the number or rolling preamble symbol needed for detection
*
* \param [IN] value number of preamble symbol
*/
void SX1276LoRaSetNbTrigPeaks( uint8_t value );
/*!
* \brief Get the number or rolling preamble symbol needed for detection
*
* \retval value number of preamble symbol
*/
uint8_t SX1276LoRaGetNbTrigPeaks( void );
#endif

View File

@ -0,0 +1,327 @@
/*
* THE FOLLOWING FIRMWARE IS PROVIDED: (1) "AS IS" WITH NO WARRANTY; AND
* (2)TO ENABLE ACCESS TO CODING INFORMATION TO GUIDE AND FACILITATE CUSTOMER.
* CONSEQUENTLY, SEMTECH SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR
* CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
* OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION
* CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* Copyright (C) SEMTECH S.A.
*/
/*!
* \file sx1276.c
* \brief SX1276 RF chip high level functions driver
*
* \remark Optional support functions.
* These functions are defined only to easy the change of the
* parameters.
* For a final firmware the radio parameters will be known so
* there is no need to support all possible parameters.
* Removing these functions will greatly reduce the final firmware
* size.
*
* \version 2.0.0
* \date May 6 2013
* \author Gregory Cristian
*
* Last modified by Miguel Luis on Jun 19 2013
*/
/*************************************************
File name: sx1276.c
Description: support aiit board configure and register function
History:
1. Date: 2021-04-25
Author: AIIT XUOS Lab
Modification:
1. replace original macro and basic date type with AIIT XUOS Lab's own defination
*************************************************/
#include "platform.h"
#include "radio.h"
#if defined(USE_SX1276_RADIO)
#include "sx1276.h"
#include "sx1276-Hal.h"
#include "sx1276-Fsk.h"
#include "sx1276-LoRa.h"
uint8_t SX1276Regs[0x70];
static bool LoRaOn = true;
static bool LoRaOnState = false;
static int sx1276_tx_sem, sx1276_rx_sem;
static int sx1276_radio_task;
void SX1276Reset(void)
{
uint32_t startTick;
SX1276SetReset(RADIO_RESET_ON);
DDL_DelayMS(1);
SX1276SetReset(RADIO_RESET_OFF);
DDL_DelayMS(6);
}
void SX1276_SetLoRaOn(bool enable)
{
if(LoRaOnState == enable) {
return;
}
LoRaOnState = enable;
LoRaOn = enable;
if(LoRaOn == true) {
SX1276LoRaSetOpMode(RFLR_OPMODE_SLEEP);
SX1276LR->RegOpMode = (SX1276LR->RegOpMode & RFLR_OPMODE_LONGRANGEMODE_MASK) | RFLR_OPMODE_LONGRANGEMODE_ON;
SX1276Write(REG_LR_OPMODE, SX1276LR->RegOpMode);
SX1276LoRaSetOpMode(RFLR_OPMODE_STANDBY);
// RxDone RxTimeout FhssChangeChannel CadDone
SX1276LR->RegDioMapping1 = RFLR_DIOMAPPING1_DIO0_00 | RFLR_DIOMAPPING1_DIO1_00 | RFLR_DIOMAPPING1_DIO2_00 | RFLR_DIOMAPPING1_DIO3_00;
// CadDetected ModeReady
SX1276LR->RegDioMapping2 = RFLR_DIOMAPPING2_DIO4_00 | RFLR_DIOMAPPING2_DIO5_00;
SX1276WriteBuffer(REG_LR_DIOMAPPING1, &SX1276LR->RegDioMapping1, 2);
SX1276ReadBuffer(REG_LR_OPMODE, SX1276Regs + 1, 0x70 - 1);
} else {
SX1276LoRaSetOpMode(RFLR_OPMODE_SLEEP);
SX1276LR->RegOpMode = (SX1276LR->RegOpMode & RFLR_OPMODE_LONGRANGEMODE_MASK) | RFLR_OPMODE_LONGRANGEMODE_OFF;
SX1276Write(REG_LR_OPMODE, SX1276LR->RegOpMode);
SX1276LoRaSetOpMode(RFLR_OPMODE_STANDBY);
SX1276ReadBuffer(REG_OPMODE, SX1276Regs + 1, 0x70 - 1);
}
}
bool SX1276_GetLoRaOn(void)
{
return LoRaOn;
}
void SX1276SetOpMode(uint8_t opMode)
{
if(LoRaOn == false) {
SX1276FskSetOpMode(opMode);
} else {
SX1276LoRaSetOpMode(opMode);
}
}
uint8_t SX1276_GetOpMode(void)
{
if(LoRaOn == false) {
return SX1276FskGetOpMode();
} else {
return SX1276LoRaGetOpMode();
}
}
double SX1276ReadRssi(void)
{
if(LoRaOn == false) {
return SX1276FskReadRssi();
} else {
return SX1276LoRaReadRssi();
}
}
uint8_t SX1276_ReadRxGain(void)
{
if(LoRaOn == false) {
return SX1276FskReadRxGain();
} else {
return SX1276LoRaReadRxGain();
}
}
uint8_t SX1276_GetPacketRxGain(void)
{
if(LoRaOn == false) {
return SX1276FskGetPacketRxGain();
} else {
return SX1276LoRaGetPacketRxGain();
}
}
int8_t SX1276_GetPacketSnr(void)
{
if(LoRaOn == false) {
while(1) {
// Useless in FSK mode
// Block program here
}
} else {
return SX1276LoRaGetPacketSnr();
}
}
double SX1276_GetPacketRssi(void)
{
if(LoRaOn == false) {
return SX1276FskGetPacketRssi();
} else {
return SX1276LoRaGetPacketRssi();
}
}
uint32_t SX1276GetPacketAfc(void)
{
if(LoRaOn == false) {
return SX1276FskGetPacketAfc();
} else {
while(1) {
// Useless in LoRa mode
// Block program here
}
}
}
void SX1276StartRx(void)
{
if(LoRaOn == false) {
SX1276FskSetRFState(RF_STATE_RX_INIT);
} else {
SX1276LoRaSetRFState(RFLR_STATE_RX_INIT);
}
}
void SX1276GetRxPacket(void *buffer, uint16_t *size)
{
if(LoRaOn == false) {
SX1276FskGetRxPacket(buffer, size);
} else {
SX1276LoRaGetRxPacket(buffer, size);
}
}
int SX1276GetRx(void *buffer, uint16_t *size)
{
int ret = -1;
SX1276StartRx();
//receive timeout 10s
ret = KSemaphoreObtain(sx1276_rx_sem, 10000);
if (0 == ret) {
SX1276LoRaSetRFState(RFLR_STATE_IDLE);
SX1276GetRxPacket(buffer, size);
}
return ret;
}
void SX1276SetTxPacket(const void *buffer, uint16_t size)
{
if(LoRaOn == false) {
SX1276FskSetTxPacket(buffer, size);
} else {
SX1276LoRaSetTxPacket(buffer, size);
}
}
void SX1276SetTx(const void *buffer, uint16_t size)
{
SX1276SetTxPacket(buffer, size);
KSemaphoreObtain(sx1276_tx_sem, WAITING_FOREVER);
SX1276StartRx();
}
uint8_t SX1276GetRFState(void)
{
if(LoRaOn == false) {
return SX1276FskGetRFState();
} else {
return SX1276LoRaGetRFState();
}
}
void SX1276SetRFState(uint8_t state)
{
if(LoRaOn == false) {
SX1276FskSetRFState(state);
} else {
SX1276LoRaSetRFState(state);
}
}
uint32_t SX1276Process(void)
{
if(LoRaOn == false) {
return SX1276FskProcess();
} else {
return SX1276LoRaProcess();
}
}
static void Sx1276RadioEntry(void *parameter)
{
uint32_t result;
while(1) {
result = SX1276Process();
if (RF_RX_DONE == result) {
KSemaphoreAbandon(sx1276_rx_sem);
}
if (RF_TX_DONE == result) {
KSemaphoreAbandon(sx1276_tx_sem);
}
}
}
uint32_t SX1276ChannelEmpty(void)
{
if(LoRaOn == false) {
return true;
} else {
SX1276LoraChannelEmpty();
}
}
void SX1276Init(void)
{
uint8_t TempReg;
SX1276 = (tSX1276 *)SX1276Regs;
SX1276LR = (tSX1276LR *)SX1276Regs;
SX1276InitIo();
SX1276Reset();
SX1276Read(0x06, &TempReg);
if(TempReg != 0x6C) {
KPrintf("Hard SPI Err!\r\n");
}
SX1276Read(0x42, &TempReg);
if(TempReg != 0x12) {
KPrintf("Hard SPI Err! version 0x%x\r\n", TempReg);
}
#if (LORA == 0)
LoRaOn = false;
SX1276_SetLoRaOn(LoRaOn);
SX1276FskInit();
#else
LoRaOn = true;
SX1276_SetLoRaOn(LoRaOn);
SX1276LoRaInit();
#endif
sx1276_rx_sem = KSemaphoreCreate(0);
sx1276_tx_sem = KSemaphoreCreate(0);
sx1276_radio_task = KTaskCreate("radio", Sx1276RadioEntry , NONE, 2048, 20);
StartupKTask(sx1276_radio_task);
}
#endif

View File

@ -0,0 +1,97 @@
/*
* THE FOLLOWING FIRMWARE IS PROVIDED: (1) "AS IS" WITH NO WARRANTY; AND
* (2)TO ENABLE ACCESS TO CODING INFORMATION TO GUIDE AND FACILITATE CUSTOMER.
* CONSEQUENTLY, SEMTECH SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR
* CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
* OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION
* CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* Copyright (C) SEMTECH S.A.
*/
/*!
* \file sx1276.h
* \brief SX1276 RF chip high level functions driver
*
* \remark Optional support functions.
* These functions are defined only to easy the change of the
* parameters.
* For a final firmware the radio parameters will be known so
* there is no need to support all possible parameters.
* Removing these functions will greatly reduce the final firmware
* size.
*
* \version 2.0.0
* \date May 6 2013
* \author Gregory Cristian
*
* Last modified by Miguel Luis on Jun 19 2013
*/
/*************************************************
File name: sx1276.h
Description: support aiit board configure and register function
History:
1. Date: 2021-04-25
Author: AIIT XUOS Lab
Modification:
1. replace original macro and basic date type with AIIT XUOS Lab's own defination
*************************************************/
#ifndef __SX1276_H__
#define __SX1276_H__
#include <stdint.h>
#include <stdbool.h>
extern uint8_t SX1276Regs[0x70]; //SX1276寄存器数组
void SX1276Init( void ); //初始化SX1276
void SX1276Reset( void ); //重置SX1276
/*以下函数都没有被使用到因为在sx1276-LoRa.h里面又定义了一系列与下面作用相同的函数*/
void SX1276_SetLoRaOn( bool enable ); //启用LoRa调制解调器或FSK调制解调器
bool SX1276_GetLoRaOn( void ); //获取LoRa调制解调器状态
void SX1276SetOpMode( uint8_t opMode ); //设置SX1276操作模式
uint8_t SX1276_GetOpMode( void ); //获取SX1276操作模式
uint8_t SX1276_ReadRxGain( void ); //读取当前Rx增益设置
double SX1276ReadRssi( void ); //读取无线信号强度
uint8_t SX1276_GetPacketRxGain( void ); //获取数据时的增益值
int8_t SX1276_GetPacketSnr( void ); //获取数据时的信噪比值,信号和噪声的比值,信噪比越高,说明信号干扰越小。
double SX1276_GetPacketRssi( void ); //获取数据是的无线信号强度
/*!
* \brief Gets the AFC value measured while receiving the packet
*
* \retval afcValue Current AFC value in [Hz]
*/
uint32_t SX1276GetPacketAfc( void ); //此函数不知道作用
void SX1276StartRx( void ); //开始接收
void SX1276GetRxPacket( void *buffer, uint16_t *size ); //得到接收的数据
int SX1276GetRx(void *buffer, uint16_t *size); //应用接收数据,无数据时阻塞
void SX1276SetTxPacket( const void *buffer, uint16_t size ); //发送数据
void SX1276SetTx( const void *buffer, uint16_t size ); //应用发送数据
uint8_t SX1276GetRFState( void ); //得到RFLRState状态
void SX1276SetRFState( uint8_t state ); //设置RFLRState状态RFLRState的值决定了下面的函数处理哪一步的代码
uint32_t SX1276Process( void ); //SX1276模块接发收数据的处理函数
uint32_t SX1276ChannelEmpty( void );
#endif

View File

@ -34,8 +34,8 @@ config BSP_USING_RS485
default n
menuconfig BSP_USING_UART6
bool "Enable USART6"
default n
bool "Enable USART6 for 4G EC200A"
default y
if BSP_USING_UART6
config SERIAL_BUS_NAME_6
string "serial bus 6 name"