update rt-thread bsp(xidatong-arm and aiit-arm32-board) from tian_chunyu

it is OK
This commit is contained in:
xuedongliang 2022-07-01 16:13:20 +08:00
commit b4a92c91f5
101 changed files with 8288 additions and 113 deletions

@ -0,0 +1 @@
Subproject commit d7ac9f271158d1f8ed1ebaddcb8c2ce4b0927d19

View File

@ -0,0 +1,18 @@
import os
Import('RTT_ROOT')
from building import *
SOURCES = []
SOURCES = ['adapter_4g.c'] + SOURCES
objs = []
cwd = GetCurrentDir()
path = [cwd]
group = DefineGroup('4g', SOURCES, depend = [], CPPPATH = [cwd])
objs = objs + group
list = os.listdir(cwd)
for d in list:
path = os.path.join(cwd, d)
if os.path.isfile(os.path.join(path, 'SConscript')):
objs = objs + SConscript(os.path.join(path, 'SConscript'))
Return('objs')

View File

@ -111,3 +111,6 @@ int Adapter4GTest(void)
return 0;
}
// SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_PARAM_NUM(0)|SHELL_CMD_DISABLE_RETURN, Adapter4GTest, Adapter4GTest, show adapter 4G information);
#ifdef ADD_RTTHREAD_FETURES
MSH_CMD_EXPORT(Adapter4GTestRTThread,a 4G adpter sample);
#endif

View File

@ -3,19 +3,13 @@ config ADAPTER_4G_EC200T
default "ec200t"
if ADD_XIZI_FETURES
config ADAPTER_EC200T_USING_PWRKEY
bool "EC200T using PWRKEY pin number"
default n
config ADAPTER_EC200T_PWRKEY
int "EC200T PWRKEY pin number"
default "97"
if ADAPTER_EC200T_USING_PWRKEY
config ADAPTER_EC200T_PWRKEY
int "EC200T PWRKEY pin number"
default "97"
config ADAPTER_EC200T_PIN_DRIVER
string "EC200T device pin driver path"
default "/dev/pin_dev"
endif
config ADAPTER_EC200T_PIN_DRIVER
string "EC200T device pin driver path"
default "/dev/pin_dev"
config ADAPTER_EC200T_DRIVER_EXTUART
bool "Using extra uart to support 4G"
@ -45,5 +39,31 @@ if ADD_NUTTX_FETURES
endif
if ADD_RTTHREAD_FETURES
config ADAPTER_EC200T_PWRKEY
int "EC200T PWRKEY pin number"
default "97"
config ADAPTER_EC200T_PIN_DRIVER
string "EC200T device pin driver path"
default "/dev/pin_dev"
config ADAPTER_EC200T_DRIVER_EXTUART
bool "Using extra uart to support 4G"
default n
config ADAPTER_EC200T_DRIVER
string "EC200T device uart driver path"
default "/dev/usart8"
depends on !ADAPTER_EC200T_DRIVER_EXTUART
if ADAPTER_EC200T_DRIVER_EXTUART
config ADAPTER_EC200T_DRIVER
string "EC200T device extra uart driver path"
default "/dev/extuart_dev5"
config ADAPTER_EC200T_DRIVER_EXT_PORT
int "if EC200T device using extuart, choose port"
default "5"
endif
endif

View File

@ -0,0 +1,10 @@
from building import *
import os
cwd = GetCurrentDir()
src = []
if GetDepend(['ADAPTER_EC200T']):
src += ['ec200t.c']
group = DefineGroup('connection 4g ec200t', src, depend = [], CPPPATH = [cwd])
Return('group')

View File

@ -40,10 +40,12 @@
#ifdef ADD_NUTTX_FETURES
static void Ec200tPowerSet(void){ return; }
#else
static void Ec200tPowerSet(void)
{
#ifdef ADAPTER_EC200T_USING_PWRKEY
#else
#ifdef ADD_RTTHREAD_FETURES
static void Ec200tPowerSet(void){ return; }
#else
static void Ec200tPowerSet(void)
{
int pin_fd;
pin_fd = PrivOpen(ADAPTER_EC200T_PIN_DRIVER, O_RDWR);
if (pin_fd < 0) {
@ -74,8 +76,8 @@ static void Ec200tPowerSet(void)
PrivClose(pin_fd);
PrivTaskDelay(10000);
#endif
}
}
#endif
#endif
static int Ec200tOpen(struct Adapter *adapter)
@ -150,6 +152,9 @@ out:
#ifdef ADD_NUTTX_FETURES
static int Ec200tIoctl(struct Adapter *adapter, int cmd, void *args){ return 0;}
#else
#ifdef ADD_RTTHREAD_FETURES
static int Ec200tIoctl(struct Adapter *adapter, int cmd, void *args){ return 0;}
#else
static int Ec200tIoctl(struct Adapter *adapter, int cmd, void *args)
{
if (OPE_INT != cmd) {
@ -177,12 +182,14 @@ static int Ec200tIoctl(struct Adapter *adapter, int cmd, void *args)
ioctl_cfg.ioctl_driver_type = SERIAL_TYPE;
ioctl_cfg.args = &serial_cfg;
PrivIoctl(adapter->fd, OPE_INT, &ioctl_cfg);
Ec200tPowerSet();
return 0;
}
#endif
#endif
static int Ec200tConnect(struct Adapter *adapter, enum NetRoleType net_role, const char *ip, const char *port, enum IpType ip_type)
{

View File

@ -0,0 +1,19 @@
import os
Import('RTT_ROOT')
from building import *
SOURCES = []
if GetDepend(['CONNECTION_ADAPTER_LORA']):
SOURCES = ['adapter_lora.c'] + SOURCES
objs = []
cwd = GetCurrentDir()
path = [cwd]
group = DefineGroup('lora', SOURCES, depend = [], CPPPATH = [cwd])
objs = objs + group
list = os.listdir(cwd)
for d in list:
path = os.path.join(cwd, d)
if os.path.isfile(os.path.join(path, 'SConscript')):
objs = objs + SConscript(os.path.join(path, 'SConscript'))
Return('objs')

View File

@ -16,5 +16,8 @@ if ADD_NUTTX_FETURES
endif
if ADD_RTTHREAD_FETURES
config ADAPTER_SX1278_DRIVER
string "SX1278 device spi driver path"
default "/dev/sx1278"
endif

View File

@ -0,0 +1,10 @@
from building import *
import os
cwd = GetCurrentDir()
src = []
if GetDepend(['ADAPTER_SX1278']):
src += ['sx1278.c']
group = DefineGroup('connection lora sx1278', src, depend = [], CPPPATH = [cwd])
Return('group')

View File

@ -199,6 +199,9 @@ int wifiopen(void)
#ifdef ADD_XIZI_FETURES
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_PARAM_NUM(0)|SHELL_CMD_DISABLE_RETURN, wifiopen, wifiopen, open adapter wifi );
#endif
#ifdef ADD_RTTHREAD_FETURES
MSH_CMD_EXPORT(wifiopen,a wifi adpter sample);
#endif
int wificlose(void)
{
struct Adapter* adapter = AdapterDeviceFindByName(ADAPTER_WIFI_NAME);
@ -207,6 +210,9 @@ int wificlose(void)
#ifdef ADD_XIZI_FETURES
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_PARAM_NUM(0)|SHELL_CMD_DISABLE_RETURN, wificlose, wificlose, close adapter wifi );
#endif
#ifdef ADD_RTTHREAD_FETURES
MSH_CMD_EXPORT(wificlose,a wifi adpter sample);
#endif
int wifisetup(int argc, char *argv[])
{
struct Adapter* adapter = AdapterDeviceFindByName(ADAPTER_WIFI_NAME);
@ -222,6 +228,9 @@ int wifisetup(int argc, char *argv[])
#ifdef ADD_XIZI_FETURES
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN)|SHELL_CMD_PARAM_NUM(3)|SHELL_CMD_DISABLE_RETURN, wifisetup, wifisetup, setup adapter wifi );
#endif
#ifdef ADD_RTTHREAD_FETURES
MSH_CMD_EXPORT(wifisetup,a wifi adpter sample:wifisetup <server|client>);
#endif
int wifiaddrset(int argc, char *argv[])
{
struct Adapter* adapter = AdapterDeviceFindByName(ADAPTER_WIFI_NAME);
@ -236,6 +245,9 @@ int wifiaddrset(int argc, char *argv[])
#ifdef ADD_XIZI_FETURES
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN)|SHELL_CMD_PARAM_NUM(4)|SHELL_CMD_DISABLE_RETURN, wifiaddrset, wifiaddrset, addrset adapter wifi);
#endif
#ifdef ADD_RTTHREAD_FETURES
MSH_CMD_EXPORT(wifiaddrset,a wifi adpter sample:wifiaddrset <server|client>);
#endif
int wifiping(int argc, char *argv[])
{
struct Adapter* adapter = AdapterDeviceFindByName(ADAPTER_WIFI_NAME);
@ -245,6 +257,9 @@ int wifiping(int argc, char *argv[])
#ifdef ADD_XIZI_FETURES
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN)|SHELL_CMD_PARAM_NUM(3), wifiping, wifiping, wifiping adapter );
#endif
#ifdef ADD_RTTHREAD_FETURES
MSH_CMD_EXPORT(wifiping,a wifi adpter sample:wifiping <server|client>);
#endif
int wificonnect(int argc, char *argv[])
{
struct Adapter* adapter = AdapterDeviceFindByName(ADAPTER_WIFI_NAME);
@ -266,6 +281,9 @@ int wificonnect(int argc, char *argv[])
#ifdef ADD_XIZI_FETURES
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN)|SHELL_CMD_PARAM_NUM(4)|SHELL_CMD_DISABLE_RETURN, wificonnect, wificonnect, wificonnect adapter);
#endif
#ifdef ADD_RTTHREAD_FETURES
MSH_CMD_EXPORT(wificonnect,a wifi adpter sample:wificonnect <server|client>);
#endif
int wifisend(int argc, char *argv[])
{
struct Adapter* adapter = AdapterDeviceFindByName(ADAPTER_WIFI_NAME);
@ -281,6 +299,9 @@ int wifisend(int argc, char *argv[])
#ifdef ADD_XIZI_FETURES
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN)|SHELL_CMD_PARAM_NUM(3)|SHELL_CMD_DISABLE_RETURN, wifisend, wifisend, wifisend adapter wifi information);
#endif
#ifdef ADD_RTTHREAD_FETURES
MSH_CMD_EXPORT(wifisend,a wifi adpter sample:wifisend <server|client>);
#endif
int wifirecv(int argc, char *argv[])
{
struct Adapter* adapter = AdapterDeviceFindByName(ADAPTER_WIFI_NAME);
@ -295,6 +316,9 @@ int wifirecv(int argc, char *argv[])
#ifdef ADD_XIZI_FETURES
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN)|SHELL_CMD_PARAM_NUM(3)|SHELL_CMD_DISABLE_RETURN, wifirecv, wifirecv, wifirecv adapter wifi information);
#endif
#ifdef ADD_RTTHREAD_FETURES
MSH_CMD_EXPORT(wifirecv,a wifi adpter sample:wifirecv <server|client>);
#endif
#ifdef ADD_NUTTX_FETURES

View File

@ -46,5 +46,25 @@ if ADD_NUTTX_FETURES
endif
if ADD_RTTHREAD_FETURES
if ADD_RTTHREAD_FETURES
config ADAPTER_ESP07S_DRIVER_EXTUART
bool "Using extra uart to support wifi"
default n
config ADAPTER_ESP07S_DRIVER
string "ESP07S device uart driver path"
default "/dev/uart2"
depends on !ADAPTER_ESP07S_DRIVER_EXTUART
if ADAPTER_ESP07S_DRIVER_EXTUART_RT
config ADAPTER_ESP07S_DRIVER
string "ESP07S device extra uart driver path"
default "/dev/extuart_dev6_rt"
config ADAPTER_ESP07S_DRIVER_EXT_PORT
int "if ESP07S device using extuart, choose port"
default "6"
endif
endif
endif

View File

@ -0,0 +1,12 @@
from building import *
import os
cwd = GetCurrentDir()
src = []
if GetDepend(['ADAPTER_ESP07S_WIFI']):
src += ['esp07s_wifi.c']
group = DefineGroup('connection wifi esp07s', src, depend = [], CPPPATH = [cwd])
Return('group')

View File

@ -35,6 +35,12 @@ config SENSOR_HS300X_HUMIDITY
endif
if ADD_RTTHREAD_FETURES
config SENSOR_DEVICE_HS300X_DEV
string "HS300x device name"
default "/dev/i2c1"
config SENSOR_DEVICE_HS300X_I2C_ADDR
hex "HS300x device i2c address"
default 0x44
endif
endif

View File

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

View File

@ -0,0 +1,10 @@
from building import *
import os
cwd = GetCurrentDir()
src = []
if GetDepend(['SENSOR_HS300X_HUMIDITY']):
src += ['hs300x_humi.c']
group = DefineGroup('sensor humidity hs300x', src, depend = [], CPPPATH = [cwd])
Return('group')

View File

@ -34,6 +34,12 @@ config SENSOR_HS300X_TEMPERATURE
endif
if ADD_RTTHREAD_FETURES
config SENSOR_DEVICE_HS300X_DEV
string "HS300x device name"
default "/dev/i2c1"
config SENSOR_DEVICE_HS300X_I2C_ADDR
hex "HS300x device i2c address"
default 0x44
endif
endif

View File

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

View File

@ -0,0 +1,10 @@
from building import *
import os
cwd = GetCurrentDir()
src = []
if GetDepend(['SENSOR_HS300X_TEMPERATURE']):
src += ['hs300x_temp.c']
group = DefineGroup('sensor temperature hs300x', src, depend = [], CPPPATH = [cwd])
Return('group')

View File

@ -67,7 +67,10 @@ int PrivSemaphoreAbandon(sem_t *sem)
{
return sem_post(sem);
}
int PrivSemaphoreObtainWaitForever(sem_t *sem)
{
return sem_wait(sem);
}
/**************************task*************************/
int PrivTaskCreate(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine)(void *), void *arg)

View File

@ -173,6 +173,7 @@ int PrivSemaphoreDelete(sem_t *sem);
int PrivSemaphoreObtainWait(sem_t *sem, const struct timespec *abstime);
int PrivSemaphoreObtainNoWait(sem_t *sem);
int PrivSemaphoreAbandon(sem_t *sem);
int PrivSemaphoreObtainWaitForever(sem_t *sem);
int32_t PrivSemaphoreSetValue(int32_t sem, uint16_t val);
/*********************task**************************/

View File

