forked from xuos/xiuos
Add LoRa module
This commit is contained in:
parent
18da044bb7
commit
849f5d7dd5
|
@ -25,9 +25,9 @@ ifeq ($(CONFIG_RESOURCES_SPI_SD), y)
|
|||
SRC_FILES += spi_sd_card_mount.c
|
||||
endif
|
||||
|
||||
# ifeq ($(CONFIG_CONNECTION_COMMUNICATION_BOOTSTART_LORA_NET_SAMPLE), y)
|
||||
# SRC_DIR += connection_demo/adhoc_lora_demo
|
||||
# endif
|
||||
ifeq ($(CONFIG_CONNECTION_COMMUNICATION_BOOTSTART_LORA_NET_SAMPLE), y)
|
||||
SRC_DIR += connection_demo/adhoc_lora_demo
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_CONNECTION_COMMUNICATION_ZIGBEE), y)
|
||||
SRC_DIR += connection_demo/zigbee_demo
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
SRC_FILES := client.c gateway.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -0,0 +1,108 @@
|
|||
#include <user_api.h>
|
||||
#include <string.h>
|
||||
#include <xs_adapter_lora.h>
|
||||
#include <xs_adapter_manager.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
char client_name[DEVNAME_LEN_MAX] = "lora_dev_123";
|
||||
|
||||
void success_cb(void *param)
|
||||
{
|
||||
printf("success_cb, param = %s\n", param);
|
||||
}
|
||||
|
||||
void invert_param(void *param)
|
||||
{
|
||||
printf("success_cb02 invoke, invert bool param.\n");
|
||||
bool *bparam = (bool *)param;
|
||||
if (*bparam)
|
||||
{
|
||||
*bparam = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
*bparam = true;
|
||||
}
|
||||
}
|
||||
|
||||
void net_lora_client(int argc, char *argv[])
|
||||
{
|
||||
int pkg_count = 10;
|
||||
if (argc >= 1)
|
||||
{
|
||||
memset(client_name, 0, DEVNAME_LEN_MAX);
|
||||
strncpy(client_name, argv[1], strlen(argv[1]));
|
||||
printf("lora client set clientName(%s).\n", client_name);
|
||||
}
|
||||
|
||||
if (argc >= 2)
|
||||
{
|
||||
pkg_count = atoi(argv[2]);
|
||||
printf("lora client set pkg_count(%d).\n", pkg_count);
|
||||
}
|
||||
|
||||
// 1.Create an adapter for a specific agreement (LORA)
|
||||
static struct AdapterLora lora_adapter;
|
||||
memset(&lora_adapter, 0, sizeof(lora_adapter));
|
||||
struct AdapterDone lora_example_done = {
|
||||
.NetAiitOpen = LoraAdapterOpen,
|
||||
.NetAiitClose = LoraAdapterCose,
|
||||
.NetAiitSend = LoraAdapterSendc2g,
|
||||
.NetAiitReceive = NULL,
|
||||
.NetAiitJoin = LoraAdapterJoin,
|
||||
.NetAiitIoctl = NULL,
|
||||
};
|
||||
lora_adapter.parent.done = lora_example_done; // Bind adapter operation
|
||||
lora_adapter.name = client_name; // Set adapter name
|
||||
lora_adapter.spi_lora_fd = -1; // Set adapter information
|
||||
lora_adapter.deve_ui = "xxx";
|
||||
lora_adapter.app_key = "yyy";
|
||||
|
||||
// 2.Register the adapter in the list
|
||||
LoraAdapterInit();
|
||||
LoraAdapterRegister((adapter_t)&lora_adapter);
|
||||
|
||||
// 3.Find from the list of registered adapters
|
||||
adapter_t padapter = LoraAdapterFind(client_name);
|
||||
if (NONE == padapter)
|
||||
{
|
||||
printf("adapter find failed!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// 4.Open adapter
|
||||
if (0 != padapter->done.NetAiitOpen(padapter))
|
||||
{
|
||||
printf("adapter open failed!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// 5.Join the specified network segment as client
|
||||
printf("NetAiitJoin start. \n");
|
||||
padapter->done.NetAiitJoin(padapter, ROLE_TYPE_SLAVE, CONNECTION_COMMUNICATION_LORA_NET_ID);
|
||||
printf("NetAiitJoin end. \n");
|
||||
|
||||
// 6.Point to point sending data to gateway
|
||||
int i = 0;
|
||||
while (i < pkg_count)
|
||||
{
|
||||
char data[120] = {0};
|
||||
sprintf(data, "***** I am %s, data_num = %d ******" ,client_name, i);
|
||||
|
||||
bool v = false;
|
||||
padapter->done.NetAiitSend(padapter, data, strlen(data) + 1, true, 10000, 0, invert_param, &v, NULL);
|
||||
while (!v) // Asynchronous analog synchronization
|
||||
{
|
||||
UserTaskDelay(100);
|
||||
}
|
||||
printf("send success(main thread)... %s\n" ,data);
|
||||
|
||||
i++;
|
||||
UserTaskDelay(800); // Contract interval
|
||||
}
|
||||
printf("all pkg send success(main thread), quit.\n");
|
||||
|
||||
padapter->done.NetAiitClose(padapter);
|
||||
printf("client quit.\n");
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
#include <user_api.h>
|
||||
#include <string.h>
|
||||
#include <xs_klist.h>
|
||||
#include <xs_adapter_lora.h>
|
||||
#include <xs_adapter_manager.h>
|
||||
|
||||
extern DoubleLinklistType online_user_head;
|
||||
|
||||
void net_lora_gateway(int argc, char *argv[])
|
||||
{
|
||||
// 1.New specific agreement (LORA) adapter
|
||||
static struct AdapterLora lora_adapter;
|
||||
memset(&lora_adapter, 0, sizeof(lora_adapter));
|
||||
struct AdapterDone lora_example_done = {
|
||||
.NetAiitOpen = LoraAdapterOpen,
|
||||
.NetAiitClose = NULL,
|
||||
.NetAiitSend = NULL,
|
||||
.NetAiitReceive = LoraAdapterReceive,
|
||||
.NetAiitJoin = LoraAdapterJoin,
|
||||
.NetAiitIoctl = NULL,
|
||||
};
|
||||
lora_adapter.parent.done = lora_example_done; // Bind adapter operation
|
||||
lora_adapter.name = "lora_dev_456"; // Set adapter name
|
||||
lora_adapter.spi_lora_fd = -1; // Set adapter information
|
||||
lora_adapter.deve_ui = "xxx";
|
||||
lora_adapter.app_key = "yyy";
|
||||
|
||||
// 2.Register the adapter in the list
|
||||
LoraAdapterInit();
|
||||
LoraAdapterRegister((adapter_t)&lora_adapter);
|
||||
|
||||
// 3.Find from the list of registered adapters
|
||||
adapter_t padapter = LoraAdapterFind("lora_dev_456");
|
||||
if (NONE == padapter)
|
||||
{
|
||||
printf("adapter find failed!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// 4.Open adapter
|
||||
if (0 != padapter->done.NetAiitOpen(padapter))
|
||||
{
|
||||
printf("adapter open failed!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// 5.Join the specified network segment as gateway
|
||||
padapter->done.NetAiitJoin(padapter, ROLE_TYPE_MASTER, CONNECTION_COMMUNICATION_LORA_NET_ID);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void net_lora_connectedlist(int argc, char *argv[])
|
||||
{
|
||||
DoubleLinklistType* pNode;
|
||||
printf("******** connected users *********\n");
|
||||
DOUBLE_LINKLIST_FOR_EACH(pNode, &online_user_head)
|
||||
{
|
||||
OnlineUser* pUser =CONTAINER_OF(pNode, OnlineUser, link);
|
||||
printf("%s\n", pUser->user_name);
|
||||
}
|
||||
printf("*********************************\n");
|
||||
}
|
|
@ -17,7 +17,7 @@ extern int SensorFrameworkInit(void);
|
|||
extern int RegisterAdapterEthernet(void);
|
||||
extern int RegisterAdapterWifi(void);
|
||||
extern int RegisterAdapterZigbee(void);
|
||||
extern int LORA_sx12xx_spi_device_init();
|
||||
extern int LoraSx12xxSpiDeviceInit();
|
||||
|
||||
extern int D124VoiceInit(void);
|
||||
extern int Hs300xTemperatureInit(void);
|
||||
|
@ -94,7 +94,7 @@ static struct InitDesc connection_desc[] =
|
|||
#endif
|
||||
|
||||
#ifdef CONNECTION_COMMUNICATION_LORA
|
||||
{ "lora adpter", LORA_sx12xx_spi_device_init},
|
||||
{ "lora adpter", LoraSx12xxSpiDeviceInit},
|
||||
#endif
|
||||
|
||||
#ifdef CONNECTION_COMMUNICATION_ZIGBEE
|
||||
|
|
|
@ -44,6 +44,11 @@ menu "aiit-arm32-board feature"
|
|||
string "wifi uart name"
|
||||
default "/dev/usart3_dev3"
|
||||
endif
|
||||
if CONNECTION_COMMUNICATION_LORA
|
||||
config LORA_SPI_NAME
|
||||
string "lora spi name"
|
||||
default "/dev/spi2_lora"
|
||||
endif
|
||||
endmenu
|
||||
|
||||
endmenu
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* 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_spi_lora.h
|
||||
* @brief define spi lora dev function and struct using bus driver framework
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021-04-24
|
||||
*/
|
||||
|
||||
#ifndef CONNECT_SPI_LORA_H
|
||||
#define CONNECT_SPI_LORA_H
|
||||
|
||||
#include <bus.h>
|
||||
#include <connect_spi.h>
|
||||
#include <device.h>
|
||||
#include <radio.h>
|
||||
#include <hardware_gpio.h>
|
||||
#include <stm32f4xx.h>
|
||||
#include <spi_lora_sx12xx.h>
|
||||
#include <sx1276.h>
|
||||
#include <sx1276-Hal.h>
|
||||
#include <sx1276-LoRa.h>
|
||||
#include <sx1276-LoRaMisc.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define SPI_LORA_FREQUENCY 10000000
|
||||
#define SPI_LORA_BUFFER_SIZE 256
|
||||
|
||||
typedef struct SpiLoraDevice *SpiLoraDeviceType;
|
||||
|
||||
struct LoraDevDone
|
||||
{
|
||||
uint32 (*open) (void *dev);
|
||||
uint32 (*close) (void *dev);
|
||||
uint32 (*write) (void *dev, struct BusBlockWriteParam *write_param);
|
||||
uint32 (*read) (void *dev, struct BusBlockReadParam *read_param);
|
||||
};
|
||||
|
||||
struct SpiLoraDevice
|
||||
{
|
||||
struct SpiHardwareDevice *spi_dev;
|
||||
struct SpiHardwareDevice lora_dev;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -22,6 +22,45 @@ if BSP_USING_SPI2
|
|||
config SPI_2_DRV_NAME
|
||||
string "spi bus 2 driver name"
|
||||
default "spi2_drv"
|
||||
menuconfig CONNECTION_COMMUNICATION_LORA_USING_SX1278
|
||||
bool "Using spi lora SX1278"
|
||||
default n
|
||||
if CONNECTION_COMMUNICATION_LORA_USING_SX1278
|
||||
config SX12XX_SPI_DEVICE_NAME
|
||||
string "SX1278 device spi name"
|
||||
default "spi2_dev0"
|
||||
config SX12XX_DEVICE_NAME
|
||||
string "SX1278 device name"
|
||||
default "spi2_lora"
|
||||
|
||||
config CONNECTION_COMMUNICATION_LORA_SX12XX_RST_PIN
|
||||
int
|
||||
default 10
|
||||
|
||||
config CONNECTION_COMMUNICATION_LORA_SX12XX_DO0_PIN
|
||||
int
|
||||
default 10
|
||||
|
||||
config CONNECTION_COMMUNICATION_LORA_SX12XX_DO1_PIN
|
||||
int
|
||||
default 10
|
||||
|
||||
config CONNECTION_COMMUNICATION_LORA_SX12XX_DO2_PIN
|
||||
int
|
||||
default 10
|
||||
|
||||
config CONNECTION_COMMUNICATION_LORA_SX12XX_DO3_PIN
|
||||
int
|
||||
default 10
|
||||
|
||||
config CONNECTION_COMMUNICATION_LORA_SX12XX_DO4_PIN
|
||||
int
|
||||
default 10
|
||||
|
||||
config CONNECTION_COMMUNICATION_LORA_SX12XX_DO5_PIN
|
||||
int
|
||||
default 10
|
||||
endif
|
||||
endif
|
||||
|
||||
config BSP_USING_SPI3
|
||||
|
|
|
@ -4,4 +4,9 @@ ifeq ($(CONFIG_RESOURCES_SPI_SFUD),y)
|
|||
SRC_FILES += connect_flash_spi.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_CONNECTION_COMMUNICATION_LORA_USING_SX1278),y)
|
||||
SRC_DIR += third_party_spi_lora
|
||||
SRC_FILES += connect_lora_spi.c
|
||||
endif
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
|
|
|
@ -0,0 +1,543 @@
|
|||
/*
|
||||
* Original Copyright (c) 2006-2018, RT-Thread Development Team
|
||||
* Modified Copyright (c) 2020 AIIT XUOS Lab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2019-02-20 XiaojieFan the first version
|
||||
*/
|
||||
|
||||
/*
|
||||
* Modified by: AIIT XUOS Lab
|
||||
* Modified date: 2020-09-01
|
||||
* Description: replace original macro and basic date type with AIIT XUOS Lab's own defination
|
||||
* start using AIIT XUOS Lab's own functional interfaces
|
||||
* change some header files
|
||||
*/
|
||||
|
||||
#include <connect_spi_lora.h>
|
||||
|
||||
static struct HardwareDev *g_spi_lora_dev;
|
||||
static BusType buspin;
|
||||
tRadioDriver *Radio = NONE;
|
||||
void SX1276InitIo(void)
|
||||
{
|
||||
struct PinParam PinCfg;
|
||||
struct PinStat PinStat;
|
||||
|
||||
struct BusConfigureInfo configure_info;
|
||||
struct BusBlockWriteParam write_param;
|
||||
|
||||
write_param.buffer = (void *)&PinStat;
|
||||
configure_info.configure_cmd = OPE_CFG;
|
||||
configure_info.private_data = (void *)&PinCfg;
|
||||
|
||||
buspin = PinBusInitGet();
|
||||
|
||||
PinCfg.cmd = GPIO_CONFIG_MODE;
|
||||
PinCfg.pin = CONNECTION_COMMUNICATION_LORA_SX12XX_DO0_PIN;
|
||||
PinCfg.mode = GPIO_CFG_INPUT;
|
||||
BusDrvConfigure(buspin->owner_driver, &configure_info);
|
||||
|
||||
PinCfg.cmd = GPIO_CONFIG_MODE;
|
||||
PinCfg.pin = CONNECTION_COMMUNICATION_LORA_SX12XX_DO1_PIN;
|
||||
PinCfg.mode = GPIO_CFG_INPUT;
|
||||
BusDrvConfigure(buspin->owner_driver, &configure_info);
|
||||
|
||||
PinCfg.cmd = GPIO_CONFIG_MODE;
|
||||
PinCfg.pin = CONNECTION_COMMUNICATION_LORA_SX12XX_DO2_PIN;
|
||||
PinCfg.mode = GPIO_CFG_INPUT;
|
||||
BusDrvConfigure(buspin->owner_driver, &configure_info);
|
||||
}
|
||||
|
||||
inline uint8_t SX1276ReadDio0(void)
|
||||
{
|
||||
struct PinStat PinStat;
|
||||
|
||||
struct BusBlockReadParam read_param;
|
||||
read_param.buffer = (void *)&PinStat;
|
||||
|
||||
PinStat.pin = CONNECTION_COMMUNICATION_LORA_SX12XX_DO0_PIN;
|
||||
|
||||
return BusDevReadData(buspin->owner_haldev, &read_param);
|
||||
}
|
||||
|
||||
inline uint8_t SX1276ReadDio1(void)
|
||||
{
|
||||
struct PinStat PinStat;
|
||||
|
||||
struct BusBlockReadParam read_param;
|
||||
read_param.buffer = (void *)&PinStat;
|
||||
|
||||
PinStat.pin = CONNECTION_COMMUNICATION_LORA_SX12XX_DO1_PIN;
|
||||
|
||||
return BusDevReadData(buspin->owner_haldev, &read_param);
|
||||
}
|
||||
|
||||
inline uint8_t SX1276ReadDio2(void)
|
||||
{
|
||||
struct PinStat PinStat;
|
||||
|
||||
struct BusBlockReadParam read_param;
|
||||
read_param.buffer = (void *)&PinStat;
|
||||
|
||||
PinStat.pin = CONNECTION_COMMUNICATION_LORA_SX12XX_DO2_PIN;
|
||||
|
||||
return BusDevReadData(buspin->owner_haldev, &read_param);
|
||||
}
|
||||
|
||||
inline uint8_t SX1276ReadDio3(void)
|
||||
{
|
||||
struct PinStat PinStat;
|
||||
|
||||
struct BusBlockReadParam read_param;
|
||||
read_param.buffer = (void *)&PinStat;
|
||||
|
||||
PinStat.pin = CONNECTION_COMMUNICATION_LORA_SX12XX_DO3_PIN;
|
||||
|
||||
return BusDevReadData(buspin->owner_haldev, &read_param);
|
||||
}
|
||||
|
||||
inline uint8_t SX1276ReadDio4(void)
|
||||
{
|
||||
struct PinStat PinStat;
|
||||
|
||||
struct BusBlockReadParam read_param;
|
||||
read_param.buffer = (void *)&PinStat;
|
||||
|
||||
PinStat.pin = CONNECTION_COMMUNICATION_LORA_SX12XX_DO4_PIN;
|
||||
|
||||
return BusDevReadData(buspin->owner_haldev, &read_param);
|
||||
}
|
||||
|
||||
inline uint8_t SX1276ReadDio5(void)
|
||||
{
|
||||
struct PinStat PinStat;
|
||||
|
||||
struct BusBlockReadParam read_param;
|
||||
read_param.buffer = (void *)&PinStat;
|
||||
|
||||
PinStat.pin = CONNECTION_COMMUNICATION_LORA_SX12XX_DO5_PIN;
|
||||
|
||||
return BusDevReadData(buspin->owner_haldev, &read_param);
|
||||
}
|
||||
|
||||
inline void SX1276WriteRxTx(uint8_t txEnable)
|
||||
{
|
||||
if (txEnable != 0)
|
||||
{
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void SX1276SetReset(uint8_t state)
|
||||
{
|
||||
struct PinParam PinCfg;
|
||||
struct PinStat PinStat;
|
||||
|
||||
struct BusConfigureInfo configure_info;
|
||||
struct BusBlockWriteParam write_param;
|
||||
|
||||
configure_info.configure_cmd = OPE_CFG;
|
||||
configure_info.private_data = (void *)&PinCfg;
|
||||
write_param.buffer = (void *)&PinStat;
|
||||
|
||||
if (state == RADIO_RESET_ON)
|
||||
{
|
||||
PinCfg.cmd = GPIO_CONFIG_MODE;
|
||||
PinCfg.pin = CONNECTION_COMMUNICATION_LORA_SX12XX_RST_PIN;
|
||||
PinCfg.mode = GPIO_CFG_OUTPUT;
|
||||
BusDrvConfigure(buspin->owner_driver, &configure_info);
|
||||
|
||||
PinStat.val = GPIO_LOW;
|
||||
PinStat.pin = CONNECTION_COMMUNICATION_LORA_SX12XX_RST_PIN;
|
||||
BusDevWriteData(buspin->owner_haldev, &write_param);
|
||||
}
|
||||
else
|
||||
{
|
||||
PinCfg.cmd = GPIO_CONFIG_MODE;
|
||||
PinCfg.pin = CONNECTION_COMMUNICATION_LORA_SX12XX_RST_PIN;
|
||||
PinCfg.mode = GPIO_CFG_INPUT;
|
||||
BusDrvConfigure(buspin->owner_driver, &configure_info);
|
||||
}
|
||||
}
|
||||
|
||||
void SX1276Write(uint8_t addr, uint8_t data)
|
||||
{
|
||||
SX1276WriteBuffer(addr, &data, 1);
|
||||
}
|
||||
|
||||
void SX1276Read(uint8_t addr, uint8_t *data)
|
||||
{
|
||||
SX1276ReadBuffer(addr, data, 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);
|
||||
}
|
||||
|
||||
uint8_t SX1276_Spi_Check()
|
||||
{
|
||||
uint8_t test = 0;
|
||||
KPrintf("SX1276_Spi_Check start\n");
|
||||
tLoRaSettings settings;
|
||||
SX1276Read(REG_LR_VERSION,&test);
|
||||
KPrintf("version code of the chip is %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);
|
||||
|
||||
uint8 i;
|
||||
char Msg[SPI_LORA_BUFFER_SIZE] = {0};
|
||||
|
||||
if (write_param->size > 120) {
|
||||
KPrintf("SpiLoraWrite ERROR:The message is too long!\n");
|
||||
return ERROR;
|
||||
} else {
|
||||
//Radio->SetTxPacket(write_param->buffer, write_param->size);
|
||||
//while(Radio->Process() != RF_TX_DONE);
|
||||
SX1276SetTxPacket(write_param->buffer, write_param->size);
|
||||
while(SX1276Process() != RF_TX_DONE);
|
||||
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);
|
||||
|
||||
//Radio->StartRx();
|
||||
SX1276StartRx();
|
||||
KPrintf("SpiLoraRead Ready!\n");
|
||||
|
||||
//while(Radio->Process() != RF_RX_DONE);
|
||||
//Radio->GetRxPacket(read_param->buffer, (uint16 *)&read_param->read_length);
|
||||
while(SX1276Process() != RF_RX_DONE);
|
||||
SX1276GetRxPacket(read_param->buffer, (uint16 *)&read_param->read_length);
|
||||
KPrintf("SpiLoraRead : %s\n", read_param->buffer);
|
||||
|
||||
return EOK;
|
||||
}
|
||||
|
||||
static uint32 SpiLoraOpen(void *dev)
|
||||
{
|
||||
NULL_PARAM_CHECK(dev);
|
||||
|
||||
KPrintf("SpiLoraOpen start\n");
|
||||
|
||||
x_err_t ret = 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;
|
||||
spi_master_param.spi_maxfrequency = SPI_LORA_FREQUENCY;
|
||||
spi_master_param.spi_data_endian = 0;
|
||||
|
||||
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 != SX1276_Spi_Check()) {
|
||||
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 120 characters\n");
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct LoraDevDone lora_done =
|
||||
{
|
||||
.open = SpiLoraOpen,
|
||||
.close = NONE,
|
||||
.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 flash_name flash 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;
|
||||
|
||||
spi_lora_dev->spi_dev->haldev.owner_bus->owner_driver = SpiDriverFind(drv_name, TYPE_SPI_DRV);
|
||||
if (NONE == spi_lora_dev->spi_dev->haldev.owner_bus->owner_driver) {
|
||||
KPrintf("SpiLoraInit find spi driver %s error! \n", drv_name);
|
||||
free(spi_lora_dev);
|
||||
return NONE;
|
||||
}
|
||||
|
||||
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
|
||||
__IO uint32_t tmpreg = 0x00U;
|
||||
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;
|
||||
tmpreg = RCC->AHB1ENR & RCC_AHB1ENR_GPIOAEN;
|
||||
(void)tmpreg;
|
||||
|
||||
if (EOK != HwSpiDeviceAttach(SPI_BUS_NAME_2, SX12XX_SPI_DEVICE_NAME, GPIOC, GPIO_Pin_6)) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
if (NONE == SpiLoraInit(SPI_BUS_NAME_2, SX12XX_SPI_DEVICE_NAME, SPI_2_DRV_NAME, SX12XX_DEVICE_NAME)) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return EOK;
|
||||
}
|
||||
|
||||
|
||||
/*Just for lora test*/
|
||||
static struct Bus *bus;
|
||||
static struct HardwareDev *dev;
|
||||
static struct Driver *drv;
|
||||
|
||||
void LoraOpen(void)
|
||||
{
|
||||
x_err_t ret = EOK;
|
||||
|
||||
ret = LoraSx12xxSpiDeviceInit();
|
||||
if (EOK != ret) {
|
||||
KPrintf("LoraSx12xxSpiDeviceInit failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
bus = BusFind(SPI_BUS_NAME_2);
|
||||
dev = BusFindDevice(bus, SX12XX_DEVICE_NAME);
|
||||
drv = BusFindDriver(bus, SPI_2_DRV_NAME);
|
||||
|
||||
bus->match(drv, dev);
|
||||
|
||||
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)
|
||||
{
|
||||
struct BusBlockReadParam read_param;
|
||||
memset(&read_param, 0, sizeof(struct BusBlockReadParam));
|
||||
|
||||
read_param.buffer = malloc(SPI_LORA_BUFFER_SIZE);
|
||||
|
||||
SpiLoraRead(dev, &read_param);
|
||||
|
||||
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);
|
||||
|
||||
SpiLoraWrite(dev, &write_param);
|
||||
}
|
||||
}
|
||||
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN),
|
||||
LoraSend, LoraSend, lora send message );
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
SRC_DIR += src
|
||||
|
||||
ifeq ($(ARCH), arm)
|
||||
SRC_DIR += ports
|
||||
endif
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* Original Copyright (c) 2006-2018, RT-Thread Development Team
|
||||
* Modified Copyright (c) 2020 AIIT XUOS Lab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2019-02-25 XiaojieFan the first version
|
||||
*/
|
||||
|
||||
/*
|
||||
* Modified by: AIIT XUOS Lab
|
||||
* Modified date: 2020-09-01
|
||||
* Description:
|
||||
*/
|
||||
/*************************************************
|
||||
File name: spi_lora_sx12xx.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 __SPI_LORA_SX12XX_H_
|
||||
#define __SPI_LORA_SX12XX_H_
|
||||
|
||||
#include <xiuos.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/*!
|
||||
* \brief Gets the SX1272 DIO0 hardware pin status
|
||||
*
|
||||
* \retval status Current hardware pin status [1, 0]
|
||||
*/
|
||||
uint8_t SX1276ReadDio0(void);
|
||||
|
||||
/*!
|
||||
* \brief Gets the SX1272 DIO1 hardware pin status
|
||||
*
|
||||
* \retval status Current hardware pin status [1, 0]
|
||||
*/
|
||||
uint8_t SX1276ReadDio1(void);
|
||||
|
||||
/*!
|
||||
* \brief Gets the SX1272 DIO2 hardware pin status
|
||||
*
|
||||
* \retval status Current hardware pin status [1, 0]
|
||||
*/
|
||||
uint8_t SX1276ReadDio2(void);
|
||||
|
||||
/*!
|
||||
* \brief Gets the SX1272 DIO3 hardware pin status
|
||||
*
|
||||
* \retval status Current hardware pin status [1, 0]
|
||||
*/
|
||||
uint8_t SX1276ReadDio3(void);
|
||||
|
||||
/*!
|
||||
* \brief Gets the SX1272 DIO4 hardware pin status
|
||||
*
|
||||
* \retval status Current hardware pin status [1, 0]
|
||||
*/
|
||||
uint8_t SX1276ReadDio4(void);
|
||||
|
||||
/*!
|
||||
* \brief Gets the SX1272 DIO5 hardware pin status
|
||||
*
|
||||
* \retval status Current hardware pin status [1, 0]
|
||||
*/
|
||||
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 SX1276_Spi_Check(void);
|
||||
void SX1276WriteRxTx(uint8_t txEnable);
|
||||
#endif
|
|
@ -0,0 +1,3 @@
|
|||
SRC_FILES := sx12xx_device.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Original Copyright (c) 2006-2018, RT-Thread Development Team
|
||||
* Modified Copyright (c) 2020 AIIT XUOS Lab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2019-02-20 XiaojieFan the first version
|
||||
*/
|
||||
|
||||
/*************************************************
|
||||
File name: sx12xx_device.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 "connect_spi.h"
|
||||
#include "board.h"
|
||||
// #include "gpio.h"
|
||||
#include "stm32f4xx.h"
|
||||
#include "hardware_gpio.h"
|
||||
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
|
||||
SRC_FILES += radio/radio.c \
|
||||
radio/sx1276-Fsk.c \
|
||||
radio/sx1276-FskMisc.c \
|
||||
radio/sx1276-LoRa.c \
|
||||
radio/sx1276-LoRaMisc.c \
|
||||
radio/sx1276.c
|
||||
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -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 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 "sx12xxEiger/sx12xxEiger.h"
|
||||
#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__
|
|
@ -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;
|
||||
}
|
|
@ -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__
|
|
@ -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
|
File diff suppressed because it is too large
Load Diff
|
@ -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, ®PaConfigInitVal );
|
||||
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
|
|
@ -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__
|
|
@ -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__
|
|
@ -0,0 +1,800 @@
|
|||
/*
|
||||
* 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];
|
||||
|
||||
/*!
|
||||
* 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 );
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
|
||||
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 * )RFBuffer, 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_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 );
|
||||
|
||||
|
||||
// RxDone
|
||||
SX1276LR->RegDioMapping1 = RFLR_DIOMAPPING1_DIO0_00 | RFLR_DIOMAPPING1_DIO1_00 | RFLR_DIOMAPPING1_DIO2_00 | RFLR_DIOMAPPING1_DIO3_00;
|
||||
// CadDetected
|
||||
SX1276LR->RegDioMapping2 = RFLR_DIOMAPPING2_DIO4_10 | RFLR_DIOMAPPING2_DIO5_00;
|
||||
|
||||
SX1276WriteBuffer( REG_LR_DIOMAPPING1, &SX1276LR->RegDioMapping1, 2 );
|
||||
|
||||
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,®Value);
|
||||
//if( DIO0 == 1 ) // 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;
|
||||
}
|
||||
//if( DIO2 == 1 ) // 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;
|
||||
}
|
||||
|
||||
/* {
|
||||
uint8_t rxSnrEstimate;
|
||||
|
||||
SX1276Read( REG_LR_PKTSNRVALUE, &rxSnrEstimate );
|
||||
if( rxSnrEstimate & 0x80 )
|
||||
{
|
||||
|
||||
RxPacketSnrEstimate = ( ( ~rxSnrEstimate + 1 ) & 0xFF ) >> 2;
|
||||
RxPacketSnrEstimate = -RxPacketSnrEstimate;
|
||||
}
|
||||
else
|
||||
{
|
||||
RxPacketSnrEstimate = ( rxSnrEstimate & 0xFF ) >> 2;
|
||||
}
|
||||
}
|
||||
if( LoRaSettings.RFFrequency < 860000000 )
|
||||
{
|
||||
if( RxPacketSnrEstimate < 0 )
|
||||
{
|
||||
|
||||
RxPacketRssiValue = NOISE_ABSOLUTE_ZERO + 10.0 * SignalBwLog[LoRaSettings.SignalBw] + NOISE_FIGURE_LF + ( double )RxPacketSnrEstimate;
|
||||
}
|
||||
else
|
||||
{
|
||||
SX1276Read( REG_LR_PKTRSSIVALUE, &SX1276LR->RegPktRssiValue );
|
||||
RxPacketRssiValue = RssiOffsetLF[LoRaSettings.SignalBw] + ( double )SX1276LR->RegPktRssiValue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( RxPacketSnrEstimate < 0 )
|
||||
{
|
||||
RxPacketRssiValue = NOISE_ABSOLUTE_ZERO + 10.0 * SignalBwLog[LoRaSettings.SignalBw] + NOISE_FIGURE_HF + ( double )RxPacketSnrEstimate;
|
||||
}
|
||||
else
|
||||
{
|
||||
SX1276Read( REG_LR_PKTRSSIVALUE, &SX1276LR->RegPktRssiValue );
|
||||
RxPacketRssiValue = RssiOffsetHF[LoRaSettings.SignalBw] + ( double )SX1276LR->RegPktRssiValue;
|
||||
}
|
||||
}*/
|
||||
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;
|
||||
SX1276LoRaSetOpMode( RFLR_OPMODE_STANDBY );
|
||||
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 );
|
||||
// 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 );
|
||||
// Write payload buffer to LORA modem
|
||||
SX1276WriteFifo( RFBuffer, SX1276LR->RegPayloadLength );
|
||||
// TxDone RxTimeout FhssChangeChannel ValidHeader
|
||||
SX1276LR->RegDioMapping1 = RFLR_DIOMAPPING1_DIO0_01 | RFLR_DIOMAPPING1_DIO1_00 | RFLR_DIOMAPPING1_DIO2_00 | RFLR_DIOMAPPING1_DIO3_01;
|
||||
// PllLock Mode Ready
|
||||
SX1276LR->RegDioMapping2 = RFLR_DIOMAPPING2_DIO4_01 | RFLR_DIOMAPPING2_DIO5_00;
|
||||
|
||||
SX1276WriteBuffer( REG_LR_DIOMAPPING1, &SX1276LR->RegDioMapping1, 2 );
|
||||
|
||||
SX1276LoRaSetOpMode( RFLR_OPMODE_TRANSMITTER );
|
||||
|
||||
RFLRState = RFLR_STATE_TX_RUNNING;
|
||||
break;
|
||||
case RFLR_STATE_TX_RUNNING:
|
||||
SX1276Read(0x12,®Value);
|
||||
//if( DIO0 == 1 ) // TxDone
|
||||
if(regValue & (1<<3))
|
||||
{
|
||||
// Clear Irq
|
||||
SX1276Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_TXDONE );
|
||||
RFLRState = RFLR_STATE_TX_DONE;
|
||||
}
|
||||
//if( DIO2 == 1 ) // 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 );
|
||||
|
||||
// RxDone RxTimeout FhssChangeChannel CadDone
|
||||
SX1276LR->RegDioMapping1 = RFLR_DIOMAPPING1_DIO0_00 | RFLR_DIOMAPPING1_DIO1_00 | RFLR_DIOMAPPING1_DIO2_00 | RFLR_DIOMAPPING1_DIO3_00;
|
||||
// CAD Detected ModeReady
|
||||
SX1276LR->RegDioMapping2 = RFLR_DIOMAPPING2_DIO4_00 | RFLR_DIOMAPPING2_DIO5_00;
|
||||
SX1276WriteBuffer( REG_LR_DIOMAPPING1, &SX1276LR->RegDioMapping1, 2 );
|
||||
|
||||
|
||||
SX1276LoRaSetOpMode( RFLR_OPMODE_CAD );
|
||||
RFLRState = RFLR_STATE_CAD_RUNNING;
|
||||
|
||||
break;
|
||||
case RFLR_STATE_CAD_RUNNING:
|
||||
SX1276Read(0x12,®Value);
|
||||
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
|
|
@ -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)(寄存器地址0x06,0x07,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
|
|
@ -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
|
|
@ -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
|
|
@ -0,0 +1,360 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
void SX1276Init( void )
|
||||
{
|
||||
uint8_t TempReg;
|
||||
|
||||
SX1276=(tSX1276*)SX1276Regs;
|
||||
SX1276LR=(tSX1276LR*)SX1276Regs;
|
||||
|
||||
SX1276InitIo( );
|
||||
|
||||
SX1276Reset( );
|
||||
|
||||
SX1276Read(0x06, &TempReg);
|
||||
KPrintf("SX1276 Read 0x%x\n", &TempReg);
|
||||
|
||||
if(TempReg != 0x6C)
|
||||
{
|
||||
KPrintf("Hard SPI Err!\r\n");
|
||||
}
|
||||
|
||||
#if ( LORA == 0 )
|
||||
LoRaOn = false;
|
||||
SX1276_SetLoRaOn( LoRaOn );
|
||||
SX1276FskInit( );
|
||||
#else
|
||||
LoRaOn = true;
|
||||
SX1276_SetLoRaOn( LoRaOn );
|
||||
SX1276LoRaInit( );
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void SX1276Reset( void )
|
||||
{
|
||||
|
||||
|
||||
uint32_t startTick;
|
||||
|
||||
SX1276SetReset( RADIO_RESET_ON );
|
||||
|
||||
|
||||
|
||||
startTick = GET_TICK_COUNT( );
|
||||
while( ( GET_TICK_COUNT( ) - startTick ) < TICK_RATE_MS( 1 ) );
|
||||
|
||||
|
||||
SX1276SetReset( RADIO_RESET_OFF );
|
||||
|
||||
|
||||
|
||||
startTick = GET_TICK_COUNT( );
|
||||
while( ( GET_TICK_COUNT( ) - startTick ) < TICK_RATE_MS( 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 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SX1276SetTxPacket( const void *buffer, uint16_t size )
|
||||
{
|
||||
if( LoRaOn == false )
|
||||
{
|
||||
SX1276FskSetTxPacket( buffer, size );
|
||||
}
|
||||
else
|
||||
{
|
||||
SX1276LoRaSetTxPacket( buffer, size );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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( );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint32_t SX1276ChannelEmpty( void )
|
||||
{
|
||||
if( LoRaOn == false )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
SX1276LoraChannelEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* 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 ); //得到接收的数据
|
||||
|
||||
void SX1276SetTxPacket( 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
|
|
@ -46,7 +46,11 @@ menu "aiit-riscv64-board feature"
|
|||
string "wifi uart name"
|
||||
default "/dev/uart3_dev3"
|
||||
endif
|
||||
|
||||
if CONNECTION_COMMUNICATION_LORA
|
||||
config LORA_SPI_NAME
|
||||
string "lora spi name"
|
||||
default "/dev/spi1_lora"
|
||||
endif
|
||||
endmenu
|
||||
|
||||
endmenu
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* 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_spi_lora.h
|
||||
* @brief define spi lora dev function and struct using bus driver framework
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021-04-24
|
||||
*/
|
||||
|
||||
#ifndef CONNECT_SPI_LORA_H
|
||||
#define CONNECT_SPI_LORA_H
|
||||
|
||||
#include <bus.h>
|
||||
#include <connect_spi.h>
|
||||
#include <device.h>
|
||||
#include <radio.h>
|
||||
// #include <hardware_gpio.h>
|
||||
// #include <stm32f4xx.h>
|
||||
#include <spi_lora_sx12xx.h>
|
||||
#include <sx1276.h>
|
||||
#include <sx1276-Hal.h>
|
||||
#include <sx1276-LoRa.h>
|
||||
#include <sx1276-LoRaMisc.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define SPI_LORA_FREQUENCY 10000000
|
||||
#define SPI_LORA_BUFFER_SIZE 256
|
||||
|
||||
typedef struct SpiLoraDevice *SpiLoraDeviceType;
|
||||
|
||||
struct LoraDevDone
|
||||
{
|
||||
uint32 (*open) (void *dev);
|
||||
uint32 (*close) (void *dev);
|
||||
uint32 (*write) (void *dev, struct BusBlockWriteParam *write_param);
|
||||
uint32 (*read) (void *dev, struct BusBlockReadParam *read_param);
|
||||
};
|
||||
|
||||
struct SpiLoraDevice
|
||||
{
|
||||
struct SpiHardwareDevice *spi_dev;
|
||||
struct SpiHardwareDevice lora_dev;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -29,6 +29,41 @@ if BSP_USING_SPI1
|
|||
config BSP_SPI1_SS0_PIN
|
||||
int "spi1 ss0 pin number"
|
||||
default 9
|
||||
menuconfig CONNECTION_COMMUNICATION_LORA_USING_SX1278
|
||||
bool "Using spi lora SX1278"
|
||||
default n
|
||||
if CONNECTION_COMMUNICATION_LORA_USING_SX1278
|
||||
config SX12XX_DEVICE_NAME
|
||||
string "SX1278 device name"
|
||||
default "spi1_lora"
|
||||
config CONNECTION_COMMUNICATION_LORA_SX12XX_RST_PIN
|
||||
int
|
||||
default 10
|
||||
|
||||
config CONNECTION_COMMUNICATION_LORA_SX12XX_DO0_PIN
|
||||
int
|
||||
default 10
|
||||
|
||||
config CONNECTION_COMMUNICATION_LORA_SX12XX_DO1_PIN
|
||||
int
|
||||
default 10
|
||||
|
||||
config CONNECTION_COMMUNICATION_LORA_SX12XX_DO2_PIN
|
||||
int
|
||||
default 10
|
||||
|
||||
config CONNECTION_COMMUNICATION_LORA_SX12XX_DO3_PIN
|
||||
int
|
||||
default 10
|
||||
|
||||
config CONNECTION_COMMUNICATION_LORA_SX12XX_DO4_PIN
|
||||
int
|
||||
default 10
|
||||
|
||||
config CONNECTION_COMMUNICATION_LORA_SX12XX_DO5_PIN
|
||||
int
|
||||
default 10
|
||||
endif
|
||||
endif
|
||||
menuconfig BSP_SPI1_USING_SS1
|
||||
bool "SPI1 Enable SS1"
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
SRC_FILES := connect_spi.c hardware_spi.c
|
||||
|
||||
|
||||
|
||||
ifeq ($(CONFIG_CONNECTION_COMMUNICATION_LORA_USING_SX1278),y)
|
||||
SRC_DIR += third_party_spi_lora
|
||||
SRC_FILES += connect_lora_spi.c
|
||||
endif
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
|
|
|
@ -0,0 +1,535 @@
|
|||
/*
|
||||
* Original Copyright (c) 2006-2018, RT-Thread Development Team
|
||||
* Modified Copyright (c) 2020 AIIT XUOS Lab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2019-02-20 XiaojieFan the first version
|
||||
*/
|
||||
|
||||
/*
|
||||
* Modified by: AIIT XUOS Lab
|
||||
* Modified date: 2020-09-01
|
||||
* Description: replace original macro and basic date type with AIIT XUOS Lab's own defination
|
||||
* start using AIIT XUOS Lab's own functional interfaces
|
||||
* change some header files
|
||||
*/
|
||||
|
||||
#include <connect_spi_lora.h>
|
||||
|
||||
static struct HardwareDev *g_spi_lora_dev;
|
||||
static BusType buspin;
|
||||
tRadioDriver *Radio = NONE;
|
||||
void SX1276InitIo(void)
|
||||
{
|
||||
struct PinParam PinCfg;
|
||||
struct PinStat PinStat;
|
||||
|
||||
struct BusConfigureInfo configure_info;
|
||||
struct BusBlockWriteParam write_param;
|
||||
|
||||
write_param.buffer = (void *)&PinStat;
|
||||
configure_info.configure_cmd = OPE_CFG;
|
||||
configure_info.private_data = (void *)&PinCfg;
|
||||
|
||||
buspin = PinBusInitGet();
|
||||
|
||||
PinCfg.cmd = GPIO_CONFIG_MODE;
|
||||
PinCfg.pin = CONNECTION_COMMUNICATION_LORA_SX12XX_DO0_PIN;
|
||||
PinCfg.mode = GPIO_CFG_INPUT;
|
||||
BusDrvConfigure(buspin->owner_driver, &configure_info);
|
||||
|
||||
PinCfg.cmd = GPIO_CONFIG_MODE;
|
||||
PinCfg.pin = CONNECTION_COMMUNICATION_LORA_SX12XX_DO1_PIN;
|
||||
PinCfg.mode = GPIO_CFG_INPUT;
|
||||
BusDrvConfigure(buspin->owner_driver, &configure_info);
|
||||
|
||||
PinCfg.cmd = GPIO_CONFIG_MODE;
|
||||
PinCfg.pin = CONNECTION_COMMUNICATION_LORA_SX12XX_DO2_PIN;
|
||||
PinCfg.mode = GPIO_CFG_INPUT;
|
||||
BusDrvConfigure(buspin->owner_driver, &configure_info);
|
||||
}
|
||||
|
||||
inline uint8_t SX1276ReadDio0(void)
|
||||
{
|
||||
struct PinStat PinStat;
|
||||
|
||||
struct BusBlockReadParam read_param;
|
||||
read_param.buffer = (void *)&PinStat;
|
||||
|
||||
PinStat.pin = CONNECTION_COMMUNICATION_LORA_SX12XX_DO0_PIN;
|
||||
|
||||
return BusDevReadData(buspin->owner_haldev, &read_param);
|
||||
}
|
||||
|
||||
inline uint8_t SX1276ReadDio1(void)
|
||||
{
|
||||
struct PinStat PinStat;
|
||||
|
||||
struct BusBlockReadParam read_param;
|
||||
read_param.buffer = (void *)&PinStat;
|
||||
|
||||
PinStat.pin = CONNECTION_COMMUNICATION_LORA_SX12XX_DO1_PIN;
|
||||
|
||||
return BusDevReadData(buspin->owner_haldev, &read_param);
|
||||
}
|
||||
|
||||
inline uint8_t SX1276ReadDio2(void)
|
||||
{
|
||||
struct PinStat PinStat;
|
||||
|
||||
struct BusBlockReadParam read_param;
|
||||
read_param.buffer = (void *)&PinStat;
|
||||
|
||||
PinStat.pin = CONNECTION_COMMUNICATION_LORA_SX12XX_DO2_PIN;
|
||||
|
||||
return BusDevReadData(buspin->owner_haldev, &read_param);
|
||||
}
|
||||
|
||||
inline uint8_t SX1276ReadDio3(void)
|
||||
{
|
||||
struct PinStat PinStat;
|
||||
|
||||
struct BusBlockReadParam read_param;
|
||||
read_param.buffer = (void *)&PinStat;
|
||||
|
||||
PinStat.pin = CONNECTION_COMMUNICATION_LORA_SX12XX_DO3_PIN;
|
||||
|
||||
return BusDevReadData(buspin->owner_haldev, &read_param);
|
||||
}
|
||||
|
||||
inline uint8_t SX1276ReadDio4(void)
|
||||
{
|
||||
struct PinStat PinStat;
|
||||
|
||||
struct BusBlockReadParam read_param;
|
||||
read_param.buffer = (void *)&PinStat;
|
||||
|
||||
PinStat.pin = CONNECTION_COMMUNICATION_LORA_SX12XX_DO4_PIN;
|
||||
|
||||
return BusDevReadData(buspin->owner_haldev, &read_param);
|
||||
}
|
||||
|
||||
inline uint8_t SX1276ReadDio5(void)
|
||||
{
|
||||
struct PinStat PinStat;
|
||||
|
||||
struct BusBlockReadParam read_param;
|
||||
read_param.buffer = (void *)&PinStat;
|
||||
|
||||
PinStat.pin = CONNECTION_COMMUNICATION_LORA_SX12XX_DO5_PIN;
|
||||
|
||||
return BusDevReadData(buspin->owner_haldev, &read_param);
|
||||
}
|
||||
|
||||
inline void SX1276WriteRxTx(uint8_t txEnable)
|
||||
{
|
||||
if (txEnable != 0)
|
||||
{
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void SX1276SetReset(uint8_t state)
|
||||
{
|
||||
struct PinParam PinCfg;
|
||||
struct PinStat PinStat;
|
||||
|
||||
struct BusConfigureInfo configure_info;
|
||||
struct BusBlockWriteParam write_param;
|
||||
|
||||
configure_info.configure_cmd = OPE_CFG;
|
||||
configure_info.private_data = (void *)&PinCfg;
|
||||
write_param.buffer = (void *)&PinStat;
|
||||
|
||||
if (state == RADIO_RESET_ON)
|
||||
{
|
||||
PinCfg.cmd = GPIO_CONFIG_MODE;
|
||||
PinCfg.pin = CONNECTION_COMMUNICATION_LORA_SX12XX_RST_PIN;
|
||||
PinCfg.mode = GPIO_CFG_OUTPUT;
|
||||
BusDrvConfigure(buspin->owner_driver, &configure_info);
|
||||
|
||||
PinStat.val = GPIO_LOW;
|
||||
PinStat.pin = CONNECTION_COMMUNICATION_LORA_SX12XX_RST_PIN;
|
||||
BusDevWriteData(buspin->owner_haldev, &write_param);
|
||||
}
|
||||
else
|
||||
{
|
||||
PinCfg.cmd = GPIO_CONFIG_MODE;
|
||||
PinCfg.pin = CONNECTION_COMMUNICATION_LORA_SX12XX_RST_PIN;
|
||||
PinCfg.mode = GPIO_CFG_INPUT;
|
||||
BusDrvConfigure(buspin->owner_driver, &configure_info);
|
||||
}
|
||||
}
|
||||
|
||||
void SX1276Write(uint8_t addr, uint8_t data)
|
||||
{
|
||||
SX1276WriteBuffer(addr, &data, 1);
|
||||
}
|
||||
|
||||
void SX1276Read(uint8_t addr, uint8_t *data)
|
||||
{
|
||||
SX1276ReadBuffer(addr, data, 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);
|
||||
}
|
||||
|
||||
uint8_t SX1276_Spi_Check()
|
||||
{
|
||||
uint8_t test = 0;
|
||||
KPrintf("SX1276_Spi_Check start\n");
|
||||
tLoRaSettings settings;
|
||||
SX1276Read(REG_LR_VERSION,&test);
|
||||
KPrintf("version code of the chip is %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);
|
||||
|
||||
uint8 i;
|
||||
char Msg[SPI_LORA_BUFFER_SIZE] = {0};
|
||||
|
||||
if (write_param->size > 120) {
|
||||
KPrintf("SpiLoraWrite ERROR:The message is too long!\n");
|
||||
return ERROR;
|
||||
} else {
|
||||
//Radio->SetTxPacket(write_param->buffer, write_param->size);
|
||||
//while(Radio->Process() != RF_TX_DONE);
|
||||
SX1276SetTxPacket(write_param->buffer, write_param->size);
|
||||
while(SX1276Process() != RF_TX_DONE);
|
||||
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);
|
||||
|
||||
//Radio->StartRx();
|
||||
SX1276StartRx();
|
||||
KPrintf("SpiLoraRead Ready!\n");
|
||||
|
||||
//while(Radio->Process() != RF_RX_DONE);
|
||||
//Radio->GetRxPacket(read_param->buffer, (uint16 *)&read_param->read_length);
|
||||
while(SX1276Process() != RF_RX_DONE);
|
||||
SX1276GetRxPacket(read_param->buffer, (uint16 *)&read_param->read_length);
|
||||
KPrintf("SpiLoraRead : %s\n", read_param->buffer);
|
||||
|
||||
return EOK;
|
||||
}
|
||||
|
||||
static uint32 SpiLoraOpen(void *dev)
|
||||
{
|
||||
NULL_PARAM_CHECK(dev);
|
||||
|
||||
KPrintf("SpiLoraOpen start\n");
|
||||
|
||||
x_err_t ret = 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;
|
||||
spi_master_param.spi_maxfrequency = SPI_LORA_FREQUENCY;
|
||||
spi_master_param.spi_data_endian = 0;
|
||||
|
||||
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 != SX1276_Spi_Check()) {
|
||||
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 120 characters\n");
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct LoraDevDone lora_done =
|
||||
{
|
||||
.open = SpiLoraOpen,
|
||||
.close = NONE,
|
||||
.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 flash_name flash 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;
|
||||
|
||||
spi_lora_dev->spi_dev->haldev.owner_bus->owner_driver = SpiDriverFind(drv_name, TYPE_SPI_DRV);
|
||||
if (NONE == spi_lora_dev->spi_dev->haldev.owner_bus->owner_driver) {
|
||||
KPrintf("SpiLoraInit find spi driver %s error! \n", drv_name);
|
||||
free(spi_lora_dev);
|
||||
return NONE;
|
||||
}
|
||||
|
||||
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_SPI1
|
||||
|
||||
if (NONE == SpiLoraInit(SPI_BUS_NAME_1, SPI_1_DEVICE_NAME_0, SPI_1_DRV_NAME, SX12XX_DEVICE_NAME)) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return EOK;
|
||||
}
|
||||
|
||||
|
||||
/*Just for lora test*/
|
||||
static struct Bus *bus;
|
||||
static struct HardwareDev *dev;
|
||||
static struct Driver *drv;
|
||||
|
||||
void LoraOpen(void)
|
||||
{
|
||||
x_err_t ret = EOK;
|
||||
|
||||
ret = LoraSx12xxSpiDeviceInit();
|
||||
if (EOK != ret) {
|
||||
KPrintf("LoraSx12xxSpiDeviceInit failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
bus = BusFind(SPI_BUS_NAME_1);
|
||||
dev = BusFindDevice(bus, SX12XX_DEVICE_NAME);
|
||||
drv = BusFindDriver(bus, SPI_1_DRV_NAME);
|
||||
|
||||
bus->match(drv, dev);
|
||||
|
||||
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)
|
||||
{
|
||||
struct BusBlockReadParam read_param;
|
||||
memset(&read_param, 0, sizeof(struct BusBlockReadParam));
|
||||
|
||||
read_param.buffer = malloc(SPI_LORA_BUFFER_SIZE);
|
||||
|
||||
SpiLoraRead(dev, &read_param);
|
||||
|
||||
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);
|
||||
|
||||
SpiLoraWrite(dev, &write_param);
|
||||
}
|
||||
}
|
||||
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN),
|
||||
LoraSend, LoraSend, lora send message );
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
SRC_DIR += src
|
||||
|
||||
ifeq ($(ARCH), arm)
|
||||
SRC_DIR += ports
|
||||
endif
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* Original Copyright (c) 2006-2018, RT-Thread Development Team
|
||||
* Modified Copyright (c) 2020 AIIT XUOS Lab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2019-02-25 XiaojieFan the first version
|
||||
*/
|
||||
|
||||
/*
|
||||
* Modified by: AIIT XUOS Lab
|
||||
* Modified date: 2020-09-01
|
||||
* Description:
|
||||
*/
|
||||
/*************************************************
|
||||
File name: spi_lora_sx12xx.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 __SPI_LORA_SX12XX_H_
|
||||
#define __SPI_LORA_SX12XX_H_
|
||||
|
||||
#include <xiuos.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/*!
|
||||
* \brief Gets the SX1272 DIO0 hardware pin status
|
||||
*
|
||||
* \retval status Current hardware pin status [1, 0]
|
||||
*/
|
||||
uint8_t SX1276ReadDio0(void);
|
||||
|
||||
/*!
|
||||
* \brief Gets the SX1272 DIO1 hardware pin status
|
||||
*
|
||||
* \retval status Current hardware pin status [1, 0]
|
||||
*/
|
||||
uint8_t SX1276ReadDio1(void);
|
||||
|
||||
/*!
|
||||
* \brief Gets the SX1272 DIO2 hardware pin status
|
||||
*
|
||||
* \retval status Current hardware pin status [1, 0]
|
||||
*/
|
||||
uint8_t SX1276ReadDio2(void);
|
||||
|
||||
/*!
|
||||
* \brief Gets the SX1272 DIO3 hardware pin status
|
||||
*
|
||||
* \retval status Current hardware pin status [1, 0]
|
||||
*/
|
||||
uint8_t SX1276ReadDio3(void);
|
||||
|
||||
/*!
|
||||
* \brief Gets the SX1272 DIO4 hardware pin status
|
||||
*
|
||||
* \retval status Current hardware pin status [1, 0]
|
||||
*/
|
||||
uint8_t SX1276ReadDio4(void);
|
||||
|
||||
/*!
|
||||
* \brief Gets the SX1272 DIO5 hardware pin status
|
||||
*
|
||||
* \retval status Current hardware pin status [1, 0]
|
||||
*/
|
||||
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 SX1276_Spi_Check(void);
|
||||
void SX1276WriteRxTx(uint8_t txEnable);
|
||||
#endif
|
|
@ -0,0 +1,3 @@
|
|||
SRC_FILES := sx12xx_device.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Original Copyright (c) 2006-2018, RT-Thread Development Team
|
||||
* Modified Copyright (c) 2020 AIIT XUOS Lab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2019-02-20 XiaojieFan the first version
|
||||
*/
|
||||
|
||||
/*************************************************
|
||||
File name: sx12xx_device.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 "connect_spi.h"
|
||||
#include "board.h"
|
||||
// #include "gpio.h"
|
||||
#include "stm32f4xx.h"
|
||||
#include "hardware_gpio.h"
|
||||
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
|
||||
SRC_FILES += radio/radio.c \
|
||||
radio/sx1276-Fsk.c \
|
||||
radio/sx1276-FskMisc.c \
|
||||
radio/sx1276-LoRa.c \
|
||||
radio/sx1276-LoRaMisc.c \
|
||||
radio/sx1276.c
|
||||
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -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 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 "sx12xxEiger/sx12xxEiger.h"
|
||||
#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__
|
|
@ -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;
|
||||
}
|
|
@ -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__
|
|
@ -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
|
File diff suppressed because it is too large
Load Diff
|
@ -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, ®PaConfigInitVal );
|
||||
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
|
|
@ -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__
|
|
@ -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__
|
|
@ -0,0 +1,800 @@
|
|||
/*
|
||||
* 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];
|
||||
|
||||
/*!
|
||||
* 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 );
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
|
||||
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 * )RFBuffer, 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_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 );
|
||||
|
||||
|
||||
// RxDone
|
||||
SX1276LR->RegDioMapping1 = RFLR_DIOMAPPING1_DIO0_00 | RFLR_DIOMAPPING1_DIO1_00 | RFLR_DIOMAPPING1_DIO2_00 | RFLR_DIOMAPPING1_DIO3_00;
|
||||
// CadDetected
|
||||
SX1276LR->RegDioMapping2 = RFLR_DIOMAPPING2_DIO4_10 | RFLR_DIOMAPPING2_DIO5_00;
|
||||
|
||||
SX1276WriteBuffer( REG_LR_DIOMAPPING1, &SX1276LR->RegDioMapping1, 2 );
|
||||
|
||||
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,®Value);
|
||||
//if( DIO0 == 1 ) // 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;
|
||||
}
|
||||
//if( DIO2 == 1 ) // 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;
|
||||
}
|
||||
|
||||
/* {
|
||||
uint8_t rxSnrEstimate;
|
||||
|
||||
SX1276Read( REG_LR_PKTSNRVALUE, &rxSnrEstimate );
|
||||
if( rxSnrEstimate & 0x80 )
|
||||
{
|
||||
|
||||
RxPacketSnrEstimate = ( ( ~rxSnrEstimate + 1 ) & 0xFF ) >> 2;
|
||||
RxPacketSnrEstimate = -RxPacketSnrEstimate;
|
||||
}
|
||||
else
|
||||
{
|
||||
RxPacketSnrEstimate = ( rxSnrEstimate & 0xFF ) >> 2;
|
||||
}
|
||||
}
|
||||
if( LoRaSettings.RFFrequency < 860000000 )
|
||||
{
|
||||
if( RxPacketSnrEstimate < 0 )
|
||||
{
|
||||
|
||||
RxPacketRssiValue = NOISE_ABSOLUTE_ZERO + 10.0 * SignalBwLog[LoRaSettings.SignalBw] + NOISE_FIGURE_LF + ( double )RxPacketSnrEstimate;
|
||||
}
|
||||
else
|
||||
{
|
||||
SX1276Read( REG_LR_PKTRSSIVALUE, &SX1276LR->RegPktRssiValue );
|
||||
RxPacketRssiValue = RssiOffsetLF[LoRaSettings.SignalBw] + ( double )SX1276LR->RegPktRssiValue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( RxPacketSnrEstimate < 0 )
|
||||
{
|
||||
RxPacketRssiValue = NOISE_ABSOLUTE_ZERO + 10.0 * SignalBwLog[LoRaSettings.SignalBw] + NOISE_FIGURE_HF + ( double )RxPacketSnrEstimate;
|
||||
}
|
||||
else
|
||||
{
|
||||
SX1276Read( REG_LR_PKTRSSIVALUE, &SX1276LR->RegPktRssiValue );
|
||||
RxPacketRssiValue = RssiOffsetHF[LoRaSettings.SignalBw] + ( double )SX1276LR->RegPktRssiValue;
|
||||
}
|
||||
}*/
|
||||
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;
|
||||
SX1276LoRaSetOpMode( RFLR_OPMODE_STANDBY );
|
||||
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 );
|
||||
// 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 );
|
||||
// Write payload buffer to LORA modem
|
||||
SX1276WriteFifo( RFBuffer, SX1276LR->RegPayloadLength );
|
||||
// TxDone RxTimeout FhssChangeChannel ValidHeader
|
||||
SX1276LR->RegDioMapping1 = RFLR_DIOMAPPING1_DIO0_01 | RFLR_DIOMAPPING1_DIO1_00 | RFLR_DIOMAPPING1_DIO2_00 | RFLR_DIOMAPPING1_DIO3_01;
|
||||
// PllLock Mode Ready
|
||||
SX1276LR->RegDioMapping2 = RFLR_DIOMAPPING2_DIO4_01 | RFLR_DIOMAPPING2_DIO5_00;
|
||||
|
||||
SX1276WriteBuffer( REG_LR_DIOMAPPING1, &SX1276LR->RegDioMapping1, 2 );
|
||||
|
||||
SX1276LoRaSetOpMode( RFLR_OPMODE_TRANSMITTER );
|
||||
|
||||
RFLRState = RFLR_STATE_TX_RUNNING;
|
||||
break;
|
||||
case RFLR_STATE_TX_RUNNING:
|
||||
SX1276Read(0x12,®Value);
|
||||
//if( DIO0 == 1 ) // TxDone
|
||||
if(regValue & (1<<3))
|
||||
{
|
||||
// Clear Irq
|
||||
SX1276Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_TXDONE );
|
||||
RFLRState = RFLR_STATE_TX_DONE;
|
||||
}
|
||||
//if( DIO2 == 1 ) // 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 );
|
||||
|
||||
// RxDone RxTimeout FhssChangeChannel CadDone
|
||||
SX1276LR->RegDioMapping1 = RFLR_DIOMAPPING1_DIO0_00 | RFLR_DIOMAPPING1_DIO1_00 | RFLR_DIOMAPPING1_DIO2_00 | RFLR_DIOMAPPING1_DIO3_00;
|
||||
// CAD Detected ModeReady
|
||||
SX1276LR->RegDioMapping2 = RFLR_DIOMAPPING2_DIO4_00 | RFLR_DIOMAPPING2_DIO5_00;
|
||||
SX1276WriteBuffer( REG_LR_DIOMAPPING1, &SX1276LR->RegDioMapping1, 2 );
|
||||
|
||||
|
||||
SX1276LoRaSetOpMode( RFLR_OPMODE_CAD );
|
||||
RFLRState = RFLR_STATE_CAD_RUNNING;
|
||||
|
||||
break;
|
||||
case RFLR_STATE_CAD_RUNNING:
|
||||
SX1276Read(0x12,®Value);
|
||||
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
|
|
@ -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)(寄存器地址0x06,0x07,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
|
|
@ -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
|
|
@ -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
|
|
@ -0,0 +1,360 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
void SX1276Init( void )
|
||||
{
|
||||
uint8_t TempReg;
|
||||
|
||||
SX1276=(tSX1276*)SX1276Regs;
|
||||
SX1276LR=(tSX1276LR*)SX1276Regs;
|
||||
|
||||
SX1276InitIo( );
|
||||
|
||||
SX1276Reset( );
|
||||
|
||||
SX1276Read(0x06, &TempReg);
|
||||
KPrintf("SX1276 Read 0x%x\n", &TempReg);
|
||||
|
||||
if(TempReg != 0x6C)
|
||||
{
|
||||
KPrintf("Hard SPI Err!\r\n");
|
||||
}
|
||||
|
||||
#if ( LORA == 0 )
|
||||
LoRaOn = false;
|
||||
SX1276_SetLoRaOn( LoRaOn );
|
||||
SX1276FskInit( );
|
||||
#else
|
||||
LoRaOn = true;
|
||||
SX1276_SetLoRaOn( LoRaOn );
|
||||
SX1276LoRaInit( );
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void SX1276Reset( void )
|
||||
{
|
||||
|
||||
|
||||
uint32_t startTick;
|
||||
|
||||
SX1276SetReset( RADIO_RESET_ON );
|
||||
|
||||
|
||||
|
||||
startTick = GET_TICK_COUNT( );
|
||||
while( ( GET_TICK_COUNT( ) - startTick ) < TICK_RATE_MS( 1 ) );
|
||||
|
||||
|
||||
SX1276SetReset( RADIO_RESET_OFF );
|
||||
|
||||
|
||||
|
||||
startTick = GET_TICK_COUNT( );
|
||||
while( ( GET_TICK_COUNT( ) - startTick ) < TICK_RATE_MS( 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 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SX1276SetTxPacket( const void *buffer, uint16_t size )
|
||||
{
|
||||
if( LoRaOn == false )
|
||||
{
|
||||
SX1276FskSetTxPacket( buffer, size );
|
||||
}
|
||||
else
|
||||
{
|
||||
SX1276LoRaSetTxPacket( buffer, size );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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( );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint32_t SX1276ChannelEmpty( void )
|
||||
{
|
||||
if( LoRaOn == false )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
SX1276LoraChannelEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* 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 ); //得到接收的数据
|
||||
|
||||
void SX1276SetTxPacket( 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
|
|
@ -1,7 +1,13 @@
|
|||
menuconfig CONNECTION_COMMUNICATION_WIFI
|
||||
bool "Enable Wifi"
|
||||
default n
|
||||
|
||||
|
||||
menuconfig CONNECTION_COMMUNICATION_LORA
|
||||
bool "Enable LORA"
|
||||
default n
|
||||
if CONNECTION_COMMUNICATION_LORA
|
||||
source "$KERNEL_DIR/framework/connection/Adapter/lora/Kconfig"
|
||||
endif
|
||||
|
||||
menuconfig CONNECTION_COMMUNICATION_ETHERNET
|
||||
bool "Enable Ethernet"
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
|
||||
SRC_DIR := src
|
||||
|
||||
# ifeq ($(CONFIG_CONNECTION_COMMUNICATION_LORA), y)
|
||||
# SRC_DIR += lora
|
||||
# endif
|
||||
ifeq ($(CONFIG_CONNECTION_COMMUNICATION_LORA), y)
|
||||
SRC_DIR += lora
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_CONNECTION_COMMUNICATION_ETHERNET), y)
|
||||
SRC_DIR += ethernet
|
||||
|
|
|
@ -0,0 +1,184 @@
|
|||
/*
|
||||
* 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 xs_adapterLora.h
|
||||
* @brief lora adhoc logic
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021.04.22
|
||||
*/
|
||||
|
||||
#ifndef XS_ADAPTER_LORA_H
|
||||
#define XS_ADAPTER_LORA_H
|
||||
|
||||
#include "xs_adapter.h"
|
||||
|
||||
#define DEVNAME_LEN_MAX 32
|
||||
#define NETNAME_LEN_MAX 32
|
||||
#define CONNECTED_CLIENTS_MAX 512
|
||||
|
||||
#define CLIENT_SEND_CELL_LEN 120
|
||||
|
||||
|
||||
struct AdapterLora {
|
||||
struct Adapter parent; /* inherit from Adapter */
|
||||
const char * name; /* name of the adapter instance */
|
||||
|
||||
const char *deve_ui; /* Lora specific value */
|
||||
const char *app_key; /* Lora specific value */
|
||||
|
||||
int spi_lora_fd;
|
||||
};
|
||||
typedef struct AdapterLora *AdapterLoraT;
|
||||
|
||||
int LoraAdapterOpen(adapter_t padapter);
|
||||
void LoraAdapterCose(struct Adapter *padapter);
|
||||
int LoraAdapterSend(struct Adapter *padapter, const char* data, int len, bool block, int time_out, int delay, void *p);
|
||||
int LoraAdapterReceive(adapter_t padapter, char* rev_buffer, int buffer_len,int time_out, bool block, void *p);
|
||||
int LoraAdapterJoin(adapter_t sadapter, int dev_type, char* net_id);
|
||||
int LoraAdapterSendc2g(adapter_t padapter, const char *data, int len, bool block, int time_out, int delay, send_success cb, void* param, void *p);
|
||||
|
||||
// Client state machine
|
||||
enum LoraClientStatus
|
||||
{
|
||||
LORA_CLIENT_IDLE = 0,
|
||||
LORA_CLIENT_LOOKING4GATEWAY,
|
||||
LORA_CLIENT_CONNECTING2GATEWAY,
|
||||
LORA_CLIENT_CONNECTED,
|
||||
LORA_CLIENT_WAITTING_FOR_DISCONNECTED,
|
||||
LORA_CLIENT_DISCONNECTED,
|
||||
};
|
||||
|
||||
struct LoraClientStatusInfo
|
||||
{
|
||||
enum LoraClientStatus status;
|
||||
int user_id;
|
||||
char gateway_name[DEVNAME_LEN_MAX];
|
||||
char client_name[DEVNAME_LEN_MAX];
|
||||
};
|
||||
|
||||
enum LoraOpcode
|
||||
{
|
||||
LORA_OPCODE_START = 0xFFF0,
|
||||
LORA_JOIN_REQ = 0xFFF1,
|
||||
LORA_JOIN_RSP = 0xFFF2,
|
||||
LORA_HANDSHAKE_REQ = 0xFFF3,
|
||||
LORA_HANDSHAKE_RSP = 0xFFF4,
|
||||
LORA_C2G_DATA_REQ = 0xFFF5,
|
||||
LORA_C2G_DATA_RSP = 0xFFF6,
|
||||
LORA_CLOSE_REQ = 0xFFF7,
|
||||
LORA_CLOSE_RSP = 0xFFF8,
|
||||
LORA_OPCODE_END,
|
||||
};
|
||||
|
||||
enum WorkThreadStatus
|
||||
{
|
||||
WORK_THREAD_RX = 1,
|
||||
WORK_THREAD_TX,
|
||||
};
|
||||
|
||||
// pkg header
|
||||
typedef struct
|
||||
{
|
||||
int op_code;
|
||||
int length;
|
||||
}LoraHeader;
|
||||
|
||||
// Network access, handshake function protocol
|
||||
typedef struct
|
||||
{
|
||||
char net_id[NETNAME_LEN_MAX];
|
||||
}LoraProtoJoinReq;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char net_id[NETNAME_LEN_MAX];
|
||||
char gateway_name[DEVNAME_LEN_MAX];
|
||||
int signal_strength;
|
||||
int error_code;
|
||||
}LoraProtoJoinRsp;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char client_name[DEVNAME_LEN_MAX];
|
||||
char gateway_name[DEVNAME_LEN_MAX];
|
||||
}LoraProtoHandshakeReq;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char client_name[DEVNAME_LEN_MAX];
|
||||
char gateway_name[DEVNAME_LEN_MAX];
|
||||
int user_id;
|
||||
int error_code;
|
||||
}LoraProtoHandshakeRsp;
|
||||
|
||||
|
||||
// Data transmission protocol
|
||||
typedef struct
|
||||
{
|
||||
int user_id;
|
||||
int pkg_id;
|
||||
int data_len;
|
||||
int crc;
|
||||
}LoraProtoC2GDataReq;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int user_id;
|
||||
int ack_id;
|
||||
int data_len;
|
||||
int crc;
|
||||
}LoraProtoC2GDataRsp;
|
||||
|
||||
// Client active disconnect
|
||||
typedef struct
|
||||
{
|
||||
int user_id;
|
||||
}LoraProtoCloseReq;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int user_id;
|
||||
int error_code;
|
||||
}LoraProtoCloseRsp;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char* data;
|
||||
int len;
|
||||
bool* prsp_flag;
|
||||
adapter_t padapter;
|
||||
}CheckRspParam;
|
||||
|
||||
typedef void(*send_success)(void* param);
|
||||
typedef struct
|
||||
{
|
||||
bool has_data;
|
||||
int crc;
|
||||
int pkg_id;
|
||||
char data[CLIENT_SEND_CELL_LEN];
|
||||
int data_len;
|
||||
send_success callback;
|
||||
void* param;
|
||||
}ClientSendCell;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char user_name[DEVNAME_LEN_MAX];
|
||||
int user_id;
|
||||
DoubleLinklistType link;
|
||||
}OnlineUser;
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
#LORA adhoc configuration
|
||||
#Set same netID, and then join one adhoc net.
|
||||
|
||||
menuconfig CONNECTION_COMMUNICATION_BOOTSTART_LORA_NET_SAMPLE
|
||||
bool "use bootstart lora net sample"
|
||||
default n
|
||||
|
||||
if CONNECTION_COMMUNICATION_BOOTSTART_LORA_NET_SAMPLE
|
||||
menuconfig CONNECTION_COMMUNICATION_SET_AS_LORA_CLIENT
|
||||
bool "set this as lora client "
|
||||
default n
|
||||
|
||||
if CONNECTION_COMMUNICATION_SET_AS_LORA_CLIENT
|
||||
config CONNECTION_COMMUNICATION_LORA_CLIENT_NAME
|
||||
string "config lora net client name"
|
||||
default "lora_client_name0"
|
||||
|
||||
config CONNECTION_COMMUNICATION_LORA_CLIENT_PKG_COUNT
|
||||
int "config lora send pkg count"
|
||||
default 1000
|
||||
endif
|
||||
|
||||
menuconfig CONNECTION_COMMUNICATION_SET_AS_LORA_GATEWAY
|
||||
bool "set this as lora gateway"
|
||||
default n
|
||||
|
||||
config CONNECTION_COMMUNICATION_LORA_NET_ID
|
||||
string "config lora net ID"
|
||||
default "intelligence grain"
|
||||
endif
|
|
@ -0,0 +1,3 @@
|
|||
SRC_FILES := xs_adapter_lora.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -0,0 +1,849 @@
|
|||
/*
|
||||
* 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 xs_AdapterLora.c
|
||||
* @brief lora adhoc logic
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021.04.22
|
||||
*/
|
||||
|
||||
#include <xs_adapter_lora.h>
|
||||
#include "spi_lora_sx12xx.h"
|
||||
#include "radio.h"
|
||||
#include "sx1276-LoRa.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <user_api.h>
|
||||
|
||||
#define SLEEP_MS 50
|
||||
|
||||
enum NetRoleType _role_type = ROLE_TYPE_NONE;
|
||||
|
||||
bool gateway_listening = false;
|
||||
bool client_work_thread_running = false;
|
||||
|
||||
char gateway_net_id[NETNAME_LEN_MAX];
|
||||
char client_net_id[NETNAME_LEN_MAX];
|
||||
|
||||
struct LoraClientStatusInfo g_client_status_info;
|
||||
int pkg_id_c2g;
|
||||
|
||||
#define BUFFER_LEN_MAX 120
|
||||
char rec_buffer[BUFFER_LEN_MAX] = {0};
|
||||
char client_rec_buffer[BUFFER_LEN_MAX] = {0};
|
||||
|
||||
char send_buffer[BUFFER_LEN_MAX] = {0};
|
||||
|
||||
DoubleLinklistType online_user_head = {&online_user_head, &online_user_head};
|
||||
|
||||
// Client send buffer. Only one element is set temporarily
|
||||
ClientSendCell client_send_buffer;
|
||||
int pclient_send_buffer_mutex = -1;
|
||||
enum WorkThreadStatus g_work_thread_status;
|
||||
bool need_send_data = false;
|
||||
|
||||
int32 ServerTask = NONE;
|
||||
int32 ClientTask = NONE;
|
||||
|
||||
static int spi_lora_fd_intern = -1;
|
||||
|
||||
extern tRadioDriver *Radio;
|
||||
|
||||
/**
|
||||
* @description: open lora adapter
|
||||
* @param padapter - lora adapter pointer
|
||||
*/
|
||||
int LoraAdapterOpen(adapter_t padapter)
|
||||
{
|
||||
int fd = ((AdapterLoraT)padapter)->spi_lora_fd;
|
||||
if (fd < 0){
|
||||
fd = open(LORA_SPI_NAME,O_RDWR);
|
||||
}
|
||||
|
||||
if(fd < 0){
|
||||
printf("LoRa check failed!\n!");
|
||||
return ERROR;
|
||||
} else {
|
||||
((AdapterLoraT)padapter)->spi_lora_fd = fd;
|
||||
spi_lora_fd_intern = fd;
|
||||
|
||||
memset(&g_client_status_info, 0, sizeof(g_client_status_info));
|
||||
g_client_status_info.status = LORA_CLIENT_IDLE;
|
||||
pkg_id_c2g = 1;
|
||||
_role_type = ROLE_TYPE_NONE;
|
||||
printf("LoRa check ok!\nNote: The length of the message that can be sent in a single time is 120 characters\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: close lora adapter
|
||||
* @param padapter - lora adapter pointer
|
||||
*/
|
||||
void LoraAdapterCose(struct Adapter *padapter)
|
||||
{
|
||||
if (((AdapterLoraT)padapter)->spi_lora_fd < 0){
|
||||
printf("LoRa device not found! close failed!\n");
|
||||
} else {
|
||||
// Disconnect
|
||||
int count = 10;
|
||||
g_client_status_info.status = LORA_CLIENT_WAITTING_FOR_DISCONNECTED;
|
||||
need_send_data = true;
|
||||
while (count > 0 && g_client_status_info.status == LORA_CLIENT_WAITTING_FOR_DISCONNECTED)
|
||||
{
|
||||
printf("lora client waitting for rsp, count(%d)\n", count);
|
||||
UserTaskDelay(1000);
|
||||
count--;
|
||||
}
|
||||
if (g_client_status_info.status != LORA_CLIENT_DISCONNECTED){
|
||||
printf("lora send close pkg failed!\n");
|
||||
}
|
||||
|
||||
gateway_listening = false;
|
||||
client_work_thread_running = false;
|
||||
|
||||
// Release thread
|
||||
if (NONE != ServerTask){
|
||||
UserTaskDelete(ServerTask);
|
||||
ServerTask = NONE;
|
||||
}
|
||||
|
||||
if (NONE != ClientTask){
|
||||
UserTaskDelete(ClientTask);
|
||||
ClientTask = NONE;
|
||||
}
|
||||
|
||||
// Release the lock
|
||||
if (pclient_send_buffer_mutex != NONE) {
|
||||
UserMutexDelete(pclient_send_buffer_mutex);
|
||||
pclient_send_buffer_mutex = NONE;
|
||||
}
|
||||
|
||||
// Driver
|
||||
((AdapterLoraT)padapter)->spi_lora_fd = NONE;
|
||||
}
|
||||
}
|
||||
|
||||
bool lora_channel_avtive()
|
||||
{
|
||||
return Radio->ChannelEmpty() == 0;
|
||||
}
|
||||
|
||||
int LoraAdapterSend(struct Adapter *padapter, const char *data, int len, bool block, int time_out, int delay, void *p)
|
||||
{
|
||||
if (len > 120){
|
||||
printf("ERROR:The message is too long!\n");
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
if (((AdapterLoraT)padapter)->spi_lora_fd == NONE){
|
||||
printf("LoRa device not found!\n");
|
||||
return ERROR;
|
||||
} else {
|
||||
int time_counter = 0;
|
||||
int time_sleep_gap = 500;
|
||||
while (false == lora_channel_avtive()) {
|
||||
|
||||
if (time_counter * time_sleep_gap > time_out) {
|
||||
printf("LoRa_adapter_send failed! time_out!\n");
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
|
||||
UserTaskDelay(time_sleep_gap);
|
||||
time_counter++;
|
||||
}
|
||||
|
||||
char Msg[120] = {0};
|
||||
memcpy(Msg, data, len);
|
||||
|
||||
Radio->SetTxPacket(Msg, len);
|
||||
while (Radio->Process() != RF_TX_DONE)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
int lora_send(const char *data, int len)
|
||||
{
|
||||
if (len > 120) {
|
||||
printf("ERROR:The message is too long!\n");
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
int time_counter = 0;
|
||||
int time_sleep_gap = 500;
|
||||
int time_out = 10000;
|
||||
while (false == lora_channel_avtive()) {
|
||||
if (time_counter * time_sleep_gap > time_out) {
|
||||
printf("LoRa send failed! time_out!\n");
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
UserTaskDelay(time_sleep_gap);
|
||||
time_counter++;
|
||||
}
|
||||
|
||||
char Msg[120] = {0};
|
||||
memcpy(Msg, data, len);
|
||||
|
||||
Radio->SetTxPacket(Msg, len);
|
||||
while (Radio->Process() != RF_TX_DONE)
|
||||
;
|
||||
}
|
||||
|
||||
int LoraAdapterSendc2g(adapter_t padapter, const char *data, int len, bool block, int time_out, int delay, send_success cb, void *param, void *p)
|
||||
{
|
||||
if (_role_type == ROLE_TYPE_SLAVE && g_client_status_info.status == LORA_CLIENT_CONNECTED) {
|
||||
LoraHeader header;
|
||||
memset(&header, 0, sizeof(header));
|
||||
header.op_code = LORA_C2G_DATA_REQ;
|
||||
header.length = sizeof(LoraHeader) + sizeof(LoraProtoC2GDataReq) + len;
|
||||
|
||||
if (header.length > 120) {
|
||||
printf("Send failed, LoRa send max length is 120.\n");
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
if (client_send_buffer.has_data == true){
|
||||
printf("Send failed, last pakage is resending\n");
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
LoraProtoC2GDataReq req;
|
||||
req.user_id = g_client_status_info.user_id;
|
||||
req.pkg_id = pkg_id_c2g;
|
||||
req.data_len = len;
|
||||
req.crc = 0xFFFF;
|
||||
|
||||
memcpy(send_buffer, &header, sizeof(header));
|
||||
memcpy(send_buffer + sizeof(header), &req, sizeof(req));
|
||||
memcpy(send_buffer + sizeof(header) + sizeof(req), data, len);
|
||||
|
||||
// Write data to buffer (lock)
|
||||
UserMutexObtain(pclient_send_buffer_mutex, WAITING_FOREVER);
|
||||
client_send_buffer.has_data = true;
|
||||
client_send_buffer.pkg_id = pkg_id_c2g;
|
||||
client_send_buffer.crc = 0xFFFF;
|
||||
memcpy(client_send_buffer.data, send_buffer, header.length);
|
||||
client_send_buffer.data_len = header.length;
|
||||
client_send_buffer.callback = cb;
|
||||
client_send_buffer.param = param;
|
||||
|
||||
UserMutexAbandon(pclient_send_buffer_mutex);
|
||||
// printf("copy to send buffer. len = %d\n", header.length);
|
||||
|
||||
// Switch worker thread state
|
||||
need_send_data = true;
|
||||
return ERROR;
|
||||
} else {
|
||||
printf("LoRa client is unconnected! can not send data!\n");
|
||||
}
|
||||
}
|
||||
|
||||
OnlineUser *find_user_by_name(char *name)
|
||||
{
|
||||
DoubleLinklistType *pLink;
|
||||
DOUBLE_LINKLIST_FOR_EACH(pLink, &online_user_head)
|
||||
{
|
||||
OnlineUser *pUer =CONTAINER_OF(pLink, OnlineUser, link);
|
||||
if (strcmp(pUer->user_name, name) == 0) {
|
||||
return pUer;
|
||||
}
|
||||
}
|
||||
return NONE;
|
||||
}
|
||||
|
||||
OnlineUser *find_user_by_id(int id)
|
||||
{
|
||||
DoubleLinklistType *pLink;
|
||||
DOUBLE_LINKLIST_FOR_EACH(pLink, &online_user_head)
|
||||
{
|
||||
OnlineUser *pUer =CONTAINER_OF(pLink, OnlineUser, link);
|
||||
if (pUer->user_id == id) {
|
||||
return pUer;
|
||||
}
|
||||
}
|
||||
return NONE;
|
||||
}
|
||||
|
||||
int insert_connected_clients(char *name, int user_id)
|
||||
{
|
||||
OnlineUser *pUser = malloc(sizeof(OnlineUser));
|
||||
if (NONE == pUser)
|
||||
return ERROR;
|
||||
|
||||
pUser->user_id = user_id;
|
||||
strcpy(pUser->user_name, name);
|
||||
DoubleLinkListInsertNodeAfter(&online_user_head, &pUser->link);
|
||||
|
||||
return EOK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void CheckSendBuffer()
|
||||
{
|
||||
UserMutexObtain(pclient_send_buffer_mutex, WAITING_FOREVER);
|
||||
if (client_send_buffer.has_data == true)
|
||||
{
|
||||
//Sending or packet loss retransmission
|
||||
lora_send(client_send_buffer.data, client_send_buffer.data_len);
|
||||
// printf("client check and send. len = %d\n", client_send_buffer.data_len);
|
||||
}
|
||||
UserMutexAbandon(pclient_send_buffer_mutex);
|
||||
}
|
||||
|
||||
int LoraAdapterReceive(adapter_t padapter, char *rev_buffer, int buffer_len, int time_out, bool block, void *p)
|
||||
{
|
||||
uint16 BufferSize = buffer_len;
|
||||
|
||||
memset(rev_buffer, 0, buffer_len);
|
||||
|
||||
if (((AdapterLoraT)padapter)->spi_lora_fd == NONE)
|
||||
{
|
||||
printf("LoRa device not found!\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
Radio->StartRx();
|
||||
printf("Ready!\n");
|
||||
|
||||
while (Radio->Process() != RF_RX_DONE)
|
||||
{
|
||||
// if (time_out < 0)
|
||||
// {
|
||||
// printf("LoRa device receive failed! Timeout!\n");
|
||||
// return ERROR;
|
||||
// }
|
||||
// UserTaskDelay(SLEEP_MS);
|
||||
// time_out -= SLEEP_MS;
|
||||
}
|
||||
|
||||
Radio->GetRxPacket(rev_buffer, (uint16 *)&BufferSize);
|
||||
if (BufferSize == buffer_len)
|
||||
{
|
||||
printf("rev_buffer is too small!\n");
|
||||
}
|
||||
|
||||
printf("RX : %s\n", rev_buffer);
|
||||
return BufferSize;
|
||||
}
|
||||
}
|
||||
|
||||
int LoraGatewayProcess(adapter_t padapter, char *pkg, int rec_len)
|
||||
{
|
||||
struct AdapterLora* lora_adapter = (struct AdapterLora*)padapter;
|
||||
|
||||
if (rec_len > 0)
|
||||
{
|
||||
LoraHeader header;
|
||||
memset(&header, 0, sizeof(header));
|
||||
char *start = (char *)pkg;
|
||||
LoraHeader *pheader = (LoraHeader *)start;
|
||||
|
||||
char *req = start + sizeof(LoraHeader);
|
||||
|
||||
if (pheader->op_code < LORA_OPCODE_START || pheader->op_code > LORA_OPCODE_END)
|
||||
{
|
||||
printf("Illegal opcode, discard data!\n");
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
if (rec_len != pheader->length)
|
||||
{
|
||||
printf("pkg is not complete!, discard data!\n");
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
printf("gateway receive pkg opcode(%4x)\n", pheader->op_code);
|
||||
switch (pheader->op_code)
|
||||
{
|
||||
case LORA_JOIN_REQ: // There is a client request to join the network segment
|
||||
if (strcmp(((LoraProtoJoinReq *)req)->net_id, gateway_net_id) == 0) // The request is really this network segment
|
||||
{
|
||||
LoraProtoJoinReq *req = (LoraProtoJoinReq *)(start + sizeof(LoraHeader));
|
||||
|
||||
header.op_code = LORA_JOIN_RSP;
|
||||
header.length = sizeof(LoraHeader) + sizeof(LoraProtoJoinRsp);
|
||||
|
||||
LoraProtoJoinRsp rsp;
|
||||
memset(&rsp, 0, sizeof(rsp));
|
||||
rsp.error_code = 0;
|
||||
rsp.signal_strength = 0; // signal intensity
|
||||
|
||||
printf(" 11aa strlen(lora_adapter->name) = %d\n", strlen(lora_adapter->name));
|
||||
printf(" 11aa lora_adapter->name = %s\n", lora_adapter->name);
|
||||
|
||||
strcpy(rsp.gateway_name, lora_adapter->name);
|
||||
strcpy(rsp.net_id, gateway_net_id);
|
||||
|
||||
memcpy(send_buffer, &header, sizeof(header));
|
||||
memcpy(send_buffer + sizeof(header), &rsp, sizeof(rsp));
|
||||
|
||||
printf("LoraProtoJoinRsp rsp.gateway_name = %s rsp.net_id = %s\n", rsp.gateway_name, rsp.net_id);
|
||||
lora_send(send_buffer, header.length);
|
||||
printf("gateway send pkg opcode(%4x)\n", header.op_code);
|
||||
}
|
||||
break;
|
||||
case LORA_HANDSHAKE_REQ:
|
||||
if (strcmp(((LoraProtoHandshakeReq *)req)->gateway_name, lora_adapter->name) == 0) //The other party really wants to connect themselves
|
||||
{
|
||||
// Construction reply, connection confirmation
|
||||
LoraProtoHandshakeReq *req = (LoraProtoHandshakeReq *)(start + sizeof(LoraHeader));
|
||||
int user_id = 0;
|
||||
// If it can be found, it will prove that it is connected. It may be packet loss, so normal retransmission is good
|
||||
OnlineUser *pUser = find_user_by_name(req->client_name);
|
||||
if (NONE == pUser)
|
||||
{
|
||||
// New virtual connection
|
||||
user_id = rand() % UINT32_SIZE_MAX;
|
||||
if (ERROR == insert_connected_clients(req->client_name, user_id))
|
||||
{
|
||||
return ERROR;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Packet loss
|
||||
user_id = pUser->user_id;
|
||||
}
|
||||
|
||||
header.op_code = LORA_HANDSHAKE_RSP;
|
||||
header.length = sizeof(LoraHeader) + sizeof(LoraProtoHandshakeRsp);
|
||||
|
||||
LoraProtoHandshakeRsp rsp;
|
||||
memset(&rsp, 0, sizeof(rsp));
|
||||
strcpy(rsp.client_name, req->client_name);
|
||||
strcpy(rsp.gateway_name, req->gateway_name);
|
||||
rsp.user_id = user_id;
|
||||
rsp.error_code = 0;
|
||||
|
||||
memcpy(send_buffer, &header, sizeof(header));
|
||||
memcpy(send_buffer + sizeof(header), &rsp, sizeof(rsp));
|
||||
|
||||
printf("LoraProtoHandshakeRsp, rsp.client_name = %s, rsp.gateway_name = %s\n", rsp.client_name, rsp.gateway_name);
|
||||
lora_send(send_buffer, header.length);
|
||||
printf("gateway send pkg opcode(%4x)\n", header.op_code);
|
||||
}
|
||||
break;
|
||||
case LORA_C2G_DATA_REQ:
|
||||
{
|
||||
OnlineUser *pUser = find_user_by_id(((LoraProtoC2GDataReq *)req)->user_id);
|
||||
if (pUser) //What the other party wants to send is really himself
|
||||
{
|
||||
LoraProtoC2GDataReq *req = (LoraProtoC2GDataReq *)(start + sizeof(LoraHeader));
|
||||
|
||||
char *data = start + sizeof(LoraHeader) + sizeof(LoraProtoC2GDataReq);
|
||||
// printf("receive data from client(%s), content(%s)", pUser->user_name, data);
|
||||
printf(" receive data from \033[0;31m client(%s)\033[0m \n, content(%s). ", pUser->user_name, data);
|
||||
// Logic layer to deal with
|
||||
|
||||
// CRC calculation for data and reply to client
|
||||
header.op_code = LORA_C2G_DATA_RSP;
|
||||
header.length = sizeof(LoraHeader) + sizeof(LoraProtoC2GDataRsp);
|
||||
|
||||
LoraProtoC2GDataRsp rsp;
|
||||
memset(&rsp, 0, sizeof(rsp));
|
||||
rsp.user_id = req->user_id;
|
||||
rsp.crc = 0xFFFF;
|
||||
rsp.data_len = rec_len;
|
||||
rsp.ack_id = req->pkg_id;
|
||||
|
||||
memcpy(send_buffer, &header, sizeof(header));
|
||||
memcpy(send_buffer + sizeof(header), &rsp, sizeof(rsp));
|
||||
|
||||
lora_send(send_buffer, header.length);
|
||||
printf("gateway send pkg opcode(%4x), ack_id(%d)\n", header.op_code, rsp.ack_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("user unconnected, discard data.\n");
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case LORA_CLOSE_REQ:
|
||||
{
|
||||
LoraProtoCloseReq *req = (LoraProtoCloseReq *)(start + sizeof(LoraHeader));
|
||||
|
||||
//log
|
||||
DoubleLinklistType *pNode;
|
||||
printf("******** connected users *********\n");
|
||||
DOUBLE_LINKLIST_FOR_EACH(pNode, &online_user_head)
|
||||
{
|
||||
OnlineUser *pUser =CONTAINER_OF(pNode, OnlineUser, link);
|
||||
printf("pUser->user_name %s\n", pUser->user_name);
|
||||
printf("pUser->user_id %d\n", pUser->user_id);
|
||||
}
|
||||
printf("*********************************\n");
|
||||
|
||||
printf("req->user_id = %d\n", req->user_id);
|
||||
|
||||
OnlineUser *pUser = find_user_by_id(req->user_id);
|
||||
if (pUser)
|
||||
{
|
||||
DoubleLinkListRmNode(&pUser->link);
|
||||
|
||||
header.op_code = LORA_CLOSE_RSP;
|
||||
header.length = sizeof(LoraHeader) + sizeof(LoraProtoCloseRsp);
|
||||
LoraProtoCloseRsp rsp;
|
||||
rsp.error_code = 0;
|
||||
rsp.user_id = req->user_id;
|
||||
memcpy(send_buffer, &header, sizeof(header));
|
||||
memcpy(send_buffer + sizeof(header), &rsp, sizeof(rsp));
|
||||
|
||||
lora_send(send_buffer, header.length);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("find user failed!\n");
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Gateway receives requests from clients in a loop
|
||||
static void LoraGateWayListen(void *parameter)
|
||||
{
|
||||
// adapter_t padapter = (adapter_t)malloc(sizeof(struct Adapter));
|
||||
adapter_t padapter = parameter;
|
||||
|
||||
while (gateway_listening)
|
||||
{
|
||||
printf("444x(0x%x), %d, %d \n", ((AdapterLoraT)padapter)->spi_lora_fd, sizeof(rec_buffer), BUFFER_LEN_MAX);
|
||||
|
||||
int rec_len = LoraAdapterReceive(padapter, rec_buffer, BUFFER_LEN_MAX, 10000, true, NULL);
|
||||
UserTaskDelay(50); //Afraid the other party hasn't entered reception mode yet
|
||||
LoraGatewayProcess(padapter, rec_buffer, rec_len);
|
||||
}
|
||||
}
|
||||
|
||||
// All client packets received are processed here
|
||||
int LoraClientProcess(adapter_t padapter, char *pkg, int pkg_len)
|
||||
{
|
||||
struct AdapterLora* lora_adapter = (struct AdapterLora*)padapter;
|
||||
|
||||
LoraHeader *pheader = (LoraHeader *)pkg;
|
||||
|
||||
LoraHeader header;
|
||||
memset(&header, 0, sizeof(header));
|
||||
|
||||
char *data_start = pkg + sizeof(LoraHeader);
|
||||
|
||||
switch (pheader->op_code)
|
||||
{
|
||||
case LORA_JOIN_RSP:
|
||||
if (g_client_status_info.status == LORA_CLIENT_LOOKING4GATEWAY)
|
||||
{
|
||||
LoraProtoJoinRsp *data = (LoraProtoJoinRsp *)data_start;
|
||||
|
||||
if (strcmp(data->net_id, client_net_id) != 0)
|
||||
break;
|
||||
|
||||
strcpy(g_client_status_info.gateway_name, data->gateway_name);
|
||||
strcpy(g_client_status_info.client_name, lora_adapter->name);
|
||||
g_client_status_info.status = LORA_CLIENT_CONNECTING2GATEWAY;
|
||||
break;
|
||||
}
|
||||
case LORA_HANDSHAKE_RSP:
|
||||
if (strcmp(((LoraProtoHandshakeRsp *)data_start)->client_name, lora_adapter->name) == 0) // Confirm that it was sent to yourself
|
||||
{
|
||||
LoraProtoHandshakeRsp *data = (LoraProtoHandshakeRsp *)data_start;
|
||||
printf("get LoraProtoHandshakeRsp data->client_name = %s, data->gateway_name = %s\n", data->client_name, data->gateway_name);
|
||||
// Confirm the connection and record the status information
|
||||
g_client_status_info.status = LORA_CLIENT_CONNECTED;
|
||||
g_client_status_info.user_id = data->user_id;
|
||||
|
||||
strcpy(g_client_status_info.gateway_name, data->gateway_name);
|
||||
|
||||
printf("client is connected to gateway(%s)\n", g_client_status_info.gateway_name);
|
||||
}
|
||||
break;
|
||||
|
||||
case LORA_C2G_DATA_RSP:
|
||||
if (((LoraProtoC2GDataRsp *)data_start)->user_id == g_client_status_info.user_id) // Confirm that it was sent to yourself
|
||||
{
|
||||
LoraProtoC2GDataRsp *data = (LoraProtoC2GDataRsp *)data_start;
|
||||
|
||||
UserMutexObtain(pclient_send_buffer_mutex, WAITING_FOREVER);
|
||||
if (data->ack_id == client_send_buffer.pkg_id)
|
||||
{
|
||||
if (data->crc == client_send_buffer.crc)
|
||||
{
|
||||
// Send successfully, execute external callback
|
||||
if (client_send_buffer.callback)
|
||||
{
|
||||
client_send_buffer.callback(client_send_buffer.param);
|
||||
}
|
||||
|
||||
//Reset buffer
|
||||
memset(&client_send_buffer, 0, sizeof(client_send_buffer));
|
||||
client_send_buffer.has_data = false;
|
||||
// printf("pkg_id(%d) get ack. send success. send buffer clear.\n", data->ack_id);
|
||||
|
||||
pkg_id_c2g++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Then do nothing and wait for the retransmission
|
||||
printf("client send failed.crc check failed.\n");
|
||||
}
|
||||
}
|
||||
UserMutexAbandon(pclient_send_buffer_mutex);
|
||||
}
|
||||
break;
|
||||
|
||||
case LORA_CLOSE_RSP:
|
||||
{
|
||||
LoraProtoCloseRsp *rsp = (LoraProtoCloseRsp *)data_start;
|
||||
printf("case LORA_CLOSE_RSP rsp->user_id(%d)\n", rsp->user_id);
|
||||
printf("case LORA_CLOSE_RSP g_client_status_info.user_id(%d)\n", g_client_status_info.user_id);
|
||||
|
||||
if (rsp->user_id == g_client_status_info.user_id)
|
||||
{
|
||||
g_client_status_info.status = LORA_CLIENT_DISCONNECTED;
|
||||
printf("client close success.\n");
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// The client requests the gateway to disconnect
|
||||
int SendCloseReq()
|
||||
{
|
||||
LoraHeader header;
|
||||
memset(&header, 0, sizeof(header));
|
||||
header.op_code = LORA_CLOSE_REQ;
|
||||
header.length = sizeof(LoraHeader) + sizeof(LoraProtoCloseReq);
|
||||
|
||||
LoraProtoCloseReq req;
|
||||
req.user_id = g_client_status_info.user_id;
|
||||
memcpy(send_buffer, &header, sizeof(header));
|
||||
memcpy(send_buffer + sizeof(header), &req, sizeof(req));
|
||||
printf("client send close req");
|
||||
lora_send(send_buffer, header.length);
|
||||
}
|
||||
|
||||
// The client broadcasts the name of the network segment that it wants to join
|
||||
int SendJoinReq(char *net_id)
|
||||
{
|
||||
LoraHeader header;
|
||||
memset(&header, 0, sizeof(header));
|
||||
header.op_code = LORA_JOIN_REQ;
|
||||
header.length = sizeof(LoraHeader) + sizeof(LoraProtoJoinReq);
|
||||
|
||||
LoraProtoJoinReq req;
|
||||
memcpy(req.net_id, net_id, strlen(net_id) + 1);
|
||||
memcpy(send_buffer, &header, sizeof(header));
|
||||
memcpy(send_buffer + sizeof(header), &req, sizeof(req));
|
||||
|
||||
lora_send(send_buffer, header.length);
|
||||
}
|
||||
|
||||
// Client requests connection from gateway
|
||||
int SendHandShakeReq(char *client_name, char *gateway_name)
|
||||
{
|
||||
LoraHeader header;
|
||||
header.op_code = LORA_HANDSHAKE_REQ;
|
||||
header.length = sizeof(LoraHeader) + sizeof(LoraProtoHandshakeReq);
|
||||
|
||||
LoraProtoHandshakeReq req;
|
||||
memset(&req, 0, sizeof(req));
|
||||
strcpy(req.client_name, client_name);
|
||||
strcpy(req.gateway_name, gateway_name);
|
||||
|
||||
memcpy(send_buffer, &header, sizeof(header));
|
||||
memcpy(send_buffer + sizeof(header), &req, sizeof(req));
|
||||
|
||||
printf("LoraProtoHandshakeReq, req.client_name = %s req.gateway_name = %s\n", req.client_name, req.gateway_name);
|
||||
lora_send(send_buffer, header.length);
|
||||
}
|
||||
|
||||
void work_thread_process(adapter_t padapter)
|
||||
{
|
||||
if (g_work_thread_status == WORK_THREAD_RX)
|
||||
{
|
||||
// printf("client start receiving \n");
|
||||
uint16 len;
|
||||
int counter = 0;
|
||||
Radio->StartRx();
|
||||
while (Radio->Process() != RF_RX_DONE)
|
||||
{
|
||||
// Receive external signal, check buffer
|
||||
if (need_send_data)
|
||||
{
|
||||
g_work_thread_status = WORK_THREAD_TX;
|
||||
need_send_data = false;
|
||||
return;
|
||||
}
|
||||
|
||||
//Jump out of the monitoring cycle regularly to see if there is anything that needs to be retransmitted
|
||||
if (counter > 100000)
|
||||
{
|
||||
if (g_client_status_info.status == LORA_CLIENT_CONNECTED)
|
||||
{
|
||||
//printf("check send buffer.\n");
|
||||
}
|
||||
if (g_client_status_info.status >= LORA_CLIENT_LOOKING4GATEWAY &&
|
||||
g_client_status_info.status <= LORA_CLIENT_CONNECTING2GATEWAY)
|
||||
{
|
||||
printf("retry to handshake.\n");
|
||||
}
|
||||
g_work_thread_status = WORK_THREAD_TX;
|
||||
// printf("client end receiving.\n");
|
||||
return;
|
||||
}
|
||||
counter++;
|
||||
}
|
||||
|
||||
enum LoraClientStatus old = g_client_status_info.status;
|
||||
Radio->GetRxPacket(rec_buffer, (uint16 *)&len);
|
||||
LoraClientProcess(padapter, rec_buffer, len);
|
||||
|
||||
//If the client state machine changes, there is something to send to the other party, and it will be switched to the sending mode immediately
|
||||
if (old != g_client_status_info.status)
|
||||
{
|
||||
g_work_thread_status = WORK_THREAD_TX;
|
||||
UserTaskDelay(50); //Afraid the other party hasn't entered reception mode yet
|
||||
}
|
||||
}
|
||||
else if (g_work_thread_status == WORK_THREAD_TX)
|
||||
{
|
||||
// Temporarily designed not to be interrupted
|
||||
switch (g_client_status_info.status)
|
||||
{
|
||||
case LORA_CLIENT_LOOKING4GATEWAY:
|
||||
SendJoinReq(client_net_id);
|
||||
break;
|
||||
case LORA_CLIENT_CONNECTING2GATEWAY:
|
||||
SendHandShakeReq(g_client_status_info.client_name, g_client_status_info.gateway_name);
|
||||
break;
|
||||
case LORA_CLIENT_CONNECTED:
|
||||
CheckSendBuffer();
|
||||
break;
|
||||
case LORA_CLIENT_WAITTING_FOR_DISCONNECTED:
|
||||
SendCloseReq(g_client_status_info.user_id);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
g_work_thread_status = WORK_THREAD_RX;
|
||||
}
|
||||
}
|
||||
|
||||
void static work_thread_func(void *parameter)
|
||||
{
|
||||
adapter_t padapter = (adapter_t)parameter;
|
||||
while (client_work_thread_running)
|
||||
{
|
||||
work_thread_process(padapter);
|
||||
}
|
||||
}
|
||||
int LoraAdapterJoin(adapter_t padapter, int net_role_type, char *net_id)
|
||||
{
|
||||
UtaskType lora_utask_master;
|
||||
UtaskType lora_utask_slave;
|
||||
do
|
||||
{
|
||||
_role_type = net_role_type;
|
||||
x_err_t err;
|
||||
if (_role_type == ROLE_TYPE_MASTER)
|
||||
{
|
||||
strcpy(gateway_net_id, net_id);
|
||||
|
||||
//Single child thread gateway loop monitoring req
|
||||
gateway_listening = true;
|
||||
printf("GateWayListen thread create...");
|
||||
|
||||
strncpy(lora_utask_master.name,"GateWayListen",strlen("GateWayListen"));
|
||||
lora_utask_master.func_entry = LoraGateWayListen;
|
||||
lora_utask_master.func_param = padapter;
|
||||
lora_utask_master.prio = 10;
|
||||
lora_utask_master.stack_size = 2048;
|
||||
|
||||
ServerTask = UserTaskCreate(lora_utask_master);
|
||||
err = UserTaskStartup(ServerTask);
|
||||
if (err != EOK)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (_role_type == ROLE_TYPE_SLAVE)
|
||||
{
|
||||
strcpy(client_net_id, net_id);
|
||||
|
||||
// Create lock
|
||||
if (pclient_send_buffer_mutex < 0)
|
||||
{
|
||||
pclient_send_buffer_mutex = UserMutexCreate();
|
||||
}
|
||||
|
||||
// Update state machine
|
||||
g_client_status_info.status = LORA_CLIENT_LOOKING4GATEWAY;
|
||||
|
||||
// Start single child thread client loop to listen for RSP
|
||||
client_send_buffer.has_data = false;
|
||||
memset(&client_send_buffer, 0, sizeof(client_send_buffer));
|
||||
client_work_thread_running = true;
|
||||
g_work_thread_status = WORK_THREAD_TX;
|
||||
|
||||
strncpy(lora_utask_slave.name,"ClientWorkThread",strlen("ClientWorkThread"));
|
||||
lora_utask_slave.func_entry = work_thread_func;
|
||||
lora_utask_slave.func_param = padapter;
|
||||
lora_utask_slave.prio = 10;
|
||||
lora_utask_slave.stack_size = 2048;
|
||||
|
||||
ClientTask = UserTaskCreate(lora_utask_slave);
|
||||
|
||||
err = UserTaskStartup(ClientTask);
|
||||
if (err != EOK)
|
||||
{
|
||||
break;
|
||||
}
|
||||
// Block detection for a period of time
|
||||
int counter = 100;
|
||||
while (counter > 0)
|
||||
{
|
||||
if (g_client_status_info.status == LORA_CLIENT_CONNECTED)
|
||||
{
|
||||
break; // Successful connection
|
||||
}
|
||||
else
|
||||
{
|
||||
UserTaskDelay(300);
|
||||
}
|
||||
counter--;
|
||||
}
|
||||
return (counter > 0) ? 0 : ERROR;
|
||||
}
|
||||
return EOK;
|
||||
} while (false);
|
||||
|
||||
// Exception handling, releasing resources
|
||||
LoraAdapterCose(padapter);
|
||||
return ERROR;
|
||||
}
|
|
@ -26,6 +26,9 @@
|
|||
#ifdef CONNECTION_COMMUNICATION_ZIGBEE
|
||||
#include <xs_adapter_zigbee.h>
|
||||
#endif
|
||||
#ifdef CONNECTION_COMMUNICATION_LORA
|
||||
#include <xs_adapter_lora.h>
|
||||
#endif
|
||||
|
||||
|
||||
// Zigbee Adapter List
|
||||
|
@ -48,8 +51,7 @@ void* ZigbeeAdapterFind(char* name)
|
|||
DoubleLinklistType* phead = &zigbee_adapter_list;
|
||||
struct AdapterZigbee* padapter = NONE;
|
||||
|
||||
for(pnode = phead->node_next; pnode != phead; pnode = pnode->node_next)
|
||||
{
|
||||
for(pnode = phead->node_next; pnode != phead; pnode = pnode->node_next) {
|
||||
padapter = (struct AdapterZigbee*)SYS_DOUBLE_LINKLIST_ENTRY(pnode, struct Adapter, link);
|
||||
// KPrintf("ZigbeeReceiveDemo bbb\n");
|
||||
if (0 == strcmp(padapter->name, name)){
|
||||
|
@ -61,7 +63,37 @@ void* ZigbeeAdapterFind(char* name)
|
|||
}
|
||||
#endif
|
||||
|
||||
// Lora Adapter List
|
||||
#ifdef CONNECTION_COMMUNICATION_LORA
|
||||
static DoubleLinklistType lora_adapter_list;
|
||||
|
||||
void LoraAdapterInit()
|
||||
{
|
||||
InitDoubleLinkList(&lora_adapter_list);
|
||||
}
|
||||
|
||||
void LoraAdapterRegister(adapter_t padapter)
|
||||
{
|
||||
DoubleLinkListInsertNodeAfter(&lora_adapter_list, &(padapter->link));
|
||||
}
|
||||
|
||||
void* LoraAdapterFind(char* name)
|
||||
{
|
||||
DoubleLinklistType* pnode = NONE;
|
||||
DoubleLinklistType* phead = &lora_adapter_list;
|
||||
struct AdapterLora* padapter = NONE;
|
||||
|
||||
for(pnode = phead->node_next; pnode != phead; pnode = pnode->node_next) {
|
||||
padapter = (struct AdapterLora*)SYS_DOUBLE_LINKLIST_ENTRY(pnode, struct Adapter, link);
|
||||
|
||||
if (0 == strcmp(padapter->name, name)) {
|
||||
return padapter;
|
||||
}
|
||||
}
|
||||
|
||||
return padapter;
|
||||
}
|
||||
#endif
|
||||
|
||||
// AT Adapter List
|
||||
static DoubleLinklistType at_adapter_list;
|
||||
|
@ -86,8 +118,7 @@ void* ATAdapterFind(uint32 adapter_id)
|
|||
struct AdapterAT* padapter = NONE;
|
||||
|
||||
|
||||
for(pnode = phead->node_next; pnode != phead; pnode = pnode->node_next)
|
||||
{
|
||||
for(pnode = phead->node_next; pnode != phead; pnode = pnode->node_next) {
|
||||
padapter = (struct AdapterAT*)SYS_DOUBLE_LINKLIST_ENTRY(pnode, struct AdapterAT, link);
|
||||
|
||||
if (padapter->at_adapter_id == adapter_id){
|
||||
|
|
|
@ -41,6 +41,8 @@ KERNELPATHS :=-I$(BSP_ROOT) \
|
|||
-I$(BSP_ROOT)/third_party_driver \
|
||||
-I$(BSP_ROOT)/include \
|
||||
-I$(BSP_ROOT)/third_party_driver/include \
|
||||
-I$(BSP_ROOT)/third_party_driver/spi/third_party_spi_lora/inc \
|
||||
-I$(BSP_ROOT)/third_party_driver/spi/third_party_spi_lora/src/radio \
|
||||
-I$(BSP_ROOT)/third_party_driver/usb/STM32_USB_OTG_Driver/inc \
|
||||
-I$(KERNEL_ROOT)/include \
|
||||
-I$(BSP_ROOT)/include #
|
||||
|
@ -86,6 +88,8 @@ KERNELPATHS :=-I$(BSP_ROOT) \
|
|||
-I$(BSP_ROOT)/third_party_driver \
|
||||
-I$(BSP_ROOT)/include \
|
||||
-I$(BSP_ROOT)/third_party_driver/include \
|
||||
-I$(BSP_ROOT)/third_party_driver/spi/third_party_spi_lora/inc \
|
||||
-I$(BSP_ROOT)/third_party_driver/spi/third_party_spi_lora/src/radio \
|
||||
-I$(BSP_ROOT)/third_party_driver/camera \
|
||||
-I$(BSP_ROOT)/third_party_driver/drivers \
|
||||
-I$(BSP_ROOT)/third_party_driver/lcd \
|
||||
|
|
Loading…
Reference in New Issue