@ -1,43 +0,0 @@
/*
* @Author: yongliang
* @Date: 2022-03-31 16:00:00
* @Description: uart_test code
* @FilePath: \xiuos\Ubiquitous\RT_Thread\aiit_board\stm32f407_mini_board\applications\uart_test.c
*/
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
*/
#include <rtthread.h>
#include <board.h>
#include <stdio.h>
#include <string.h>
int main (void)
{
/*1.设置系统中断优先组*/
/*2.串口初始化*/
while(1)
{
if(USART_RX_STA&0X8000)
{
len =USART_RX_STA&0X3fff;
printf("发送的消息为:\r\n");
for(t=0;t<len;t++)
{
USART_SendData(USART1,USART_RX_BUF[T]);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 191 KiB

View File

@ -376,6 +376,8 @@ CONFIG_PHY_RESET_PIN=3
#
# CONFIG_PKG_USING_RW007 is not set
# CONFIG_DRV_USING_OV2640 is not set
# CONFIG_DRV_USING_HS300X is not set
# CONFIG_DRV_USING_SX1278 is not set
#
# APP_Framework
@ -436,6 +438,7 @@ CONFIG_MAIN_KTASK_STACK_SIZE=1024
#
# CONFIG_APPLICATION_SENSOR is not set
# CONFIG_USING_EMBEDDED_DATABASE_APP is not set
# CONFIG_APP_USING_WEBNET is not set
#
# lib
@ -445,4 +448,9 @@ CONFIG_APP_SELECT_NEWLIB=y
# CONFIG_LIB_USING_CJSON is not set
# CONFIG_LIB_USING_QUEUE is not set
# CONFIG_LIB_LV is not set
#
# LVGL configuration
#
# CONFIG_LV_CONF_MINIMAL is not set
# CONFIG_USING_EMBEDDED_DATABASE is not set

View File

@ -0,0 +1,115 @@
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2019-04-29 tyustli first version
*
*/
#include <rtdevice.h>
#include <rtthread.h>
#include "drv_gpio.h"
#include <board.h>
/* defined the LED pin: GPIO1_IO9 */
#define LED0_PIN GET_PIN(1,9)
int main(void)
{
/* set LED0 pin mode to output */
rt_pin_mode(LED0_PIN, PIN_MODE_OUTPUT);
rt_kprintf("XIUOS xidatong build %s %s\n",__DATE__,__TIME__);
while (1)
{
rt_pin_write(LED0_PIN, PIN_HIGH);
rt_thread_mdelay(500);
rt_pin_write(LED0_PIN, PIN_LOW);
rt_thread_mdelay(500);
}
}
#ifdef BSP_USING_SDRAM
static void sdram_test2(void)
{
char *p =NULL;
p = rt_malloc(1024*1024*8);
if(p == NULL)
{
rt_kprintf("apply for 8MB memory fail ~!!!");
}
else
{
rt_kprintf("appyle for 8MB memory success!!!");
}
rt_free(p);
}
MSH_CMD_EXPORT(sdram_test2, sdram test2);
#endif
#ifdef BSP_USB1_HOST
#include <dfs_posix.h>
static char test_data[120], buffer[120];
#define TEST_FN "/testusb.c"
void readwrite(const char* filename)
{
int fd;
int index, length;
fd = open(TEST_FN, O_WRONLY | O_CREAT | O_TRUNC, 0);
if (fd < 0)
{
rt_kprintf("open file for write failed\n");
return;
}
for (index = 0; index < sizeof(test_data); index ++)
{
test_data[index] = index + 27;
}
length = write(fd, test_data, sizeof(test_data));
if (length != sizeof(test_data))
{
rt_kprintf("write data failed\n");
close(fd);
return;
}
close(fd);
fd = open(TEST_FN, O_RDONLY, 0);
if (fd < 0)
{
rt_kprintf("check: open file for read failed\n");
return;
}
length = read(fd, buffer, sizeof(buffer));
if (length != sizeof(buffer))
{
rt_kprintf("check: read file failed\n");
close(fd);
return;
}
for (index = 0; index < sizeof(test_data); index ++)
{
if (test_data[index] != buffer[index])
{
rt_kprintf("check: check data failed at %d\n", index);
close(fd);
return;
}
}
rt_kprintf("usb host read/write udisk successful\r\n");
close(fd);
}
MSH_CMD_EXPORT(readwrite, usb host read write test);
#endif

View File

@ -221,6 +221,14 @@ menu "Onboard Peripheral Drivers"
select RT_USING_DFS
select RT_USING_DFS_ELMFAT
default n
config BSP_USB0_HOST
bool "Enable USB0 Host"
default n
config BSP_USB1_HOST
bool "Enable USB1 Host"
default n
menuconfig BSP_USING_ETH
bool "Enable Ethernet"

View File

@ -9,7 +9,7 @@ MCUX_Config/clock_config.c
MCUX_Config/pin_mux.c
""")
CPPPATH = [cwd,cwd + '/MCUX_Config',cwd + '/ports']
CPPPATH = [cwd,cwd + '/MCUX_Config',cwd + '/ports',cwd + '/usb']
CPPDEFINES = ['CPU_MIMXRT1052CVL5B', 'SKIP_SYSCLK_INIT', 'EVK_MCIMXRM', 'FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL=1','XIP_EXTERNAL_FLASH=1']
if GetDepend('BSP_USING_PHY') and GetDepend('PHY_USING_8720A'):
src += ['./ports/LAN8720A.c']
@ -18,6 +18,8 @@ if GetDepend('BSP_USING_SDCARD'):
if GetDepend(['RT_USING_DFS_ROMFS']):
src += ['ports/romfs.c']
src += ['ports/mnt_romfs.c']
if GetDepend('RT_USING_USB_HOST'):
src += ['usb/drv_usbh.c']
group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH, CPPDEFINES=CPPDEFINES)
Return('group')

View File

@ -0,0 +1,732 @@
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2017-10-30 ZYH the first version
* 2019-12-19 tyustli port to stm32 series
* 2021-01-19 Leslie Lee port to imxrt series
*/
#include <rtthread.h>
#if defined(BSP_USB0_HOST) || defined(BSP_USB1_HOST)
#include "drv_usbh.h"
#include <usb/include/usb_host_config.h>
#include <usb/include/usb.h>
#include <usb/phy/usb_phy.h>
#include <usb/host/usb_host.h>
#include <usb/host/usb_host_hci.h>
#include <usb/host/usb_host_ehci.h>
#include <rtdevice.h>
/* USB PHY configuration */
#ifndef BOARD_USB_PHY_D_CAL
#define BOARD_USB_PHY_D_CAL (0x0CU)
#endif
#ifndef BOARD_USB_PHY_TXCAL45DP
#define BOARD_USB_PHY_TXCAL45DP (0x06U)
#endif
#ifndef BOARD_USB_PHY_TXCAL45DM
#define BOARD_USB_PHY_TXCAL45DM (0x06U)
#endif
#define USB_HOST_INTERRUPT_PRIORITY 3
enum
{
#ifdef BSP_USB0_HOST
USBH0_INDEX,
#endif
#ifdef BSP_USB1_HOST
USBH1_INDEX,
#endif
};
struct imxrt_usb_host_pipe
{
usb_host_pipe_handle pipe_handle;
struct rt_completion urb_completion;
usb_status_t transfer_status;
};
struct imxrt_usb_host
{
struct uhcd uhcd;
usb_host_handle host_handle;
usb_device_handle device_handle;
struct imxrt_usb_host_pipe pipes[16];
volatile rt_bool_t connect_status;
char *name;
};
static struct imxrt_usb_host imxrt_usb_host_obj[] =
{
#ifdef BSP_USB0_HOST
{
.connect_status = RT_FALSE,
.name = "usbh0"
},
#endif
#ifdef BSP_USB1_HOST
{
.connect_status = RT_FALSE,
.name = "usbh1"
},
#endif
};
static void _imxrt_usb_host_send_callback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
{
struct imxrt_usb_host_pipe *pipe = (struct imxrt_usb_host_pipe *)param;
pipe->transfer_status = status;
rt_completion_done(&pipe->urb_completion);
}
/*!
* @brief Initializes USB specific setting that was not set by the Clocks tool.
*/
static void USB_HostClockInit(usb_controller_index_t controller_id)
{
usb_phy_config_struct_t phyConfig = {
BOARD_USB_PHY_D_CAL, BOARD_USB_PHY_TXCAL45DP, BOARD_USB_PHY_TXCAL45DM,
};
uint32_t notUsed = 0;
if (controller_id == kUSB_ControllerEhci0)
{
CLOCK_EnableUsbhs0PhyPllClock(kCLOCK_Usbphy480M, 480000000U);
CLOCK_EnableUsbhs0Clock(kCLOCK_Usb480M, 480000000U);
}
else
{
CLOCK_EnableUsbhs1PhyPllClock(kCLOCK_Usbphy480M, 480000000U);
CLOCK_EnableUsbhs1Clock(kCLOCK_Usb480M, 480000000U);
}
USB_EhciPhyInit(controller_id, 24000000U, &phyConfig);
}
/*!
* @brief Enables interrupt service routines for device.
*/
void USB_HostIsrEnable(usb_controller_index_t controller_id)
{
uint8_t irqNumber;
#if ((defined USB_HOST_CONFIG_EHCI) && (USB_HOST_CONFIG_EHCI > 0U))
IRQn_Type usbHOSTEhciIrq[] = USBHS_IRQS;
irqNumber = usbHOSTEhciIrq[controller_id - kUSB_ControllerEhci0];
#endif
/* Install isr, set priority, and enable IRQ. */
#if defined(__GIC_PRIO_BITS)
GIC_SetPriority((IRQn_Type)irqNumber, USB_HOST_INTERRUPT_PRIORITY);
#else
NVIC_SetPriority((IRQn_Type)irqNumber, USB_HOST_INTERRUPT_PRIORITY);
#endif
EnableIRQ((IRQn_Type)irqNumber);
}
#ifdef BSP_USB0_HOST
void USB_OTG1_IRQHandler(void)
{
/* enter interrupt */
rt_interrupt_enter();
USB_HostEhciIsrFunction(imxrt_usb_host_obj[USBH0_INDEX].host_handle);
/* leave interrupt */
rt_interrupt_leave();
}
static rt_err_t _ehci0_reset_port(rt_uint8_t port)
{
// No reset port function available
return RT_EOK;
}
static uint8_t _ehci0_pipe_buf[64];
static uint8_t _ehci0_pipe_idx;
static int _ehci0_pipe_xfer(upipe_t pipe, rt_uint8_t token, void *buffer, int nbytes, int timeouts)
{
int timeout = timeouts;
if (!imxrt_usb_host_obj[USBH0_INDEX].connect_status)
{
return -1;
}
usb_host_transfer_t *transfer;
if (imxrt_usb_host_obj[USBH0_INDEX].pipes[pipe->pipe_index].pipe_handle == NULL)
{
RT_DEBUG_LOG(RT_DEBUG_USB, ("error operation on null pipe\n"));
return -1;
}
if (USB_HostMallocTransfer(imxrt_usb_host_obj[USBH0_INDEX].host_handle, &transfer) != kStatus_USB_Success)
{
RT_DEBUG_LOG(RT_DEBUG_USB, ("error to get transfer\n"));
return -1;
}
transfer->transferBuffer = buffer;
transfer->transferLength = nbytes;
transfer->transferSofar = 0;
transfer->callbackFn = _imxrt_usb_host_send_callback;
transfer->callbackParam = &(imxrt_usb_host_obj[USBH0_INDEX].pipes[pipe->pipe_index]);
transfer->direction = (pipe->ep.bEndpointAddress & USB_DIR_IN) ? USB_IN : USB_OUT;
if (pipe->ep.bmAttributes == USB_ENDPOINT_CONTROL)
{
if (token == USBH_PID_SETUP)
{
struct urequest *setup = (struct urequest *)buffer;
transfer->setupStatus = 0;
transfer->setupPacket->bmRequestType = setup->request_type;
transfer->setupPacket->bRequest = setup->bRequest;
transfer->setupPacket->wIndex = setup->wIndex;
transfer->setupPacket->wLength = setup->wLength;
transfer->setupPacket->wValue = setup->wValue;
transfer->transferBuffer = RT_NULL;
transfer->transferLength = 0;
transfer->next = RT_NULL;
if ((transfer->setupPacket->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) == USB_REQUEST_TYPE_DIR_IN)
{
transfer->direction = USB_IN;
transfer->transferBuffer = _ehci0_pipe_buf;
transfer->transferLength = setup->wLength;
_ehci0_pipe_idx = 0;
}
else
{
transfer->direction = USB_OUT;
}
}
else
{
rt_memcpy(buffer, _ehci0_pipe_buf + _ehci0_pipe_idx, nbytes);
imxrt_usb_host_obj[USBH0_INDEX].pipes[pipe->pipe_index].transfer_status = kStatus_USB_Success;
transfer->transferSofar = nbytes;
_ehci0_pipe_idx += nbytes;
if (_ehci0_pipe_idx >= 64)
{
_ehci0_pipe_idx = 0;
}
goto _ehci0_pipe_xfer_finish;
}
}
rt_completion_init(&(imxrt_usb_host_obj[USBH0_INDEX].pipes[pipe->pipe_index].urb_completion));
if (USB_HostEhciWritePipe(((usb_host_instance_t *)imxrt_usb_host_obj[USBH0_INDEX].host_handle)->controllerHandle, imxrt_usb_host_obj[USBH0_INDEX].pipes[pipe->pipe_index].pipe_handle, transfer) != kStatus_USB_Success)
{
RT_DEBUG_LOG(RT_DEBUG_USB, ("usb host failed to send\n"));
(void)USB_HostFreeTransfer(imxrt_usb_host_obj[USBH0_INDEX].host_handle, transfer);
return -1;
}
if (-RT_ETIMEOUT == rt_completion_wait(&(imxrt_usb_host_obj[USBH0_INDEX].pipes[pipe->pipe_index].urb_completion), RT_WAITING_FOREVER))
{
RT_DEBUG_LOG(RT_DEBUG_USB, ("usb transfer timeout\n"));
(void)USB_HostFreeTransfer(imxrt_usb_host_obj[USBH0_INDEX].host_handle, transfer);
return -1;
}
_ehci0_pipe_xfer_finish:
switch (imxrt_usb_host_obj[USBH0_INDEX].pipes[pipe->pipe_index].transfer_status)
{
case kStatus_USB_Success:
{
RT_DEBUG_LOG(RT_DEBUG_USB, ("ok\n"));
pipe->status = UPIPE_STATUS_OK;
if (pipe->callback != RT_NULL)
{
pipe->callback(pipe);
}
size_t size = transfer->transferSofar;
(void)USB_HostFreeTransfer(imxrt_usb_host_obj[USBH0_INDEX].host_handle, transfer);
if (pipe->ep.bEndpointAddress & 0x80)
{
return size;
}
else if (pipe->ep.bEndpointAddress & 0x00)
{
return size;
}
return nbytes;
break;
}
case kStatus_USB_TransferStall:
{
RT_DEBUG_LOG(RT_DEBUG_USB, ("stall\n"));
pipe->status = UPIPE_STATUS_STALL;
if (pipe->callback != RT_NULL)
{
pipe->callback(pipe);
}
(void)USB_HostFreeTransfer(imxrt_usb_host_obj[USBH0_INDEX].host_handle, transfer);
return -1;
break;
}
case kStatus_USB_TransferFailed:
default:
{
RT_DEBUG_LOG(RT_DEBUG_USB, ("error\n"));
pipe->status = UPIPE_STATUS_ERROR;
if (pipe->callback != RT_NULL)
{
pipe->callback(pipe);
}
(void)USB_HostFreeTransfer(imxrt_usb_host_obj[USBH0_INDEX].host_handle, transfer);
return -1;
break;
}
}
}
static rt_uint16_t _ehci0_pipe_index = 0;
static rt_uint8_t _ehci0_get_free_pipe_index(void)
{
rt_uint8_t idx;
for (idx = 1; idx < 16; idx++)
{
if (!(_ehci0_pipe_index & (0x01 << idx)))
{
_ehci0_pipe_index |= (0x01 << idx);
return idx;
}
}
return 0xff;
}
static void _ehci0_free_pipe_index(rt_uint8_t index)
{
_ehci0_pipe_index &= ~(0x01 << index);
}
static rt_err_t _ehci0_open_pipe(upipe_t pipe)
{
pipe->pipe_index = _ehci0_get_free_pipe_index();
if (pipe->pipe_index == 0xFF)
{
return -RT_ERROR;
}
usb_host_pipe_init_t pipe_init =
{
.devInstance = imxrt_usb_host_obj[USBH0_INDEX].device_handle,
.pipeType = pipe->ep.bmAttributes,
.direction = (pipe->ep.bEndpointAddress & USB_DIR_IN) ? USB_IN : USB_OUT,
.endpointAddress = (pipe->ep.bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_MASK),
.interval = pipe->ep.bInterval,
.maxPacketSize = (uint16_t)(pipe->ep.wMaxPacketSize & USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_SIZE_MASK),
.numberPerUframe = (uint8_t)(pipe->ep.wMaxPacketSize & USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_MULT_TRANSACTIONS_MASK),
.nakCount = USB_HOST_CONFIG_MAX_NAK,
};
USB_HostOpenPipe(imxrt_usb_host_obj[USBH0_INDEX].host_handle, &imxrt_usb_host_obj[USBH0_INDEX].pipes[pipe->pipe_index].pipe_handle, &pipe_init);
return RT_EOK;
}
static rt_err_t _ehci0_close_pipe(upipe_t pipe)
{
(void)USB_HostClosePipe(imxrt_usb_host_obj[USBH0_INDEX].host_handle, imxrt_usb_host_obj[USBH0_INDEX].pipes[pipe->pipe_index].pipe_handle);
_ehci0_free_pipe_index(pipe->pipe_index);
return RT_EOK;
}
static struct uhcd_ops _ehci0_uhcd_ops =
{
_ehci0_reset_port,
_ehci0_pipe_xfer,
_ehci0_open_pipe,
_ehci0_close_pipe,
};
static usb_status_t usb0_host_callback(usb_device_handle handle, usb_host_configuration_handle config_handle, rt_uint32_t event_code)
{
usb_status_t status = kStatus_USB_Success;
switch (event_code)
{
case kUSB_HostEventAttach:
if (!imxrt_usb_host_obj[USBH0_INDEX].connect_status)
{
imxrt_usb_host_obj[USBH0_INDEX].connect_status = RT_TRUE;
imxrt_usb_host_obj[USBH0_INDEX].device_handle = handle;
RT_DEBUG_LOG(RT_DEBUG_USB, ("usb connected\n"));
rt_usbh_root_hub_connect_handler(&(imxrt_usb_host_obj[USBH0_INDEX].uhcd), OTG_PORT, RT_TRUE);
}
break;
case kUSB_HostEventNotSupported:
RT_DEBUG_LOG(RT_DEBUG_USB, ("usb device not supported\n"));
break;
case kUSB_HostEventEnumerationDone:
RT_DEBUG_LOG(RT_DEBUG_USB, ("enumeration done\n"));
break;
case kUSB_HostEventDetach:
if (imxrt_usb_host_obj[USBH0_INDEX].connect_status)
{
imxrt_usb_host_obj[USBH0_INDEX].connect_status = RT_FALSE;
imxrt_usb_host_obj[USBH0_INDEX].device_handle = handle;
RT_DEBUG_LOG(RT_DEBUG_USB, ("usb disconnnect\n"));
rt_usbh_root_hub_disconnect_handler(&(imxrt_usb_host_obj[USBH0_INDEX].uhcd), OTG_PORT);
(void)USB_HostCloseDeviceInterface(handle, NULL);
}
break;
default:
break;
}
return status;
}
rt_thread_t usbh0_thread;
static void _ehci0_usbh_thread(void* param)
{
while (1)
{
USB_HostEhciTaskFunction(imxrt_usb_host_obj[USBH0_INDEX].host_handle);
}
}
static rt_err_t _ehci0_usbh_init(rt_device_t device)
{
USB_HostClockInit(kUSB_ControllerEhci0);
if (kStatus_USB_Success == USB_HostInit(kUSB_ControllerEhci0, &imxrt_usb_host_obj[USBH0_INDEX].host_handle, usb0_host_callback))
{
usbh0_thread = rt_thread_create("ehci0", _ehci0_usbh_thread, RT_NULL, 500, 4, 9999999);
rt_thread_startup(usbh0_thread);
USB_HostIsrEnable(kUSB_ControllerEhci0);
}
else
{
rt_kprintf("USB_HostInit ehci0 error\r\n");
return -RT_ERROR;
}
return RT_EOK;
}
#endif
#ifdef BSP_USB1_HOST
void USB_OTG2_IRQHandler(void)
{
/* enter interrupt */
rt_interrupt_enter();
USB_HostEhciIsrFunction(imxrt_usb_host_obj[USBH1_INDEX].host_handle);
/* leave interrupt */
rt_interrupt_leave();
}
static rt_err_t _ehci1_reset_port(rt_uint8_t port)
{
// No reset port function available
return RT_EOK;
}
static uint8_t _ehci1_pipe_buf[64];
static uint8_t _ehci1_pipe_idx;
static int _ehci1_pipe_xfer(upipe_t pipe, rt_uint8_t token, void *buffer, int nbytes, int timeouts)
{
int timeout = timeouts;
if (!imxrt_usb_host_obj[USBH1_INDEX].connect_status)
{
return -1;
}
usb_host_transfer_t *transfer;
if (imxrt_usb_host_obj[USBH1_INDEX].pipes[pipe->pipe_index].pipe_handle == NULL)
{
RT_DEBUG_LOG(RT_DEBUG_USB, ("error operation on null pipe\n"));
return -1;
}
if (USB_HostMallocTransfer(imxrt_usb_host_obj[USBH1_INDEX].host_handle, &transfer) != kStatus_USB_Success)
{
RT_DEBUG_LOG(RT_DEBUG_USB, ("error to get transfer\n"));
return -1;
}
transfer->transferBuffer = buffer;
transfer->transferLength = nbytes;
transfer->transferSofar = 0;
transfer->callbackFn = _imxrt_usb_host_send_callback;
transfer->callbackParam = &(imxrt_usb_host_obj[USBH1_INDEX].pipes[pipe->pipe_index]);
transfer->direction = (pipe->ep.bEndpointAddress & USB_DIR_IN) ? USB_IN : USB_OUT;
if (pipe->ep.bmAttributes == USB_ENDPOINT_CONTROL)
{
if (token == USBH_PID_SETUP)
{
struct urequest *setup = (struct urequest *)buffer;
transfer->setupStatus = 0;
transfer->setupPacket->bmRequestType = setup->request_type;
transfer->setupPacket->bRequest = setup->bRequest;
transfer->setupPacket->wIndex = setup->wIndex;
transfer->setupPacket->wLength = setup->wLength;
transfer->setupPacket->wValue = setup->wValue;
transfer->transferBuffer = RT_NULL;
transfer->transferLength = 0;
transfer->next = RT_NULL;
if ((transfer->setupPacket->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) == USB_REQUEST_TYPE_DIR_IN)
{
transfer->direction = USB_IN;
transfer->transferBuffer = _ehci1_pipe_buf;
transfer->transferLength = setup->wLength;
_ehci1_pipe_idx = 0;
}
else
{
transfer->direction = USB_OUT;
}
}
else
{
rt_memcpy(buffer, _ehci1_pipe_buf + _ehci1_pipe_idx, nbytes);
imxrt_usb_host_obj[USBH1_INDEX].pipes[pipe->pipe_index].transfer_status = kStatus_USB_Success;
transfer->transferSofar = nbytes;
_ehci1_pipe_idx += nbytes;
if (_ehci1_pipe_idx >= 64)
{
_ehci1_pipe_idx = 0;
}
goto _ehci1_pipe_xfer_finish;
}
}
rt_completion_init(&(imxrt_usb_host_obj[USBH1_INDEX].pipes[pipe->pipe_index].urb_completion));
if (USB_HostEhciWritePipe(((usb_host_instance_t *)imxrt_usb_host_obj[USBH1_INDEX].host_handle)->controllerHandle, imxrt_usb_host_obj[USBH1_INDEX].pipes[pipe->pipe_index].pipe_handle, transfer) != kStatus_USB_Success)
{
RT_DEBUG_LOG(RT_DEBUG_USB, ("usb host failed to send\n"));
(void)USB_HostFreeTransfer(imxrt_usb_host_obj[USBH1_INDEX].host_handle, transfer);
return -1;
}
if (-RT_ETIMEOUT == rt_completion_wait(&(imxrt_usb_host_obj[USBH1_INDEX].pipes[pipe->pipe_index].urb_completion), RT_WAITING_FOREVER))
{
RT_DEBUG_LOG(RT_DEBUG_USB, ("usb transfer timeout\n"));
(void)USB_HostFreeTransfer(imxrt_usb_host_obj[USBH1_INDEX].host_handle, transfer);
return -1;
}
// rt_thread_mdelay(1);
_ehci1_pipe_xfer_finish:
switch (imxrt_usb_host_obj[USBH1_INDEX].pipes[pipe->pipe_index].transfer_status)
{
case kStatus_USB_Success:
{
RT_DEBUG_LOG(RT_DEBUG_USB, ("ok\n"));
pipe->status = UPIPE_STATUS_OK;
if (pipe->callback != RT_NULL)
{
pipe->callback(pipe);
}
size_t size = transfer->transferSofar;
(void)USB_HostFreeTransfer(imxrt_usb_host_obj[USBH1_INDEX].host_handle, transfer);
if (pipe->ep.bEndpointAddress & 0x80)
{
return size;
}
else if (pipe->ep.bEndpointAddress & 0x00)
{
return size;
}
return nbytes;
break;
}
case kStatus_USB_TransferStall:
{
RT_DEBUG_LOG(RT_DEBUG_USB, ("stall\n"));
pipe->status = UPIPE_STATUS_STALL;
if (pipe->callback != RT_NULL)
{
pipe->callback(pipe);
}
(void)USB_HostFreeTransfer(imxrt_usb_host_obj[USBH1_INDEX].host_handle, transfer);
return -1;
break;
}
case kStatus_USB_TransferFailed:
default:
{
RT_DEBUG_LOG(RT_DEBUG_USB, ("error\n"));
pipe->status = UPIPE_STATUS_ERROR;
if (pipe->callback != RT_NULL)
{
pipe->callback(pipe);
}
(void)USB_HostFreeTransfer(imxrt_usb_host_obj[USBH1_INDEX].host_handle, transfer);
return -1;
break;
}
}
}
static rt_uint16_t _ehci1_pipe_index = 0;
static rt_uint8_t _ehci1_get_free_pipe_index(void)
{
rt_uint8_t idx;
for (idx = 1; idx < 16; idx++)
{
if (!(_ehci1_pipe_index & (0x01 << idx)))
{
_ehci1_pipe_index |= (0x01 << idx);
return idx;
}
}
return 0xff;
}
static void _ehci1_free_pipe_index(rt_uint8_t index)
{
_ehci1_pipe_index &= ~(0x01 << index);
}
static rt_err_t _ehci1_open_pipe(upipe_t pipe)
{
pipe->pipe_index = _ehci1_get_free_pipe_index();
if (pipe->pipe_index == 0xFF)
{
return -RT_ERROR;
}
usb_host_pipe_init_t pipe_init =
{
.devInstance = imxrt_usb_host_obj[USBH1_INDEX].device_handle,
.pipeType = pipe->ep.bmAttributes,
.direction = (pipe->ep.bEndpointAddress & USB_DIR_IN) ? USB_IN : USB_OUT,
.endpointAddress = (pipe->ep.bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_MASK),
.interval = pipe->ep.bInterval,
.maxPacketSize = (uint16_t)(pipe->ep.wMaxPacketSize & USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_SIZE_MASK),
.numberPerUframe = (uint8_t)(pipe->ep.wMaxPacketSize & USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_MULT_TRANSACTIONS_MASK),
.nakCount = USB_HOST_CONFIG_MAX_NAK,
};
USB_HostOpenPipe(imxrt_usb_host_obj[USBH1_INDEX].host_handle, &imxrt_usb_host_obj[USBH1_INDEX].pipes[pipe->pipe_index].pipe_handle, &pipe_init);
return RT_EOK;
}
static rt_err_t _ehci1_close_pipe(upipe_t pipe)
{
(void)USB_HostClosePipe(imxrt_usb_host_obj[USBH1_INDEX].host_handle, imxrt_usb_host_obj[USBH1_INDEX].pipes[pipe->pipe_index].pipe_handle);
_ehci1_free_pipe_index(pipe->pipe_index);
return RT_EOK;
}
static struct uhcd_ops _ehci1_uhcd_ops =
{
_ehci1_reset_port,
_ehci1_pipe_xfer,
_ehci1_open_pipe,
_ehci1_close_pipe,
};
static usb_status_t usb1_host_callback(usb_device_handle handle, usb_host_configuration_handle config_handle, rt_uint32_t event_code)
{
usb_status_t status = kStatus_USB_Success;
switch (event_code)
{
case kUSB_HostEventAttach:
if (!imxrt_usb_host_obj[USBH1_INDEX].connect_status)
{
imxrt_usb_host_obj[USBH1_INDEX].connect_status = RT_TRUE;
imxrt_usb_host_obj[USBH1_INDEX].device_handle = handle;
RT_DEBUG_LOG(RT_DEBUG_USB, ("usb connected\n"));
rt_usbh_root_hub_connect_handler(&(imxrt_usb_host_obj[USBH1_INDEX].uhcd), OTG_PORT, RT_TRUE);
}
break;
case kUSB_HostEventNotSupported:
RT_DEBUG_LOG(RT_DEBUG_USB, ("usb device not supported\n"));
break;
case kUSB_HostEventEnumerationDone:
RT_DEBUG_LOG(RT_DEBUG_USB, ("enumeration done\n"));
break;
case kUSB_HostEventDetach:
if (imxrt_usb_host_obj[USBH1_INDEX].connect_status)
{
imxrt_usb_host_obj[USBH1_INDEX].connect_status = RT_FALSE;
imxrt_usb_host_obj[USBH1_INDEX].device_handle = handle;
RT_DEBUG_LOG(RT_DEBUG_USB, ("usb disconnnect\n"));
rt_usbh_root_hub_disconnect_handler(&(imxrt_usb_host_obj[USBH1_INDEX].uhcd), OTG_PORT);
(void)USB_HostCloseDeviceInterface(handle, NULL);
}
break;
default:
break;
}
return status;
}
rt_thread_t usbh1_thread;
static void _ehci1_usbh_thread(void* param)
{
while (1)
{
USB_HostEhciTaskFunction(imxrt_usb_host_obj[USBH1_INDEX].host_handle);
}
}
static rt_err_t _ehci1_usbh_init(rt_device_t device)
{
USB_HostClockInit(kUSB_ControllerEhci1);
if (kStatus_USB_Success == USB_HostInit(kUSB_ControllerEhci1, &imxrt_usb_host_obj[USBH1_INDEX].host_handle, usb1_host_callback))
{
usbh1_thread = rt_thread_create("ehci1", _ehci1_usbh_thread, RT_NULL, 500, 4, 9999999);
rt_thread_startup(usbh1_thread);
USB_HostIsrEnable(kUSB_ControllerEhci1);
}
else
{
rt_kprintf("USB_HostInit ehci1 error\r\n");
return -RT_ERROR;
}
return RT_EOK;
}
#endif
int imxrt_usbh_register(void)
{
rt_kprintf("register usbh1\r\n");
rt_err_t res = -RT_ERROR;
struct imxrt_usb_host *usb_host_obj;
#ifdef BSP_USB0_HOST
usb_host_obj = &(imxrt_usb_host_obj[USBH0_INDEX]);
rt_memset((void *)(&(usb_host_obj->uhcd)), 0, sizeof(struct uhcd));
usb_host_obj->uhcd.parent.type = RT_Device_Class_USBHost;
usb_host_obj->uhcd.parent.init = _ehci0_usbh_init;
usb_host_obj->uhcd.parent.user_data = usb_host_obj;
usb_host_obj->uhcd.ops = &_ehci0_uhcd_ops;
usb_host_obj->uhcd.num_ports = OTG_PORT;
res = rt_device_register(&(usb_host_obj->uhcd.parent), usb_host_obj->name, RT_DEVICE_FLAG_DEACTIVATE);
if (res != RT_EOK)
{
rt_kprintf("register usb0 host failed res = %d\r\n", res);
return -RT_ERROR;
}
/*modify by zjr*/
rt_usb_host_init();
#endif
#ifdef BSP_USB1_HOST
usb_host_obj = &(imxrt_usb_host_obj[USBH1_INDEX]);
rt_memset((void *)(&(usb_host_obj->uhcd)), 0, sizeof(struct uhcd));
usb_host_obj->uhcd.parent.type = RT_Device_Class_USBHost;
usb_host_obj->uhcd.parent.init = _ehci1_usbh_init;
usb_host_obj->uhcd.parent.user_data = usb_host_obj;
usb_host_obj->uhcd.ops = &_ehci1_uhcd_ops;
usb_host_obj->uhcd.num_ports = OTG_PORT;
res = rt_device_register(&(usb_host_obj->uhcd.parent), usb_host_obj->name, RT_DEVICE_FLAG_DEACTIVATE);
if (res != RT_EOK)
{
rt_kprintf("register usb0 host failed res = %d\r\n", res);
return -RT_ERROR;
}
/*modify by zjr*/
rt_usb_host_init();
// rt_usb_host_init(usb_host_obj->name);
#endif
return RT_EOK;
}
INIT_DEVICE_EXPORT(imxrt_usbh_register);
#endif

View File

@ -0,0 +1,22 @@
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2017-12-12 ZYH the first version
* 2019-12-19 tyustli port to stm32 series
* 2021-01-19 Leslie Lee port to imxrt series
*/
#ifndef __DRV_USBH_H__
#define __DRV_USBH_H__
#include <rtthread.h>
#define OTG_PORT 1
int imxrt_usbh_register(void);
#endif
/************* end of file ************/

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@ -1,50 +0,0 @@
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2019-04-29 tyustli first version
*
*/
#include <rtdevice.h>
#include <rtthread.h>
#include "drv_gpio.h"
#include <board.h>
/* defined the LED pin: GPIO1_IO9 */
#define LED0_PIN GET_PIN(1,9)
int main(void)
{
/* set LED0 pin mode to output */
rt_pin_mode(LED0_PIN, PIN_MODE_OUTPUT);
rt_kprintf("XIUOS xidatong build %s %s\n",__DATE__,__TIME__);
while (1)
{
rt_pin_write(LED0_PIN, PIN_HIGH);
rt_thread_mdelay(500);
rt_pin_write(LED0_PIN, PIN_LOW);
rt_thread_mdelay(500);
}
}
#ifdef BSP_USING_SDRAM
static void sdram_test2(void)
{
char *p =NULL;
p = rt_malloc(1024*1024*8);
if(p == NULL)
{
rt_kprintf("apply for 8MB memory fail ~!!!");
}
else
{
rt_kprintf("appyle for 8MB memory success!!!");
}
rt_free(p);
}
MSH_CMD_EXPORT(sdram_test2, sdram test2);
#endif

View File

@ -2,4 +2,6 @@ menu "More Drivers"
source "$RT_Thread_DIR/app_match_rt-thread/rw007/Kconfig"
source "$RT_Thread_DIR/app_match_rt-thread/ov2640/Kconfig"
source "$RT_Thread_DIR/app_match_rt-thread/hs300x/Kconfig"
source "$RT_Thread_DIR/app_match_rt-thread/sx1278/Kconfig"
endmenu

View File

@ -0,0 +1,23 @@
menuconfig DRV_USING_HS300X
bool "hs300x driver"
default n
help
note:
hs300x can read Temperature and Humidity
if DRV_USING_HS300X
config SENSOR_DEVICE_HS300X
string "HS300x sensor name"
default "HS300x"
config HS300X_DEV_ADDRESS
hex "hs300x device i2c address"
default 0x22
config HS300X_TEMP_RANGE_MAX
int "max temperature"
default 80
config HS300X_TEMP_RANGE_MIN
int "min temperature"
default -10
endif

View File

@ -0,0 +1,7 @@
Import('RTT_ROOT')
from building import *
cwd = GetCurrentDir()
objs = SConscript(os.path.join(cwd, 'hs300x_source', 'SConscript'))
Return('objs')

View File

@ -0,0 +1,14 @@
import os
from building import *
Import('RTT_ROOT')
Import('rtconfig')
cwd = GetCurrentDir()
DEPENDS = ["DRV_USING_HS300X"]
SOURCES = []
if GetDepend(['DRV_USING_HS300X']):
SOURCES += ['drv_hs300x.c']
path = [cwd]
objs = DefineGroup('hs300x', src = SOURCES, depend = DEPENDS,CPPPATH = path)
Return("objs")

View File

@ -0,0 +1,223 @@
#include "board.h"
#include <rtthread.h>
#include <rtdevice.h>
#include <drv_hs300x.h>
#include <dfs_file.h>
#ifdef RT_USING_POSIX
#include <dfs_posix.h>
#include <dfs_poll.h>
#endif
#ifdef DRV_USING_HS300X
static rt_bool_t init_flag = RT_FALSE;
struct temp_humi_device
{
struct rt_device parent;
};
struct temp_humi_device hs300x_device;
static struct rt_i2c_bus_device *i2c_bus = RT_NULL;
static rt_err_t rt_hs300x_open(rt_device_t dev,rt_uint16_t oflag)
{
RT_ASSERT(dev !=RT_NULL);
return RT_EOK;
}
static rt_err_t rt_hs300x_close(rt_device_t dev)
{
RT_ASSERT(dev !=RT_NULL);
return RT_EOK;
}
static rt_err_t hs300x_i2c_write(struct rt_i2c_bus_device *bus,rt_uint8_t len,rt_uint8_t *buf)
{
struct rt_i2c_msg msgs;
msgs.addr = HS300X_DEV_ADDRESS;
msgs.flags = RT_I2C_WR;
msgs.buf = buf;
msgs.len = len;
if(rt_i2c_transfer(bus,&msgs,1)==1)
{
return RT_EOK;
}
else
{
return -RT_ERROR;
}
}
static rt_err_t hs300x_i2c_read(struct rt_i2c_bus_device *bus,rt_uint8_t len,rt_uint8_t *buf)
{
struct rt_i2c_msg msg[2];
msg[0].addr = HS300X_DEV_ADDRESS;
msg[0].flags = RT_I2C_WR;
msg[0].buf = RT_NULL;
msg[0].len = 0;
msg[1].addr = HS300X_DEV_ADDRESS;
msg[1].flags = RT_I2C_RD;
msg[1].buf = buf;
msg[1].len = len;
if(rt_i2c_transfer(bus,&msg,2)==2)
{
return RT_EOK;
}
else{
return -RT_ERROR;
}
}
static rt_size_t rt_hs300x_read(rt_device_t dev,rt_off_t pos,void *buffer,rt_size_t size)
{
RT_ASSERT(dev!=RT_NULL);
return RT_EOK;
}
static rt_size_t rt_hs300x_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
{
RT_ASSERT(dev !=RT_NULL);
return RT_EOK;
}
static rt_err_t rt_hs300x_init (rt_device_t dev)
{
RT_ASSERT(dev!=RT_NULL);
return RT_EOK;
}
static void read_temp_humi(float *cur_temp,float *cur_humi)
{
rt_uint8_t temperature[4];
hs300x_i2c_read(i2c_bus,4,temperature);
*cur_temp = ((temperature[2]<<8|temperature[3])>>2)*165.0 /((1<<14)-1)-40;
*cur_humi = ((temperature[0]<<8|temperature[1])& 0x3fff)*100.0 /((1<<14)-1);
}
static void hs300x_i2c_sample(void)
{
float hs300x_temp = 0.0;
float hs300x_humi = 0.0;
i2c_bus = (struct rt_i2c_bus_device *)rt_device_find(I2C_NAME);
if(i2c_bus ==RT_NULL)
{
rt_kprintf("device find err\n");
return -RT_ERROR;
}
for(int i=0;i<100;i++)
{
read_temp_humi(&hs300x_temp,&hs300x_humi);
rt_kprintf("humidity: %d.%d %%\n",(int)hs300x_humi,(int)(hs300x_humi*10)%10);
if(hs300x_temp>0)
{
rt_kprintf("temperature:%d.%d C\n",(int)hs300x_temp,(int)(hs300x_temp*10)%10);
}
else
{
rt_kprintf("temperature:%d.%d C\n",(int)hs300x_temp,(int)(-hs300x_temp*10)%10);
}
rt_thread_mdelay(5000);
}
}
static int hs300x_fops_open(struct dfs_fd *fd)
{
rt_err_t ret;
rt_device_t dev;
dev = (rt_device_t)fd->data;
RT_ASSERT(dev !=RT_NULL);
ret = rt_device_open(dev,RT_DEVICE_FLAG_RDONLY);
if(ret == RT_EOK)
{
return RT_EOK;
}
return RT_ERROR;
}
static int hs300x_fops_close(struct dfs_fd *fd)
{
rt_device_t dev;
dev = (rt_device_t)fd->data;
rt_device_set_rx_indicate(dev,RT_NULL);
rt_device_close(dev);
return RT_EOK;
}
static int hs300x_fops_read(struct dfs_fd *fd,void *buf,size_t count)
{
rt_device_t dev;
dev = (rt_device_t)fd->data;
RT_ASSERT(dev!=RT_NULL);
rt_err_t ret;
if(count !=4 )
{
rt_kprintf("can only read 4bytes!\n");
}
i2c_bus = (struct rt_i2c_bus_device *)rt_device_find(I2C_NAME);
ret = hs300x_i2c_read(i2c_bus,count,buf);
if (ret ==RT_EOK)
{
return RT_EOK;
}
return RT_ERROR;
}
static int hs300x_fops_write(struct dfs_fd *fd,const void *buf,size_t count)
{
rt_device_t dev;
dev = (rt_device_t)fd->data;
RT_ASSERT(dev !=RT_NULL);
rt_err_t ret;
i2c_bus = (struct rt_i2c_bus_device *)rt_device_find(I2C_NAME);
ret = hs300x_i2c_write(i2c_bus,0,RT_NULL);
if(ret ==RT_EOK)
{
return RT_EOK;
}
return RT_ERROR;
}
const static struct dfs_file_ops hs300x_fops =
{
hs300x_fops_open,
hs300x_fops_close,
RT_NULL,
hs300x_fops_read,
hs300x_fops_write,
RT_NULL,
RT_NULL,
RT_NULL,
RT_NULL,
};
int sensor_hs300x_init()
{
rt_err_t ret = RT_EOK;
hs300x_device.parent.open = rt_hs300x_open;
hs300x_device.parent.close = rt_hs300x_close;
hs300x_device.parent.read = rt_hs300x_read;
hs300x_device.parent.write = rt_hs300x_write;
hs300x_device.parent.init = rt_hs300x_init;
ret = rt_device_register(&hs300x_device.parent,"hs300x",RT_DEVICE_FLAG_RDONLY);
#ifdef RT_USING_POSIX
hs300x_device.parent.fops = &hs300x_fops;
#endif
if(ret !=RT_EOK)
{
rt_kprintf("hs300x register failed!\n\r");
return -RT_ERROR;
}
rt_kprintf("hs300x register success!\n\r");
return RT_EOK;
}
INIT_APP_EXPORT(sensor_hs300x_init);
MSH_CMD_EXPORT(hs300x_i2c_sample, a read temp sample);
#endif

View File

@ -0,0 +1,29 @@
#ifndef __HS300X_H__
#define __HS300X_H__
#include <rtthread.h>
#include <rtdevice.h>
#include <rthw.h>
#ifdef __cplusplus
extern "C"{
#endif
#ifndef HS300X_I2C_FREQUENCY
#define HS300X_I2C_FREQUENCY 40000
#endif
#define I2C_NAME "i2c1"
#define buflen 4
#define HS300X_TEMP_RANGE_MAX (80)
#define HS300X_TEMP_RANGE_MIN (-10)
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,38 @@
menuconfig DRV_USING_SX1278
bool "sx1278 driver"
default n
help
note:
lora connection
if DRV_USING_SX1278
config SX1278_SPI_DEVICE_NAME
string "SX1278 Lora Device Spi Name"
default "spi20"
config SX1278_DEVICE_NAME
string "SX1278 Lora Device Name"
default "spi2_lora"
config SX1278_DEVICE_RST_PIN
int
default 1
config SX1278_DEVICE_DIO0_PIN
int
default 1
config SX1278_DEVICE_DIO1_PIN
int
default 1
config SX1278_DEVICE_DIO2_PIN
int
default 1
config SX1278_DEVICE_DIO3_PIN
int
default 1
config SX1278_DEVICE_DIO4_PIN
int
default 1
config SX1278_DEVICE_DIO5_PIN
int
default 1
endif

View File

@ -0,0 +1,7 @@
Import('RTT_ROOT')
from building import *
cwd = GetCurrentDir()
objs = SConscript(os.path.join(cwd, 'sx1278_source', 'SConscript'))
Return('objs')

View File

@ -0,0 +1,19 @@
import os
from building import *
Import('RTT_ROOT')
Import('rtconfig')
cwd = GetCurrentDir()
DEPENDS = ["DRV_USING_SX1278"]
SOURCES = []
if GetDepend(['DRV_USING_SX1278']):
SOURCES += ['drv_sx1278.c']
SOURCES += Glob('src/radio/sx1276*.c')
SOURCES += Glob('src/radio/radio.c')
SOURCES += Glob('port/*.c')
path = [cwd + '/inc']
path += ['src/radio']
objs = DefineGroup('sx1278', src = SOURCES, depend = DEPENDS,CPPPATH = path)
Return("objs")

View File

@ -0,0 +1,510 @@
#include "board.h"
#include <rtthread.h>
#include <rtdevice.h>
#include "drv_sx1278.h"
#include <dfs_file.h>
#include <radio.h>
#include "spi_lora_sx12xx.h"
#include "sx1276-Hal.h"
#include "sx1276-Lora.h"
#include "sx1276-LoraMisc.h"
#include <sx1276.h>
#include <stdio.h>
#ifdef RT_USING_POSIX
#include <dfs_posix.h>
#include <dfs_poll.h>
#endif
#ifdef DRV_USING_SX1278
#define SX12XX_DO0_PIN GET_PIN(C, 1)
#define SX12XX_DO1_PIN GET_PIN(C, 0)
#define SX12XX_RST_PIN GET_PIN(F,11)
static rt_bool_t init_flag = RT_FALSE;
static rt_bool_t enable_master = RT_FALSE;
tRadioDriver *Radio = RT_NULL;
struct lora_device
{
struct rt_device parent;
};
struct lora_device sx1278_device;
static struct rt_spi_device *spi_bus;
void SX1276InitIo(void)
{
rt_pin_mode(SX12XX_DO0_PIN, PIN_MODE_INPUT);
rt_pin_mode(SX12XX_DO1_PIN, PIN_MODE_INPUT);
}
void SX1276SetReset(rt_uint8_t state)
{
if (state == RADIO_RESET_ON)
{
rt_pin_mode(SX12XX_RST_PIN, PIN_MODE_OUTPUT);
rt_pin_write(SX12XX_RST_PIN, PIN_LOW);
}
else
{
rt_pin_mode(SX12XX_RST_PIN, PIN_MODE_INPUT);
}
}
inline rt_uint8_t SX1276ReadDio0(void)
{
return rt_pin_read(SX12XX_DO0_PIN);
}
inline rt_uint8_t SX1276ReadDio1(void)
{
return rt_pin_read(SX12XX_DO1_PIN);
}
inline rt_uint8_t SX1276ReadDio2(void)
{
return rt_pin_read(SX1278_DEVICE_DIO2_PIN);
}
inline rt_uint8_t SX1276ReadDio3(void)
{
return rt_pin_read(SX1278_DEVICE_DIO3_PIN);
}
inline rt_uint8_t SX1276ReadDio4(void)
{
return rt_pin_read(SX1278_DEVICE_DIO4_PIN);
}
inline rt_uint8_t SX1276ReadDio5(void)
{
return rt_pin_read(SX1278_DEVICE_DIO5_PIN);
}
inline void SX1276WriteRxTx(rt_uint8_t txEnable)
{
if (txEnable != 0)
{
}
else
{
}
}
void SX1276Write(rt_uint8_t addr, rt_uint8_t data)
{
SX1276WriteBuffer(addr, &data, 1);
}
void SX1276Read(rt_uint8_t addr, rt_uint8_t *data)
{
SX1276ReadBuffer(addr, data, 1);
}
void SX1276WriteBuffer(rt_uint8_t addr, rt_uint8_t *buffer, rt_uint8_t size)
{
spi_bus = (struct rt_spi_device *)rt_device_find(SPI_NAME);
struct rt_spi_message msg1, msg2;
rt_uint8_t data = (addr | 0x80);
msg1.send_buf = &data;
msg1.recv_buf = RT_NULL;
msg1.length = 1;
msg1.cs_take = 1;
msg1.cs_release = 0;
msg1.next = &msg2;
msg2.send_buf = buffer;
msg2.recv_buf = RT_NULL;
msg2.length = size;
msg2.cs_take = 0;
msg2.cs_release = 1;
msg2.next = RT_NULL;
rt_spi_transfer_message(spi_bus, &msg1);
}
void SX1276ReadBuffer(rt_uint8_t addr, rt_uint8_t *buffer, rt_uint8_t size)
{
spi_bus = (struct rt_spi_device *)rt_device_find(SPI_NAME);
struct rt_spi_message msg1, msg2;
rt_uint8_t data = (addr & 0x7F);
msg1.send_buf = &data;
msg1.recv_buf = RT_NULL;
msg1.length = 1;
msg1.cs_take = 1;
msg1.cs_release = 0;
msg1.next = &msg2;
msg2.send_buf = RT_NULL;
msg2.recv_buf = buffer;
msg2.length = size;
msg2.cs_take = 0;
msg2.cs_release = 1;
msg2.next = RT_NULL;
rt_spi_transfer_message(spi_bus, &msg1);
}
void SX1276WriteFifo(rt_uint8_t *buffer, rt_uint8_t size)
{
SX1276WriteBuffer(0, buffer, size);
}
void SX1276ReadFifo(rt_uint8_t *buffer, rt_uint8_t size)
{
SX1276ReadBuffer(0, buffer, size);
}
struct rt_spi_device *sx12xx_init(const char *dev_name, rt_uint8_t param)
{
RT_ASSERT(dev_name);
spi_bus = (struct rt_spi_device *)rt_device_find(dev_name);
if (!spi_bus)
{
rt_kprintf("spi sample run failed! cant't find %s device!\n", dev_name);
return RT_NULL;
}
/* config spi */
else
{
struct rt_spi_configuration cfg;
cfg.data_width = 8;
cfg.mode = RT_SPI_MODE_0 | RT_SPI_MSB; /* SPI Compatible: Mode 0. */
cfg.max_hz = 10 * 1000000; /* max 10M */
rt_spi_configure(spi_bus, &cfg);
}
Radio = RadioDriverInit();
Radio->Init();
return spi_bus;
}
/*
* This function supports to read data from the lora
*/
static rt_size_t lora_sx1278_read(rt_device_t dev,rt_off_t pos,void *buffer,rt_size_t size)
{
RT_ASSERT(dev!=RT_NULL);
int read_times = 100;
SX1276StartRx();
rt_kprintf("read lora ready!\n");
while (read_times)
{
if(SX1276Process()!=RF_RX_DONE)
{
read_times --;
rt_thread_mdelay(500);
}
else
{
break;
}
}
if(read_times>0)
{
SX1276GetRxPacket(buffer,(uint16_t *)&size);
}
else
{
size = 0;
}
return size;
}
/*
* This function supports to write data to the lora
*/
static rt_size_t lora_sx1278_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
{
RT_ASSERT(dev !=RT_NULL);
if(size > 256)
{
rt_kprintf("error:message is too long!\n");
return RT_ERROR;
}
else
{
SX1276SetTxPacket(buffer,size);
while(SX1276Process() != RF_TX_DONE);
rt_kprintf("write success!\n");
}
return RT_EOK;
}
static int sx1278_test(int argc,char **argv)
{
char name[RT_NAME_MAX];
if(argc ==2)
{
rt_strncpy(name,argv[1],RT_NAME_MAX);
}
else
{
rt_strncpy(name,"spi20",RT_NAME_MAX);
}
if(spi_bus == RT_NULL)
{
spi_bus = sx12xx_init("spi20",RT_NULL);
if(spi_bus == RT_NULL)
{
rt_kprintf("sx12xx init failed\n");
return -1;
}
}
rt_kprintf("sx12xx init succeed\n");
if (0x91 != SX1276_Spi_Check())
{
rt_kprintf("sx12xx spi check failed!\n!");
}
else
{
rt_kprintf("sx12xx spi check ok!\n");
}
return 0;
}
MSH_CMD_EXPORT(sx1278_test,SAMPLE);
rt_uint8_t SX1276_Spi_Check()
{
uint8_t test = 0;
tLoRaSettings settings;
spi_bus = (struct rt_spi_device *)rt_device_find(SPI_NAME);
SX1276Read(REG_LR_VERSION,&test);
rt_kprintf("version code of the chip is %x\n",test);
settings.RFFrequency = SX1276LoRaGetRFFrequency();
rt_kprintf("SX1278 Lora parameters are :\nRFFrequency is %d\n",settings.RFFrequency);
settings.Power = SX1276LoRaGetRFPower();
rt_kprintf("RFPower is %d\n",settings.Power);
settings.SignalBw = SX1276LoRaGetSignalBandwidth();
rt_kprintf("SignalBw is %d\n",settings.SignalBw);
settings.SpreadingFactor = SX1276LoRaGetSpreadingFactor();
rt_kprintf("SpreadingFactor is %d\n",settings.SpreadingFactor);
SX1276Write(REG_LR_HOPPERIOD, 0x91); //选一个用不到的寄存器来做验证
SX1276Read(REG_LR_HOPPERIOD, &test);
if (test != 0x91)
{
return -1;
}
return test;
}
static rt_uint16_t ComputerCrc (rt_uint8_t *data,rt_uint16_t length)
{
int i;
rt_uint16_t crc ;
while (length --)
{
crc ^= *data++;
for(i =0;i<8;i++)
{
if(crc & 0x01)
crc = crc >>1^ 0xA001;
else
crc = crc >>1;
}
}
return crc;
}
static rt_err_t CrcCheck(rt_uint8_t *data,rt_uint16_t length)
{
rt_uint16_t crc_data;
rt_uint16_t input_data ;
input_data = (((rt_uint16_t)data[length - 1] << 8) & 0xFF00) | ((rt_uint16_t)data[length - 2] & 0x00FF);
crc_data = ComputerCrc(data,length-2);
if(crc_data == input_data)
{
return RT_EOK;
}
else
{
return -RT_ERROR;
}
}
static int sx1278_fops_open(struct dfs_fd *fd)
{
rt_err_t ret;
rt_device_t dev;
dev = (rt_device_t)fd->data;
RT_ASSERT(dev !=RT_NULL);
ret = rt_device_open(dev,RT_DEVICE_FLAG_RDONLY);
if(ret ==RT_EOK)
{
return RT_EOK;
}
spi_bus = (struct rt_spi_device *)rt_device_find(SPI_NAME);
if(!spi_bus)
{
rt_kprintf("can not find spi bus\n");
return -RT_ERROR;
}
struct rt_spi_configuration cfg;
cfg.data_width = 8 ;
cfg.max_hz = 10* 1000000;
cfg.mode = RT_SPI_MODE_0 |RT_SPI_MSB;
rt_spi_configure(spi_bus,&cfg);
Radio = RadioDriverInit();
Radio->Init();
}
static int sx1278_fops_close(struct dfs_fd *fd)
{
rt_device_t dev;
dev = (rt_device_t)fd->data;
rt_device_set_rx_indicate(dev,RT_NULL);
rt_device_close(dev);
return RT_EOK;
}
static int sx1278_fops_read(struct dfs_fd *fd,void *buf,rt_size_t count)
{
rt_device_t dev;
dev = (rt_device_t)fd->data;
RT_ASSERT(dev!=RT_NULL);
rt_err_t ret;
ret = lora_sx1278_read(dev,0,buf,count);
if(ret < 0 )
{
return -RT_ERROR;
}
}
static int sx1278_fops_write(struct dfs_fd *fd,void *buf,rt_size_t count)
{
rt_device_t dev;
dev = (rt_device_t)fd->data;
RT_ASSERT(dev!=RT_NULL);
rt_err_t ret ;
ret = lora_sx1278_write(dev,0,buf,count);
if(ret<0)
{
return -RT_ERROR;
}
}
static rt_err_t lora_sx1278_open(rt_device_t dev,rt_uint16_t oflag)
{
RT_ASSERT(dev !=RT_NULL);
return RT_EOK;
}
static rt_err_t lora_sx1278_close(rt_device_t dev)
{
RT_ASSERT(dev !=RT_NULL);
return RT_EOK;
}
static rt_err_t lora_sx1278_init(rt_device_t dev)
{
RT_ASSERT(dev!=RT_NULL);
spi_bus = (struct rt_spi_device *)rt_device_find(SPI_NAME);
if(!spi_bus)
{
rt_kprintf("can not find spi bus\n");
return -RT_ERROR;
}
struct rt_spi_configuration cfg;
cfg.data_width = 8 ;
cfg.max_hz = 10* 1000000;
cfg.mode = RT_SPI_MODE_0 |RT_SPI_MSB;
rt_spi_configure(spi_bus,&cfg);
Radio = RadioDriverInit();
Radio->Init();
return RT_EOK;
}
/* ------------------test--------------------*/
static rt_err_t LoraSend(int argc,char**argv)
{
rt_device_t dev;
struct BlockWriteParam write_param;
dev = rt_device_find("sx1278");
int result;
int len;
char msg[LORA_BUFFER_SIZE] = {0};
if(argc<2)
{
rt_kprintf("Usage: %s <string>\n",argv[0]);
return -RT_ERROR;
}
rt_strncpy(msg,argv[1],LORA_BUFFER_SIZE);
len = strlen(msg);
write_param.buffer = msg;
write_param.size = rt_strlen(msg);
result = lora_sx1278_write(dev,0,write_param.buffer,write_param.size);
rt_memset(&write_param,0,sizeof(struct BlockWriteParam));
if(result < 0)
{
rt_kprintf("send error!\n");
return -RT_ERROR;
}
return RT_EOK;
}
MSH_CMD_EXPORT(LoraSend,lora send sample);
static rt_err_t LoraReceive(void)
{
char sx1278_recv_msg[256];
int ret;
rt_device_t dev;
dev = rt_device_find("sx1278");
while(1)
{
ret = lora_sx1278_read(dev,0,sx1278_recv_msg,256);
if(ret<0)
{
rt_kprintf("receive error!\n");
return -RT_ERROR;
}
rt_memset(sx1278_recv_msg,0,256);
return RT_EOK;
}
}
MSH_CMD_EXPORT(LoraReceive,lora receive sample);
const static struct dfs_file_ops sx1278_fops =
{
sx1278_fops_open,
sx1278_fops_close,
RT_NULL,
sx1278_fops_read,
sx1278_fops_write,
RT_NULL,
RT_NULL,
RT_NULL,
RT_NULL,
};
int sx1278_init()
{
rt_err_t ret = RT_EOK;
sx1278_device.parent.open = lora_sx1278_open;
sx1278_device.parent.close = lora_sx1278_close;
sx1278_device.parent.read = lora_sx1278_read;
sx1278_device.parent.write = lora_sx1278_write;
sx1278_device.parent.init = lora_sx1278_init;
ret = rt_device_register(&sx1278_device.parent,"sx1278",RT_DEVICE_FLAG_RDONLY);
#ifdef RT_USING_POSIX
sx1278_device.parent.fops = &sx1278_fops;
#endif
if(ret !=RT_EOK)
{
rt_kprintf("sx1278 register failed!\n\r");
return -RT_ERROR;
}
rt_kprintf("sx1278 register success!\n\r");
return RT_EOK;
}
INIT_APP_EXPORT(sx1278_init);
#endif

View File

@ -0,0 +1,25 @@
#ifndef __DRV_SX1278_H__
#define __DRV_SX1278_H__
#include <rtthread.h>
#include <rtdevice.h>
#include <rthw.h>
#define SPI_NAME "spi20"
#define LORA_BUFFER_SIZE 256
struct BlockReadParam
{
rt_off_t pos;
void * buffer;
rt_size_t size;
};
struct BlockWriteParam
{
rt_off_t pos;
const void *buffer;
rt_size_t size;
};
#endif

View File

@ -0,0 +1,96 @@
/*
* 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 <rtthread.h>
#include <stdbool.h>
#include "type.h"
/*!
* \brief Gets the SX1272 DIO0 hardware pin status
*
* \retval status Current hardware pin status [1, 0]
*/
rt_uint8_t SX1276ReadDio0(void);
/*!
* \brief Gets the SX1272 DIO1 hardware pin status
*
* \retval status Current hardware pin status [1, 0]
*/
rt_uint8_t SX1276ReadDio1(void);
/*!
* \brief Gets the SX1272 DIO2 hardware pin status
*
* \retval status Current hardware pin status [1, 0]
*/
rt_uint8_t SX1276ReadDio2(void);
/*!
* \brief Gets the SX1272 DIO3 hardware pin status
*
* \retval status Current hardware pin status [1, 0]
*/
rt_uint8_t SX1276ReadDio3(void);
/*!
* \brief Gets the SX1272 DIO4 hardware pin status
*
* \retval status Current hardware pin status [1, 0]
*/
rt_uint8_t SX1276ReadDio4(void);
/*!
* \brief Gets the SX1272 DIO5 hardware pin status
*
* \retval status Current hardware pin status [1, 0]
*/
rt_uint8_t SX1276ReadDio5(void);
void SX1276Write(rt_uint8_t addr, rt_uint8_t data);
void SX1276Read(rt_uint8_t addr, rt_uint8_t *data);
void SX1276WriteBuffer(rt_uint8_t addr, rt_uint8_t *buffer, rt_uint8_t size);
void SX1276ReadBuffer(rt_uint8_t addr, rt_uint8_t *buffer, rt_uint8_t size);
void SX1276WriteFifo(rt_uint8_t *buffer, rt_uint8_t size);
void SX1276ReadFifo(rt_uint8_t *buffer, rt_uint8_t size);
void SX1276SetReset(rt_uint8_t state);
rt_uint8_t SX1276_Spi_Check(void);
void SX1276WriteRxTx(rt_uint8_t txEnable);
#endif

View File

@ -0,0 +1,33 @@
/*
File Name : type.h
Author : Yichip
Version : V1.0
Date : 2018/05/25
Description : Data type definition.
*/
#ifndef __TYPE_H__
#define __TYPE_H__
#if defined (__CC_ARM) || defined ( __ICCARM__ )
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef unsigned long long uint64_t;
typedef unsigned char byte;
typedef unsigned short word;
typedef signed char int8_t;
typedef signed short int16_t;
typedef signed int int32_t;
typedef signed long long int64_t;
#else
#include "stdio.h"
typedef unsigned char byte;
typedef unsigned short word;
#endif
#endif /*__TYPE_H__*/

View File

@ -0,0 +1,17 @@
#include <rtthread.h>
#include "drv_spi.h"
#include <board.h>
#include <spi_msd.h>
#include <dfs_elm.h>
#include <dfs_fs.h>
#include <drv_spi.h>
#include <dfs_posix.h>
#include <rtdbg.h>
static int sx12xx_spi_device_init(void)
{
__HAL_RCC_GPIOC_CLK_ENABLE();
rt_hw_spi_device_attach("spi2","spi20",GPIOC,GPIO_PIN_6);
}
INIT_APP_EXPORT(sx12xx_spi_device_init);

View File

@ -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

View File

@ -0,0 +1,88 @@
/*
* 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
*/
#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__

View File

@ -0,0 +1,64 @@
/*
* 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
*/
#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;
#else
#error "Missing define: USE_XXXXXX_RADIO (ie. USE_SX1272_RADIO)"
#endif
return &RadioDriver;
}

View File

@ -0,0 +1,66 @@
/*
* 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
*/
#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 );
}tRadioDriver;
/*!
* \brief Initializes the RadioDriver structure with specific radio
* functions.
*
* \retval radioDriver Pointer to the radio driver variable
*/
tRadioDriver* RadioDriverInit( void );
#endif // __RADIO_H__

View File

@ -0,0 +1,606 @@
/*
* 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
*/
#include <string.h>
#include <math.h>
#include "platform.h"
#if defined( USE_SX1276_RADIO )
#include "radio.h"
#include "sx1276-Hal.h"
#include "sx1276.h"
#include "sx1276-FskMisc.h"
#include "sx1276-Fsk.h"
// Default settings
tFskSettings FskSettings =
{
870000000, // RFFrequency
9600, // Bitrate
50000, // Fdev
20, // Power
100000, // RxBw
150000, // RxBwAfc
true, // CrcOn
true, // AfcOn
255 // PayloadLength (set payload size to the maximum for variable mode, else set the exact payload length)
};
/*!
* SX1276 FSK registers variable
*/
tSX1276* SX1276;
/*!
* Local RF buffer for communication support
*/
static uint8_t RFBuffer[RF_BUFFER_SIZE];
/*!
* Chunk size of data write in buffer
*/
static uint8_t DataChunkSize = 32;
/*!
* RF state machine variable
*/
static uint8_t RFState = RF_STATE_IDLE;
/*!
* Rx management support variables
*/
/*!
* PacketTimeout holds the RF packet timeout
* SyncSize = [0..8]
* VariableSize = [0;1]
* AddressSize = [0;1]
* PayloadSize = [0..RF_BUFFER_SIZE]
* CrcSize = [0;2]
* PacketTimeout = ( ( 8 * ( VariableSize + AddressSize + PayloadSize + CrcSize ) / BR ) * 1000.0 ) + 1
* Computed timeout is in miliseconds
*/
static uint32_t PacketTimeout;
/*!
* Preamble2SyncTimeout
* Preamble2SyncTimeout = ( ( 8 * ( PremableSize + SyncSize ) / RFBitrate ) * 1000.0 ) + 1
* Computed timeout is in miliseconds
*/
static uint32_t Preamble2SyncTimeout;
static bool PreambleDetected = false;
static bool SyncWordDetected = false;
static bool PacketDetected = false;
static uint16_t RxPacketSize = 0;
static uint8_t RxBytesRead = 0;
static uint8_t TxBytesSent = 0;
static double RxPacketRssiValue;
static uint32_t RxPacketAfcValue;
static uint8_t RxGain = 1;
static uint32_t RxTimeoutTimer = 0;
static uint32_t Preamble2SyncTimer = 0;
/*!
* Tx management support variables
*/
static uint16_t TxPacketSize = 0;
static uint32_t TxTimeoutTimer = 0;
void SX1276FskInit( void )
{
RFState = RF_STATE_IDLE;
SX1276FskSetDefaults( );
SX1276ReadBuffer( REG_OPMODE, SX1276Regs + 1, 0x70 - 1 );
// Set the device in FSK mode and Sleep Mode
SX1276->RegOpMode = RF_OPMODE_MODULATIONTYPE_FSK | RF_OPMODE_SLEEP;
SX1276Write( REG_OPMODE, SX1276->RegOpMode );
SX1276->RegPaRamp = RF_PARAMP_MODULATIONSHAPING_01;
SX1276Write( REG_PARAMP, SX1276->RegPaRamp );
SX1276->RegLna = RF_LNA_GAIN_G1;
SX1276Write( REG_LNA, SX1276->RegLna );
if( FskSettings.AfcOn == true )
{
SX1276->RegRxConfig = RF_RXCONFIG_RESTARTRXONCOLLISION_OFF | RF_RXCONFIG_AFCAUTO_ON |
RF_RXCONFIG_AGCAUTO_ON | RF_RXCONFIG_RXTRIGER_PREAMBLEDETECT;
}
else
{
SX1276->RegRxConfig = RF_RXCONFIG_RESTARTRXONCOLLISION_OFF | RF_RXCONFIG_AFCAUTO_OFF |
RF_RXCONFIG_AGCAUTO_ON | RF_RXCONFIG_RXTRIGER_PREAMBLEDETECT;
}
SX1276->RegPreambleLsb = 8;
SX1276->RegPreambleDetect = RF_PREAMBLEDETECT_DETECTOR_ON | RF_PREAMBLEDETECT_DETECTORSIZE_2 |
RF_PREAMBLEDETECT_DETECTORTOL_10;
SX1276->RegRssiThresh = 0xFF;
SX1276->RegSyncConfig = RF_SYNCCONFIG_AUTORESTARTRXMODE_WAITPLL_ON | RF_SYNCCONFIG_PREAMBLEPOLARITY_AA |
RF_SYNCCONFIG_SYNC_ON |
RF_SYNCCONFIG_SYNCSIZE_4;
SX1276->RegSyncValue1 = 0x69;
SX1276->RegSyncValue2 = 0x81;
SX1276->RegSyncValue3 = 0x7E;
SX1276->RegSyncValue4 = 0x96;
SX1276->RegPacketConfig1 = RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE | RF_PACKETCONFIG1_DCFREE_OFF |
( FskSettings.CrcOn << 4 ) | RF_PACKETCONFIG1_CRCAUTOCLEAR_ON |
RF_PACKETCONFIG1_ADDRSFILTERING_OFF | RF_PACKETCONFIG1_CRCWHITENINGTYPE_CCITT;
SX1276FskGetPacketCrcOn( ); // Update CrcOn on FskSettings
SX1276->RegPayloadLength = FskSettings.PayloadLength;
// we can now update the registers with our configuration
SX1276WriteBuffer( REG_OPMODE, SX1276Regs + 1, 0x70 - 1 );
// then we need to set the RF settings
SX1276FskSetRFFrequency( FskSettings.RFFrequency );
SX1276FskSetBitrate( FskSettings.Bitrate );
SX1276FskSetFdev( FskSettings.Fdev );
SX1276FskSetDccBw( &SX1276->RegRxBw, 0, FskSettings.RxBw );
SX1276FskSetDccBw( &SX1276->RegAfcBw, 0, FskSettings.RxBwAfc );
SX1276FskSetRssiOffset( 0 );
#if( ( MODULE_SX1276RF1IAS == 1 ) || ( MODULE_SX1276RF1KAS == 1 ) )
if( FskSettings.RFFrequency > 860000000 )
{
SX1276FskSetPAOutput( RF_PACONFIG_PASELECT_RFO );
SX1276FskSetPa20dBm( false );
FskSettings.Power = 14;
SX1276FskSetRFPower( FskSettings.Power );
}
else
{
SX1276FskSetPAOutput( RF_PACONFIG_PASELECT_PABOOST );
SX1276FskSetPa20dBm( true );
FskSettings.Power = 20;
SX1276FskSetRFPower( FskSettings.Power );
}
#elif( MODULE_SX1276RF1JAS == 1 )
if( FskSettings.RFFrequency > 860000000 )
{
SX1276FskSetPAOutput( RF_PACONFIG_PASELECT_PABOOST );
SX1276FskSetPa20dBm( true );
FskSettings.Power = 20;
SX1276FskSetRFPower( FskSettings.Power );
}
else
{
SX1276FskSetPAOutput( RF_PACONFIG_PASELECT_RFO );
SX1276FskSetPa20dBm( false );
FskSettings.Power = 14;
SX1276FskSetRFPower( FskSettings.Power );
}
#endif
SX1276FskSetOpMode( RF_OPMODE_STANDBY );
// Calibrate the HF
SX1276FskRxCalibrate( );
}
void SX1276FskSetDefaults( void )
{
// REMARK: See SX1276 datasheet for modified default values.
SX1276Read( REG_VERSION, &SX1276->RegVersion );
}
void SX1276FskSetOpMode( uint8_t opMode )
{
static uint8_t opModePrev = RF_OPMODE_STANDBY;
static bool antennaSwitchTxOnPrev = true;
bool antennaSwitchTxOn = false;
opModePrev = SX1276->RegOpMode & ~RF_OPMODE_MASK;
if( opMode != opModePrev )
{
if( opMode == RF_OPMODE_TRANSMITTER )
{
antennaSwitchTxOn = true;
}
else
{
antennaSwitchTxOn = false;
}
if( antennaSwitchTxOn != antennaSwitchTxOnPrev )
{
antennaSwitchTxOnPrev = antennaSwitchTxOn;
RXTX( antennaSwitchTxOn ); // Antenna switch control
}
SX1276->RegOpMode = ( SX1276->RegOpMode & RF_OPMODE_MASK ) | opMode;
SX1276Write( REG_OPMODE, SX1276->RegOpMode );
}
}
uint8_t SX1276FskGetOpMode( void )
{
SX1276Read( REG_OPMODE, &SX1276->RegOpMode );
return SX1276->RegOpMode & ~RF_OPMODE_MASK;
}
int32_t SX1276FskReadFei( void )
{
SX1276ReadBuffer( REG_FEIMSB, &SX1276->RegFeiMsb, 2 ); // Reads the FEI value
return ( int32_t )( double )( ( ( uint16_t )SX1276->RegFeiMsb << 8 ) | ( uint16_t )SX1276->RegFeiLsb ) * ( double )FREQ_STEP;
}
int32_t SX1276FskReadAfc( void )
{
SX1276ReadBuffer( REG_AFCMSB, &SX1276->RegAfcMsb, 2 ); // Reads the AFC value
return ( int32_t )( double )( ( ( uint16_t )SX1276->RegAfcMsb << 8 ) | ( uint16_t )SX1276->RegAfcLsb ) * ( double )FREQ_STEP;
}
uint8_t SX1276FskReadRxGain( void )
{
SX1276Read( REG_LNA, &SX1276->RegLna );
return( SX1276->RegLna >> 5 ) & 0x07;
}
double SX1276FskReadRssi( void )
{
SX1276Read( REG_RSSIVALUE, &SX1276->RegRssiValue ); // Reads the RSSI value
return -( double )( ( double )SX1276->RegRssiValue / 2.0 );
}
uint8_t SX1276FskGetPacketRxGain( void )
{
return RxGain;
}
double SX1276FskGetPacketRssi( void )
{
return RxPacketRssiValue;
}
uint32_t SX1276FskGetPacketAfc( void )
{
return RxPacketAfcValue;
}
void SX1276FskStartRx( void )
{
SX1276FskSetRFState( RF_STATE_RX_INIT );
}
void SX1276FskGetRxPacket( void *buffer, uint16_t *size )
{
*size = RxPacketSize;
RxPacketSize = 0;
memcpy( ( void * )buffer, ( void * )RFBuffer, ( size_t )*size );
}
void SX1276FskSetTxPacket( const void *buffer, uint16_t size )
{
TxPacketSize = size;
memcpy( ( void * )RFBuffer, buffer, ( size_t )TxPacketSize );
RFState = RF_STATE_TX_INIT;
}
// Remark: SX1276 must be fully initialized before calling this function
uint16_t SX1276FskGetPacketPayloadSize( void )
{
uint16_t syncSize;
uint16_t variableSize;
uint16_t addressSize;
uint16_t payloadSize;
uint16_t crcSize;
syncSize = ( SX1276->RegSyncConfig & 0x07 ) + 1;
variableSize = ( ( SX1276->RegPacketConfig1 & 0x80 ) == 0x80 ) ? 1 : 0;
addressSize = ( ( SX1276->RegPacketConfig1 & 0x06 ) != 0x00 ) ? 1 : 0;
payloadSize = SX1276->RegPayloadLength;
crcSize = ( ( SX1276->RegPacketConfig1 & 0x10 ) == 0x10 ) ? 2 : 0;
return syncSize + variableSize + addressSize + payloadSize + crcSize;
}
// Remark: SX1276 must be fully initialized before calling this function
uint16_t SX1276FskGetPacketHeaderSize( void )
{
uint16_t preambleSize;
uint16_t syncSize;
preambleSize = ( ( uint16_t )SX1276->RegPreambleMsb << 8 ) | ( uint16_t )SX1276->RegPreambleLsb;
syncSize = ( SX1276->RegSyncConfig & 0x07 ) + 1;
return preambleSize + syncSize;
}
uint8_t SX1276FskGetRFState( void )
{
return RFState;
}
void SX1276FskSetRFState( uint8_t state )
{
RFState = state;
}
uint32_t SX1276FskProcess( void )
{
uint32_t result = RF_BUSY;
switch( RFState )
{
case RF_STATE_IDLE:
break;
// Rx management
case RF_STATE_RX_INIT:
// DIO mapping setup
if( ( SX1276->RegPacketConfig1 & RF_PACKETCONFIG1_CRC_ON ) == RF_PACKETCONFIG1_CRC_ON )
{
// CrcOk, FifoLevel, SyncAddr, FifoEmpty
SX1276->RegDioMapping1 = RF_DIOMAPPING1_DIO0_01 | RF_DIOMAPPING1_DIO1_00 | RF_DIOMAPPING1_DIO2_11 | RF_DIOMAPPING1_DIO3_00;
}
else
{
// PayloadReady, FifoLevel, SyncAddr, FifoEmpty
SX1276->RegDioMapping1 = RF_DIOMAPPING1_DIO0_00 | RF_DIOMAPPING1_DIO1_00 | RF_DIOMAPPING1_DIO2_11 | RF_DIOMAPPING1_DIO3_00;
}
// Preamble, Data
SX1276->RegDioMapping2 = RF_DIOMAPPING2_DIO4_11 | RF_DIOMAPPING2_DIO5_10 | RF_DIOMAPPING2_MAP_PREAMBLEDETECT;
SX1276WriteBuffer( REG_DIOMAPPING1, &SX1276->RegDioMapping1, 2 );
SX1276FskSetOpMode( RF_OPMODE_RECEIVER );
memset( RFBuffer, 0, ( size_t )RF_BUFFER_SIZE );
PacketTimeout = ( uint16_t )( round( ( 8.0 * ( ( double )SX1276FskGetPacketPayloadSize( ) ) / ( double )FskSettings.Bitrate ) * 1000.0 ) + 1.0 );
PacketTimeout = PacketTimeout + ( PacketTimeout >> 1 ); // Set the Packet timeout as 1.5 times the full payload transmission time
Preamble2SyncTimeout = PacketTimeout;
Preamble2SyncTimer = RxTimeoutTimer = GET_TICK_COUNT( );
SX1276->RegFifoThresh = RF_FIFOTHRESH_TXSTARTCONDITION_FIFONOTEMPTY | 0x20; // 32 bytes of data
SX1276Write( REG_FIFOTHRESH, SX1276->RegFifoThresh );
PreambleDetected = false;
SyncWordDetected = false;
PacketDetected = false;
RxBytesRead = 0;
RxPacketSize = 0;
RFState = RF_STATE_RX_SYNC;
break;
case RF_STATE_RX_SYNC:
if( ( DIO4 == 1 ) && ( PreambleDetected == false ) )// Preamble
{
PreambleDetected = true;
Preamble2SyncTimer = GET_TICK_COUNT( );
}
if( ( DIO2 == 1 ) && ( PreambleDetected == true ) && ( SyncWordDetected == false ) ) // SyncAddr
{
SyncWordDetected = true;
RxPacketRssiValue = SX1276FskReadRssi( );
RxPacketAfcValue = SX1276FskReadAfc( );
RxGain = SX1276FskReadRxGain( );
Preamble2SyncTimer = RxTimeoutTimer = GET_TICK_COUNT( );
RFState = RF_STATE_RX_RUNNING;
}
// Preamble 2 SyncAddr timeout
if( ( SyncWordDetected == false ) && ( PreambleDetected == true ) && ( ( GET_TICK_COUNT( ) - Preamble2SyncTimer ) > Preamble2SyncTimeout ) )
{
RFState = RF_STATE_RX_INIT;
SX1276Write( REG_RXCONFIG, SX1276->RegRxConfig | RF_RXCONFIG_RESTARTRXWITHPLLLOCK );
}
if( ( SyncWordDetected == false ) &&
( PreambleDetected == false ) &&
( PacketDetected == false ) &&
( ( GET_TICK_COUNT( ) - RxTimeoutTimer ) > PacketTimeout ) )
{
RFState = RF_STATE_RX_TIMEOUT;
}
break;
case RF_STATE_RX_RUNNING:
if( RxPacketSize > RF_BUFFER_SIZE_MAX )
{
RFState = RF_STATE_RX_LEN_ERROR;
break;
}
#if 1
if( DIO1 == 1 ) // FifoLevel
{
if( ( RxPacketSize == 0 ) && ( RxBytesRead == 0 ) ) // Read received packet size
{
if( ( SX1276->RegPacketConfig1 & RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE ) == RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE )
{
SX1276ReadFifo( ( uint8_t* )&RxPacketSize, 1 );
}
else
{
RxPacketSize = SX1276->RegPayloadLength;
}
}
if( ( RxPacketSize - RxBytesRead ) > ( SX1276->RegFifoThresh & 0x3F ) )
{
SX1276ReadFifo( ( RFBuffer + RxBytesRead ), ( SX1276->RegFifoThresh & 0x3F ) );
RxBytesRead += ( SX1276->RegFifoThresh & 0x3F );
}
else
{
SX1276ReadFifo( ( RFBuffer + RxBytesRead ), RxPacketSize - RxBytesRead );
RxBytesRead += ( RxPacketSize - RxBytesRead );
}
}
#endif
if( DIO0 == 1 ) // PayloadReady/CrcOk
{
RxTimeoutTimer = GET_TICK_COUNT( );
if( ( RxPacketSize == 0 ) && ( RxBytesRead == 0 ) ) // Read received packet size
{
if( ( SX1276->RegPacketConfig1 & RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE ) == RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE )
{
SX1276ReadFifo( ( uint8_t* )&RxPacketSize, 1 );
}
else
{
RxPacketSize = SX1276->RegPayloadLength;
}
SX1276ReadFifo( RFBuffer + RxBytesRead, RxPacketSize - RxBytesRead );
RxBytesRead += ( RxPacketSize - RxBytesRead );
PacketDetected = true;
RFState = RF_STATE_RX_DONE;
}
else
{
SX1276ReadFifo( RFBuffer + RxBytesRead, RxPacketSize - RxBytesRead );
RxBytesRead += ( RxPacketSize - RxBytesRead );
PacketDetected = true;
RFState = RF_STATE_RX_DONE;
}
}
// Packet timeout
if( ( PacketDetected == false ) && ( ( GET_TICK_COUNT( ) - RxTimeoutTimer ) > PacketTimeout ) )
{
RFState = RF_STATE_RX_TIMEOUT;
}
break;
case RF_STATE_RX_DONE:
RxBytesRead = 0;
RFState = RF_STATE_RX_INIT;
result = RF_RX_DONE;
break;
case RF_STATE_RX_TIMEOUT:
RxBytesRead = 0;
RxPacketSize = 0;
SX1276Write( REG_RXCONFIG, SX1276->RegRxConfig | RF_RXCONFIG_RESTARTRXWITHPLLLOCK );
RFState = RF_STATE_RX_INIT;
result = RF_RX_TIMEOUT;
break;
case RF_STATE_RX_LEN_ERROR:
RxBytesRead = 0;
RxPacketSize = 0;
SX1276Write( REG_RXCONFIG, SX1276->RegRxConfig | RF_RXCONFIG_RESTARTRXWITHPLLLOCK );
RFState = RF_STATE_RX_INIT;
result = RF_LEN_ERROR;
break;
// Tx management
case RF_STATE_TX_INIT:
// Packet DIO mapping setup
// PacketSent, FifoLevel, FifoFull, TxReady
SX1276->RegDioMapping1 = RF_DIOMAPPING1_DIO0_00 | RF_DIOMAPPING1_DIO1_00 | RF_DIOMAPPING1_DIO2_00 | RF_DIOMAPPING1_DIO3_01;
// LowBat, Data
SX1276->RegDioMapping2 = RF_DIOMAPPING2_DIO4_00 | RF_DIOMAPPING2_DIO5_10;
SX1276WriteBuffer( REG_DIOMAPPING1, &SX1276->RegDioMapping1, 2 );
SX1276->RegFifoThresh = RF_FIFOTHRESH_TXSTARTCONDITION_FIFONOTEMPTY | 0x18; // 24 bytes of data
SX1276Write( REG_FIFOTHRESH, SX1276->RegFifoThresh );
SX1276FskSetOpMode( RF_OPMODE_TRANSMITTER );
RFState = RF_STATE_TX_READY_WAIT;
TxBytesSent = 0;
break;
case RF_STATE_TX_READY_WAIT:
if( DIO3 == 1 ) // TxReady
{
if( ( SX1276->RegPacketConfig1 & RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE ) == RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE )
{
SX1276WriteFifo( ( uint8_t* )&TxPacketSize, 1 );
}
if( ( TxPacketSize > 0 ) && ( TxPacketSize <= 64 ) )
{
DataChunkSize = TxPacketSize;
}
else
{
DataChunkSize = 32;
}
SX1276WriteFifo( RFBuffer, DataChunkSize );
TxBytesSent += DataChunkSize;
TxTimeoutTimer = GET_TICK_COUNT( );
RFState = RF_STATE_TX_RUNNING;
}
break;
case RF_STATE_TX_RUNNING:
if( DIO1 == 0 ) // FifoLevel below thresold
{
if( ( TxPacketSize - TxBytesSent ) > DataChunkSize )
{
SX1276WriteFifo( ( RFBuffer + TxBytesSent ), DataChunkSize );
TxBytesSent += DataChunkSize;
}
else
{
// we write the last chunk of data
SX1276WriteFifo( RFBuffer + TxBytesSent, TxPacketSize - TxBytesSent );
TxBytesSent += TxPacketSize - TxBytesSent;
}
}
if( DIO0 == 1 ) // PacketSent
{
TxTimeoutTimer = GET_TICK_COUNT( );
RFState = RF_STATE_TX_DONE;
SX1276FskSetOpMode( RF_OPMODE_STANDBY );
}
// Packet timeout
if( ( GET_TICK_COUNT( ) - TxTimeoutTimer ) > TICK_RATE_MS( 1000 ) )
{
RFState = RF_STATE_TX_TIMEOUT;
}
break;
case RF_STATE_TX_DONE:
RFState = RF_STATE_IDLE;
result = RF_TX_DONE;
break;
case RF_STATE_TX_TIMEOUT:
RFState = RF_STATE_IDLE;
result = RF_TX_TIMEOUT;
break;
default:
break;
}
return result;
}
#endif // USE_SX1276_RADIO

View File

@ -0,0 +1,521 @@
/*
* 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
*/
#include <math.h>
#include "platform.h"
#if defined( USE_SX1276_RADIO )
#include "sx1276-Hal.h"
#include "sx1276.h"
#include "sx1276-Fsk.h"
#include "sx1276-FskMisc.h"
extern tFskSettings FskSettings;
void SX1276FskSetRFFrequency( uint32_t freq )
{
FskSettings.RFFrequency = freq;
freq = ( uint32_t )( ( double )freq / ( double )FREQ_STEP );
SX1276->RegFrfMsb = ( uint8_t )( ( freq >> 16 ) & 0xFF );
SX1276->RegFrfMid = ( uint8_t )( ( freq >> 8 ) & 0xFF );
SX1276->RegFrfLsb = ( uint8_t )( freq & 0xFF );
SX1276WriteBuffer( REG_FRFMSB, &SX1276->RegFrfMsb, 3 );
}
uint32_t SX1276FskGetRFFrequency( void )
{
SX1276ReadBuffer( REG_FRFMSB, &SX1276->RegFrfMsb, 3 );
FskSettings.RFFrequency = ( ( uint32_t )SX1276->RegFrfMsb << 16 ) | ( ( uint32_t )SX1276->RegFrfMid << 8 ) | ( ( uint32_t )SX1276->RegFrfLsb );
FskSettings.RFFrequency = ( uint32_t )( ( double )FskSettings.RFFrequency * ( double )FREQ_STEP );
return FskSettings.RFFrequency;
}
void SX1276FskRxCalibrate( void )
{
// the function RadioRxCalibrate is called just after the reset so all register are at their default values
uint8_t regPaConfigInitVal;
uint32_t initialFreq;
// save register values;
SX1276Read( REG_PACONFIG, &regPaConfigInitVal );
initialFreq = SX1276FskGetRFFrequency( );
// Cut the PA just in case
SX1276->RegPaConfig = 0x00; // RFO output, power = -1 dBm
SX1276Write( REG_PACONFIG, SX1276->RegPaConfig );
// Set Frequency in HF band
SX1276FskSetRFFrequency( 860000000 );
// Rx chain re-calibration workaround
SX1276Read( REG_IMAGECAL, &SX1276->RegImageCal );
SX1276->RegImageCal = ( SX1276->RegImageCal & RF_IMAGECAL_IMAGECAL_MASK ) | RF_IMAGECAL_IMAGECAL_START;
SX1276Write( REG_IMAGECAL, SX1276->RegImageCal );
SX1276Read( REG_IMAGECAL, &SX1276->RegImageCal );
// rx_cal_run goes low when calibration in finished
while( ( SX1276->RegImageCal & RF_IMAGECAL_IMAGECAL_RUNNING ) == RF_IMAGECAL_IMAGECAL_RUNNING )
{
SX1276Read( REG_IMAGECAL, &SX1276->RegImageCal );
}
// reload saved values into the registers
SX1276->RegPaConfig = regPaConfigInitVal;
SX1276Write( REG_PACONFIG, SX1276->RegPaConfig );
SX1276FskSetRFFrequency( initialFreq );
}
void SX1276FskSetBitrate( uint32_t bitrate )
{
FskSettings.Bitrate = bitrate;
bitrate = ( uint16_t )( ( double )XTAL_FREQ / ( double )bitrate );
SX1276->RegBitrateMsb = ( uint8_t )( bitrate >> 8 );
SX1276->RegBitrateLsb = ( uint8_t )( bitrate & 0xFF );
SX1276WriteBuffer( REG_BITRATEMSB, &SX1276->RegBitrateMsb, 2 );
}
uint32_t SX1276FskGetBitrate( void )
{
SX1276ReadBuffer( REG_BITRATEMSB, &SX1276->RegBitrateMsb, 2 );
FskSettings.Bitrate = ( ( ( uint32_t )SX1276->RegBitrateMsb << 8 ) | ( ( uint32_t )SX1276->RegBitrateLsb ) );
FskSettings.Bitrate = ( uint16_t )( ( double )XTAL_FREQ / ( double )FskSettings.Bitrate );
return FskSettings.Bitrate;
}
void SX1276FskSetFdev( uint32_t fdev )
{
FskSettings.Fdev = fdev;
SX1276Read( REG_FDEVMSB, &SX1276->RegFdevMsb );
fdev = ( uint16_t )( ( double )fdev / ( double )FREQ_STEP );
SX1276->RegFdevMsb = ( ( SX1276->RegFdevMsb & RF_FDEVMSB_FDEV_MASK ) | ( ( ( uint8_t )( fdev >> 8 ) ) & ~RF_FDEVMSB_FDEV_MASK ) );
SX1276->RegFdevLsb = ( uint8_t )( fdev & 0xFF );
SX1276WriteBuffer( REG_FDEVMSB, &SX1276->RegFdevMsb, 2 );
}
uint32_t SX1276FskGetFdev( void )
{
SX1276ReadBuffer( REG_FDEVMSB, &SX1276->RegFdevMsb, 2 );
FskSettings.Fdev = ( ( ( uint32_t )( ( SX1276->RegFdevMsb << 8 ) & ~RF_FDEVMSB_FDEV_MASK ) ) | ( ( uint32_t )SX1276->RegFdevLsb ) );
FskSettings.Fdev = ( uint16_t )( ( double )FskSettings.Fdev * ( double )FREQ_STEP );
return FskSettings.Fdev;
}
void SX1276FskSetRFPower( int8_t power )
{
SX1276Read( REG_PACONFIG, &SX1276->RegPaConfig );
SX1276Read( REG_PADAC, &SX1276->RegPaDac );
if( ( SX1276->RegPaConfig & RF_PACONFIG_PASELECT_PABOOST ) == RF_PACONFIG_PASELECT_PABOOST )
{
if( ( SX1276->RegPaDac & 0x87 ) == 0x87 )
{
if( power < 5 )
{
power = 5;
}
if( power > 20 )
{
power = 20;
}
SX1276->RegPaConfig = ( SX1276->RegPaConfig & RF_PACONFIG_MAX_POWER_MASK ) | 0x70;
SX1276->RegPaConfig = ( SX1276->RegPaConfig & RF_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power - 5 ) & 0x0F );
}
else
{
if( power < 2 )
{
power = 2;
}
if( power > 17 )
{
power = 17;
}
SX1276->RegPaConfig = ( SX1276->RegPaConfig & RF_PACONFIG_MAX_POWER_MASK ) | 0x70;
SX1276->RegPaConfig = ( SX1276->RegPaConfig & RF_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power - 2 ) & 0x0F );
}
}
else
{
if( power < -1 )
{
power = -1;
}
if( power > 14 )
{
power = 14;
}
SX1276->RegPaConfig = ( SX1276->RegPaConfig & RF_PACONFIG_MAX_POWER_MASK ) | 0x70;
SX1276->RegPaConfig = ( SX1276->RegPaConfig & RF_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power + 1 ) & 0x0F );
}
SX1276Write( REG_PACONFIG, SX1276->RegPaConfig );
FskSettings.Power = power;
}
int8_t SX1276FskGetRFPower( void )
{
SX1276Read( REG_PACONFIG, &SX1276->RegPaConfig );
SX1276Read( REG_PADAC, &SX1276->RegPaDac );
if( ( SX1276->RegPaConfig & RF_PACONFIG_PASELECT_PABOOST ) == RF_PACONFIG_PASELECT_PABOOST )
{
if( ( SX1276->RegPaDac & 0x07 ) == 0x07 )
{
FskSettings.Power = 5 + ( SX1276->RegPaConfig & ~RF_PACONFIG_OUTPUTPOWER_MASK );
}
else
{
FskSettings.Power = 2 + ( SX1276->RegPaConfig & ~RF_PACONFIG_OUTPUTPOWER_MASK );
}
}
else
{
FskSettings.Power = -1 + ( SX1276->RegPaConfig & ~RF_PACONFIG_OUTPUTPOWER_MASK );
}
return FskSettings.Power;
}
/*!
* \brief Computes the Rx bandwidth with the mantisse and exponent
*
* \param [IN] mantisse Mantisse of the bandwidth value
* \param [IN] exponent Exponent of the bandwidth value
* \retval bandwidth Computed bandwidth
*/
static uint32_t SX1276FskComputeRxBw( uint8_t mantisse, uint8_t exponent )
{
// rxBw
if( ( SX1276->RegOpMode & RF_OPMODE_MODULATIONTYPE_FSK ) == RF_OPMODE_MODULATIONTYPE_FSK )
{
return ( uint32_t )( ( double )XTAL_FREQ / ( mantisse * ( double )pow( 2, exponent + 2 ) ) );
}
else
{
return ( uint32_t )( ( double )XTAL_FREQ / ( mantisse * ( double )pow( 2, exponent + 3 ) ) );
}
}
/*!
* \brief Computes the mantisse and exponent from the bandwitdh value
*
* \param [IN] rxBwValue Bandwidth value
* \param [OUT] mantisse Mantisse of the bandwidth value
* \param [OUT] exponent Exponent of the bandwidth value
*/
static void SX1276FskComputeRxBwMantExp( uint32_t rxBwValue, uint8_t* mantisse, uint8_t* exponent )
{
uint8_t tmpExp = 0;
uint8_t tmpMant = 0;
double tmpRxBw = 0;
double rxBwMin = 10e6;
for( tmpExp = 0; tmpExp < 8; tmpExp++ )
{
for( tmpMant = 16; tmpMant <= 24; tmpMant += 4 )
{
if( ( SX1276->RegOpMode & RF_OPMODE_MODULATIONTYPE_FSK ) == RF_OPMODE_MODULATIONTYPE_FSK )
{
tmpRxBw = ( double )XTAL_FREQ / ( tmpMant * ( double )pow( 2, tmpExp + 2 ) );
}
else
{
tmpRxBw = ( double )XTAL_FREQ / ( tmpMant * ( double )pow( 2, tmpExp + 3 ) );
}
if( fabs( tmpRxBw - rxBwValue ) < rxBwMin )
{
rxBwMin = fabs( tmpRxBw - rxBwValue );
*mantisse = tmpMant;
*exponent = tmpExp;
}
}
}
}
void SX1276FskSetDccBw( uint8_t* reg, uint32_t dccValue, uint32_t rxBwValue )
{
uint8_t mantisse = 0;
uint8_t exponent = 0;
if( reg == &SX1276->RegRxBw )
{
*reg = ( uint8_t )dccValue & 0x60;
}
else
{
*reg = 0;
}
SX1276FskComputeRxBwMantExp( rxBwValue, &mantisse, &exponent );
switch( mantisse )
{
case 16:
*reg |= ( uint8_t )( 0x00 | ( exponent & 0x07 ) );
break;
case 20:
*reg |= ( uint8_t )( 0x08 | ( exponent & 0x07 ) );
break;
case 24:
*reg |= ( uint8_t )( 0x10 | ( exponent & 0x07 ) );
break;
default:
// Something went terribely wrong
break;
}
if( reg == &SX1276->RegRxBw )
{
SX1276Write( REG_RXBW, *reg );
FskSettings.RxBw = rxBwValue;
}
else
{
SX1276Write( REG_AFCBW, *reg );
FskSettings.RxBwAfc = rxBwValue;
}
}
uint32_t SX1276FskGetBw( uint8_t* reg )
{
uint32_t rxBwValue = 0;
uint8_t mantisse = 0;
switch( ( *reg & 0x18 ) >> 3 )
{
case 0:
mantisse = 16;
break;
case 1:
mantisse = 20;
break;
case 2:
mantisse = 24;
break;
default:
break;
}
rxBwValue = SX1276FskComputeRxBw( mantisse, ( uint8_t )*reg & 0x07 );
if( reg == &SX1276->RegRxBw )
{
return FskSettings.RxBw = rxBwValue;
}
else
{
return FskSettings.RxBwAfc = rxBwValue;
}
}
void SX1276FskSetPacketCrcOn( bool enable )
{
SX1276Read( REG_PACKETCONFIG1, &SX1276->RegPacketConfig1 );
SX1276->RegPacketConfig1 = ( SX1276->RegPacketConfig1 & RF_PACKETCONFIG1_CRC_MASK ) | ( enable << 4 );
SX1276Write( REG_PACKETCONFIG1, SX1276->RegPacketConfig1 );
FskSettings.CrcOn = enable;
}
bool SX1276FskGetPacketCrcOn( void )
{
SX1276Read( REG_PACKETCONFIG1, &SX1276->RegPacketConfig1 );
FskSettings.CrcOn = ( SX1276->RegPacketConfig1 & RF_PACKETCONFIG1_CRC_ON ) >> 4;
return FskSettings.CrcOn;
}
void SX1276FskSetAfcOn( bool enable )
{
SX1276Read( REG_RXCONFIG, &SX1276->RegRxConfig );
SX1276->RegRxConfig = ( SX1276->RegRxConfig & RF_RXCONFIG_AFCAUTO_MASK ) | ( enable << 4 );
SX1276Write( REG_RXCONFIG, SX1276->RegRxConfig );
FskSettings.AfcOn = enable;
}
bool SX1276FskGetAfcOn( void )
{
SX1276Read( REG_RXCONFIG, &SX1276->RegRxConfig );
FskSettings.AfcOn = ( SX1276->RegRxConfig & RF_RXCONFIG_AFCAUTO_ON ) >> 4;
return FskSettings.AfcOn;
}
void SX1276FskSetPayloadLength( uint8_t value )
{
SX1276->RegPayloadLength = value;
SX1276Write( REG_PAYLOADLENGTH, SX1276->RegPayloadLength );
FskSettings.PayloadLength = value;
}
uint8_t SX1276FskGetPayloadLength( void )
{
SX1276Read( REG_PAYLOADLENGTH, &SX1276->RegPayloadLength );
FskSettings.PayloadLength = SX1276->RegPayloadLength;
return FskSettings.PayloadLength;
}
void SX1276FskSetPa20dBm( bool enale )
{
SX1276Read( REG_PADAC, &SX1276->RegPaDac );
SX1276Read( REG_PACONFIG, &SX1276->RegPaConfig );
if( ( SX1276->RegPaConfig & RF_PACONFIG_PASELECT_PABOOST ) == RF_PACONFIG_PASELECT_PABOOST )
{
if( enale == true )
{
SX1276->RegPaDac = 0x87;
}
}
else
{
SX1276->RegPaDac = 0x84;
}
SX1276Write( REG_PADAC, SX1276->RegPaDac );
}
bool SX1276FskGetPa20dBm( void )
{
SX1276Read( REG_PADAC, &SX1276->RegPaDac );
return ( ( SX1276->RegPaDac & 0x07 ) == 0x07 ) ? true : false;
}
void SX1276FskSetPAOutput( uint8_t outputPin )
{
SX1276Read( REG_PACONFIG, &SX1276->RegPaConfig );
SX1276->RegPaConfig = (SX1276->RegPaConfig & RF_PACONFIG_PASELECT_MASK ) | outputPin;
SX1276Write( REG_PACONFIG, SX1276->RegPaConfig );
}
uint8_t SX1276FskGetPAOutput( void )
{
SX1276Read( REG_PACONFIG, &SX1276->RegPaConfig );
return SX1276->RegPaConfig & ~RF_PACONFIG_PASELECT_MASK;
}
void SX1276FskSetPaRamp( uint8_t value )
{
SX1276Read( REG_PARAMP, &SX1276->RegPaRamp );
SX1276->RegPaRamp = ( SX1276->RegPaRamp & RF_PARAMP_MASK ) | ( value & ~RF_PARAMP_MASK );
SX1276Write( REG_PARAMP, SX1276->RegPaRamp );
}
uint8_t SX1276FskGetPaRamp( void )
{
SX1276Read( REG_PARAMP, &SX1276->RegPaRamp );
return SX1276->RegPaRamp & ~RF_PARAMP_MASK;
}
void SX1276FskSetRssiOffset( int8_t offset )
{
SX1276Read( REG_RSSICONFIG, &SX1276->RegRssiConfig );
if( offset < 0 )
{
offset = ( ~offset & 0x1F );
offset += 1;
offset = -offset;
}
SX1276->RegRssiConfig |= ( uint8_t )( ( offset & 0x1F ) << 3 );
SX1276Write( REG_RSSICONFIG, SX1276->RegRssiConfig );
}
int8_t SX1276FskGetRssiOffset( void )
{
SX1276Read( REG_RSSICONFIG, &SX1276->RegRssiConfig );
int8_t offset = SX1276->RegRssiConfig >> 3;
if( ( offset & 0x10 ) == 0x10 )
{
offset = ( ~offset & 0x1F );
offset += 1;
offset = -offset;
}
return offset;
}
int8_t SX1276FskGetRawTemp( void )
{
int8_t temp = 0;
uint8_t previousOpMode;
uint32_t startTick;
// Enable Temperature reading
SX1276Read( REG_IMAGECAL, &SX1276->RegImageCal );
SX1276->RegImageCal = ( SX1276->RegImageCal & RF_IMAGECAL_TEMPMONITOR_MASK ) | RF_IMAGECAL_TEMPMONITOR_ON;
SX1276Write( REG_IMAGECAL, SX1276->RegImageCal );
// save current Op Mode
SX1276Read( REG_OPMODE, &SX1276->RegOpMode );
previousOpMode = SX1276->RegOpMode;
// put device in FSK RxSynth
SX1276->RegOpMode = RF_OPMODE_SYNTHESIZER_RX;
SX1276Write( REG_OPMODE, SX1276->RegOpMode );
// Wait 1ms
startTick = GET_TICK_COUNT( );
while( ( GET_TICK_COUNT( ) - startTick ) < TICK_RATE_MS( 1 ) );
// Disable Temperature reading
SX1276Read( REG_IMAGECAL, &SX1276->RegImageCal );
SX1276->RegImageCal = ( SX1276->RegImageCal & RF_IMAGECAL_TEMPMONITOR_MASK ) | RF_IMAGECAL_TEMPMONITOR_OFF;
SX1276Write( REG_IMAGECAL, SX1276->RegImageCal );
// Read temperature
SX1276Read( REG_TEMP, &SX1276->RegTemp );
temp = SX1276->RegTemp & 0x7F;
if( ( SX1276->RegTemp & 0x80 ) == 0x80 )
{
temp *= -1;
}
// Reload previous Op Mode
SX1276Write( REG_OPMODE, previousOpMode );
return temp;
}
int8_t SX1276FskCalibreateTemp( int8_t actualTemp )
{
return actualTemp - SX1276FskGetRawTemp( );
}
int8_t SX1276FskGetTemp( int8_t compensationFactor )
{
return SX1276FskGetRawTemp( ) + compensationFactor;
}
#endif // USE_SX1276_RADIO

View File

@ -0,0 +1,241 @@
/*
* 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
*/
#ifndef __SX1276_FSK_MISC_H__
#define __SX1276_FSK_MISC_H__
/*!
* \brief Writes the new RF frequency value
*
* \param [IN] freq New RF frequency value in [Hz]
*/
void SX1276FskSetRFFrequency( uint32_t freq );
/*!
* \brief Reads the current RF frequency value
*
* \retval freq Current RF frequency value in [Hz]
*/
uint32_t SX1276FskGetRFFrequency( void );
/*!
* \brief Calibrate RSSI and I/Q mismatch for HF
*
* \retval none
*/
void SX1276FskRxCalibrate( void );
/*!
* \brief Writes the new bitrate value
*
* \param [IN] bitrate New bitrate value in [bps]
*/
void SX1276FskSetBitrate( uint32_t bitrate );
/*!
* \brief Reads the current bitrate value
*
* \retval bitrate Current bitrate value in [bps]
*/
uint32_t SX1276FskGetBitrate( void );
/*!
* \brief Writes the new frequency deviation value
*
* \param [IN] fdev New frequency deviation value in [Hz]
*/
void SX1276FskSetFdev( uint32_t fdev );
/*!
* \brief Reads the current frequency deviation value
*
* \retval fdev Current frequency deviation value in [Hz]
*/
uint32_t SX1276FskGetFdev( void );
/*!
* \brief Writes the new RF output power value
*
* \param [IN] power New output power value in [dBm]
*/
void SX1276FskSetRFPower( int8_t power );
/*!
* \brief Reads the current RF output power value
*
* \retval power Current output power value in [dBm]
*/
int8_t SX1276FskGetRFPower( void );
/*!
* \brief Writes the DC offset canceller and Rx bandwidth values
*
* \remark For SX1276 there is no DCC setting. dccValue should be 0
* ie: SX1276SetDccBw( &SX1276.RegRxBw, 0, 62500 );
*
* \param [IN] reg Register pointer to either SX1231.RegRxBw or SX1231.RegAfcBw
* \param [IN] dccValue New DC offset canceller value in [Hz] ( SX1231 only )
* \param [IN] rxBwValue New Rx bandwidth value in [Hz]
*/
void SX1276FskSetDccBw( uint8_t* reg, uint32_t dccValue, uint32_t rxBwValue );
/*!
* \brief Reads the current bandwidth setting
*
* \param [IN] reg Register pointer to either SX1231.RegRxBw or SX1231.RegAfcBw
*
* \retval bandwidth Bandwidth value
*/
uint32_t SX1276FskGetBw( uint8_t* reg );
/*!
* \brief Enables/Disables CRC
*
* \param [IN] enable CRC enable/disable
*/
void SX1276FskSetPacketCrcOn( bool enable );
/*!
* \brief Reads the current CRC Enable/Disbale value
*
* \retval enable Current CRC Enable/Disbale value
*/
bool SX1276FskGetPacketCrcOn( void );
/*!
* \brief Enables/Disables AFC
*
* \param [IN] enable AFC enable/disable
*/
void SX1276FskSetAfcOn( bool enable );
/*!
* \brief Reads the current AFC Enable/Disbale value
*
* \retval enable Current AFC Enable/Disbale value
*/
bool SX1276FskGetAfcOn( void );
/*!
* \brief Writes the new payload length value
*
* \param [IN] value New payload length value
*/
void SX1276FskSetPayloadLength( uint8_t value );
/*!
* \brief Reads the current payload length value
*
* \retval value Current payload length value
*/
uint8_t SX1276FskGetPayloadLength( void );
/*!
* \brief Enables/Disables the 20 dBm PA
*
* \param [IN] enable [true, false]
*/
void SX1276FskSetPa20dBm( bool enale );
/*!
* \brief Gets the current 20 dBm PA status
*
* \retval enable [true, false]
*/
bool SX1276FskGetPa20dBm( void );
/*!
* \brief Set the RF Output pin
*
* \param [IN] RF_PACONFIG_PASELECT_PABOOST or RF_PACONFIG_PASELECT_RFO
*/
void SX1276FskSetPAOutput( uint8_t outputPin );
/*!
* \brief Gets the used RF Ouptu pin
*
* \retval RF_PACONFIG_PASELECT_PABOOST or RF_PACONFIG_PASELECT_RFO
*/
uint8_t SX1276FskGetPAOutput( void );
/*!
* \brief Writes the new PA rise/fall time of ramp up/down value
*
* \param [IN] value New PaRamp value
*/
void SX1276FskSetPaRamp( uint8_t value );
/*!
* \brief Reads the current PA rise/fall time of ramp up/down value
*
* \retval value Current PaRamp value
*/
uint8_t SX1276FskGetPaRamp( void );
/*!
* \brief Applies an offset to the RSSI. Compensates board components
*
* \param [IN] offset Offset to be applied (+/-)
*/
void SX1276FskSetRssiOffset( int8_t offset );
/*!
* \brief Gets the current RSSI offset.
*
* \retval offset Current offset (+/-)
*/
int8_t SX1276FskGetRssiOffset( void );
/*!
* \brief Writes the new value for the preamble size
*
* \param [IN] size New value of pramble size
*/
void SX1276FskSetPreambleSize( uint16_t size );
/*!
* Reads the raw temperature
* \retval temperature New raw temperature reading in 2's complement format
*/
int8_t SX1276FskGetRawTemp( void );
/*!
* Computes the temperature compensation factor
* \param [IN] actualTemp Actual temperature measured by an external device
* \retval compensationFactor Computed compensation factor
*/
int8_t SX1276FskCalibreateTemp( int8_t actualTemp );
/*!
* Gets the actual compensated temperature
* \param [IN] compensationFactor Return value of the calibration function
* \retval New compensated temperature value
*/
int8_t SX1276FskGetTemp( int8_t compensationFactor );
#endif //__SX1276_FSK_MISC_H__

View File

@ -0,0 +1,162 @@
/*
* 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 May 6 2013
* \author Gregory Cristian
*
* Last modified by Miguel Luis on Jun 19 2013
*/
#ifndef __SX1276_HAL_H__
#define __SX1276_HAL_H__
//#include "ioe.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( ) rt_tick_get()//( TickCounter )
#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( rt_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( rt_uint8_t addr, rt_uint8_t data );
/*!
* \brief Reads the radio register at the specified address
*
* \param [IN]: addr Register address
* \param [OUT]: data Register value
*/
void SX1276Read( rt_uint8_t addr, rt_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( rt_uint8_t addr, rt_uint8_t *buffer, rt_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( rt_uint8_t addr, rt_uint8_t *buffer, rt_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( rt_uint8_t *buffer, rt_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( rt_uint8_t *buffer, rt_uint8_t size );
/*!
* \brief Gets the SX1276 DIO0 hardware pin status
*
* \retval status Current hardware pin status [1, 0]
*/
inline rt_uint8_t SX1276ReadDio0( void );
/*!
* \brief Gets the SX1276 DIO1 hardware pin status
*
* \retval status Current hardware pin status [1, 0]
*/
inline rt_uint8_t SX1276ReadDio1( void );
/*!
* \brief Gets the SX1276 DIO2 hardware pin status
*
* \retval status Current hardware pin status [1, 0]
*/
inline rt_uint8_t SX1276ReadDio2( void );
/*!
* \brief Gets the SX1276 DIO3 hardware pin status
*
* \retval status Current hardware pin status [1, 0]
*/
inline rt_uint8_t SX1276ReadDio3( void );
/*!
* \brief Gets the SX1276 DIO4 hardware pin status
*
* \retval status Current hardware pin status [1, 0]
*/
inline rt_uint8_t SX1276ReadDio4( void );
/*!
* \brief Gets the SX1276 DIO5 hardware pin status
*
* \retval status Current hardware pin status [1, 0]
*/
inline rt_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( rt_uint8_t txEnable );
#endif //__SX1276_HAL_H__

View File

@ -0,0 +1,797 @@
/*
* 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
typedef unsigned int uint32;
volatile uint32 TickCounter = 0;
uint32 Tx_Time_Start,Tx_Time_End;
uint32 Rx_Time_Start,Rx_Time_End;
//Signal bandwidth, used to calculate RSSI
const double SignalBwLog[] =
{
3.8927900303521316335038277369285, // 7.8 kHz
4.0177301567005500940384239336392, // 10.4 kHz
4.193820026016112828717566631653, // 15.6 kHz
4.31875866931372901183597627752391, // 20.8 kHz
4.4948500216800940239313055263775, // 31.2 kHz
4.6197891057238405255051280399961, // 41.6 kHz
4.795880017344075219145044421102, // 62.5 kHz
5.0969100130080564143587833158265, // 125 kHz
5.397940008672037609572522210551, // 250 kHz
5.6989700043360188047862611052755 // 500 kHz
};
//These values need testing
const double RssiOffsetLF[] =
{
-155.0,
-155.0,
-155.0,
-155.0,
-155.0,
-155.0,
-155.0,
-155.0,
-155.0,
-155.0,
};
//These values need testing
const double RssiOffsetHF[] =
{
-150.0,
-150.0,
-150.0,
-150.0,
-150.0,
-150.0,
-150.0,
-150.0,
-150.0,
-150.0,
};
/*!
* Frequency hopping frequencies table
*/
const int32_t HoppingFrequencies[] =
{
916500000,
923500000,
906500000,
917500000,
917500000,
909000000,
903000000,
916000000,
912500000,
926000000,
925000000,
909500000,
913000000,
918500000,
918500000,
902500000,
911500000,
926500000,
902500000,
922000000,
924000000,
903500000,
913000000,
922000000,
926000000,
910000000,
920000000,
922500000,
911000000,
922000000,
909500000,
926000000,
922000000,
918000000,
925500000,
908000000,
917500000,
926500000,
908500000,
916000000,
905500000,
916000000,
903000000,
905000000,
915000000,
913000000,
907000000,
910000000,
926500000,
925500000,
911000000,
};
// Default settings
tLoRaSettings LoRaSettings =
{
LoRa_FREQENCY , // RFFrequency
20, // Power
9, // SignalBw [0: 125 kHz, 1: 250 kHz, 2: 500 kHz, 3: Reserved]
12, // SpreadingFactor [6: 64, 7: 128, 8: 256, 9: 512, 10: 1024, 11: 2048, 12: 4096 chips]
2, // ErrorCoding [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8]
true, // CrcOn [0: OFF, 1: ON]
false, // ImplicitHeaderOn [0: OFF, 1: ON]
0, // RxSingleOn [0: Continuous, 1 Single]
0, // FreqHopOn [0: OFF, 1: ON]
4, // HopPeriod Hops every frequency hopping period symbols
1000, // TxPacketTimeout
1000, // RxPacketTimeout
128, // PayloadLength (used for implicit header mode)
};
/*!
* SX1276 LoRa registers variable
*/
tSX1276LR* SX1276LR;
/*!
* Local RF buffer for communication support
*/
static uint8_t RFBuffer[RF_BUFFER_SIZE];
static uint8_t TFBuffer[RF_BUFFER_SIZE];
/*!
* RF state machine variable
*/
static uint8_t RFLRState = RFLR_STATE_IDLE;
/*!
* Rx management support variables
*/
static uint16_t RxPacketSize = 0;
static int8_t RxPacketSnrEstimate;
static double RxPacketRssiValue;
static uint8_t RxGain = 1;
static uint32_t RxTimeoutTimer = 0;
/*!
* PacketTimeout Stores the Rx window time value for packet reception
*/
static uint32_t PacketTimeout;
/*!
* Tx management support variables
*/
static uint16_t TxPacketSize = 0;
void SX1276LoRaInit( void )
{
RFLRState = RFLR_STATE_IDLE;
SX1276LoRaSetDefaults();
SX1276ReadBuffer( REG_LR_OPMODE, SX1276Regs + 1, 0x70 - 1 );
//SX1276LoRaSetOpMode( RFLR_OPMODE_SLEEP );
SX1276LR->RegLna = RFLR_LNA_GAIN_G1;
SX1276WriteBuffer( REG_LR_OPMODE, SX1276Regs + 1, 0x70 - 1 );
// set the RF settings
SX1276LoRaSetRFFrequency( LoRaSettings.RFFrequency );
SX1276LoRaSetSpreadingFactor( LoRaSettings.SpreadingFactor );
SX1276LoRaSetErrorCoding( LoRaSettings.ErrorCoding );
SX1276LoRaSetPacketCrcOn( LoRaSettings.CrcOn );
SX1276LoRaSetSignalBandwidth( LoRaSettings.SignalBw );
SX1276LoRaSetImplicitHeaderOn( LoRaSettings.ImplicitHeaderOn );
SX1276LoRaSetSymbTimeout(0x3FF);
SX1276LoRaSetPayloadLength( LoRaSettings.PayloadLength );
SX1276LoRaSetLowDatarateOptimize( true );
#if( ( MODULE_SX1276RF1IAS == 1 ) || ( MODULE_SX1276RF1KAS == 1 ) )
if( LoRaSettings.RFFrequency > 860000000 )
{
SX1276LoRaSetPAOutput( RFLR_PACONFIG_PASELECT_RFO );
SX1276LoRaSetPa20dBm( false );
LoRaSettings.Power = 14;
SX1276LoRaSetRFPower( LoRaSettings.Power );
}
else
{
//SX1276Write( REG_LR_OCP, 0x3f );
SX1276LoRaSetPAOutput( RFLR_PACONFIG_PASELECT_PABOOST );
SX1276LoRaSetPa20dBm( true );
LoRaSettings.Power = 20;
SX1276LoRaSetRFPower( LoRaSettings.Power );
}
#elif( MODULE_SX1276RF1JAS == 1 )
if( LoRaSettings.RFFrequency > 380000000 )
{
SX1276LoRaSetPAOutput( RFLR_PACONFIG_PASELECT_PABOOST );
SX1276LoRaSetPa20dBm( true );
LoRaSettings.Power = 20;
SX1276LoRaSetRFPower( LoRaSettings.Power );
}
else
{
SX1276LoRaSetPAOutput( RFLR_PACONFIG_PASELECT_RFO );
SX1276LoRaSetPa20dBm( false );
LoRaSettings.Power = 14;
SX1276LoRaSetRFPower( LoRaSettings.Power );
}
#endif
SX1276LoRaSetOpMode( RFLR_OPMODE_STANDBY );
}
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 * )TFBuffer, buffer, ( size_t )TxPacketSize );
RFLRState = RFLR_STATE_TX_INIT;
}
uint8_t SX1276LoRaGetRFState( void )
{
return RFLRState;
}
void SX1276LoRaSetRFState( uint8_t state )
{
RFLRState = state;
}
/*!
* \brief Process the LoRa modem Rx and Tx state machines depending on the
* SX1276 operating mode.
*
* \retval rfState Current RF state [RF_IDLE, RF_BUSY,
* RF_RX_DONE, RF_RX_TIMEOUT,
* RF_TX_DONE, RF_TX_TIMEOUT]
*/
uint32_t SX1276LoRaProcess( void )
{
uint32_t result = RF_BUSY;
uint8_t regValue=0;
switch( RFLRState )
{
case RFLR_STATE_IDLE:
break;
case RFLR_STATE_RX_INIT:
SX1276LoRaSetOpMode(RFLR_OPMODE_STANDBY);
SX1276LR->RegIrqFlagsMask = RFLR_IRQFLAGS_RXTIMEOUT |
RFLR_IRQFLAGS_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,&regValue);
//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( TFBuffer, 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:
if( DIO0 == 1 ) // TxDone
{
// Clear Irq
SX1276Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_TXDONE );
RFLRState = RFLR_STATE_TX_DONE;
}
if( DIO2 == 1 ) // FHSS Changed Channel
{
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,&regValue);
int cad_done = regValue & (1<<2);
int cad_detected = regValue & (1<<0);
if( cad_done ) //CAD Done interrupt
{
SX1276Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_CADDONE );
if( cad_detected ) // CAD Detected interrupt
{
SX1276Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_CADDETECTED );
//CAD detected, we have a LoRa preamble
RFLRState = RFLR_STATE_RX_INIT;
result = RF_CHANNEL_ACTIVITY_DETECTED;
}
else
{
// The device goes in Standby Mode automatically
RFLRState = RFLR_STATE_IDLE;
result = RF_CHANNEL_EMPTY;
}
}
break;
default:
break;
}
return result;
}
uint32_t SX1276LoraChannelEmpty( void )
{
uint32_t result = 0;
RFLRState = RFLR_STATE_CAD_INIT;
SX1276LoRaProcess();
while(RFLRState == RFLR_STATE_CAD_RUNNING)
{
//KPrintf("\nLora--SX1276LoRaProcess()");
result = SX1276LoRaProcess();
}
if(result == RF_CHANNEL_EMPTY)
{
KPrintf("\nLora--信道可用RF_CHANNEL_EMPTY\n");
return 0;
}
else if(result == RF_CHANNEL_ACTIVITY_DETECTED)
{
KPrintf("\nLora--信道正被占用RF_CHANNEL_ACTIVITY_DETECTED\n");
return 1;
}
else
{
return 2;
}
}
#endif // USE_SX1276_RADIO

View File

@ -0,0 +1,922 @@
/*
* 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-LoRa.h
* \brief SX1276 RF chip driver mode LoRa
*
* \version 2.0.B2
* \date May 6 2013
* \author Gregory Cristian
*
* Last modified by Miguel Luis on Jun 19 2013
*/
#ifndef __SX1276_LORA_H__
#define __SX1276_LORA_H__
/*!
* SX1276 LoRa General parameters definition
*/
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; // [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 packet definition
*/
#define RF_BUFFER_SIZE_MAX 256
#define RF_BUFFER_SIZE 256
/*!
* RF state machine
*/
//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
/*!
* SX1276 Internal registers Address
*/
#define REG_LR_FIFO 0x00
// Common settings
#define REG_LR_OPMODE 0x01
#define REG_LR_BANDSETTING 0x04
#define REG_LR_FRFMSB 0x06
#define REG_LR_FRFMID 0x07
#define REG_LR_FRFLSB 0x08
// Tx settings
#define REG_LR_PACONFIG 0x09
#define REG_LR_PARAMP 0x0A
#define REG_LR_OCP 0x0B
// Rx settings
#define REG_LR_LNA 0x0C
// LoRa registers
#define REG_LR_FIFOADDRPTR 0x0D
#define REG_LR_FIFOTXBASEADDR 0x0E
#define REG_LR_FIFORXBASEADDR 0x0F
#define REG_LR_FIFORXCURRENTADDR 0x10
#define REG_LR_IRQFLAGSMASK 0x11
#define REG_LR_IRQFLAGS 0x12
#define REG_LR_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
#define REG_LR_FEIMSB 0x28
#define REG_LR_FEIMIB 0x29
#define REG_LR_FEILSB 0x2A
#define REG_LR_LORADETECTOPTIMIZE 0x31
#define REG_LR_INVERTIQ 0x33
#define REG_LR_DETECTIONTHRESHOLD 0x37
// end of documented register in datasheet
// I/O settings
#define REG_LR_DIOMAPPING1 0x40
#define REG_LR_DIOMAPPING2 0x41
// Version
#define REG_LR_VERSION 0x42
// Additional settings
#define REG_LR_PLLHOP 0x44
#define REG_LR_TCXO 0x4B
#define REG_LR_PADAC 0x4D
#define REG_LR_FORMERTEMP 0x5B
#define REG_LR_BITRATEFRAC 0x5D
#define REG_LR_AGCREF 0x61
#define REG_LR_AGCTHRESH1 0x62
#define REG_LR_AGCTHRESH2 0x63
#define REG_LR_AGCTHRESH3 0x64
/*!
* SX1276 LoRa bit control definition
*/
/*!
* RegFifo
*/
/*!
* RegOpMode
*/
#define RFLR_OPMODE_LONGRANGEMODE_MASK 0x7F
#define RFLR_OPMODE_LONGRANGEMODE_OFF 0x00 // Default
#define RFLR_OPMODE_LONGRANGEMODE_ON 0x80
#define RFLR_OPMODE_ACCESSSHAREDREG_MASK 0xBF
#define RFLR_OPMODE_ACCESSSHAREDREG_ENABLE 0x40
#define RFLR_OPMODE_ACCESSSHAREDREG_DISABLE 0x00 // Default
#define RFLR_OPMODE_FREQMODE_ACCESS_MASK 0xF7
#define RFLR_OPMODE_FREQMODE_ACCESS_LF 0x08 // Default
#define RFLR_OPMODE_FREQMODE_ACCESS_HF 0x00
#define RFLR_OPMODE_MASK 0xF8
#define RFLR_OPMODE_SLEEP 0x00
#define RFLR_OPMODE_STANDBY 0x01 // Default
#define RFLR_OPMODE_SYNTHESIZER_TX 0x02
#define RFLR_OPMODE_TRANSMITTER 0x03
#define RFLR_OPMODE_SYNTHESIZER_RX 0x04
#define RFLR_OPMODE_RECEIVER 0x05
// LoRa specific modes
#define RFLR_OPMODE_RECEIVER_SINGLE 0x06
#define RFLR_OPMODE_CAD 0x07
/*!
* RegBandSetting
*/
#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)
*/
#define RFLR_FRFMSB_434_MHZ 0x6C // Default
#define RFLR_FRFMID_434_MHZ 0x80 // Default
#define RFLR_FRFLSB_434_MHZ 0x00 // 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
/*!
* RegPaConfig
*/
#define RFLR_PACONFIG_PASELECT_MASK 0x7F
#define RFLR_PACONFIG_PASELECT_PABOOST 0x80
#define RFLR_PACONFIG_PASELECT_RFO 0x00 // Default
#define RFLR_PACONFIG_MAX_POWER_MASK 0x8F
#define RFLR_PACONFIG_OUTPUTPOWER_MASK 0xF0
/*!
* RegPaRamp
*/
#define RFLR_PARAMP_TXBANDFORCE_MASK 0xEF
#define RFLR_PARAMP_TXBANDFORCE_BAND_SEL 0x10
#define RFLR_PARAMP_TXBANDFORCE_AUTO 0x00 // Default
#define RFLR_PARAMP_MASK 0xF0
#define RFLR_PARAMP_3400_US 0x00
#define RFLR_PARAMP_2000_US 0x01
#define RFLR_PARAMP_1000_US 0x02
#define RFLR_PARAMP_0500_US 0x03
#define RFLR_PARAMP_0250_US 0x04
#define RFLR_PARAMP_0125_US 0x05
#define RFLR_PARAMP_0100_US 0x06
#define RFLR_PARAMP_0062_US 0x07
#define RFLR_PARAMP_0050_US 0x08
#define RFLR_PARAMP_0040_US 0x09 // Default
#define RFLR_PARAMP_0031_US 0x0A
#define RFLR_PARAMP_0025_US 0x0B
#define RFLR_PARAMP_0020_US 0x0C
#define RFLR_PARAMP_0015_US 0x0D
#define RFLR_PARAMP_0012_US 0x0E
#define RFLR_PARAMP_0010_US 0x0F
/*!
* RegOcp
*/
#define RFLR_OCP_MASK 0xDF
#define RFLR_OCP_ON 0x20 // Default
#define RFLR_OCP_OFF 0x00
#define RFLR_OCP_TRIM_MASK 0xE0
#define RFLR_OCP_TRIM_045_MA 0x00
#define RFLR_OCP_TRIM_050_MA 0x01
#define RFLR_OCP_TRIM_055_MA 0x02
#define RFLR_OCP_TRIM_060_MA 0x03
#define RFLR_OCP_TRIM_065_MA 0x04
#define RFLR_OCP_TRIM_070_MA 0x05
#define RFLR_OCP_TRIM_075_MA 0x06
#define RFLR_OCP_TRIM_080_MA 0x07
#define RFLR_OCP_TRIM_085_MA 0x08
#define RFLR_OCP_TRIM_090_MA 0x09
#define RFLR_OCP_TRIM_095_MA 0x0A
#define RFLR_OCP_TRIM_100_MA 0x0B // Default
#define RFLR_OCP_TRIM_105_MA 0x0C
#define RFLR_OCP_TRIM_110_MA 0x0D
#define RFLR_OCP_TRIM_115_MA 0x0E
#define RFLR_OCP_TRIM_120_MA 0x0F
#define RFLR_OCP_TRIM_130_MA 0x10
#define RFLR_OCP_TRIM_140_MA 0x11
#define RFLR_OCP_TRIM_150_MA 0x12
#define RFLR_OCP_TRIM_160_MA 0x13
#define RFLR_OCP_TRIM_170_MA 0x14
#define RFLR_OCP_TRIM_180_MA 0x15
#define RFLR_OCP_TRIM_190_MA 0x16
#define RFLR_OCP_TRIM_200_MA 0x17
#define RFLR_OCP_TRIM_210_MA 0x18
#define RFLR_OCP_TRIM_220_MA 0x19
#define RFLR_OCP_TRIM_230_MA 0x1A
#define RFLR_OCP_TRIM_240_MA 0x1B
/*!
* RegLna
*/
#define RFLR_LNA_GAIN_MASK 0x1F
#define RFLR_LNA_GAIN_G1 0x20 // Default
#define RFLR_LNA_GAIN_G2 0x40
#define RFLR_LNA_GAIN_G3 0x60
#define RFLR_LNA_GAIN_G4 0x80
#define RFLR_LNA_GAIN_G5 0xA0
#define RFLR_LNA_GAIN_G6 0xC0
#define RFLR_LNA_BOOST_LF_MASK 0xE7
#define RFLR_LNA_BOOST_LF_DEFAULT 0x00 // Default
#define RFLR_LNA_BOOST_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
/*!
* RegFifoAddrPtr
*/
#define RFLR_FIFOADDRPTR 0x00 // Default
/*!
* RegFifoTxBaseAddr
*/
#define RFLR_FIFOTXBASEADDR 0x80 // Default
/*!
* RegFifoTxBaseAddr
*/
#define RFLR_FIFORXBASEADDR 0x00 // Default
/*!
* RegFifoRxCurrentAddr (Read Only)
*/
/*!
* RegIrqFlagsMask
*/
#define RFLR_IRQFLAGS_RXTIMEOUT_MASK 0x80
#define RFLR_IRQFLAGS_RXDONE_MASK 0x40
#define RFLR_IRQFLAGS_PAYLOADCRCERROR_MASK 0x20
#define RFLR_IRQFLAGS_VALIDHEADER_MASK 0x10
#define RFLR_IRQFLAGS_TXDONE_MASK 0x08
#define RFLR_IRQFLAGS_CADDONE_MASK 0x04
#define RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL_MASK 0x02
#define RFLR_IRQFLAGS_CADDETECTED_MASK 0x01
/*!
* RegIrqFlags
*/
#define RFLR_IRQFLAGS_RXTIMEOUT 0x80
#define RFLR_IRQFLAGS_RXDONE 0x40
#define RFLR_IRQFLAGS_PAYLOADCRCERROR 0x20
#define RFLR_IRQFLAGS_VALIDHEADER 0x10
#define RFLR_IRQFLAGS_TXDONE 0x08
#define RFLR_IRQFLAGS_CADDONE 0x04
#define RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL 0x02
#define RFLR_IRQFLAGS_CADDETECTED 0x01
/*!
* RegFifoRxNbBytes (Read Only) //
*/
/*!
* RegRxHeaderCntValueMsb (Read Only) //
*/
/*!
* RegRxHeaderCntValueLsb (Read Only) //
*/
/*!
* RegRxPacketCntValueMsb (Read Only) //
*/
/*!
* RegRxPacketCntValueLsb (Read Only) //
*/
/*!
* RegModemStat (Read Only) //
*/
#define RFLR_MODEMSTAT_RX_CR_MASK 0x1F
#define RFLR_MODEMSTAT_MODEM_STATUS_MASK 0xE0
/*!
* RegPktSnrValue (Read Only) //
*/
/*!
* RegPktRssiValue (Read Only) //
*/
/*!
* RegRssiValue (Read Only) //
*/
/*!
* RegHopChannel (Read Only) //
*/
#define RFLR_HOP_CHANNEL_PAYLOAD_CRC_ON_MASK 0xBF
#define RFLR_HOP_CHANNEL_PAYLOAD_CRC_ON 0x40
#define RFLR_HOP_CHANNEL_PAYLOAD_CRC_OFF 0x00
/*!
* RegModemConfig1
*/
#define RFLR_MODEMCONFIG1_BW_MASK 0x0F
#define RFLR_MODEMCONFIG1_BW_7_81_KHZ 0x00
#define RFLR_MODEMCONFIG1_BW_10_41_KHZ 0x10
#define RFLR_MODEMCONFIG1_BW_15_62_KHZ 0x20
#define RFLR_MODEMCONFIG1_BW_20_83_KHZ 0x30
#define RFLR_MODEMCONFIG1_BW_31_25_KHZ 0x40
#define RFLR_MODEMCONFIG1_BW_41_66_KHZ 0x50
#define RFLR_MODEMCONFIG1_BW_62_50_KHZ 0x60
#define RFLR_MODEMCONFIG1_BW_125_KHZ 0x70 // Default
#define RFLR_MODEMCONFIG1_BW_250_KHZ 0x80
#define RFLR_MODEMCONFIG1_BW_500_KHZ 0x90
#define RFLR_MODEMCONFIG1_CODINGRATE_MASK 0xF1
#define RFLR_MODEMCONFIG1_CODINGRATE_4_5 0x02
#define RFLR_MODEMCONFIG1_CODINGRATE_4_6 0x04 // Default
#define RFLR_MODEMCONFIG1_CODINGRATE_4_7 0x06
#define RFLR_MODEMCONFIG1_CODINGRATE_4_8 0x08
#define RFLR_MODEMCONFIG1_IMPLICITHEADER_MASK 0xFE
#define RFLR_MODEMCONFIG1_IMPLICITHEADER_ON 0x01
#define RFLR_MODEMCONFIG1_IMPLICITHEADER_OFF 0x00 // Default
/*!
* RegModemConfig2
*/
#define RFLR_MODEMCONFIG2_SF_MASK 0x0F
#define RFLR_MODEMCONFIG2_SF_6 0x60
#define RFLR_MODEMCONFIG2_SF_7 0x70 // Default
#define RFLR_MODEMCONFIG2_SF_8 0x80
#define RFLR_MODEMCONFIG2_SF_9 0x90
#define RFLR_MODEMCONFIG2_SF_10 0xA0
#define RFLR_MODEMCONFIG2_SF_11 0xB0
#define RFLR_MODEMCONFIG2_SF_12 0xC0
#define RFLR_MODEMCONFIG2_TXCONTINUOUSMODE_MASK 0xF7
#define RFLR_MODEMCONFIG2_TXCONTINUOUSMODE_ON 0x08
#define RFLR_MODEMCONFIG2_TXCONTINUOUSMODE_OFF 0x00
#define RFLR_MODEMCONFIG2_RXPAYLOADCRC_MASK 0xFB
#define RFLR_MODEMCONFIG2_RXPAYLOADCRC_ON 0x04
#define RFLR_MODEMCONFIG2_RXPAYLOADCRC_OFF 0x00 // Default
#define RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB_MASK 0xFC
#define RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB 0x00 // Default
/*!
* 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; // 0x27
uint8_t RegFeiMsb; // 0x28
uint8_t RegFeiMib; // 0x29
uint8_t RegFeiLsb; // 0x2A
uint8_t RegTestReserved2B[0x30 - 0x2B]; // 0x2B-0x30
uint8_t RegDetectOptimize; // 0x31
uint8_t RegTestReserved32; // 0x32
uint8_t RegInvertIQ; // 0x33
uint8_t RegTestReserved34[0x36 - 0x34]; // 0x34-0x36
uint8_t RegDetectionThreshold; // 0x37
uint8_t RegTestReserved38[0x3F - 0x38]; // 0x38-0x3F
// I/O settings
uint8_t RegDioMapping1; // 0x40
uint8_t RegDioMapping2; // 0x41
// Version
uint8_t RegVersion; // 0x42
// Test
uint8_t RegTestReserved43; // 0x43
// Additional settings
uint8_t RegPllHop; // 0x44
// Test
uint8_t RegTestReserved45[0x4A - 0x45]; // 0x45-0x4A
// Additional settings
uint8_t RegTcxo; // 0x4B
// Test
uint8_t RegTestReserved4C; // 0x4C
// Additional settings
uint8_t RegPaDac; // 0x4D
// Test
uint8_t RegTestReserved4E[0x5A - 0x4E]; // 0x4E-0x5A
// Additional settings
uint8_t RegFormerTemp; // 0x5B
// Test
uint8_t RegTestReserved5C; // 0x5C
// Additional settings
uint8_t RegBitrateFrac; // 0x5D
// Additional settings
uint8_t RegTestReserved5E[0x60 - 0x5E]; // 0x5E-0x60
// Additional settings
uint8_t RegAgcRef; // 0x60
uint8_t RegAgcThresh1; // 0x61
uint8_t RegAgcThresh2; // 0x62
uint8_t RegAgcThresh3; // 0x63
// Test
uint8_t RegTestReserved64[0x70 - 0x64]; // 0x64-0x70
}tSX1276LR;
extern tSX1276LR* SX1276LR;
/*!
* \brief Initializes the SX1276
*/
void SX1276LoRaInit( void );
/*!
* \brief Sets the SX1276 to datasheet default values
*/
void SX1276LoRaSetDefaults( void );
/*!
* \brief Enables/Disables the LoRa modem
*
* \param [IN]: enable [true, false]
*/
void SX1276LoRaSetLoRaOn( bool enable );
/*!
* \brief Sets the SX1276 operating mode
*
* \param [IN] opMode New operating mode
*/
void SX1276LoRaSetOpMode( uint8_t opMode );
/*!
* \brief Gets the SX1276 operating mode
*
* \retval opMode Current operating mode
*/
uint8_t SX1276LoRaGetOpMode( void );
/*!
* \brief Reads the current Rx gain setting
*
* \retval rxGain Current gain setting
*/
uint8_t SX1276LoRaReadRxGain( void );
/*!
* \brief Trigs and reads the current RSSI value
*
* \retval rssiValue Current RSSI value in [dBm]
*/
double SX1276LoRaReadRssi( void );
/*!
* \brief Gets the Rx gain value measured while receiving the packet
*
* \retval rxGainValue Current Rx gain value
*/
uint8_t SX1276LoRaGetPacketRxGain( void );
/*!
* \brief Gets the SNR value measured while receiving the packet
*
* \retval snrValue Current SNR value in [dB]
*/
int8_t SX1276LoRaGetPacketSnr( void );
/*!
* \brief Gets the RSSI value measured while receiving the packet
*
* \retval rssiValue Current RSSI value in [dBm]
*/
double SX1276LoRaGetPacketRssi( void );
/*!
* \brief Sets the radio in Rx mode. Waiting for a packet
*/
void SX1276LoRaStartRx( void );
/*!
* \brief Gets a copy of the current received buffer
*
* \param [IN]: buffer Buffer pointer
* \param [IN]: size Buffer size
*/
void SX1276LoRaGetRxPacket( void *buffer, uint16_t *size );
/*!
* \brief Sets a copy of the buffer to be transmitted
*
* \param [IN]: buffer Buffer pointer
* \param [IN]: size Buffer size
*/
void SX1276LoRaSetTxPacket( const void *buffer, uint16_t size );
/*!
* \brief Gets the current RFState
*
* \retval rfState Current RF state [RF_IDLE, RF_BUSY,
* RF_RX_DONE, RF_RX_TIMEOUT,
* RF_TX_DONE, RF_TX_TIMEOUT]
*/
uint8_t SX1276LoRaGetRFState( void );
/*!
* \brief Sets the new state of the RF state machine
*
* \param [IN]: state New RF state machine state
*/
void SX1276LoRaSetRFState( uint8_t 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 );
#endif //__SX1276_LORA_H__

View File

@ -0,0 +1,411 @@
/*
* 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
*/
#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->RegDetectOptimize );
SX1276LR->RegDetectOptimize = ( SX1276LR->RegDetectOptimize & 0xF8 ) | value;
SX1276Write( 0x31, SX1276LR->RegDetectOptimize );
}
uint8_t SX1276LoRaGetNbTrigPeaks( void )
{
SX1276Read( 0x31, &SX1276LR->RegDetectOptimize );
return ( SX1276LR->RegDetectOptimize & 0x07 );
}
#endif // USE_SX1276_RADIO

View File

@ -0,0 +1,315 @@
/*
* 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.B2
* \date May 6 2013
* \author Gregory Cristian
*
* Last modified by Miguel Luis on Jun 19 2013
*/
#ifndef __SX1276_LORA_MISC_H__
#define __SX1276_LORA_MISC_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 //__SX1276_LORA_MISC_H__

View File

@ -0,0 +1,304 @@
/*
* 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
*/
#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"
/*!
* SX1276 registers variable
*/
uint8_t SX1276Regs[0x70];
static bool LoRaOn = true;
static bool LoRaOnState = false;
void SX1276Init( void )
{
// Initialize FSK and LoRa registers structure
SX1276 = ( tSX1276* )SX1276Regs;
SX1276LR = ( tSX1276LR* )SX1276Regs;
SX1276InitIo( );
SX1276Reset( );
// REMARK: After radio reset the default modem is FSK
#if ( LORA == 0 )
LoRaOn = false;
SX1276SetLoRaOn( LoRaOn );
// Initialize FSK modem
SX1276FskInit( );
#else
LoRaOn = true;
SX1276SetLoRaOn( LoRaOn );
// Initialize LoRa modem
SX1276LoRaInit( );
#endif
}
void SX1276Reset( void )
{
SX1276SetReset( RADIO_RESET_ON );
// Wait 1ms
uint32_t 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 SX1276SetLoRaOn( 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 SX1276GetLoRaOn( void )
{
return LoRaOn;
}
void SX1276SetOpMode( uint8_t opMode )
{
if( LoRaOn == false )
{
SX1276FskSetOpMode( opMode );
}
else
{
SX1276LoRaSetOpMode( opMode );
}
}
uint8_t SX1276GetOpMode( void )
{
if( LoRaOn == false )
{
return SX1276FskGetOpMode( );
}
else
{
return SX1276LoRaGetOpMode( );
}
}
double SX1276ReadRssi( void )
{
if( LoRaOn == false )
{
return SX1276FskReadRssi( );
}
else
{
return SX1276LoRaReadRssi( );
}
}
uint8_t SX1276ReadRxGain( void )
{
if( LoRaOn == false )
{
return SX1276FskReadRxGain( );
}
else
{
return SX1276LoRaReadRxGain( );
}
}
uint8_t SX1276GetPacketRxGain( void )
{
if( LoRaOn == false )
{
return SX1276FskGetPacketRxGain( );
}
else
{
return SX1276LoRaGetPacketRxGain( );
}
}
int8_t SX1276GetPacketSnr( void )
{
if( LoRaOn == false )
{
while( 1 )
{
// Useless in FSK mode
// Block program here
}
}
else
{
return SX1276LoRaGetPacketSnr( );
}
}
double SX1276GetPacketRssi( 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( );
}
}
#endif // USE_SX1276_RADIO

Some files were not shown because too many files have changed in this diff Show More