diff --git a/APP_Framework/Applications/Kconfig b/APP_Framework/Applications/Kconfig index eb11622e7..1545222da 100644 --- a/APP_Framework/Applications/Kconfig +++ b/APP_Framework/Applications/Kconfig @@ -20,4 +20,5 @@ menu "Applications" source "$APP_DIR/Applications/sensor_app/Kconfig" source "$APP_DIR/Applications/embedded_database_app/Kconfig" source "$APP_DIR/Applications/webnet/Kconfig" + source "$APP_DIR/Applications/mongoose/Kconfig" endmenu diff --git a/APP_Framework/Applications/Makefile b/APP_Framework/Applications/Makefile index 334845b8a..ab9e2f59a 100644 --- a/APP_Framework/Applications/Makefile +++ b/APP_Framework/Applications/Makefile @@ -39,6 +39,10 @@ ifeq ($(CONFIG_ADD_XIZI_FEATURES),y) ifeq ($(CONFIG_APP_USING_WEBNET),y) SRC_DIR += webnet endif + + ifeq ($(CONFIG_USE_MONGOOSE),y) + SRC_DIR += mongoose + endif include $(KERNEL_ROOT)/compiler.mk endif \ No newline at end of file diff --git a/APP_Framework/Applications/app_test/test_socket.c b/APP_Framework/Applications/app_test/test_socket.c index 2d4d10be9..d717ba251 100644 --- a/APP_Framework/Applications/app_test/test_socket.c +++ b/APP_Framework/Applications/app_test/test_socket.c @@ -76,10 +76,12 @@ struct IperfParam { static void* TestIperfServer(void* param) { struct IperfParam* iperf_param = (struct IperfParam*)param; - int sock = socket(AF_INET, SOCK_STREAM, 0); + int sock = socket(AF_INET, SOCK_STREAM, 6); if (sock < 0) { printf("[%s] Err: Can't create socker.\n", __func__); return NULL; + } else { + printf("[%s] Info Create server socket %d\n", __func__, sock); } uint8_t* recv_data = (uint8_t*)malloc(IPERF_BUFSZ); @@ -121,8 +123,9 @@ static void* TestIperfServer(void* param) socklen_t sin_size = sizeof(struct sockaddr_in); struct sockaddr_in client_addr; int connection = accept(sock, (struct sockaddr*)&client_addr, &sin_size); - printf("[%s] Info: New client connected from (%s, %d)\n", __func__, - inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port)); + printf("[%s] Info: New client connected from (%s, %d), connect: %d\n", __func__, + inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port), + connection); int flag = 1; setsockopt(connection, @@ -141,8 +144,8 @@ static void* TestIperfServer(void* param) inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port)); break; } else if (bytes_received < 0) { - KPrintf("recv error, client: (%s, %d)\n", - inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port)); + KPrintf("recv error: %d, client: (%s, %d)\n", + bytes_received, inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port)); break; } @@ -258,8 +261,6 @@ enum IperfParamEnum { void TestSocket(int argc, char* argv[]) { - lwip_config_tcp(0, lwip_ipaddr, lwip_netmask, lwip_gwaddr); - static char usage_info[] = "Run either a iperf server or iperf client."; static char program_info[] = "Lwip socket test task, a simple iperf."; static const char* const usages[] = { diff --git a/APP_Framework/Applications/mongoose/Kconfig b/APP_Framework/Applications/mongoose/Kconfig new file mode 100644 index 000000000..90a6f2fbb --- /dev/null +++ b/APP_Framework/Applications/mongoose/Kconfig @@ -0,0 +1,3 @@ +menuconfig USE_MONGOOSE + bool "Use mongoose as webserver" + default n \ No newline at end of file diff --git a/APP_Framework/Applications/mongoose/Makefile b/APP_Framework/Applications/mongoose/Makefile new file mode 100644 index 000000000..40f525b5e --- /dev/null +++ b/APP_Framework/Applications/mongoose/Makefile @@ -0,0 +1,3 @@ +SRC_FILES += project.c + +include $(KERNEL_ROOT)/compiler.mk \ No newline at end of file diff --git a/APP_Framework/Applications/mongoose/lib/Makefile b/APP_Framework/Applications/mongoose/lib/Makefile new file mode 100644 index 000000000..0824ed779 --- /dev/null +++ b/APP_Framework/Applications/mongoose/lib/Makefile @@ -0,0 +1,3 @@ +SRC_FILES += mongoose.c + +include $(KERNEL_ROOT)/compiler.mk \ No newline at end of file diff --git a/APP_Framework/Applications/mongoose/mongoose.a b/APP_Framework/Applications/mongoose/mongoose.a new file mode 100644 index 000000000..fd5000247 Binary files /dev/null and b/APP_Framework/Applications/mongoose/mongoose.a differ diff --git a/APP_Framework/Applications/mongoose/mongoose.h b/APP_Framework/Applications/mongoose/mongoose.h new file mode 100644 index 000000000..eaaf9c2a5 --- /dev/null +++ b/APP_Framework/Applications/mongoose/mongoose.h @@ -0,0 +1,1757 @@ +// Copyright (c) 2004-2013 Sergey Lyubka +// Copyright (c) 2013-2022 Cesanta Software Limited +// All rights reserved +// +// This software is dual-licensed: you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2 as +// published by the Free Software Foundation. For the terms of this +// license, see http://www.gnu.org/licenses/ +// +// You are free to use this software under the terms of the GNU General +// Public License, but WITHOUT ANY WARRANTY; without even the implied +// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// Alternatively, you can license this software under a commercial +// license, as set out in https://www.mongoose.ws/licensing/ +// +// SPDX-License-Identifier: GPL-2.0-only or commercial + +#ifndef MONGOOSE_H +#define MONGOOSE_H + +#define MG_VERSION "7.11" + +#ifdef __cplusplus +extern "C" { +#endif + +#define MG_ARCH MG_ARCH_RTTHREAD +#define MG_ENABLE_LWIP 1 +#define MG_ENABLE_DIRLIST 1 +#define MG_ENABLE_FATFS 1 +#define MG_ENABLE_SSI 1 +// #define MG_ENABLE_PACKED_FS 1 + +#define MG_ARCH_CUSTOM 0 // User creates its own mongoose_custom.h +#define MG_ARCH_UNIX 1 // Linux, BSD, Mac, ... +#define MG_ARCH_WIN32 2 // Windows +#define MG_ARCH_ESP32 3 // ESP32 +#define MG_ARCH_ESP8266 4 // ESP8266 +#define MG_ARCH_FREERTOS 5 // FreeRTOS +#define MG_ARCH_AZURERTOS 6 // MS Azure RTOS +#define MG_ARCH_ZEPHYR 7 // Zephyr RTOS +#define MG_ARCH_NEWLIB 8 // Bare metal ARM +#define MG_ARCH_CMSIS_RTOS1 9 // CMSIS-RTOS API v1 (Keil RTX) +#define MG_ARCH_TIRTOS 10 // Texas Semi TI-RTOS +#define MG_ARCH_RP2040 11 // Raspberry Pi RP2040 +#define MG_ARCH_ARMCC 12 // Keil MDK-Core with Configuration Wizard +#define MG_ARCH_CMSIS_RTOS2 13 // CMSIS-RTOS API v2 (Keil RTX5, FreeRTOS) +#define MG_ARCH_RTTHREAD 14 // RT-Thread RTOS + +#if !defined(MG_ARCH) +#if defined(__unix__) || defined(__APPLE__) +#define MG_ARCH MG_ARCH_UNIX +#elif defined(_WIN32) +#define MG_ARCH MG_ARCH_WIN32 +#elif defined(ICACHE_FLASH) || defined(ICACHE_RAM_ATTR) +#define MG_ARCH MG_ARCH_ESP8266 +#elif defined(__ZEPHYR__) +#define MG_ARCH MG_ARCH_ZEPHYR +#elif defined(ESP_PLATFORM) +#define MG_ARCH MG_ARCH_ESP32 +#elif defined(FREERTOS_IP_H) +#define MG_ARCH MG_ARCH_FREERTOS +#define MG_ENABLE_FREERTOS_TCP 1 +#elif defined(AZURE_RTOS_THREADX) +#define MG_ARCH MG_ARCH_AZURERTOS +#elif defined(PICO_TARGET_NAME) +#define MG_ARCH MG_ARCH_RP2040 +#elif defined(__ARMCC_VERSION) +#define MG_ARCH MG_ARCH_ARMCC +#elif defined(__RTTHREAD__) +#define MG_ARCH MG_ARCH_RTTHREAD +#endif +#endif // !defined(MG_ARCH) + +// if the user did not specify an MG_ARCH, or specified a custom one, OR +// we guessed a known IDE, pull the customized config (Configuration Wizard) +#if !defined(MG_ARCH) || (MG_ARCH == MG_ARCH_CUSTOM) || MG_ARCH == MG_ARCH_ARMCC +#include "mongoose_custom.h" // keep this include +#endif + +#if !defined(MG_ARCH) +#error "MG_ARCH is not specified and we couldn't guess it. Set -D MG_ARCH=..." +#endif + +// http://esr.ibiblio.org/?p=5095 +#define MG_BIG_ENDIAN (*(uint16_t*)"\0\xff" < 0x100) + +#if MG_ARCH == MG_ARCH_AZURERTOS + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#define PATH_MAX FX_MAXIMUM_PATH +#define MG_DIRSEP '\\' + +#define socklen_t int +#define closesocket(x) soc_close(x) + +#undef FOPEN_MAX + +#endif + +#if MG_ARCH == MG_ARCH_ESP32 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define MG_PATH_MAX 128 + +#endif + +#if MG_ARCH == MG_ARCH_ESP8266 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define MG_PATH_MAX 128 + +#endif + +#if MG_ARCH == MG_ARCH_FREERTOS + +#include +#if !defined(MG_ENABLE_LWIP) || !MG_ENABLE_LWIP +#include +#endif +#include +#include +#include +#include +#include +#include // rand(), strtol(), atoi() +#include +#if defined(__ARMCC_VERSION) +#define mode_t size_t +#include +#else +#include +#endif + +#include +#include + +#ifndef MG_IO_SIZE +#define MG_IO_SIZE 512 +#endif + +#define calloc(a, b) mg_calloc(a, b) +#define free(a) vPortFree(a) +#define malloc(a) pvPortMalloc(a) +#define strdup(s) ((char*)mg_strdup(mg_str(s)).ptr) + +// Re-route calloc/free to the FreeRTOS's functions, don't use stdlib +static inline void* mg_calloc(size_t cnt, size_t size) +{ + void* p = pvPortMalloc(cnt * size); + if (p != NULL) + memset(p, 0, size * cnt); + return p; +} + +#define mkdir(a, b) mg_mkdir(a, b) +static inline int mg_mkdir(const char* path, mode_t mode) +{ + (void)path, (void)mode; + return -1; +} + +#endif // MG_ARCH == MG_ARCH_FREERTOS + +#if MG_ARCH == MG_ARCH_NEWLIB +#define _POSIX_TIMERS + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MG_PATH_MAX 100 +#define MG_ENABLE_SOCKET 0 +#define MG_ENABLE_DIRLIST 0 + +#endif + +#if MG_ARCH == MG_ARCH_RP2040 +#include +#include +#include +#include +#include +#include +#include +#include + +#include +int mkdir(const char*, mode_t); +#endif + +#if MG_ARCH == MG_ARCH_RTTHREAD + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef MG_IO_SIZE +#define MG_IO_SIZE 1460 +#endif + +#endif // MG_ARCH == MG_ARCH_RTTHREAD + +#if MG_ARCH == MG_ARCH_ARMCC || MG_ARCH == MG_ARCH_CMSIS_RTOS1 || MG_ARCH == MG_ARCH_CMSIS_RTOS2 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if MG_ARCH == MG_ARCH_CMSIS_RTOS1 +#include "cmsis_os.h" // keep this include +// https://developer.arm.com/documentation/ka003821/latest +extern uint32_t rt_time_get(void); +#elif MG_ARCH == MG_ARCH_CMSIS_RTOS2 +#include "cmsis_os2.h" // keep this include +#endif + +#define strdup(s) ((char*)mg_strdup(mg_str(s)).ptr) + +#if defined(__ARMCC_VERSION) +#define mode_t size_t +#define mkdir(a, b) mg_mkdir(a, b) +static inline int mg_mkdir(const char* path, mode_t mode) +{ + (void)path, (void)mode; + return -1; +} +#endif + +#if (MG_ARCH == MG_ARCH_CMSIS_RTOS1 || MG_ARCH == MG_ARCH_CMSIS_RTOS2) && !defined MG_ENABLE_RL && (!defined(MG_ENABLE_LWIP) || !MG_ENABLE_LWIP) && (!defined(MG_ENABLE_TCPIP) || !MG_ENABLE_TCPIP) +#define MG_ENABLE_RL 1 +#endif + +#endif + +#if MG_ARCH == MG_ARCH_TIRTOS + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#endif + +#if MG_ARCH == MG_ARCH_UNIX + +#define _DARWIN_UNLIMITED_SELECT 1 // No limit on file descriptors + +#if defined(__APPLE__) +#include +#endif + +#if !defined(MG_ENABLE_EPOLL) && defined(__linux__) +#define MG_ENABLE_EPOLL 1 +#elif !defined(MG_ENABLE_POLL) +#define MG_ENABLE_POLL 1 +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(MG_ENABLE_EPOLL) && MG_ENABLE_EPOLL +#include +#elif defined(MG_ENABLE_POLL) && MG_ENABLE_POLL +#include +#else +#include +#endif + +#include +#include +#include +#include +#include +#include + +#ifndef MG_ENABLE_DIRLIST +#define MG_ENABLE_DIRLIST 1 +#endif + +#ifndef MG_PATH_MAX +#define MG_PATH_MAX FILENAME_MAX +#endif + +#endif + +#if MG_ARCH == MG_ARCH_WIN32 + +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif + +#ifndef _CRT_SECURE_NO_WARNINGS +#define _CRT_SECURE_NO_WARNINGS +#endif + +#ifndef _WINSOCK_DEPRECATED_NO_WARNINGS +#define _WINSOCK_DEPRECATED_NO_WARNINGS +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(_MSC_VER) && _MSC_VER < 1700 +#define __func__ "" +typedef __int64 int64_t; +typedef unsigned __int64 uint64_t; +typedef unsigned char uint8_t; +typedef char int8_t; +typedef unsigned short uint16_t; +typedef short int16_t; +typedef unsigned int uint32_t; +typedef int int32_t; +typedef enum { false = 0, + true = 1 } bool; +#else +#include +#include +#include +#endif + +#include +#include +#include + +// Protect from calls like std::snprintf in app code +// See https://github.com/cesanta/mongoose/issues/1047 +#ifndef __cplusplus +#define snprintf _snprintf +#define vsnprintf _vsnprintf +#ifndef strdup // For MSVC with _DEBUG, see #1359 +#define strdup(x) _strdup(x) +#endif +#endif + +#define MG_INVALID_SOCKET INVALID_SOCKET +#define MG_SOCKET_TYPE SOCKET +typedef unsigned long nfds_t; +#if defined(_MSC_VER) +#pragma comment(lib, "ws2_32.lib") +#ifndef alloca +#define alloca(a) _alloca(a) +#endif +#endif +#define poll(a, b, c) WSAPoll((a), (b), (c)) +#define closesocket(x) closesocket(x) + +typedef int socklen_t; +#define MG_DIRSEP '\\' + +#ifndef MG_PATH_MAX +#define MG_PATH_MAX FILENAME_MAX +#endif + +#ifndef SO_EXCLUSIVEADDRUSE +#define SO_EXCLUSIVEADDRUSE ((int)(~SO_REUSEADDR)) +#endif + +#define MG_SOCK_ERR(errcode) ((errcode) < 0 ? WSAGetLastError() : 0) + +#define MG_SOCK_PENDING(errcode) \ + (((errcode) < 0) && (WSAGetLastError() == WSAEINTR || WSAGetLastError() == WSAEINPROGRESS || WSAGetLastError() == WSAEWOULDBLOCK)) + +#define MG_SOCK_RESET(errcode) \ + (((errcode) < 0) && (WSAGetLastError() == WSAECONNRESET)) + +#define realpath(a, b) _fullpath((b), (a), MG_PATH_MAX) +#define sleep(x) Sleep((x) * 1000) +#define mkdir(a, b) _mkdir(a) + +#ifndef S_ISDIR +#define S_ISDIR(x) (((x) & _S_IFMT) == _S_IFDIR) +#endif + +#ifndef MG_ENABLE_DIRLIST +#define MG_ENABLE_DIRLIST 1 +#endif + +#ifndef SIGPIPE +#define SIGPIPE 0 +#endif + +#endif + +#if MG_ARCH == MG_ARCH_ZEPHYR + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MG_PUTCHAR(x) printk("%c", x) +#ifndef strdup +#define strdup(s) ((char*)mg_strdup(mg_str(s)).ptr) +#endif +#define strerror(x) zsock_gai_strerror(x) +#define FD_CLOEXEC 0 +#define F_SETFD 0 +#define MG_ENABLE_SSI 0 + +int rand(void); +int sscanf(const char*, const char*, ...); + +#endif + +#if defined(MG_ENABLE_FREERTOS_TCP) && MG_ENABLE_FREERTOS_TCP + +#include +#include + +#include +#include +#include // contents to be moved and file removed, some day + +#define MG_SOCKET_TYPE Socket_t +#define MG_INVALID_SOCKET FREERTOS_INVALID_SOCKET + +// Why FreeRTOS-TCP did not implement a clean BSD API, but its own thing +// with FreeRTOS_ prefix, is beyond me +#define IPPROTO_TCP FREERTOS_IPPROTO_TCP +#define IPPROTO_UDP FREERTOS_IPPROTO_UDP +#define AF_INET FREERTOS_AF_INET +#define SOCK_STREAM FREERTOS_SOCK_STREAM +#define SOCK_DGRAM FREERTOS_SOCK_DGRAM +#define SO_BROADCAST 0 +#define SO_ERROR 0 +#define SOL_SOCKET 0 +#define SO_REUSEADDR 0 + +#define MG_SOCK_ERR(errcode) ((errcode) < 0 ? (errcode) : 0) + +#define MG_SOCK_PENDING(errcode) \ + ((errcode) == -pdFREERTOS_ERRNO_EWOULDBLOCK || (errcode) == -pdFREERTOS_ERRNO_EISCONN || (errcode) == -pdFREERTOS_ERRNO_EINPROGRESS || (errcode) == -pdFREERTOS_ERRNO_EAGAIN) + +#define MG_SOCK_RESET(errcode) ((errcode) == -pdFREERTOS_ERRNO_ENOTCONN) + +// actually only if optional timeout is enabled +#define MG_SOCK_INTR(fd) (fd == NULL) + +#define sockaddr_in freertos_sockaddr +#define sockaddr freertos_sockaddr +#define accept(a, b, c) FreeRTOS_accept((a), (b), (c)) +#define connect(a, b, c) FreeRTOS_connect((a), (b), (c)) +#define bind(a, b, c) FreeRTOS_bind((a), (b), (c)) +#define listen(a, b) FreeRTOS_listen((a), (b)) +#define socket(a, b, c) FreeRTOS_socket((a), (b), (c)) +#define send(a, b, c, d) FreeRTOS_send((a), (b), (c), (d)) +#define recv(a, b, c, d) FreeRTOS_recv((a), (b), (c), (d)) +#define setsockopt(a, b, c, d, e) FreeRTOS_setsockopt((a), (b), (c), (d), (e)) +#define sendto(a, b, c, d, e, f) FreeRTOS_sendto((a), (b), (c), (d), (e), (f)) +#define recvfrom(a, b, c, d, e, f) \ + FreeRTOS_recvfrom((a), (b), (c), (d), (e), (f)) +#define closesocket(x) FreeRTOS_closesocket(x) +#define gethostbyname(x) FreeRTOS_gethostbyname(x) +#define getsockname(a, b, c) mg_getsockname((a), (b), (c)) +#define getpeername(a, b, c) mg_getpeername((a), (b), (c)) + +static inline int mg_getsockname(MG_SOCKET_TYPE fd, void* buf, socklen_t* len) +{ + (void)fd, (void)buf, (void)len; + return -1; +} + +static inline int mg_getpeername(MG_SOCKET_TYPE fd, void* buf, socklen_t* len) +{ + (void)fd, (void)buf, (void)len; + return 0; +} +#endif + +#if defined(MG_ENABLE_LWIP) && MG_ENABLE_LWIP + +#if defined(__GNUC__) && !defined(__ARMCC_VERSION) +#include +#endif + +struct timeval; + +#include + +#if !LWIP_TIMEVAL_PRIVATE +#if defined(__GNUC__) && !defined(__ARMCC_VERSION) // armclang sets both +#include +#else +struct timeval { + time_t tv_sec; + long tv_usec; +}; +#endif +#endif + +#if LWIP_SOCKET != 1 +// Sockets support disabled in LWIP by default +#error Set LWIP_SOCKET variable to 1 (in lwipopts.h) +#endif +#endif + +#if defined(MG_ENABLE_RL) && MG_ENABLE_RL +#include + +#define closesocket(x) closesocket(x) + +#define TCP_NODELAY SO_KEEPALIVE + +#define MG_SOCK_ERR(errcode) ((errcode) < 0 ? (errcode) : 0) + +#define MG_SOCK_PENDING(errcode) \ + ((errcode) == BSD_EWOULDBLOCK || (errcode) == BSD_EALREADY || (errcode) == BSD_EINPROGRESS) + +#define MG_SOCK_RESET(errcode) \ + ((errcode) == BSD_ECONNABORTED || (errcode) == BSD_ECONNRESET) + +// In blocking mode, which is enabled by default, accept() waits for a +// connection request. In non blocking mode, you must call accept() +// again if the error code BSD_EWOULDBLOCK is returned. +#define MG_SOCK_INTR(fd) (fd == BSD_EWOULDBLOCK) + +#define socklen_t int +#endif + +#ifndef MG_ENABLE_LOG +#define MG_ENABLE_LOG 1 +#endif + +#ifndef MG_ENABLE_TCPIP +#define MG_ENABLE_TCPIP 0 // Mongoose built-in network stack +#endif + +#ifndef MG_ENABLE_LWIP +#define MG_ENABLE_LWIP 0 // lWIP network stack +#endif + +#ifndef MG_ENABLE_FREERTOS_TCP +#define MG_ENABLE_FREERTOS_TCP 0 // Amazon FreeRTOS-TCP network stack +#endif + +#ifndef MG_ENABLE_RL +#define MG_ENABLE_RL 0 // ARM MDK network stack +#endif + +#ifndef MG_ENABLE_SOCKET +#define MG_ENABLE_SOCKET !MG_ENABLE_TCPIP +#endif + +#ifndef MG_ENABLE_POLL +#define MG_ENABLE_POLL 0 +#endif + +#ifndef MG_ENABLE_EPOLL +#define MG_ENABLE_EPOLL 0 +#endif + +#ifndef MG_ENABLE_FATFS +#define MG_ENABLE_FATFS 0 +#endif + +#ifndef MG_ENABLE_SSI +#define MG_ENABLE_SSI 0 +#endif + +#undef MG_ENABLE_IPV6 +#ifndef MG_ENABLE_IPV6 +#define MG_ENABLE_IPV6 0 +#endif + +#ifndef MG_IPV6_V6ONLY +#define MG_IPV6_V6ONLY 0 // IPv6 socket binds only to V6, not V4 address +#endif + +#ifndef MG_ENABLE_MD5 +#define MG_ENABLE_MD5 1 +#endif + +// Set MG_ENABLE_WINSOCK=0 for Win32 builds with external IP stack (like LWIP) +#ifndef MG_ENABLE_WINSOCK +#define MG_ENABLE_WINSOCK 1 +#endif + +#ifndef MG_ENABLE_DIRLIST +#define MG_ENABLE_DIRLIST 0 +#endif + +#ifndef MG_ENABLE_CUSTOM_RANDOM +#define MG_ENABLE_CUSTOM_RANDOM 0 +#endif + +#ifndef MG_ENABLE_CUSTOM_MILLIS +#define MG_ENABLE_CUSTOM_MILLIS 0 +#endif + +#ifndef MG_ENABLE_PACKED_FS +#define MG_ENABLE_PACKED_FS 0 +#endif + +#ifndef MG_ENABLE_ASSERT +#define MG_ENABLE_ASSERT 0 +#endif + +#ifndef MG_IO_SIZE +#define MG_IO_SIZE 2048 // Granularity of the send/recv IO buffer growth +#endif + +#ifndef MG_MAX_RECV_SIZE +#define MG_MAX_RECV_SIZE (8UL * 1024UL * 1024UL) // Maximum recv IO buffer size +#endif + +#ifndef MG_DATA_SIZE +#define MG_DATA_SIZE 32 // struct mg_connection :: data size +#endif + +#ifndef MG_MAX_HTTP_HEADERS +#define MG_MAX_HTTP_HEADERS 30 +#endif + +#ifndef MG_HTTP_INDEX +#define MG_HTTP_INDEX "index.html" +#endif + +#ifndef MG_PATH_MAX +#ifdef PATH_MAX +#define MG_PATH_MAX PATH_MAX +#else +#define MG_PATH_MAX 128 +#endif +#endif + +#ifndef MG_SOCK_LISTEN_BACKLOG_SIZE +#define MG_SOCK_LISTEN_BACKLOG_SIZE 5 +#endif + +#ifndef MG_DIRSEP +#define MG_DIRSEP '/' +#endif + +#ifndef MG_ENABLE_FILE +#if defined(FOPEN_MAX) +#define MG_ENABLE_FILE 1 +#else +#define MG_ENABLE_FILE 0 +#endif +#endif + +#ifndef MG_INVALID_SOCKET +#define MG_INVALID_SOCKET (-1) +#endif + +#ifndef MG_SOCKET_TYPE +#define MG_SOCKET_TYPE int +#endif + +#ifndef MG_SOCKET_ERRNO +#define MG_SOCKET_ERRNO errno +#endif + +#if MG_ENABLE_EPOLL +#define MG_EPOLL_ADD(c) \ + do { \ + struct epoll_event ev = { EPOLLIN | EPOLLERR | EPOLLHUP, { c } }; \ + epoll_ctl(c->mgr->epoll_fd, EPOLL_CTL_ADD, (int)(size_t)c->fd, &ev); \ + } while (0) +#define MG_EPOLL_MOD(c, wr) \ + do { \ + struct epoll_event ev = { EPOLLIN | EPOLLERR | EPOLLHUP, { c } }; \ + if (wr) \ + ev.events |= EPOLLOUT; \ + epoll_ctl(c->mgr->epoll_fd, EPOLL_CTL_MOD, (int)(size_t)c->fd, &ev); \ + } while (0) +#else +#define MG_EPOLL_ADD(c) +#define MG_EPOLL_MOD(c, wr) +#endif + +struct mg_str { + const char* ptr; // Pointer to string data + size_t len; // String len +}; + +#define MG_NULL_STR \ + { \ + NULL, 0 \ + } + +#define MG_C_STR(a) \ + { \ + (a), sizeof(a) - 1 \ + } + +// Using macro to avoid shadowing C++ struct constructor, see #1298 +#define mg_str(s) mg_str_s(s) + +struct mg_str mg_str(const char* s); +struct mg_str mg_str_n(const char* s, size_t n); +int mg_lower(const char* s); +int mg_ncasecmp(const char* s1, const char* s2, size_t len); +int mg_casecmp(const char* s1, const char* s2); +int mg_vcmp(const struct mg_str* s1, const char* s2); +int mg_vcasecmp(const struct mg_str* str1, const char* str2); +int mg_strcmp(const struct mg_str str1, const struct mg_str str2); +struct mg_str mg_strstrip(struct mg_str s); +struct mg_str mg_strdup(const struct mg_str s); +const char* mg_strstr(const struct mg_str haystack, const struct mg_str needle); +bool mg_match(struct mg_str str, struct mg_str pattern, struct mg_str* caps); +bool mg_globmatch(const char* pattern, size_t plen, const char* s, size_t n); +bool mg_commalist(struct mg_str* s, struct mg_str* k, struct mg_str* v); +bool mg_split(struct mg_str* s, struct mg_str* k, struct mg_str* v, char delim); +char* mg_hex(const void* buf, size_t len, char* dst); +void mg_unhex(const char* buf, size_t len, unsigned char* to); +unsigned long mg_unhexn(const char* s, size_t len); +bool mg_path_is_sane(const char* path); + +// Single producer, single consumer non-blocking queue + +struct mg_queue { + char* buf; + size_t size; + volatile size_t tail; + volatile size_t head; +}; + +void mg_queue_init(struct mg_queue*, char*, size_t); // Init queue +size_t mg_queue_book(struct mg_queue*, char** buf, size_t); // Reserve space +void mg_queue_add(struct mg_queue*, size_t); // Add new message +size_t mg_queue_next(struct mg_queue*, char**); // Get oldest message +void mg_queue_del(struct mg_queue*, size_t); // Delete oldest message + +typedef void (*mg_pfn_t)(char, void*); // Output function +typedef size_t (*mg_pm_t)(mg_pfn_t, void*, va_list*); // %M printer + +size_t mg_vxprintf(void (*)(char, void*), void*, const char* fmt, va_list*); +size_t mg_xprintf(void (*fn)(char, void*), void*, const char* fmt, ...); + +// Convenience wrappers around mg_xprintf +size_t mg_vsnprintf(char* buf, size_t len, const char* fmt, va_list* ap); +size_t mg_snprintf(char*, size_t, const char* fmt, ...); +char* mg_vmprintf(const char* fmt, va_list* ap); +char* mg_mprintf(const char* fmt, ...); +size_t mg_queue_vprintf(struct mg_queue*, const char* fmt, va_list*); +size_t mg_queue_printf(struct mg_queue*, const char* fmt, ...); + +// %M print helper functions +size_t mg_print_base64(void (*out)(char, void*), void* arg, va_list* ap); +size_t mg_print_esc(void (*out)(char, void*), void* arg, va_list* ap); +size_t mg_print_hex(void (*out)(char, void*), void* arg, va_list* ap); +size_t mg_print_ip(void (*out)(char, void*), void* arg, va_list* ap); +size_t mg_print_ip_port(void (*out)(char, void*), void* arg, va_list* ap); +size_t mg_print_ip4(void (*out)(char, void*), void* arg, va_list* ap); +size_t mg_print_ip6(void (*out)(char, void*), void* arg, va_list* ap); +size_t mg_print_mac(void (*out)(char, void*), void* arg, va_list* ap); + +// Various output functions +void mg_pfn_iobuf(char ch, void* param); // param: struct mg_iobuf * +void mg_pfn_stdout(char c, void* param); // param: ignored + +// A helper macro for printing JSON: mg_snprintf(buf, len, "%m", MG_ESC("hi")) +#define MG_ESC(str) mg_print_esc, 0, (str) + +enum { MG_LL_NONE, + MG_LL_ERROR, + MG_LL_INFO, + MG_LL_DEBUG, + MG_LL_VERBOSE }; +void mg_log(const char* fmt, ...); +bool mg_log_prefix(int ll, const char* file, int line, const char* fname); +void mg_log_set(int log_level); +void mg_hexdump(const void* buf, size_t len); +void mg_log_set_fn(mg_pfn_t fn, void* param); + +#if MG_ENABLE_LOG +#define MG_LOG(level, args) \ + do { \ + if (mg_log_prefix((level), __FILE__, __LINE__, __func__)) \ + mg_log args; \ + } while (0) +#else +#define MG_LOG(level, args) \ + do { \ + if (0) \ + mg_log args; \ + } while (0) +#endif + +#define MG_ERROR(args) MG_LOG(MG_LL_ERROR, args) +#define MG_INFO(args) MG_LOG(MG_LL_INFO, args) +#define MG_DEBUG(args) MG_LOG(MG_LL_DEBUG, args) +#define MG_VERBOSE(args) MG_LOG(MG_LL_VERBOSE, args) + +struct mg_timer { + unsigned long id; // Timer ID + uint64_t period_ms; // Timer period in milliseconds + uint64_t expire; // Expiration timestamp in milliseconds + unsigned flags; // Possible flags values below +#define MG_TIMER_ONCE 0 // Call function once +#define MG_TIMER_REPEAT 1 // Call function periodically +#define MG_TIMER_RUN_NOW 2 // Call immediately when timer is set + void (*fn)(void*); // Function to call + void* arg; // Function argument + struct mg_timer* next; // Linkage +}; + +void mg_timer_init(struct mg_timer** head, struct mg_timer* timer, + uint64_t milliseconds, unsigned flags, void (*fn)(void*), + void* arg); +void mg_timer_free(struct mg_timer** head, struct mg_timer*); +void mg_timer_poll(struct mg_timer** head, uint64_t new_ms); +bool mg_timer_expired(uint64_t* expiration, uint64_t period, uint64_t now); + +enum { MG_FS_READ = 1, + MG_FS_WRITE = 2, + MG_FS_DIR = 4 }; + +// Filesystem API functions +// st() returns MG_FS_* flags and populates file size and modification time +// ls() calls fn() for every directory entry, allowing to list a directory +// +// NOTE: UNIX-style shorthand names for the API functions are deliberately +// chosen to avoid conflicts with some libraries that make macros for e.g. +// stat(), write(), read() calls. +struct mg_fs { + int (*st)(const char* path, size_t* size, time_t* mtime); // stat file + void (*ls)(const char* path, void (*fn)(const char*, void*), void*); + void* (*op)(const char* path, int flags); // Open file + void (*cl)(void* fd); // Close file + size_t (*rd)(void* fd, void* buf, size_t len); // Read file + size_t (*wr)(void* fd, const void* buf, size_t len); // Write file + size_t (*sk)(void* fd, size_t offset); // Set file position + bool (*mv)(const char* from, const char* to); // Rename file + bool (*rm)(const char* path); // Delete file + bool (*mkd)(const char* path); // Create directory +}; + +extern struct mg_fs mg_fs_posix; // POSIX open/close/read/write/seek +extern struct mg_fs mg_fs_packed; // Packed FS, see examples/device-dashboard +extern struct mg_fs mg_fs_fat; // FAT FS + +// File descriptor +struct mg_fd { + void* fd; + struct mg_fs* fs; +}; + +struct mg_fd* mg_fs_open(struct mg_fs* fs, const char* path, int flags); +void mg_fs_close(struct mg_fd* fd); +char* mg_file_read(struct mg_fs* fs, const char* path, size_t* size); +bool mg_file_write(struct mg_fs* fs, const char* path, const void*, size_t); +bool mg_file_printf(struct mg_fs* fs, const char* path, const char* fmt, ...); + +// Packed API +const char* mg_unpack(const char* path, size_t* size, time_t* mtime); +const char* mg_unlist(size_t no); // Get no'th packed filename +struct mg_str mg_unpacked(const char* path); // Packed file as mg_str + +#if MG_ENABLE_ASSERT +#include +#elif !defined(assert) +#define assert(x) +#endif + +void mg_bzero(volatile unsigned char* buf, size_t len); +void mg_random(void* buf, size_t len); +char* mg_random_str(char* buf, size_t len); +uint16_t mg_ntohs(uint16_t net); +uint32_t mg_ntohl(uint32_t net); +uint32_t mg_crc32(uint32_t crc, const char* buf, size_t len); +uint64_t mg_millis(void); // Return milliseconds since boot +uint64_t mg_now(void); // Return milliseconds since Epoch + +#define mg_htons(x) mg_ntohs(x) +#define mg_htonl(x) mg_ntohl(x) + +#define MG_U32(a, b, c, d) \ + (((uint32_t)((a) & 255) << 24) | ((uint32_t)((b) & 255) << 16) | ((uint32_t)((c) & 255) << 8) | (uint32_t)((d) & 255)) + +// For printing IPv4 addresses: printf("%d.%d.%d.%d\n", MG_IPADDR_PARTS(&ip)) +#define MG_U8P(ADDR) ((uint8_t*)(ADDR)) +#define MG_IPADDR_PARTS(ADDR) \ + MG_U8P(ADDR) \ + [0], MG_U8P(ADDR)[1], MG_U8P(ADDR)[2], MG_U8P(ADDR)[3] + +#define MG_REG(x) ((volatile uint32_t*)(x))[0] +#define MG_BIT(x) (((uint32_t)1U) << (x)) +#define MG_SET_BITS(R, CLRMASK, SETMASK) (R) = ((R) & ~(CLRMASK)) | (SETMASK) + +#define MG_ROUND_UP(x, a) ((a) == 0 ? (x) : ((((x) + (a)-1) / (a)) * (a))) +#define MG_ROUND_DOWN(x, a) ((a) == 0 ? (x) : (((x) / (a)) * (a))) + +#ifdef __GNUC__ +#define MG_ARM_DISABLE_IRQ() asm volatile("cpsid i" : : : "memory") +#define MG_ARM_ENABLE_IRQ() asm volatile("cpsie i" : : : "memory") +#else +#define MG_ARM_DISABLE_IRQ() +#define MG_ARM_ENABLE_IRQ() +#endif + +struct mg_addr; +int mg_check_ip_acl(struct mg_str acl, struct mg_addr* remote_ip); + +// Linked list management macros +#define LIST_ADD_HEAD(type_, head_, elem_) \ + do { \ + (elem_)->next = (*head_); \ + *(head_) = (elem_); \ + } while (0) + +#define LIST_ADD_TAIL(type_, head_, elem_) \ + do { \ + type_** h = head_; \ + while (*h != NULL) \ + h = &(*h)->next; \ + *h = (elem_); \ + } while (0) + +#define LIST_DELETE(type_, head_, elem_) \ + do { \ + type_** h = head_; \ + while (*h != (elem_)) \ + h = &(*h)->next; \ + *h = (elem_)->next; \ + } while (0) + +unsigned short mg_url_port(const char* url); +int mg_url_is_ssl(const char* url); +struct mg_str mg_url_host(const char* url); +struct mg_str mg_url_user(const char* url); +struct mg_str mg_url_pass(const char* url); +const char* mg_url_uri(const char* url); + +struct mg_iobuf { + unsigned char* buf; // Pointer to stored data + size_t size; // Total size available + size_t len; // Current number of bytes + size_t align; // Alignment during allocation +}; + +int mg_iobuf_init(struct mg_iobuf*, size_t, size_t); +int mg_iobuf_resize(struct mg_iobuf*, size_t); +void mg_iobuf_free(struct mg_iobuf*); +size_t mg_iobuf_add(struct mg_iobuf*, size_t, const void*, size_t); +size_t mg_iobuf_del(struct mg_iobuf*, size_t ofs, size_t len); + +size_t mg_base64_update(unsigned char input_byte, char* buf, size_t len); +size_t mg_base64_final(char* buf, size_t len); +size_t mg_base64_encode(const unsigned char* p, size_t n, char* buf, size_t); +size_t mg_base64_decode(const char* src, size_t n, char* dst, size_t); + +typedef struct { + uint32_t buf[4]; + uint32_t bits[2]; + unsigned char in[64]; +} mg_md5_ctx; + +void mg_md5_init(mg_md5_ctx* c); +void mg_md5_update(mg_md5_ctx* c, const unsigned char* data, size_t len); +void mg_md5_final(mg_md5_ctx* c, unsigned char[16]); + +typedef struct { + uint32_t state[5]; + uint32_t count[2]; + unsigned char buffer[64]; +} mg_sha1_ctx; + +void mg_sha1_init(mg_sha1_ctx*); +void mg_sha1_update(mg_sha1_ctx*, const unsigned char* data, size_t len); +void mg_sha1_final(unsigned char digest[20], mg_sha1_ctx*); + +struct mg_connection; +typedef void (*mg_event_handler_t)(struct mg_connection*, int ev, + void* ev_data, void* fn_data); +void mg_call(struct mg_connection* c, int ev, void* ev_data); +void mg_error(struct mg_connection* c, const char* fmt, ...); + +enum { + MG_EV_ERROR, // Error char *error_message + MG_EV_OPEN, // Connection created NULL + MG_EV_POLL, // mg_mgr_poll iteration uint64_t *uptime_millis + MG_EV_RESOLVE, // Host name is resolved NULL + MG_EV_CONNECT, // Connection established NULL + MG_EV_ACCEPT, // Connection accepted NULL + MG_EV_TLS_HS, // TLS handshake succeeded NULL + MG_EV_READ, // Data received from socket long *bytes_read + MG_EV_WRITE, // Data written to socket long *bytes_written + MG_EV_CLOSE, // Connection closed NULL + MG_EV_HTTP_MSG, // HTTP request/response struct mg_http_message * + MG_EV_HTTP_CHUNK, // HTTP chunk (partial msg) struct mg_http_message * + MG_EV_WS_OPEN, // Websocket handshake done struct mg_http_message * + MG_EV_WS_MSG, // Websocket msg, text or bin struct mg_ws_message * + MG_EV_WS_CTL, // Websocket control msg struct mg_ws_message * + MG_EV_MQTT_CMD, // MQTT low-level command struct mg_mqtt_message * + MG_EV_MQTT_MSG, // MQTT PUBLISH received struct mg_mqtt_message * + MG_EV_MQTT_OPEN, // MQTT CONNACK received int *connack_status_code + MG_EV_SNTP_TIME, // SNTP time received uint64_t *epoch_millis + MG_EV_USER // Starting ID for user events +}; + +struct mg_dns { + const char* url; // DNS server URL + struct mg_connection* c; // DNS server connection +}; + +struct mg_addr { + uint8_t ip[16]; // Holds IPv4 or IPv6 address, in network byte order + uint16_t port; // TCP or UDP port in network byte order + bool is_ip6; // True when address is IPv6 address +}; + +struct mg_mgr { + struct mg_connection* conns; // List of active connections + struct mg_dns dns4; // DNS for IPv4 + struct mg_dns dns6; // DNS for IPv6 + int dnstimeout; // DNS resolve timeout in milliseconds + bool use_dns6; // Use DNS6 server by default, see #1532 + unsigned long nextid; // Next connection ID + unsigned long timerid; // Next timer ID + void* userdata; // Arbitrary user data pointer + void* tls_ctx; // TLS context shared by all TLS sessions + uint16_t mqtt_id; // MQTT IDs for pub/sub + void* active_dns_requests; // DNS requests in progress + struct mg_timer* timers; // Active timers + int epoll_fd; // Used when MG_EPOLL_ENABLE=1 + void* priv; // Used by the MIP stack + size_t extraconnsize; // Used by the MIP stack +#if MG_ENABLE_FREERTOS_TCP + SocketSet_t ss; // NOTE(lsm): referenced from socket struct +#endif +}; + +struct mg_connection { + struct mg_connection* next; // Linkage in struct mg_mgr :: connections + struct mg_mgr* mgr; // Our container + struct mg_addr loc; // Local address + struct mg_addr rem; // Remote address + void* fd; // Connected socket, or LWIP data + unsigned long id; // Auto-incrementing unique connection ID + struct mg_iobuf recv; // Incoming data + struct mg_iobuf send; // Outgoing data + mg_event_handler_t fn; // User-specified event handler function + void* fn_data; // User-specified function parameter + mg_event_handler_t pfn; // Protocol-specific handler function + void* pfn_data; // Protocol-specific function parameter + char data[MG_DATA_SIZE]; // Arbitrary connection data + void* tls; // TLS specific data + unsigned is_listening : 1; // Listening connection + unsigned is_client : 1; // Outbound (client) connection + unsigned is_accepted : 1; // Accepted (server) connection + unsigned is_resolving : 1; // Non-blocking DNS resolution is in progress + unsigned is_arplooking : 1; // Non-blocking ARP resolution is in progress + unsigned is_connecting : 1; // Non-blocking connect is in progress + unsigned is_tls : 1; // TLS-enabled connection + unsigned is_tls_hs : 1; // TLS handshake is in progress + unsigned is_udp : 1; // UDP connection + unsigned is_websocket : 1; // WebSocket connection + unsigned is_mqtt5 : 1; // For MQTT connection, v5 indicator + unsigned is_hexdumping : 1; // Hexdump in/out traffic + unsigned is_draining : 1; // Send remaining data, then close and free + unsigned is_closing : 1; // Close and free the connection immediately + unsigned is_full : 1; // Stop reads, until cleared + unsigned is_resp : 1; // Response is still being generated + unsigned is_readable : 1; // Connection is ready to read + unsigned is_writable : 1; // Connection is ready to write +}; + +void mg_mgr_poll(struct mg_mgr*, int ms); +void mg_mgr_init(struct mg_mgr*); +void mg_mgr_free(struct mg_mgr*); + +struct mg_connection* mg_listen(struct mg_mgr*, const char* url, + mg_event_handler_t fn, void* fn_data); +struct mg_connection* mg_connect(struct mg_mgr*, const char* url, + mg_event_handler_t fn, void* fn_data); +struct mg_connection* mg_wrapfd(struct mg_mgr* mgr, int fd, + mg_event_handler_t fn, void* fn_data); +void mg_connect_resolved(struct mg_connection*); +bool mg_send(struct mg_connection*, const void*, size_t); +size_t mg_printf(struct mg_connection*, const char* fmt, ...); +size_t mg_vprintf(struct mg_connection*, const char* fmt, va_list* ap); +bool mg_aton(struct mg_str str, struct mg_addr* addr); +int mg_mkpipe(struct mg_mgr*, mg_event_handler_t, void*, bool udp); + +// These functions are used to integrate with custom network stacks +struct mg_connection* mg_alloc_conn(struct mg_mgr*); +void mg_close_conn(struct mg_connection* c); +bool mg_open_listener(struct mg_connection* c, const char* url); + +// Utility functions +struct mg_timer* mg_timer_add(struct mg_mgr* mgr, uint64_t milliseconds, + unsigned flags, void (*fn)(void*), void* arg); + +// Low-level IO primives used by TLS layer +enum { MG_IO_ERR = -1, + MG_IO_WAIT = -2, + MG_IO_RESET = -3 }; +long mg_io_send(struct mg_connection* c, const void* buf, size_t len); +long mg_io_recv(struct mg_connection* c, void* buf, size_t len); + +struct mg_http_header { + struct mg_str name; // Header name + struct mg_str value; // Header value +}; + +struct mg_http_message { + struct mg_str method, uri, query, proto; // Request/response line + struct mg_http_header headers[MG_MAX_HTTP_HEADERS]; // Headers + struct mg_str body; // Body + struct mg_str head; // Request + headers + struct mg_str chunk; // Chunk for chunked encoding, or partial body + struct mg_str message; // Request + headers + body +}; + +// Parameter for mg_http_serve_dir() +struct mg_http_serve_opts { + const char* root_dir; // Web root directory, must be non-NULL + const char* ssi_pattern; // SSI file name pattern, e.g. #.shtml + const char* extra_headers; // Extra HTTP headers to add in responses + const char* mime_types; // Extra mime types, ext1=type1,ext2=type2,.. + const char* page404; // Path to the 404 page, or NULL by default + struct mg_fs* fs; // Filesystem implementation. Use NULL for POSIX +}; + +// Parameter for mg_http_next_multipart +struct mg_http_part { + struct mg_str name; // Form field name + struct mg_str filename; // Filename for file uploads + struct mg_str body; // Part contents +}; + +int mg_http_parse(const char* s, size_t len, struct mg_http_message*); +int mg_http_get_request_len(const unsigned char* buf, size_t buf_len); +void mg_http_printf_chunk(struct mg_connection* cnn, const char* fmt, ...); +void mg_http_write_chunk(struct mg_connection* c, const char* buf, size_t len); +void mg_http_delete_chunk(struct mg_connection* c, struct mg_http_message* hm); +struct mg_connection* mg_http_listen(struct mg_mgr*, const char* url, + mg_event_handler_t fn, void* fn_data); +struct mg_connection* mg_http_connect(struct mg_mgr*, const char* url, + mg_event_handler_t fn, void* fn_data); +void mg_http_serve_dir(struct mg_connection*, struct mg_http_message* hm, + const struct mg_http_serve_opts*); +void mg_http_serve_file(struct mg_connection*, struct mg_http_message* hm, + const char* path, const struct mg_http_serve_opts*); +void mg_http_reply(struct mg_connection*, int status_code, const char* headers, + const char* body_fmt, ...); +struct mg_str* mg_http_get_header(struct mg_http_message*, const char* name); +struct mg_str mg_http_var(struct mg_str buf, struct mg_str name); +int mg_http_get_var(const struct mg_str*, const char* name, char*, size_t); +int mg_url_decode(const char* s, size_t n, char* to, size_t to_len, int form); +size_t mg_url_encode(const char* s, size_t n, char* buf, size_t len); +void mg_http_creds(struct mg_http_message*, char*, size_t, char*, size_t); +bool mg_http_match_uri(const struct mg_http_message*, const char* glob); +long mg_http_upload(struct mg_connection* c, struct mg_http_message* hm, + struct mg_fs* fs, const char* path, size_t max_size); +void mg_http_bauth(struct mg_connection*, const char* user, const char* pass); +struct mg_str mg_http_get_header_var(struct mg_str s, struct mg_str v); +size_t mg_http_next_multipart(struct mg_str, size_t, struct mg_http_part*); +int mg_http_status(const struct mg_http_message* hm); +void mg_hello(const char* url); + +void mg_http_serve_ssi(struct mg_connection* c, const char* root, + const char* fullpath); + +#define MG_TLS_NONE 0 // No TLS support +#define MG_TLS_MBED 1 // mbedTLS +#define MG_TLS_OPENSSL 2 // OpenSSL +#define MG_TLS_BUILTIN 3 // Built-in +#define MG_TLS_CUSTOM 4 // Custom implementation + +#ifndef MG_TLS +#define MG_TLS MG_TLS_NONE +#endif + +struct mg_tls_opts { + struct mg_str ca; // PEM or DER + struct mg_str cert; // PEM or DER + struct mg_str key; // PEM or DER + struct mg_str name; // If not empty, enable host name verification +}; + +void mg_tls_init(struct mg_connection*, const struct mg_tls_opts* opts); +void mg_tls_free(struct mg_connection*); +long mg_tls_send(struct mg_connection*, const void* buf, size_t len); +long mg_tls_recv(struct mg_connection*, void* buf, size_t len); +size_t mg_tls_pending(struct mg_connection*); +void mg_tls_handshake(struct mg_connection*); + +// Private +void mg_tls_ctx_init(struct mg_mgr*); +void mg_tls_ctx_free(struct mg_mgr*); + +#if MG_TLS == MG_TLS_MBED +#include +#include +#include +#include + +struct mg_tls_ctx { + int dummy; +#ifdef MBEDTLS_SSL_SESSION_TICKETS + mbedtls_ssl_ticket_context tickets; +#endif +}; + +struct mg_tls { + mbedtls_x509_crt ca; // Parsed CA certificate + mbedtls_x509_crt cert; // Parsed certificate + mbedtls_pk_context pk; // Private key context + mbedtls_ssl_context ssl; // SSL/TLS context + mbedtls_ssl_config conf; // SSL-TLS config +#ifdef MBEDTLS_SSL_SESSION_TICKETS + mbedtls_ssl_ticket_context ticket; // Session tickets context +#endif +}; +#endif + +#if MG_TLS == MG_TLS_OPENSSL + +#include +#include + +struct mg_tls { + SSL_CTX* ctx; + SSL* ssl; +}; +#endif + +#define WEBSOCKET_OP_CONTINUE 0 +#define WEBSOCKET_OP_TEXT 1 +#define WEBSOCKET_OP_BINARY 2 +#define WEBSOCKET_OP_CLOSE 8 +#define WEBSOCKET_OP_PING 9 +#define WEBSOCKET_OP_PONG 10 + +struct mg_ws_message { + struct mg_str data; // Websocket message data + uint8_t flags; // Websocket message flags +}; + +struct mg_connection* mg_ws_connect(struct mg_mgr*, const char* url, + mg_event_handler_t fn, void* fn_data, + const char* fmt, ...); +void mg_ws_upgrade(struct mg_connection*, struct mg_http_message*, + const char* fmt, ...); +size_t mg_ws_send(struct mg_connection*, const void* buf, size_t len, int op); +size_t mg_ws_wrap(struct mg_connection*, size_t len, int op); +size_t mg_ws_printf(struct mg_connection* c, int op, const char* fmt, ...); +size_t mg_ws_vprintf(struct mg_connection* c, int op, const char* fmt, + va_list*); + +struct mg_connection* mg_sntp_connect(struct mg_mgr* mgr, const char* url, + mg_event_handler_t fn, void* fn_data); +void mg_sntp_request(struct mg_connection* c); +int64_t mg_sntp_parse(const unsigned char* buf, size_t len); + +#define MQTT_CMD_CONNECT 1 +#define MQTT_CMD_CONNACK 2 +#define MQTT_CMD_PUBLISH 3 +#define MQTT_CMD_PUBACK 4 +#define MQTT_CMD_PUBREC 5 +#define MQTT_CMD_PUBREL 6 +#define MQTT_CMD_PUBCOMP 7 +#define MQTT_CMD_SUBSCRIBE 8 +#define MQTT_CMD_SUBACK 9 +#define MQTT_CMD_UNSUBSCRIBE 10 +#define MQTT_CMD_UNSUBACK 11 +#define MQTT_CMD_PINGREQ 12 +#define MQTT_CMD_PINGRESP 13 +#define MQTT_CMD_DISCONNECT 14 +#define MQTT_CMD_AUTH 15 + +#define MQTT_PROP_PAYLOAD_FORMAT_INDICATOR 0x01 +#define MQTT_PROP_MESSAGE_EXPIRY_INTERVAL 0x02 +#define MQTT_PROP_CONTENT_TYPE 0x03 +#define MQTT_PROP_RESPONSE_TOPIC 0x08 +#define MQTT_PROP_CORRELATION_DATA 0x09 +#define MQTT_PROP_SUBSCRIPTION_IDENTIFIER 0x0B +#define MQTT_PROP_SESSION_EXPIRY_INTERVAL 0x11 +#define MQTT_PROP_ASSIGNED_CLIENT_IDENTIFIER 0x12 +#define MQTT_PROP_SERVER_KEEP_ALIVE 0x13 +#define MQTT_PROP_AUTHENTICATION_METHOD 0x15 +#define MQTT_PROP_AUTHENTICATION_DATA 0x16 +#define MQTT_PROP_REQUEST_PROBLEM_INFORMATION 0x17 +#define MQTT_PROP_WILL_DELAY_INTERVAL 0x18 +#define MQTT_PROP_REQUEST_RESPONSE_INFORMATION 0x19 +#define MQTT_PROP_RESPONSE_INFORMATION 0x1A +#define MQTT_PROP_SERVER_REFERENCE 0x1C +#define MQTT_PROP_REASON_STRING 0x1F +#define MQTT_PROP_RECEIVE_MAXIMUM 0x21 +#define MQTT_PROP_TOPIC_ALIAS_MAXIMUM 0x22 +#define MQTT_PROP_TOPIC_ALIAS 0x23 +#define MQTT_PROP_MAXIMUM_QOS 0x24 +#define MQTT_PROP_RETAIN_AVAILABLE 0x25 +#define MQTT_PROP_USER_PROPERTY 0x26 +#define MQTT_PROP_MAXIMUM_PACKET_SIZE 0x27 +#define MQTT_PROP_WILDCARD_SUBSCRIPTION_AVAILABLE 0x28 +#define MQTT_PROP_SUBSCRIPTION_IDENTIFIER_AVAILABLE 0x29 +#define MQTT_PROP_SHARED_SUBSCRIPTION_AVAILABLE 0x2A + +enum { + MQTT_PROP_TYPE_BYTE, + MQTT_PROP_TYPE_STRING, + MQTT_PROP_TYPE_STRING_PAIR, + MQTT_PROP_TYPE_BINARY_DATA, + MQTT_PROP_TYPE_VARIABLE_INT, + MQTT_PROP_TYPE_INT, + MQTT_PROP_TYPE_SHORT +}; + +enum { MQTT_OK, + MQTT_INCOMPLETE, + MQTT_MALFORMED }; + +struct mg_mqtt_prop { + uint8_t id; // Enumerated at MQTT5 Reference + uint32_t iv; // Integer value for 8-, 16-, 32-bit integers types + struct mg_str key; // Non-NULL only for user property type + struct mg_str val; // Non-NULL only for UTF-8 types and user properties +}; + +struct mg_mqtt_opts { + struct mg_str user; // Username, can be empty + struct mg_str pass; // Password, can be empty + struct mg_str client_id; // Client ID + struct mg_str topic; // message/subscription topic + struct mg_str message; // message content + uint8_t qos; // message quality of service + uint8_t version; // Can be 4 (3.1.1), or 5. If 0, assume 4 + uint16_t keepalive; // Keep-alive timer in seconds + bool retain; // Retain flag + bool clean; // Clean session flag + struct mg_mqtt_prop* props; // MQTT5 props array + size_t num_props; // number of props + struct mg_mqtt_prop* will_props; // Valid only for CONNECT packet (MQTT5) + size_t num_will_props; // Number of will props +}; + +struct mg_mqtt_message { + struct mg_str topic; // Parsed topic for PUBLISH + struct mg_str data; // Parsed message for PUBLISH + struct mg_str dgram; // Whole MQTT packet, including headers + uint16_t id; // For PUBACK, PUBREC, PUBREL, PUBCOMP, SUBACK, PUBLISH + uint8_t cmd; // MQTT command, one of MQTT_CMD_* + uint8_t qos; // Quality of service + uint8_t ack; // CONNACK return code, 0 = success + size_t props_start; // Offset to the start of the properties (MQTT5) + size_t props_size; // Length of the properties +}; + +struct mg_connection* mg_mqtt_connect(struct mg_mgr*, const char* url, + const struct mg_mqtt_opts* opts, + mg_event_handler_t fn, void* fn_data); +struct mg_connection* mg_mqtt_listen(struct mg_mgr* mgr, const char* url, + mg_event_handler_t fn, void* fn_data); +void mg_mqtt_login(struct mg_connection* c, const struct mg_mqtt_opts* opts); +void mg_mqtt_pub(struct mg_connection* c, const struct mg_mqtt_opts* opts); +void mg_mqtt_sub(struct mg_connection*, const struct mg_mqtt_opts* opts); +int mg_mqtt_parse(const uint8_t*, size_t, uint8_t, struct mg_mqtt_message*); +void mg_mqtt_send_header(struct mg_connection*, uint8_t cmd, uint8_t flags, + uint32_t len); +void mg_mqtt_ping(struct mg_connection*); +void mg_mqtt_pong(struct mg_connection*); +void mg_mqtt_disconnect(struct mg_connection*, const struct mg_mqtt_opts*); +size_t mg_mqtt_next_prop(struct mg_mqtt_message*, struct mg_mqtt_prop*, + size_t ofs); + +// Mongoose sends DNS queries that contain only one question: +// either A (IPv4) or AAAA (IPv6) address lookup. +// Therefore, we expect zero or one answer. +// If `resolved` is true, then `addr` contains resolved IPv4 or IPV6 address. +struct mg_dns_message { + uint16_t txnid; // Transaction ID + bool resolved; // Resolve successful, addr is set + struct mg_addr addr; // Resolved address + char name[256]; // Host name +}; + +struct mg_dns_header { + uint16_t txnid; // Transaction ID + uint16_t flags; + uint16_t num_questions; + uint16_t num_answers; + uint16_t num_authority_prs; + uint16_t num_other_prs; +}; + +// DNS resource record +struct mg_dns_rr { + uint16_t nlen; // Name or pointer length + uint16_t atype; // Address type + uint16_t aclass; // Address class + uint16_t alen; // Address length +}; + +void mg_resolve(struct mg_connection*, const char* url); +void mg_resolve_cancel(struct mg_connection*); +bool mg_dns_parse(const uint8_t* buf, size_t len, struct mg_dns_message*); +size_t mg_dns_parse_rr(const uint8_t* buf, size_t len, size_t ofs, + bool is_question, struct mg_dns_rr*); + +#ifndef MG_JSON_MAX_DEPTH +#define MG_JSON_MAX_DEPTH 30 +#endif + +// Error return values - negative. Successful returns are >= 0 +enum { MG_JSON_TOO_DEEP = -1, + MG_JSON_INVALID = -2, + MG_JSON_NOT_FOUND = -3 }; +int mg_json_get(struct mg_str json, const char* path, int* toklen); + +bool mg_json_get_num(struct mg_str json, const char* path, double* v); +bool mg_json_get_bool(struct mg_str json, const char* path, bool* v); +long mg_json_get_long(struct mg_str json, const char* path, long dflt); +char* mg_json_get_str(struct mg_str json, const char* path); +char* mg_json_get_hex(struct mg_str json, const char* path, int* len); +char* mg_json_get_b64(struct mg_str json, const char* path, int* len); + +bool mg_json_unescape(struct mg_str str, char* buf, size_t len); + +// JSON-RPC request descriptor +struct mg_rpc_req { + struct mg_rpc** head; // RPC handlers list head + struct mg_rpc* rpc; // RPC handler being called + mg_pfn_t pfn; // Response printing function + void* pfn_data; // Response printing function data + void* req_data; // Arbitrary request data + struct mg_str frame; // Request, e.g. {"id":1,"method":"add","params":[1,2]} +}; + +// JSON-RPC method handler +struct mg_rpc { + struct mg_rpc* next; // Next in list + struct mg_str method; // Method pattern + void (*fn)(struct mg_rpc_req*); // Handler function + void* fn_data; // Handler function argument +}; + +void mg_rpc_add(struct mg_rpc** head, struct mg_str method_pattern, + void (*handler)(struct mg_rpc_req*), void* handler_data); +void mg_rpc_del(struct mg_rpc** head, void (*handler)(struct mg_rpc_req*)); +void mg_rpc_process(struct mg_rpc_req*); + +// Helper functions to print result or error frame +void mg_rpc_ok(struct mg_rpc_req*, const char* fmt, ...); +void mg_rpc_vok(struct mg_rpc_req*, const char* fmt, va_list* ap); +void mg_rpc_err(struct mg_rpc_req*, int code, const char* fmt, ...); +void mg_rpc_verr(struct mg_rpc_req*, int code, const char* fmt, va_list*); +void mg_rpc_list(struct mg_rpc_req* r); +// Copyright (c) 2023 Cesanta Software Limited +// All rights reserved + +#define MG_OTA_NONE 0 // No OTA support +#define MG_OTA_FLASH 1 // OTA via an internal flash +#define MG_OTA_CUSTOM 100 // Custom implementation + +#ifndef MG_OTA +#define MG_OTA MG_OTA_NONE +#endif + +// Firmware update API +bool mg_ota_begin(size_t new_firmware_size); // Start writing +bool mg_ota_write(const void* buf, size_t len); // Write chunk, aligned to 1k +bool mg_ota_end(void); // Stop writing + +enum { + MG_OTA_UNAVAILABLE = 0, // No OTA information is present + MG_OTA_FIRST_BOOT = 1, // Device booting the first time after the OTA + MG_OTA_UNCOMMITTED = 2, // Ditto, but marking us for the rollback + MG_OTA_COMMITTED = 3, // The firmware is good +}; +enum { MG_FIRMWARE_CURRENT = 0, + MG_FIRMWARE_PREVIOUS = 1 }; + +int mg_ota_status(int firmware); // Return firmware status MG_OTA_* +uint32_t mg_ota_crc32(int firmware); // Return firmware checksum +uint32_t mg_ota_timestamp(int firmware); // Firmware timestamp, UNIX UTC epoch +size_t mg_ota_size(int firmware); // Firmware size + +bool mg_ota_commit(void); // Commit current firmware +bool mg_ota_rollback(void); // Rollback to the previous firmware +// Copyright (c) 2023 Cesanta Software Limited +// All rights reserved + +#define MG_SYS_NONE 0 // Dummy system +#define MG_SYS_STM32H5 1 // STM32 H5 +#define MG_SYS_STM32H7 2 // STM32 H7 +#define MG_SYS_CUSTOM 100 // Custom implementation + +#ifndef MG_SYS +#define MG_SYS MG_SYS_NONE +#endif + +// Flash information +void* mg_flash_start(void); // Return flash start address +size_t mg_flash_size(void); // Return flash size +size_t mg_flash_sector_size(void); // Return flash sector size +size_t mg_flash_write_align(void); // Return flash write align, minimum 4 +int mg_flash_bank(void); // 0: not dual bank, 1: bank1, 2: bank2 + +// Write, erase, swap bank +bool mg_flash_write(void* addr, const void* buf, size_t len); +bool mg_flash_erase(void* addr); // Must be at sector boundary +bool mg_flash_swap_bank(void); + +// Convenience functions to store data on a flash sector with wear levelling +// If `sector` is NULL, then the last sector of flash is used +bool mg_flash_load(void* sector, uint32_t key, void* buf, size_t len); +bool mg_flash_save(void* sector, uint32_t key, const void* buf, size_t len); + +void mg_sys_reset(void); // Reboot device immediately + +#if defined(MG_ENABLE_TCPIP) && MG_ENABLE_TCPIP +struct mg_tcpip_if; // Mongoose TCP/IP network interface + +struct mg_tcpip_driver { + bool (*init)(struct mg_tcpip_if*); // Init driver + size_t (*tx)(const void*, size_t, struct mg_tcpip_if*); // Transmit frame + size_t (*rx)(void* buf, size_t len, struct mg_tcpip_if*); // Receive frame + bool (*up)(struct mg_tcpip_if*); // Up/down status +}; + +// Network interface +struct mg_tcpip_if { + uint8_t mac[6]; // MAC address. Must be set to a valid MAC + uint32_t ip, mask, gw; // IP address, mask, default gateway + struct mg_str tx; // Output (TX) buffer + bool enable_dhcp_client; // Enable DCHP client + bool enable_dhcp_server; // Enable DCHP server + bool enable_crc32_check; // Do a CRC check on RX frames and strip it + bool enable_mac_check; // Do a MAC check on RX frames + struct mg_tcpip_driver* driver; // Low level driver + void* driver_data; // Driver-specific data + struct mg_mgr* mgr; // Mongoose event manager + struct mg_queue recv_queue; // Receive queue + uint16_t mtu; // Interface MTU +#define MG_TCPIP_MTU_DEFAULT 1500 + + // Internal state, user can use it but should not change it + uint8_t gwmac[6]; // Router's MAC + uint64_t now; // Current time + uint64_t timer_1000ms; // 1000 ms timer: for DHCP and link state + uint64_t lease_expire; // Lease expiration time, in ms + uint16_t eport; // Next ephemeral port + volatile uint32_t ndrop; // Number of received, but dropped frames + volatile uint32_t nrecv; // Number of received frames + volatile uint32_t nsent; // Number of transmitted frames + volatile uint32_t nerr; // Number of driver errors + uint8_t state; // Current state +#define MG_TCPIP_STATE_DOWN 0 // Interface is down +#define MG_TCPIP_STATE_UP 1 // Interface is up +#define MG_TCPIP_STATE_REQ 2 // Interface is up and has requested an IP +#define MG_TCPIP_STATE_READY 3 // Interface is up and has an IP assigned +}; + +void mg_tcpip_init(struct mg_mgr*, struct mg_tcpip_if*); +void mg_tcpip_free(struct mg_tcpip_if*); +void mg_tcpip_qwrite(void* buf, size_t len, struct mg_tcpip_if* ifp); + +extern struct mg_tcpip_driver mg_tcpip_driver_stm32; +extern struct mg_tcpip_driver mg_tcpip_driver_w5500; +extern struct mg_tcpip_driver mg_tcpip_driver_tm4c; +extern struct mg_tcpip_driver mg_tcpip_driver_stm32h; +extern struct mg_tcpip_driver mg_tcpip_driver_imxrt; +extern struct mg_tcpip_driver mg_tcpip_driver_same54; + +// Drivers that require SPI, can use this SPI abstraction +struct mg_tcpip_spi { + void* spi; // Opaque SPI bus descriptor + void (*begin)(void*); // SPI begin: slave select low + void (*end)(void*); // SPI end: slave select high + uint8_t (*txn)(void*, uint8_t); // SPI transaction: write 1 byte, read reply +}; +#endif + +struct mg_tcpip_driver_imxrt1020_data { + // MDC clock divider. MDC clock is derived from IPS Bus clock (ipg_clk), + // must not exceed 2.5MHz. Configuration for clock range 2.36~2.50 MHz + // ipg_clk MSCR mdc_cr VALUE + // ------------------------------------- + // -1 <-- tell driver to guess the value + // 25 MHz 0x04 0 + // 33 MHz 0x06 1 + // 40 MHz 0x07 2 + // 50 MHz 0x09 3 + // 66 MHz 0x0D 4 <-- value for iMXRT1020-EVK at max freq. + int mdc_cr; // Valid values: -1, 0, 1, 2, 3, 4 +}; + +#if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_SAME54) && MG_ENABLE_DRIVER_SAME54 + +struct mg_tcpip_driver_same54_data { + int mdc_cr; +}; + +#endif + +struct mg_tcpip_driver_stm32_data { + // MDC clock divider. MDC clock is derived from HCLK, must not exceed 2.5MHz + // HCLK range DIVIDER mdc_cr VALUE + // ------------------------------------- + // -1 <-- tell driver to guess the value + // 60-100 MHz HCLK/42 0 + // 100-150 MHz HCLK/62 1 + // 20-35 MHz HCLK/16 2 + // 35-60 MHz HCLK/26 3 + // 150-216 MHz HCLK/102 4 <-- value for Nucleo-F* on max speed + // 216-310 MHz HCLK/124 5 + // 110, 111 Reserved + int mdc_cr; // Valid values: -1, 0, 1, 2, 3, 4, 5 +}; + +struct mg_tcpip_driver_stm32h_data { + // MDC clock divider. MDC clock is derived from HCLK, must not exceed 2.5MHz + // HCLK range DIVIDER mdc_cr VALUE + // ------------------------------------- + // -1 <-- tell driver to guess the value + // 60-100 MHz HCLK/42 0 + // 100-150 MHz HCLK/62 1 + // 20-35 MHz HCLK/16 2 + // 35-60 MHz HCLK/26 3 + // 150-250 MHz HCLK/102 4 <-- value for Nucleo-H* on max speed + // driven by HSI 250-300 MHz HCLK/124 5 <-- value for Nucleo-H* on + // max speed driven by CSI 110, 111 Reserved + int mdc_cr; // Valid values: -1, 0, 1, 2, 3, 4, 5 +}; + +struct mg_tcpip_driver_tm4c_data { + // MDC clock divider. MDC clock is derived from SYSCLK, must not exceed 2.5MHz + // SYSCLK range DIVIDER mdc_cr VALUE + // ------------------------------------- + // -1 <-- tell driver to guess the value + // 60-100 MHz SYSCLK/42 0 + // 100-150 MHz SYSCLK/62 1 <-- value for EK-TM4C129* on max speed + // 20-35 MHz SYSCLK/16 2 + // 35-60 MHz SYSCLK/26 3 + // 0x4-0xF Reserved + int mdc_cr; // Valid values: -1, 0, 1, 2, 3 +}; + +#ifdef __cplusplus +} +#endif +#endif // MONGOOSE_H \ No newline at end of file diff --git a/APP_Framework/Applications/mongoose/project.c b/APP_Framework/Applications/mongoose/project.c new file mode 100644 index 000000000..cf05a4af9 --- /dev/null +++ b/APP_Framework/Applications/mongoose/project.c @@ -0,0 +1,142 @@ +// Copyright (c) 2022 Cesanta Software Limited +// All rights reserved +// +// UI example +// It implements the following endpoints: +// /api/config/get - respond with current config +// /api/config/set - POST a config change +// any other URI serves static files from s_root_dir +// Data and results are JSON strings + +#include "ip_addr.h" +#include "mongoose.h" +#include "netdev.h" + +char index_path[] = "login.html"; + +static const char* s_http_addr = "http://192.168.131.88:8000"; // HTTP port +static const char* s_root_dir = "webserver"; +static const char* s_enable_hexdump = "no"; +static const char* s_ssi_pattern = "#.html"; + +static const char* device_type = "Edu-ARM32"; +static const char* web_version = "XUOS Webserver 1.0"; +static int enable_4g = 0; + +static struct netdev* p_netdev; + +static struct config { + char *ip, *mask, *gw, *dns; +} s_config; + +// Try to update a single configuration value +static void update_config(struct mg_str json, const char* path, char** value) +{ + char* jval; + if ((jval = mg_json_get_str(json, path)) != NULL) { + free(*value); + *value = strdup(jval); + } +} + +static void fn(struct mg_connection* c, int ev, void* ev_data, void* fn_data) +{ + if (ev == MG_EV_HTTP_MSG) { + struct mg_http_message *hm = (struct mg_http_message*)ev_data, tmp = { 0 }; + if (mg_http_match_uri(hm, "/getSystemInfo")) { + mg_http_reply(c, 200, "Content-Type: application/json\r\n", + "{%m:%m, %m:%m, %m:%m, %m:%m, %m:%m, %m:%d}\n", + MG_ESC("ip"), MG_ESC(s_config.ip), + MG_ESC("deviceType"), MG_ESC(device_type), + MG_ESC("deviceNo"), MG_ESC("0"), + MG_ESC("systemTime"), MG_ESC("YYYY:MM:DD hh:mm:ss"), + MG_ESC("webVersion"), MG_ESC(web_version), + MG_ESC("statusOf4g"), enable_4g); + } else if (mg_http_match_uri(hm, "/net/get4gInfo")) { + mg_http_reply(c, 200, "Content-Type: application/json\r\n", + "{%m:%m}\n", + MG_ESC("enable4g"), MG_ESC(enable_4g)); + } else if (mg_http_match_uri(hm, "/net/set4gInfo")) { + struct mg_str json = hm->body; + enable_4g = mg_json_get_long(json, "$.enable4g", 0); + mg_http_reply(c, 200, "Content-Type: application/json\r\n", "{\"status\":\"success\"}\r\n"); + printf("Get enable 4g setting: %d\n", enable_4g); + } else if (mg_http_match_uri(hm, "/net/getEthernetInfo")) { + mg_http_reply(c, 200, "Content-Type: application/json\r\n", + "{%m:%m, %m:%m, %m:%m, %m:%m}\n", + MG_ESC("ip"), MG_ESC(s_config.ip), + MG_ESC("netmask"), MG_ESC(s_config.mask), + MG_ESC("gateway"), MG_ESC(s_config.gw), + MG_ESC("dns"), MG_ESC(s_config.dns)); + } else if (mg_http_match_uri(hm, "/net/setEthernetInfo")) { + struct mg_str json = hm->body; + printf("json: %s\n", json.ptr); + update_config(json, "$.ip", &s_config.ip); + update_config(json, "$.netmask", &s_config.mask); + update_config(json, "$.gateway", &s_config.gw); + update_config(json, "$.dns", &s_config.dns); + mg_http_reply(c, 200, "Content-Type: application/json\r\n", "{\"status\":\"success\"}\r\n"); + + ip_addr_t ipaddr, maskaddr, gwaddr; + inet_aton(s_config.ip, &ipaddr); + inet_aton(s_config.mask, &maskaddr); + inet_aton(s_config.gw, &gwaddr); + p_netdev->ops->set_addr_info(p_netdev, &ipaddr, &maskaddr, &gwaddr); + + printf("Board Net Configuration changed to [IP: %s, Mask: %s, GW: %s, DNS: %s]\n", + s_config.ip, + s_config.mask, + s_config.gw, + s_config.dns); + } else { + struct mg_str unknown = mg_str_n("?", 1), *cl; + struct mg_http_serve_opts opts = { .root_dir = s_root_dir, .ssi_pattern = s_ssi_pattern }; + mg_http_serve_dir(c, hm, &opts); + mg_http_parse((char*)c->send.buf, c->send.len, &tmp); + cl = mg_http_get_header(&tmp, "Content-Length"); + if (cl == NULL) + cl = &unknown; + MG_INFO(("%.*s %.*s %.*s %.*s", (int)hm->method.len, hm->method.ptr, + (int)hm->uri.len, hm->uri.ptr, (int)tmp.uri.len, tmp.uri.ptr, + (int)cl->len, cl->ptr)); + } + } + (void)fn_data; +} + +static void* do_webserver_demo(void* none) +{ + p_netdev = netdev_get_by_name("wz"); + if (p_netdev == NULL) { + MG_INFO(("Did nto find wz netdev, use default.\n")); + p_netdev = NETDEV_DEFAULT; + } + MG_INFO(("Use Netdev %s", p_netdev->name)); + s_config.ip = strdup(inet_ntoa(*p_netdev->ip_addr)); + s_config.mask = strdup(inet_ntoa(*p_netdev->netmask)); + s_config.gw = strdup(inet_ntoa(*p_netdev->gw)); + s_config.dns = strdup(inet_ntoa(p_netdev->dns_servers[0])); + + struct mg_mgr mgr; // Event manager + // mg_log_set(MG_LL_INFO); // Set to 3 to enable debug + mg_log_set(MG_LL_DEBUG); // Set to 3 to enable debug + mg_mgr_init(&mgr); // Initialise event manager + mg_http_listen(&mgr, s_http_addr, fn, NULL); // Create HTTP listener + for (;;) + mg_mgr_poll(&mgr, 50); // Infinite event loop + mg_mgr_free(&mgr); + return NULL; +} + +int webserver_demo(int argc, char* argv[]) +{ + pthread_t tid = -1; + pthread_attr_t attr; + attr.schedparam.sched_priority = 30; + attr.stacksize = 0x2000; + + PrivTaskCreate(&tid, &attr, do_webserver_demo, NULL); + + return 0; +} +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(5), Webserver, webserver_demo, webserver for project); \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/Makefile b/Ubiquitous/XiZi_IIoT/Makefile index de3ea3e86..4ecef27a7 100755 --- a/Ubiquitous/XiZi_IIoT/Makefile +++ b/Ubiquitous/XiZi_IIoT/Makefile @@ -50,6 +50,7 @@ export SRC_DIR:= $(SRC_APP_DIR) $(SRC_KERNEL_DIR) export LIBCC export MUSL_DIR := $(KERNEL_ROOT)/lib/musllib export LWIP_DIR := $(KERNEL_ROOT)/resources/ethernet +export MONGOOSE_DIR := $(KERNEL_ROOT)/../../APP_Framework/Applications/mongoose/lib PART:= @@ -74,6 +75,10 @@ ifeq ($(CONFIG_RESOURCES_LWIP), y) PART += COMPILE_LWIP endif +ifeq ($(CONFIG_USE_MONGOOSE), y) +# PART += COMPILE_MONGOOSE +endif + ifeq ($(CONFIG_MCUBOOT_BOOTLOADER), y) PART += COMPILE_BOOTLOADER else ifeq ($(CONFIG_MCUBOOT_APPLICATION), y) @@ -130,6 +135,15 @@ COMPILE_LWIP: @cp build/liblwip.a $(KERNEL_ROOT)/resources/ethernet/LwIP/liblwip.a @rm build/Makefile build/make.obj +COMPILE_MONGOOSE: + @for dir in $(MONGOOSE_DIR);do \ + $(MAKE) -C $$dir COMPILE_TYPE=$@; \ + done + @cp link_mongoose.mk build/Makefile + @$(MAKE) -C build TARGET=mongoose.a LINK_FLAGS=LFLAGS + @cp build/mongoose.a $(KERNEL_ROOT)/../../APP_Framework/Applications/mongoose/mongoose.a + @rm build/Makefile build/make.obj + COMPILE_KERNEL: @for dir in $(SRC_KERNEL_DIR);do \ $(MAKE) -C $$dir; \ diff --git a/Ubiquitous/XiZi_IIoT/board/edu-arm32/config.mk b/Ubiquitous/XiZi_IIoT/board/edu-arm32/config.mk index bb44261da..af0254884 100644 --- a/Ubiquitous/XiZi_IIoT/board/edu-arm32/config.mk +++ b/Ubiquitous/XiZi_IIoT/board/edu-arm32/config.mk @@ -1,10 +1,10 @@ export CROSS_COMPILE ?=/usr/bin/arm-none-eabi- -export CFLAGS := -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -ffunction-sections -fdata-sections -Dgcc -O0 -fgnu89-inline -Wa,-mimplicit-it=thumb -Werror -Wuninitialized +export CFLAGS := -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -ffunction-sections -fdata-sections -Dgcc -O2 -gdwarf-2 -g -fgnu89-inline -Wa,-mimplicit-it=thumb # export CFLAGS := -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -ffunction-sections -fdata-sections -Dgcc -O0 -gdwarf-2 -g -fgnu89-inline -Wa,-mimplicit-it=thumb -Werror export AFLAGS := -c -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -ffunction-sections -fdata-sections -x assembler-with-cpp -Wa,-mimplicit-it=thumb -gdwarf-2 export LFLAGS := -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -ffunction-sections -fdata-sections -Wl,--gc-sections,-Map=XiZi-edu-arm32.map,-cref,-u,Reset_Handler -T $(BSP_ROOT)/link.lds -export CXXFLAGS := -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -ffunction-sections -fdata-sections -Dgcc -O0 -Werror +export CXXFLAGS := -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -ffunction-sections -fdata-sections -Dgcc -O2 -Werror # export CXXFLAGS := -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -ffunction-sections -fdata-sections -Dgcc -O0 -gdwarf-2 -g -Werror export APPLFLAGS := diff --git a/Ubiquitous/XiZi_IIoT/board/edu-arm32/third_party_driver/ethernet/eth_driver.c b/Ubiquitous/XiZi_IIoT/board/edu-arm32/third_party_driver/ethernet/eth_driver.c index 25d106209..9b07b399d 100644 --- a/Ubiquitous/XiZi_IIoT/board/edu-arm32/third_party_driver/ethernet/eth_driver.c +++ b/Ubiquitous/XiZi_IIoT/board/edu-arm32/third_party_driver/ethernet/eth_driver.c @@ -278,10 +278,7 @@ struct pbuf* low_level_input(struct netif* netif) return p; } -extern void LwipSetIPTest(int argc, char* argv[]); int HwEthInit(void) { - // lwip_config_tcp(0, lwip_ipaddr, lwip_netmask, lwip_gwaddr); - LwipSetIPTest(1, NULL); return EOK; } diff --git a/Ubiquitous/XiZi_IIoT/board/edu-arm32/third_party_driver/ethernet/eth_netdev.c b/Ubiquitous/XiZi_IIoT/board/edu-arm32/third_party_driver/ethernet/eth_netdev.c index 1c5c9d3c5..875a35db0 100644 --- a/Ubiquitous/XiZi_IIoT/board/edu-arm32/third_party_driver/ethernet/eth_netdev.c +++ b/Ubiquitous/XiZi_IIoT/board/edu-arm32/third_party_driver/ethernet/eth_netdev.c @@ -76,6 +76,7 @@ static int lwip_netdev_set_addr_info(struct netdev* netdev, ip_addr_t* ip_addr, netif_set_gw((struct netif*)netdev->user_data, ip_2_ip4(gw)); } } + return 0; } #ifdef LWIP_DNS @@ -92,7 +93,7 @@ static int lwip_netdev_set_dns_server(struct netdev* netdev, uint8_t dns_num, ip } #endif -#ifdef LWIP_DHCP +#if LWIP_DHCP static int lwip_netdev_set_dhcp(struct netdev* netdev, bool is_enabled) { netdev_low_level_set_dhcp_status(netdev, is_enabled); @@ -120,7 +121,7 @@ static const struct netdev_ops lwip_netdev_ops = { #ifdef LWIP_DNS .set_dns_server = lwip_netdev_set_dns_server, #endif -#ifdef LWIP_DHCP +#if LWIP_DHCP .set_dhcp = lwip_netdev_set_dhcp, #endif .set_default = lwip_netdev_set_default, @@ -179,9 +180,9 @@ int lwip_netdev_add(struct netif* lwip_netif) netdev->ops = &lwip_netdev_ops; netdev->hwaddr_len = lwip_netif->hwaddr_len; memcpy(netdev->hwaddr, lwip_netif->hwaddr, lwip_netif->hwaddr_len); - netdev->ip_addr = lwip_netif->ip_addr; - netdev->gw = lwip_netif->gw; - netdev->netmask = lwip_netif->netmask; + netdev->ip_addr = &lwip_netif->ip_addr; + netdev->gw = &lwip_netif->gw; + netdev->netmask = &lwip_netif->netmask; return result; } diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/Makefile b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/Makefile index e994ce1ad..a7dae3fce 100644 --- a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/Makefile +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/Makefile @@ -1,4 +1,4 @@ # SRC_FILES := socket.c connect_w5500.c w5500.c wizchip_conf.c spi_interface.c wiz_ping.c connect_w5500_test.c wiz_iperf.c -SRC_FILES := socket.c connect_w5500.c w5500.c wizchip_conf.c spi_interface.c wiz_ping.c connect_w5500_test.c w5x00_lwip.c wiz_iperf.c +SRC_FILES := socket.c connect_w5500.c w5500.c wizchip_conf.c spi_interface.c w5x00_lwip.c include $(KERNEL_ROOT)/compiler.mk \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/connect_w5500.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/connect_w5500.c index dc29ff22d..ee99dcb78 100644 --- a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/connect_w5500.c +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/connect_w5500.c @@ -328,8 +328,12 @@ int HwWiznetInit(void) setSHAR(wiz_mac); ctlwizchip(CW_RESET_PHY, 0); + network_init(); + wiz_interrupt_init(0, wiz_irq_handler); + network_init(); + setSn_RXBUF_SIZE(0, 16); setSn_TXBUF_SIZE(0, 16); #define SOCK_ANY_PORT_NUM 0xC000 @@ -349,7 +353,5 @@ int HwWiznetInit(void) } } - network_init(); - return EOK; } \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/connect_w5500_test.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/test/connect_w5500_test.c similarity index 100% rename from Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/connect_w5500_test.c rename to Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/test/connect_w5500_test.c diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/wiz_iperf.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/test/wiz_iperf.c similarity index 100% rename from Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/wiz_iperf.c rename to Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/test/wiz_iperf.c diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/wiz_ping.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/test/wiz_ping.c similarity index 100% rename from Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/wiz_ping.c rename to Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/test/wiz_ping.c diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/wiz_ping.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/test/wiz_ping.h similarity index 100% rename from Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/wiz_ping.h rename to Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/test/wiz_ping.h diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/spi/connect_spi.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/spi/connect_spi.c index 8811d2856..75e666a6b 100644 --- a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/spi/connect_spi.c +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/spi/connect_spi.c @@ -152,6 +152,9 @@ static uint32 SpiDrvConfigure(void *drv, struct BusConfigureInfo *configure_info static uint32 SpiWriteData(struct SpiHardwareDevice *spi_dev, struct SpiDataStandard *spi_datacfg) { +#define WRITE_BUF_SIZE 1600 + static uint32_t write_buf[4 * WRITE_BUF_SIZE] = { 0 }; + SpiDeviceParam *dev_param = (SpiDeviceParam *)(spi_dev->haldev.private_data); uint8 device_id = dev_param->spi_slave_param->spi_slave_id; @@ -184,10 +187,15 @@ static uint32 SpiWriteData(struct SpiHardwareDevice *spi_dev, struct SpiDataStan dmac_set_single_mode(dev_param->spi_dma_param->spi_dmac_txchannel, &dummy, (void *)(&spi_instance[device_master_id]->dr[0]), DMAC_ADDR_NOCHANGE, DMAC_ADDR_NOCHANGE, DMAC_MSIZE_4, DMAC_TRANS_WIDTH_32, spi_datacfg->length); } else { - tx_buff = x_malloc(spi_datacfg->length * 4); - if (!tx_buff) { - goto transfer_done; + if (spi_datacfg->length > WRITE_BUF_SIZE) { + tx_buff = x_malloc(spi_datacfg->length * 4); + if (!tx_buff) { + goto transfer_done; + } + } else { + tx_buff = write_buf; } + for (i = 0; i < spi_datacfg->length; i++) { tx_buff[i] = ((uint8_t *)spi_datacfg->tx_buff)[i]; } @@ -201,10 +209,10 @@ static uint32 SpiWriteData(struct SpiHardwareDevice *spi_dev, struct SpiDataStan spi_instance[device_master_id]->ser = 0x00; spi_instance[device_master_id]->ssienr = 0x00; - transfer_done: - if (tx_buff != NULL) { - x_free(tx_buff); - } + transfer_done: + if (tx_buff != NULL && spi_datacfg->length > WRITE_BUF_SIZE) { + x_free(tx_buff); + } } if (spi_datacfg->spi_cs_release) { @@ -219,6 +227,9 @@ static uint32 SpiWriteData(struct SpiHardwareDevice *spi_dev, struct SpiDataStan static uint32 SpiReadData(struct SpiHardwareDevice *spi_dev, struct SpiDataStandard *spi_datacfg) { +#define READ_BUF_SIZE 1600 + static uint32_t read_buf[4 * READ_BUF_SIZE] = { 0 }; + SpiDeviceParam *dev_param = (SpiDeviceParam *)(spi_dev->haldev.private_data); uint32 spi_read_length = 0;; @@ -251,12 +262,15 @@ static uint32 SpiReadData(struct SpiHardwareDevice *spi_dev, struct SpiDataStand dmac_set_single_mode(dev_param->spi_dma_param->spi_dmac_rxchannel, (void *)(&spi_instance[device_master_id]->dr[0]), &dummy, DMAC_ADDR_NOCHANGE, DMAC_ADDR_NOCHANGE, DMAC_MSIZE_1, DMAC_TRANS_WIDTH_32, spi_datacfg->length); } else { - rx_buff = x_calloc(spi_datacfg->length * 4, 1); - if(!rx_buff) - { - goto transfer_done; + if (spi_datacfg->length > READ_BUF_SIZE) { + rx_buff = x_calloc(spi_datacfg->length * 4, 1); + if (!rx_buff) { + goto transfer_done; + } + } else { + rx_buff = read_buf; } - + dmac_set_single_mode(dev_param->spi_dma_param->spi_dmac_rxchannel, (void *)(&spi_instance[device_master_id]->dr[0]), rx_buff, DMAC_ADDR_NOCHANGE, DMAC_ADDR_INCREMENT, DMAC_MSIZE_1, DMAC_TRANS_WIDTH_32, spi_datacfg->length); } @@ -273,8 +287,8 @@ static uint32 SpiReadData(struct SpiHardwareDevice *spi_dev, struct SpiDataStand } } - transfer_done: - if (rx_buff) { + transfer_done: + if (rx_buff && spi_datacfg->length > READ_BUF_SIZE) { x_free(rx_buff); } } diff --git a/Ubiquitous/XiZi_IIoT/board/imxrt1176-sbc/third_party_driver/ethernet/eth_netdev.c b/Ubiquitous/XiZi_IIoT/board/imxrt1176-sbc/third_party_driver/ethernet/eth_netdev.c index 03ca27594..09957b854 100644 --- a/Ubiquitous/XiZi_IIoT/board/imxrt1176-sbc/third_party_driver/ethernet/eth_netdev.c +++ b/Ubiquitous/XiZi_IIoT/board/imxrt1176-sbc/third_party_driver/ethernet/eth_netdev.c @@ -76,6 +76,7 @@ static int lwip_netdev_set_addr_info(struct netdev* netdev, ip_addr_t* ip_addr, netif_set_gw((struct netif*)netdev->user_data, ip_2_ip4(gw)); } } + return 0; } #ifdef LWIP_DNS @@ -92,7 +93,7 @@ static int lwip_netdev_set_dns_server(struct netdev* netdev, uint8_t dns_num, ip } #endif -#ifdef LWIP_DHCP +#if LWIP_DHCP static int lwip_netdev_set_dhcp(struct netdev* netdev, bool is_enabled) { netdev_low_level_set_dhcp_status(netdev, is_enabled); @@ -120,7 +121,7 @@ static const struct netdev_ops lwip_netdev_ops = { #ifdef LWIP_DNS .set_dns_server = lwip_netdev_set_dns_server, #endif -#ifdef LWIP_DHCP +#if LWIP_DHCP .set_dhcp = lwip_netdev_set_dhcp, #endif .set_default = lwip_netdev_set_default, @@ -180,9 +181,9 @@ int lwip_netdev_add(struct netif* lwip_netif) netdev->ops = &lwip_netdev_ops; netdev->hwaddr_len = lwip_netif->hwaddr_len; memcpy(netdev->hwaddr, lwip_netif->hwaddr, lwip_netif->hwaddr_len); - netdev->ip_addr = lwip_netif->ip_addr; - netdev->gw = lwip_netif->gw; - netdev->netmask = lwip_netif->netmask; + netdev->ip_addr = &lwip_netif->ip_addr; + netdev->gw = &lwip_netif->gw; + netdev->netmask = &lwip_netif->netmask; return result; } diff --git a/Ubiquitous/XiZi_IIoT/board/ok1052-c/third_party_driver/ethernet/eth_netdev.c b/Ubiquitous/XiZi_IIoT/board/ok1052-c/third_party_driver/ethernet/eth_netdev.c index 03ca27594..09957b854 100644 --- a/Ubiquitous/XiZi_IIoT/board/ok1052-c/third_party_driver/ethernet/eth_netdev.c +++ b/Ubiquitous/XiZi_IIoT/board/ok1052-c/third_party_driver/ethernet/eth_netdev.c @@ -76,6 +76,7 @@ static int lwip_netdev_set_addr_info(struct netdev* netdev, ip_addr_t* ip_addr, netif_set_gw((struct netif*)netdev->user_data, ip_2_ip4(gw)); } } + return 0; } #ifdef LWIP_DNS @@ -92,7 +93,7 @@ static int lwip_netdev_set_dns_server(struct netdev* netdev, uint8_t dns_num, ip } #endif -#ifdef LWIP_DHCP +#if LWIP_DHCP static int lwip_netdev_set_dhcp(struct netdev* netdev, bool is_enabled) { netdev_low_level_set_dhcp_status(netdev, is_enabled); @@ -120,7 +121,7 @@ static const struct netdev_ops lwip_netdev_ops = { #ifdef LWIP_DNS .set_dns_server = lwip_netdev_set_dns_server, #endif -#ifdef LWIP_DHCP +#if LWIP_DHCP .set_dhcp = lwip_netdev_set_dhcp, #endif .set_default = lwip_netdev_set_default, @@ -180,9 +181,9 @@ int lwip_netdev_add(struct netif* lwip_netif) netdev->ops = &lwip_netdev_ops; netdev->hwaddr_len = lwip_netif->hwaddr_len; memcpy(netdev->hwaddr, lwip_netif->hwaddr, lwip_netif->hwaddr_len); - netdev->ip_addr = lwip_netif->ip_addr; - netdev->gw = lwip_netif->gw; - netdev->netmask = lwip_netif->netmask; + netdev->ip_addr = &lwip_netif->ip_addr; + netdev->gw = &lwip_netif->gw; + netdev->netmask = &lwip_netif->netmask; return result; } diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/config.mk b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/config.mk index 4085d6c06..a77d87ab0 100644 --- a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/config.mk +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/config.mk @@ -30,7 +30,7 @@ export CXXFLAGS := -mcpu=cortex-m7 -mthumb -ffunction-sections -fdata-sections - export APPLFLAGS := -mcpu=cortex-m7 -mthumb -ffunction-sections -fdata-sections -Wl,--gc-sections,-Map=XiZi-app.map,-cref,-u, -T $(BSP_ROOT)/link_userspace.lds -export DEFINES := -DHAVE_CCONFIG_H -DCPU_MIMXRT1052CVL5B -DSKIP_SYSCLK_INIT -DEVK_MCIMXRM -DFSL_SDK_ENABLE_DRIVER_CACHE_CONTROL=1 -DXIP_EXTERNAL_FLASH=1 -D__STARTUP_INITIALIZE_NONCACHEDATA -D__STARTUP_CLEAR_BSS +export DEFINES := -DHAVE_CCONFIG_H -DCPU_MIMXRT1052CVL5B -DSKIP_SYSCLK_INIT -DEVK_MCIMXRM -DFSL_SDK_ENABLE_DRIVER_CACHE_CONTROL=1 -DXIP_EXTERNAL_FLASH=1 -D__STARTUP_INITIALIZE_NONCACHEDATA -D__STARTUP_CLEAR_BSS -DCHECKSUM_BY_HARDWARE ifeq ($(CONFIG_MCUBOOT_BOOTLOADER),y) export DEFINES += -D__BOOTLOADER diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/ethernet/eth_netdev.c b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/ethernet/eth_netdev.c index 03ca27594..09957b854 100644 --- a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/ethernet/eth_netdev.c +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/ethernet/eth_netdev.c @@ -76,6 +76,7 @@ static int lwip_netdev_set_addr_info(struct netdev* netdev, ip_addr_t* ip_addr, netif_set_gw((struct netif*)netdev->user_data, ip_2_ip4(gw)); } } + return 0; } #ifdef LWIP_DNS @@ -92,7 +93,7 @@ static int lwip_netdev_set_dns_server(struct netdev* netdev, uint8_t dns_num, ip } #endif -#ifdef LWIP_DHCP +#if LWIP_DHCP static int lwip_netdev_set_dhcp(struct netdev* netdev, bool is_enabled) { netdev_low_level_set_dhcp_status(netdev, is_enabled); @@ -120,7 +121,7 @@ static const struct netdev_ops lwip_netdev_ops = { #ifdef LWIP_DNS .set_dns_server = lwip_netdev_set_dns_server, #endif -#ifdef LWIP_DHCP +#if LWIP_DHCP .set_dhcp = lwip_netdev_set_dhcp, #endif .set_default = lwip_netdev_set_default, @@ -180,9 +181,9 @@ int lwip_netdev_add(struct netif* lwip_netif) netdev->ops = &lwip_netdev_ops; netdev->hwaddr_len = lwip_netif->hwaddr_len; memcpy(netdev->hwaddr, lwip_netif->hwaddr, lwip_netif->hwaddr_len); - netdev->ip_addr = lwip_netif->ip_addr; - netdev->gw = lwip_netif->gw; - netdev->netmask = lwip_netif->netmask; + netdev->ip_addr = &lwip_netif->ip_addr; + netdev->gw = &lwip_netif->gw; + netdev->netmask = &lwip_netif->netmask; return result; } diff --git a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/.defconfig b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/.defconfig new file mode 100644 index 000000000..c49acf577 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/.defconfig @@ -0,0 +1,261 @@ +# +# Automatically generated file; DO NOT EDIT. +# XiZi_IIoT Project Configuration +# +CONFIG_BOARD_EDU_ARM32_EVB=y +CONFIG_ARCH_ARM=y + +# +# hc32f4a0 feature +# +CONFIG_BSP_USING_UART=y +CONFIG_BSP_USING_UART3=y +CONFIG_SERIAL_BUS_NAME_3="usart3" +CONFIG_SERIAL_DRV_NAME_3="usart3_drv" +CONFIG_SERIAL_3_DEVICE_NAME_0="usart3_dev3" +CONFIG_BSP_USING_UART6=y +CONFIG_SERIAL_BUS_NAME_6="usart6" +CONFIG_SERIAL_DRV_NAME_6="usart6_drv" +CONFIG_SERIAL_6_DEVICE_NAME_0="usart6_dev6" + +# +# config default board resources +# + +# +# config board app name +# +CONFIG_BOARD_APP_NAME="/XiUOS_edu_arm32_app.bin" + +# +# Hardware feature +# +CONFIG_RESOURCES_SERIAL=y +CONFIG_SERIAL_USING_DMA=y +CONFIG_SERIAL_RB_BUFSZ=128 + +# +# Kernel feature +# + +# +# separate compile(choose none for compile once) +# +# CONFIG_SEPARATE_COMPILE is not set +# CONFIG_COMPILER_APP is not set +# CONFIG_APP_STARTUP_FROM_SDCARD is not set +CONFIG_APP_STARTUP_FROM_FLASH=y +# CONFIG_COMPILER_KERNEL is not set + +# +# Memory Management +# +# CONFIG_KERNEL_MEMBLOCK is not set +CONFIG_MEM_ALIGN_SIZE=8 +# CONFIG_MEM_EXTERN_SRAM is not set +CONFIG_MM_PAGE_SIZE=4096 + +# +# Using small memory allocator +# +CONFIG_KERNEL_SMALL_MEM_ALLOC=y +CONFIG_SMALL_NUMBER_32B=64 +CONFIG_SMALL_NUMBER_64B=32 + +# +# Task feature +# +CONFIG_USER_APPLICATION=y +# CONFIG_TASK_ISOLATION is not set + +# +# Inter-Task communication +# +CONFIG_KERNEL_SEMAPHORE=y +CONFIG_KERNEL_MUTEX=y +CONFIG_KERNEL_EVENT=y +CONFIG_KERNEL_MESSAGEQUEUE=y +CONFIG_KERNEL_SOFTTIMER=y +CONFIG_SCHED_POLICY_RR_REMAINSLICE=y +# CONFIG_SCHED_POLICY_RR is not set +# CONFIG_SCHED_POLICY_FIFO is not set +# CONFIG_KTASK_PRIORITY_8 is not set +CONFIG_KTASK_PRIORITY_32=y +# CONFIG_KTASK_PRIORITY_256 is not set +CONFIG_KTASK_PRIORITY_MAX=32 +CONFIG_TICK_PER_SECOND=1000 +CONFIG_KERNEL_STACK_OVERFLOW_CHECK=y +CONFIG_IDLE_KTASK_STACKSIZE=1024 +CONFIG_ZOMBIE_KTASK_STACKSIZE=2048 + +# +# Kernel Console +# +CONFIG_KERNEL_CONSOLE=y +CONFIG_KERNEL_BANNER=y +CONFIG_KERNEL_CONSOLEBUF_SIZE=128 + +# +# Kernel Hook +# +# CONFIG_KERNEL_HOOK is not set + +# +# Command shell +# +CONFIG_TOOL_SHELL=y +CONFIG_SHELL_ENTER_CR=y +CONFIG_SHELL_ENTER_LF=y +CONFIG_SHELL_ENTER_CR_AND_LF=y +# CONFIG_SHELL_ENTER_CRLF is not set + +# +# Set shell user control +# +CONFIG_SHELL_DEFAULT_USER="letter" +CONFIG_SHELL_DEFAULT_USER_PASSWORD="" +CONFIG_SHELL_LOCK_TIMEOUT=10000 + +# +# Set shell config param +# +CONFIG_SHELL_TASK_STACK_SIZE=4096 +CONFIG_SHELL_TASK_PRIORITY=20 +CONFIG_SHELL_MAX_NUMBER=5 +CONFIG_SHELL_PARAMETER_MAX_NUMBER=8 +CONFIG_SHELL_HISTORY_MAX_NUMBER=5 +CONFIG_SHELL_PRINT_BUFFER=128 +CONFIG_SHELL_HELP_SHOW_PERMISSION=y +# CONFIG_SHELL_HELP_LIST_USER is not set +CONFIG_SHELL_HELP_LIST_VAR=y +# CONFIG_SHELL_HELP_LIST_KEY is not set + +# +# Kernel data structure Manage +# +CONFIG_KERNEL_QUEUEMANAGE=y +CONFIG_KERNEL_WORKQUEUE=y +CONFIG_WORKQUEUE_KTASK_STACKSIZE=2048 +CONFIG_WORKQUEUE_KTASK_PRIORITY=23 +CONFIG_QUEUE_MAX=16 +CONFIG_KERNEL_WAITQUEUE=y +CONFIG_KERNEL_DATAQUEUE=y +# CONFIG_KERNEL_CIRCULAR_AREA is not set +# CONFIG_KERNEL_AVL_TREE is not set + +# +# Kernel components init +# +CONFIG_KERNEL_COMPONENTS_INIT=y +CONFIG_ENV_INIT_KTASK_STACK_SIZE=2048 +CONFIG_KERNEL_USER_MAIN=y +CONFIG_NAME_NUM_MAX=32 +# CONFIG_KERNEL_DEBUG is not set +# CONFIG_ARCH_SMP is not set + +# +# hash table config +# +CONFIG_ID_HTABLE_SIZE=16 +CONFIG_ID_NUM_MAX=128 +# CONFIG_KERNEL_TEST is not set + +# +# Lib +# +CONFIG_LIB=y +CONFIG_LIB_POSIX=y +CONFIG_LIB_NEWLIB=y +# CONFIG_LIB_MUSLLIB is not set + +# +# C++ features +# +# CONFIG_LIB_CPLUSPLUS is not set + +# +# File system +# +CONFIG_FS_VFS=y +CONFIG_VFS_USING_WORKDIR=y +CONFIG_FS_VFS_DEVFS=y +CONFIG_FS_VFS_FATFS=y +# CONFIG_FS_CH376 is not set +# CONFIG_FS_LWEXT4 is not set + +# +# APP_Framework +# + +# +# Framework +# +CONFIG_TRANSFORM_LAYER_ATTRIUBUTE=y +CONFIG_ADD_XIZI_FEATURES=y +# CONFIG_ADD_NUTTX_FEATURES is not set +# CONFIG_ADD_RTTHREAD_FEATURES is not set +# CONFIG_SUPPORT_SENSOR_FRAMEWORK is not set +# CONFIG_SUPPORT_CONNECTION_FRAMEWORK is not set +# CONFIG_SUPPORT_KNOWING_FRAMEWORK is not set +# CONFIG_SUPPORT_CONTROL_FRAMEWORK is not set + +# +# Security +# +# CONFIG_CRYPTO is not set + +# +# Applications +# + +# +# config stack size and priority of main task +# +CONFIG_MAIN_KTASK_STACK_SIZE=1024 +CONFIG_MAIN_KTASK_PRIORITY=16 + +# +# ota app +# +# CONFIG_APPLICATION_OTA is not set + +# +# test app +# +# CONFIG_USER_TEST is not set + +# +# connection app +# +# CONFIG_APPLICATION_CONNECTION is not set + +# +# control app +# + +# +# knowing app +# +# CONFIG_APPLICATION_KNOWING is not set + +# +# sensor app +# +# CONFIG_APPLICATION_SENSOR is not set +# CONFIG_USING_EMBEDDED_DATABASE_APP is not set +# CONFIG_APP_USING_WEBNET is not set + +# +# lib +# +CONFIG_APP_SELECT_NEWLIB=y +# CONFIG_APP_SELECT_OTHER_LIB is not set +# 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 diff --git a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/config.mk b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/config.mk index b5b98fd35..6b0534d25 100644 --- a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/config.mk +++ b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/config.mk @@ -15,4 +15,8 @@ ifeq ($(CONFIG_RESOURCES_LWIP), y) export LINK_LWIP := $(KERNEL_ROOT)/resources/ethernet/LwIP/liblwip.a endif +ifeq ($(CONFIG_USE_MONGOOSE), y) +export LINK_MONGOOSE := $(KERNEL_ROOT)/../../APP_Framework/Applications/mongoose/mongoose.a +endif + export ARCH = arm diff --git a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/adc/Kconfig b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/adc/Kconfig new file mode 100644 index 000000000..fdc0b1c91 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/adc/Kconfig @@ -0,0 +1,13 @@ +if BSP_USING_ADC + config ADC1_BUS_NAME + string "adc 1 bus name" + default "adc1" + + config ADC1_DRIVER_NAME + string "adc 1 driver name" + default "adc1_drv" + + config ADC1_DEVICE_NAME + string "adc 1 bus device name" + default "adc1_dev" +endif diff --git a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/adc/Makefile b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/adc/Makefile new file mode 100644 index 000000000..05a476875 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/adc/Makefile @@ -0,0 +1,3 @@ +SRC_FILES := connect_adc.c + +include $(KERNEL_ROOT)/compiler.mk \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/adc/connect_adc.c b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/adc/connect_adc.c new file mode 100644 index 000000000..4e8b09475 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/adc/connect_adc.c @@ -0,0 +1,370 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file connect_adc.c +* @brief support to register ADC pointer and function +* @version 1.1 +* @author AIIT XUOS Lab +* @date 2023-02-09 +*/ + +#include + +/******************************************************************************* + * Local pre-processor symbols/macros ('#define') + ******************************************************************************/ + +/* The clock source of ADC. */ +#define ADC_CLK_SYS_CLK (1U) +#define ADC_CLK_PLLH (2U) +#define ADC_CLK_PLLA (3U) + +/* + * Selects a clock source according to the application requirements. + * PCLK4 is the clock for digital interface. + * PCLK2 is the clock for analog circuit. + * PCLK4 and PCLK2 are synchronous when the clock source is PLL. + * PCLK4 : PCLK2 = 1:1, 2:1, 4:1, 8:1, 1:2, 1:4. + * PCLK2 is in range [1MHz, 60MHz]. + * If the system clock is selected as the ADC clock, macro 'ADC_ADC_CLK' can only be defined as 'CLK_PERIPHCLK_PCLK'. + * If PLLH is selected as the ADC clock, macro 'ADC_ADC_CLK' can be defined as 'CLK_PERIPHCLK_PLLx'(x=Q, R). + * If PLLA is selected as the ADC clock, macro 'ADC_ADC_CLK' can be defined as 'CLK_PERIPHCLK_PLLXx'(x=P, Q, R). + */ +#define ADC_CLK_SEL (ADC_CLK_SYS_CLK) + +#if (ADC_CLK_SEL == ADC_CLK_SYS_CLK) +#define ADC_CLK (CLK_PERIPHCLK_PCLK) + +#elif (ADC_CLK_SEL == ADC_CLK_PLLH) +#define ADC_CLK (CLK_PERIPHCLK_PLLQ) + +#elif (ADC_CLK_SEL == ADC_CLK_PLLA) +#define ADC_CLK (CLK_PERIPHCLK_PLLXP) + +#else +#error "The clock source your selected does not exist!!!" +#endif + +/* ADC unit instance for this example. */ +#define ADC_UNIT (CM_ADC1) +#define ADC_PERIPH_CLK (FCG3_PERIPH_ADC1) + +/* Selects ADC channels that needed. */ +#define ADC_CH_POTENTIOMETER (ADC_CH3) +#define ADC_CH (ADC_CH_POTENTIOMETER) +#define ADC_CH_PORT (GPIO_PORT_A) +#define ADC_CH_PIN (GPIO_PIN_03) + +/* ADC sequence to be used. */ +#define ADC_SEQ (ADC_SEQ_A) +/* Flag of conversion end. */ +#define ADC_EOC_FLAG (ADC_FLAG_EOCA) + +/* ADC reference voltage. The voltage of pin VREFH. */ +#define ADC_VREF (3.3F) + +/* ADC accuracy(according to the resolution of ADC). */ +#define ADC_ACCURACY (1UL << 12U) + +/* Calculate the voltage(mV). */ +#define ADC_CAL_VOL(adcVal) (uint16_t)((((float32_t)(adcVal) * ADC_VREF) / ((float32_t)ADC_ACCURACY)) * 1000.F) + +/* Timeout value. */ +#define ADC_TIMEOUT_VAL (1000U) + +/** + * @brief Set specified ADC pin to analog mode. + * @param None + * @retval None + */ +static void AdcSetPinAnalogMode(void) +{ + stc_gpio_init_t stcGpioInit; + + (void)GPIO_StructInit(&stcGpioInit); + stcGpioInit.u16PinAttr = PIN_ATTR_ANALOG; + (void)GPIO_Init(ADC_CH_PORT, ADC_CH_PIN, &stcGpioInit); +} + +/** + * @brief Configures ADC clock. + * @param None + * @retval None + */ +static void AdcClockConfig(void) +{ +#if (ADC_CLK_SEL == ADC_CLK_SYS_CLK) + /* + * 1. Configures the clock divider of PCLK2 and PCLK4 here or in the function of configuring the system clock. + * In this example, the system clock is MRC@8MHz. + * PCLK4 is the digital interface clock, and PCLK2 is the analog circuit clock. + * Make sure that PCLK2 and PCLK4 meet the following conditions: + * PCLK4 : PCLK2 = 1:1, 2:1, 4:1, 8:1, 1:2, 1:4. + * PCLK2 is in range [1MHz, 60MHz]. + */ + CLK_SetClockDiv((CLK_BUS_PCLK2 | CLK_BUS_PCLK4), (CLK_PCLK2_DIV8 | CLK_PCLK4_DIV2)); + +#elif (ADC_CLK_SEL == ADC_CLK_PLLH) + /* + * 1. Configures PLLH and the divider of PLLHx(x=Q, R). + * PLLHx(x=Q, R) is used as both the digital interface clock and the analog circuit clock. + * PLLHx(x=Q, R) must be in range [1MHz, 60MHz] for ADC use. + * The input source of PLLH is XTAL(8MHz). + */ + stc_clock_pll_init_t stcPLLHInit; + stc_clock_xtal_init_t stcXtalInit; + + /* Configures XTAL. PLLH input source is XTAL. */ + (void)CLK_XtalStructInit(&stcXtalInit); + stcXtalInit.u8State = CLK_XTAL_ON; + stcXtalInit.u8Drv = CLK_XTAL_DRV_ULOW; + stcXtalInit.u8Mode = CLK_XTAL_MD_OSC; + stcXtalInit.u8StableTime = CLK_XTAL_STB_499US; + (void)CLK_XtalInit(&stcXtalInit); + + (void)CLK_PLLStructInit(&stcPLLHInit); + /* + * PLLHx(x=Q, R) = ((PLL_source / PLLM) * PLLN) / PLLx + * PLLHQ = (8 / 1) * 80 /16 = 40MHz + * PLLHR = (8 / 1) * 80 /16 = 40MHz + */ + stcPLLHInit.u8PLLState = CLK_PLL_ON; + stcPLLHInit.PLLCFGR = 0UL; + stcPLLHInit.PLLCFGR_f.PLLM = (1UL - 1UL); + stcPLLHInit.PLLCFGR_f.PLLN = (80UL - 1UL); + stcPLLHInit.PLLCFGR_f.PLLP = (4UL - 1UL); + stcPLLHInit.PLLCFGR_f.PLLQ = (16UL - 1UL); + stcPLLHInit.PLLCFGR_f.PLLR = (16UL - 1UL); + /* stcPLLHInit.PLLCFGR_f.PLLSRC = CLK_PLL_SRC_XTAL; */ + (void)CLK_PLLInit(&stcPLLHInit); + +#elif (ADC_CLK_SEL == ADC_CLK_PLLA) + /* + * 1. Configures PLLA and the divider of PLLAx(x=P, Q, R). + * PLLAx(x=P, Q, R) is used as both the digital interface clock and the analog circuit clock. + * PLLAx(x=P, Q, R) must be in range [1MHz, 60MHz] for ADC use. + * The input source of PLLA is HRC(16MHz). + */ + stc_clock_pllx_init_t stcPLLAInit; + + /* Enable HRC(16MHz) for PLLA. */ + CLK_HrcCmd(ENABLE); + + /* Specify the input source of PLLA. NOTE!!! PLLA and PLLH use the same input source. */ + CLK_SetPLLSrc(CLK_PLL_SRC_HRC); + /* PLLA configuration */ + (void)CLK_PLLxStructInit(&stcPLLAInit); + /* + * PLLAx(x=P, Q, R) = ((PLL_source / PLLM) * PLLN) / PLLx + * PLLAP = (16 / 2) * 40 / 8 = 40MHz + * PLLAQ = (16 / 2) * 40 / 10 = 32MHz + * PLLAR = (16 / 2) * 40 / 16 = 20MHz + */ + stcPLLAInit.u8PLLState = CLK_PLLX_ON; + stcPLLAInit.PLLCFGR = 0UL; + stcPLLAInit.PLLCFGR_f.PLLM = (2UL - 1UL); + stcPLLAInit.PLLCFGR_f.PLLN = (40UL - 1UL); + stcPLLAInit.PLLCFGR_f.PLLR = (8UL - 1UL); + stcPLLAInit.PLLCFGR_f.PLLQ = (10UL - 1UL); + stcPLLAInit.PLLCFGR_f.PLLP = (16UL - 1UL); + (void)CLK_PLLxInit(&stcPLLAInit); +#endif + /* 2. Specifies the clock source of ADC. */ + CLK_SetPeriClockSrc(ADC_CLK); +} + +/** + * @brief Initializes ADC. + * @param None + * @retval None + */ +static void AdcInitConfig(void) +{ + stc_adc_init_t stcAdcInit; + + /* 1. Enable ADC peripheral clock. */ + FCG_Fcg3PeriphClockCmd(ADC_PERIPH_CLK, ENABLE); + + /* 2. Modify the default value depends on the application. Not needed here. */ + (void)ADC_StructInit(&stcAdcInit); + + /* 3. Initializes ADC. */ + (void)ADC_Init(ADC_UNIT, &stcAdcInit); + + /* 4. ADC channel configuration. */ + /* 4.1 Set the ADC pin to analog input mode. */ + AdcSetPinAnalogMode(); + /* 4.2 Enable ADC channels. Call ADC_ChCmd() again to enable more channels if needed. */ + ADC_ChCmd(ADC_UNIT, ADC_SEQ, ADC_CH, ENABLE); + + /* 5. Conversion data average calculation function, if needed. + Call ADC_ConvDataAverageChCmd() again to enable more average channels if needed. */ + ADC_ConvDataAverageConfig(ADC_UNIT, ADC_AVG_CNT8); + ADC_ConvDataAverageChCmd(ADC_UNIT, ADC_CH, ENABLE); +} + +/** + * @brief Use ADC in polling mode. + * @param None + * @retval uint16_t u16AdcValue + */ +static uint16_t AdcPolling(void) +{ + uint16_t u16AdcValue = 0; + int32_t iRet = LL_ERR; + __IO uint32_t u32TimeCount = 0UL; + + /* Can ONLY start sequence A conversion. + Sequence B needs hardware trigger to start conversion. */ + ADC_Start(ADC_UNIT); + do { + if (ADC_GetStatus(ADC_UNIT, ADC_EOC_FLAG) == SET) { + ADC_ClearStatus(ADC_UNIT, ADC_EOC_FLAG); + iRet = LL_OK; + break; + } + } while (u32TimeCount++ < ADC_TIMEOUT_VAL); + + if (iRet == LL_OK) { + /* Get any ADC value of sequence A channel that needed. */ + u16AdcValue = ADC_GetValue(ADC_UNIT, ADC_CH); + KPrintf("The ADC value of potentiometer is %u, voltage is %u mV\r\n", + u16AdcValue, ADC_CAL_VOL(u16AdcValue)); + } else { + ADC_Stop(ADC_UNIT); + KPrintf("ADC exception.\r\n"); + } + + return ADC_CAL_VOL(u16AdcValue); +} + +static uint32 AdcOpen(void *dev) +{ + x_err_t ret = EOK; + struct AdcHardwareDevice* adc_dev = (struct AdcHardwareDevice*)dev; + + AdcClockConfig(); + AdcInitConfig(); + + return ret; +} + +static uint32 AdcClose(void *dev) +{ + struct AdcHardwareDevice* adc_dev = (struct AdcHardwareDevice*)dev; + CM_ADC_TypeDef *ADCx= (CM_ADC_TypeDef *)adc_dev->private_data; + + ADC_Stop(ADC_UNIT); + ADC_DeInit(ADCx); + + return EOK; +} + +static uint32 AdcRead(void *dev, struct BusBlockReadParam *read_param) +{ + *(uint16 *)read_param->buffer = AdcPolling(); + read_param->read_length = 2; + + return EOK; +} + +static uint32 AdcDrvConfigure(void *drv, struct BusConfigureInfo *configure_info) +{ + NULL_PARAM_CHECK(drv); + NULL_PARAM_CHECK(configure_info); + + x_err_t ret = EOK; + uint8 adc_channel; + + struct AdcDriver *adc_drv = (struct AdcDriver *)drv; + struct AdcHardwareDevice *adc_dev = (struct AdcHardwareDevice *)adc_drv->driver.owner_bus->owner_haldev; + struct HwAdc *adc_cfg = (struct HwAdc *)adc_dev->haldev.private_data; + + switch (configure_info->configure_cmd) + { + case OPE_CFG: + adc_cfg->adc_channel = *(uint8 *)configure_info->private_data; + if (adc_cfg->adc_channel != 1) { + KPrintf("AdcDrvConfigure set adc channel(1) %u error!", adc_cfg->adc_channel); + adc_cfg->adc_channel = 1; + ret = ERROR; + } + break; + default: + break; + } + + return ret; +} + +static const struct AdcDevDone dev_done = +{ + AdcOpen, + AdcClose, + NONE, + AdcRead, +}; + +int HwAdcInit(void) +{ + x_err_t ret = EOK; + +#ifdef BSP_USING_ADC + static struct AdcBus adc1_bus; + static struct AdcDriver adc1_drv; + static struct AdcHardwareDevice adc1_dev; + static struct HwAdc adc1_cfg; + + adc1_drv.configure = AdcDrvConfigure; + + ret = AdcBusInit(&adc1_bus, ADC1_BUS_NAME); + if (ret != EOK) { + KPrintf("ADC1 bus init error %d\n", ret); + return ERROR; + } + + ret = AdcDriverInit(&adc1_drv, ADC1_DRIVER_NAME); + if (ret != EOK) { + KPrintf("ADC1 driver init error %d\n", ret); + return ERROR; + } + ret = AdcDriverAttachToBus(ADC1_DRIVER_NAME, ADC1_BUS_NAME); + if (ret != EOK) { + KPrintf("ADC1 driver attach error %d\n", ret); + return ERROR; + } + + adc1_dev.adc_dev_done = &dev_done; + adc1_cfg.ADCx = CM_ADC1; + adc1_cfg.adc_channel = 1; + + ret = AdcDeviceRegister(&adc1_dev, (void *)&adc1_cfg, ADC1_DEVICE_NAME); + if (ret != EOK) { + KPrintf("ADC1 device register error %d\n", ret); + return ERROR; + } + ret = AdcDeviceAttachToBus(ADC1_DEVICE_NAME, ADC1_BUS_NAME); + if (ret != EOK) { + KPrintf("ADC1 device register error %d\n", ret); + return ERROR; + } +#endif + + return ret; + +} + + + + + diff --git a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/can/Kconfig b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/can/Kconfig new file mode 100644 index 000000000..a78636cbd --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/can/Kconfig @@ -0,0 +1,15 @@ +config CAN_BUS_NAME_2 + string "can bus name" + default "can2" + +config CAN_DRIVER_NAME_2 + string "can driver name" + default "can2_drv" + +config CAN_2_DEVICE_NAME_1 + string "can bus 1 device 1 name" + default "can2_dev1" + +config CAN_USING_INTERRUPT + bool "can interrupt open" + default n \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/can/Makefile b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/can/Makefile new file mode 100644 index 000000000..22aba4901 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/can/Makefile @@ -0,0 +1,4 @@ +SRC_FILES := connect_can.c + + +include $(KERNEL_ROOT)/compiler.mk \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/can/connect_can.c b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/can/connect_can.c new file mode 100644 index 000000000..088892e67 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/can/connect_can.c @@ -0,0 +1,297 @@ +/* + * Copyright (c) Guangzhou Xingyi Electronic Technology Co., Ltd + * + * Change Logs: + * Date Author Notes + * 2014-7-4 alientek first version + */ + +/** +* @file connect_can.c +* @brief support hc32f4a0 can function and register to bus framework +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2023-02-20 +*/ + +/************************************************* +File name: connect_can.c +Description: support can configure and spi bus register function for hc32f4a0 +Others: connect_can.c for references +*************************************************/ + +#include "connect_can.h" + +#define CAN_X (CM_CAN2) + +#define CAN_TX_PORT (GPIO_PORT_D) +#define CAN_TX_PIN (GPIO_PIN_07) +#define CAN_RX_PORT (GPIO_PORT_D) +#define CAN_RX_PIN (GPIO_PIN_06) +#define CAN_TX_PIN_FUNC (GPIO_FUNC_62) +#define CAN_RX_PIN_FUNC (GPIO_FUNC_63) + +#define INTSEL_REG ((uint32_t)(&CM_INTC->SEL0)) +#define CANX_IRQ_SRC INT_SRC_CAN2_HOST +#define CANX_IRQ_NUM 17 +#define IRQ_NUM_OFFSET 16 + +#define CAN_AF1_ID (0x123UL) +#define CAN_AF1_ID_MSK (0xFFFUL) +#define CAN_AF1_MSK_TYPE CAN_ID_STD +#define CAN_AF2_ID (0x005UL) +#define CAN_AF2_ID_MSK (0x00FUL) +#define CAN_AF2_MSK_TYPE CAN_ID_STD +#define CAN_AF3_ID (0x23UL) +#define CAN_AF3_ID_MSK (0xFFUL) +#define CAN_AF3_MSK_TYPE CAN_ID_STD + +#ifdef CAN_USING_INTERRUPT +void CanIrqHandler(int vector, void *param) +{ + stc_can_error_info_t err_info; + uint32_t status = CAN_GetStatusValue(CAN_X); + uint32_t error = CAN_GetErrorInfo(CAN_X,&err_info); + + KPrintf("Irq entered\n"); + + CAN_ClearStatus(CAN_X, status); +} + +static void CanIrqConfig(void) +{ + // register IRQ src in IRQn + __IO uint32_t *INTC_SELx = (__IO uint32_t *)(INTSEL_REG+ 4U * (uint32_t)(CANX_IRQ_NUM)); + WRITE_REG32(*INTC_SELx, CANX_IRQ_SRC); + isrManager.done->registerIrq(CANX_IRQ_NUM+IRQ_NUM_OFFSET,CanIrqHandler,NULL); + isrManager.done->enableIrq(CANX_IRQ_NUM); +} +#endif + +static void CanInit(struct CanDriverConfigure *can_drv_config) +{ + stc_can_init_t stcInit; + stc_can_filter_config_t astcAFCfg[] = { \ + {CAN_AF1_ID, CAN_AF1_ID_MSK, CAN_AF1_MSK_TYPE}, \ + {CAN_AF2_ID, CAN_AF2_ID_MSK, CAN_AF2_MSK_TYPE}, \ + {CAN_AF3_ID, CAN_AF3_ID_MSK, CAN_AF3_MSK_TYPE}, \ + }; + + CLK_SetCANClockSrc(CLK_CAN2,CLK_CANCLK_SYSCLK_DIV4); + + /* Set the function of CAN pins. */ + GPIO_SetFunc(CAN_TX_PORT, CAN_TX_PIN, CAN_TX_PIN_FUNC); + GPIO_SetFunc(CAN_RX_PORT, CAN_RX_PIN, CAN_RX_PIN_FUNC); + + /* Initializes CAN. */ + (void)CAN_StructInit(&stcInit); + stcInit.pstcFilter = astcAFCfg; + stcInit.u16FilterSelect = (CAN_FILTER1 | CAN_FILTER2 | CAN_FILTER3); + + // Driver's config + stcInit.stcBitCfg.u32SJW = can_drv_config->tsjw; + stcInit.stcBitCfg.u32Prescaler = can_drv_config->brp; + stcInit.stcBitCfg.u32TimeSeg1 = can_drv_config->tbs1; + stcInit.stcBitCfg.u32TimeSeg2 = can_drv_config->tbs2; + stcInit.u8WorkMode = can_drv_config->mode; + +#ifdef CAN_USING_FD + stcInit.stcFDCfg.u8TDCSSP = 16U; + stcInit.stcFDCfg.u8CANFDMode = CAN_FD_MODE_ISO_11898; + stcInit.stcFDCfg.stcFBT.u32SEG1 = 16U; + stcInit.stcFDCfg.stcFBT.u32SEG2 = 4U; + stcInit.stcFDCfg.stcFBT.u32SJW = 4U; + stcInit.stcFDCfg.stcFBT.u32Prescaler = 1U; + (void)CAN_FD_Init(APP_CAN_UNIT, &stcInit); +#else + FCG_Fcg1PeriphClockCmd(PWC_FCG1_CAN2, ENABLE); + (void)CAN_Init(CAN_X, &stcInit); +#endif + CAN_ClearStatus(CAN_X, 0xFFFFFFFFU); + +#ifdef CAN_USING_INTERRUPT + /* Configures the interrupts if needed. */ + CAN_IntCmd(CAN_X, CAN_INT_RX, ENABLE); + CanIrqConfig(); +#endif +} + +static uint32 CanConfig(void *can_drv_config) +{ + x_err_t ret = EOK; + return ret; +} + +static uint32 CanDrvConfigure(void *drv, struct BusConfigureInfo *configure_info) +{ + x_err_t ret = EOK; + NULL_PARAM_CHECK(drv); + NULL_PARAM_CHECK(configure_info); + struct CanDriverConfigure *can_drv_config; + switch (configure_info->configure_cmd) + { + case OPE_INT: // can basic init + can_drv_config = (struct CanDriverConfigure *)configure_info->private_data; + CanInit(can_drv_config); + break; + case OPE_CFG: + CanConfig(configure_info->private_data); + break; + default: + break; + } + + return ret; +} + + +static uint32 CanWriteData(void * dev , struct BusBlockWriteParam *write_param) +{ + x_err_t ret=EOK; + NULL_PARAM_CHECK(dev); + NULL_PARAM_CHECK(write_param); + struct CanSendConfigure *p_can_config = (struct CanSendConfigure*)write_param->buffer; + stc_can_tx_frame_t can_frame_obj; + memset(&can_frame_obj,0,sizeof(stc_can_tx_frame_t)); + + // configure CAN's flag bit + can_frame_obj.IDE = p_can_config->ide; + if(1==p_can_config->ide){ + can_frame_obj.u32ID = p_can_config->exdid; + }else{ + can_frame_obj.u32ID = p_can_config->stdid; + } + can_frame_obj.RTR = p_can_config->rtr; + + memcpy(can_frame_obj.au8Data,p_can_config->data,p_can_config->data_lenth); + can_frame_obj.DLC = p_can_config->data_lenth; + + //put frame_buffer in message queue + if(can_frame_obj.DLC){ + ret = CAN_FillTxFrame(CAN_X,CAN_TX_BUF_STB,&can_frame_obj); + if(EOK != ret){ + KPrintf("CAN fill tx frame failed(CODE:%d)!\n",ret); + return ERROR; + } + CAN_StartTx(CAN_X,CAN_TX_REQ_STB_ONE); + } + return ret; +} + +static uint32 CanReadData(void *dev , struct BusBlockReadParam *databuf) +{ + NULL_PARAM_CHECK(dev); + NULL_PARAM_CHECK(databuf); + x_err_t ret=EOK; + stc_can_rx_frame_t frame_received; + struct CanSendConfigure *p_can_config = (struct CanSendConfigure*)databuf->buffer; + memset(&frame_received,0,sizeof(stc_can_rx_frame_t)); + + ret = CAN_GetRxFrame(CAN_X, &frame_received); + if(EOK != ret){ + // KPrintf("CAN recv frame failed(CODE:%d)!\n",ret); + p_can_config->data_lenth = 0; + return ERROR; + } + + //put message in frame_buffer + p_can_config->ide = frame_received.IDE; + p_can_config->rtr = frame_received.RTR; + if(p_can_config->ide==1){ + p_can_config->exdid = frame_received.u32ID ; + }else{ + p_can_config->stdid = frame_received.u32ID; + p_can_config->exdid = frame_received.u32ID ; + } + p_can_config->data_lenth = frame_received.DLC; + for(int i=0;idata_lenth;i++){ + p_can_config->data[i] = frame_received.au8Data[i]; + } + + return frame_received.DLC; +} + +static struct CanDevDone can_dev_done = +{ + .open = NONE, + .close = NONE, + .write = CanWriteData, + .read = CanReadData +}; + +static int BoardCanBusInit(struct CanBus *can_bus, struct CanDriver *can_driver) +{ + x_err_t ret = EOK; + + /*Init the can bus */ + ret = CanBusInit(can_bus, CAN_BUS_NAME_2); + if (EOK != ret) { + KPrintf("Board_can_init canBusInit error %d\n", ret); + return ERROR; + } + + /*Init the can driver*/ + ret = CanDriverInit(can_driver, CAN_DRIVER_NAME_2); + if (EOK != ret) { + KPrintf("Board_can_init canDriverInit error %d\n", ret); + return ERROR; + } + /*Attach the can driver to the can bus*/ + ret = CanDriverAttachToBus(CAN_DRIVER_NAME_2, CAN_BUS_NAME_2); + if (EOK != ret) { + KPrintf("Board_can_init CanDriverAttachToBus error %d\n", ret); + return ERROR; + } + + return ret; +} + +/* Attach the can device to the can bus*/ +static int BoardCanDevBend(void) +{ + x_err_t ret = EOK; + static struct CanHardwareDevice can_device0; + memset(&can_device0, 0, sizeof(struct CanHardwareDevice)); + + can_device0.dev_done = &can_dev_done; + + ret = CanDeviceRegister(&can_device0, NONE, CAN_2_DEVICE_NAME_1); + if (EOK != ret) { + KPrintf("board_can_init CanDeviceInit device %s error %d\n", CAN_2_DEVICE_NAME_1, ret); + return ERROR; + } + + ret = CanDeviceAttachToBus(CAN_2_DEVICE_NAME_1, CAN_BUS_NAME_2); + if (EOK != ret) { + KPrintf("board_can_init CanDeviceAttachToBus device %s error %d\n", CAN_2_DEVICE_NAME_1, ret); + return ERROR; + } + + return ret; +} + +int HwCanInit(void) +{ + x_err_t ret = EOK; + + static struct CanBus can_bus; + memset(&can_bus, 0, sizeof(struct CanBus)); + + static struct CanDriver can_driver; + memset(&can_driver, 0, sizeof(struct CanDriver)); + + can_driver.configure = &(CanDrvConfigure); + + ret = BoardCanBusInit(&can_bus, &can_driver); + if (EOK != ret) { + KPrintf(" can_bus_init %s error ret %u\n", CAN_BUS_NAME_2, ret); + return ERROR; + } + + ret = BoardCanDevBend(); + if (EOK != ret) { + KPrintf("board_can_init error ret %u\n", ret); + return ERROR; + } + return EOK; +} diff --git a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/dac/Kconfig b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/dac/Kconfig new file mode 100644 index 000000000..a289b6ca9 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/dac/Kconfig @@ -0,0 +1,17 @@ +if BSP_USING_DAC + config DAC_BUS_NAME + string "dac bus name" + default "dac" + + config DAC_DRIVER_NAME + string "dac driver name" + default "dac_drv" + + config DAC_DEVICE_NAME + string "dac bus device name" + default "dac_dev" + + config DAC_GPIO_NUM + int "dac gpio pin num(only support 4 or 5)" + default "4" +endif diff --git a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/dac/Makefile b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/dac/Makefile new file mode 100644 index 000000000..a787e5457 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/dac/Makefile @@ -0,0 +1,3 @@ +SRC_FILES := connect_dac.c + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/dac/connect_dac.c b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/dac/connect_dac.c new file mode 100644 index 000000000..efcc80743 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/dac/connect_dac.c @@ -0,0 +1,398 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file connect_dac.c +* @brief support to register DAC pointer and function +* @version 2.0 +* @author AIIT XUOS Lab +* @date 2023-02-09 +*/ + +#include + +/******************************************************************************* + * Local pre-processor symbols/macros ('#define') + ******************************************************************************/ +#define DAC_UNIT1_PORT (GPIO_PORT_A) +#define DAC_UNIT1_CHN1_PIN (GPIO_PIN_04) + +#define VREFH (3.3F) +#define DAC_CHN1 (0U) +#define DAC_CHN2 (1U) +#define DAC_DATA_ALIGN_12b_R (0U) +#define DAC_DATA_ALIGN_12b_L (1U) + +#define SUPPORT_AMP +#define SUPPORT_ADP +#define SINGLE_WAVE_DAC_CHN (DAC_CHN1) +#define DAC_DATA_ALIGN (DAC_DATA_ALIGN_12b_L) + +#define SINE_DOT_NUMBER (4096U) +#define SINE_NEGATIVE_TO_POSITVE (1.0F) + +/******************************************************************************* + * Local type definitions ('typedef') + ******************************************************************************/ +typedef enum { + DAC_Unit1, + DAC_Unit2, + DAC_Unit_Max, +}en_dac_unit_t; + +typedef enum { + E_Dac_Single, + E_Dac_Dual, +}en_dac_cvt_t; + +typedef struct { + CM_DAC_TypeDef *pUnit; + en_dac_cvt_t enCvtType; + uint16_t u16Ch; +} stc_dac_handle_t; + +/******************************************************************************* + * Local variable definitions ('static') + ******************************************************************************/ +static stc_dac_handle_t m_stcDACHandle[DAC_Unit_Max] = {0}; +static uint32_t gu32SinTable[SINE_DOT_NUMBER]; +static stc_dac_handle_t *pSingleDac; + +/******************************************************************************* + * Function implementation - global ('extern') and local ('static') + ******************************************************************************/ +/** + * @brief MAU Initialization + * @param None + * @retval None + */ +static void MauInit(void) +{ + /* Enable MAU peripheral clock. */ + FCG_Fcg0PeriphClockCmd(PWC_FCG0_MAU, ENABLE); +} + +/** + * @brief MAU De-Initialization + * @param None + * @retval None + */ +static void MauDeinit(void) +{ + /* Enable MAU peripheral clock. */ + FCG_Fcg0PeriphClockCmd(PWC_FCG0_MAU, DISABLE); +} + +/** + * @brief Sin table Initialization + * @param [in] pSinTable sin table + * @param [in] u32count number of pSinTable items + * @retval None + */ +static void SinTableInit(uint32_t pSinTable[], uint32_t u32count) +{ + uint32_t i; + uint32_t u32AngAvg = (uint32_t)(float32_t)((float32_t)((float32_t)MAU_SIN_ANGIDX_TOTAL / (float32_t)u32count) + 0.5); + float32_t fSin; + for (i = 0U; i < u32count; i++) { + fSin = (((float32_t)MAU_Sin(CM_MAU, (uint16_t)(u32AngAvg * i)) + / (float32_t)MAU_SIN_Q15_SCALAR + SINE_NEGATIVE_TO_POSITVE) / VREFH) * + (float32_t)DAC_DATAREG_VALUE_MAX + 0.5F; + +#if (DAC_DATA_ALIGN == DAC_DATA_ALIGN_12b_L) + { + pSinTable[i] = (uint32_t)fSin << 4; + } +#else + { + pSinTable[i] = (uint32_t)fSin; + } +#endif + } +} + +/** + * @brief Enable DAC peripheral clock + * @param [in] enUnit The selected DAC unit + * @retval None + */ +static void DacPClkEnable(en_dac_unit_t enUnit) +{ + uint32_t u32PClk; + switch (enUnit) { + case DAC_Unit1: + u32PClk = PWC_FCG3_DAC1; + break; + case DAC_Unit2: + u32PClk = PWC_FCG3_DAC2; + break; + default: + u32PClk = PWC_FCG3_DAC1 | PWC_FCG3_DAC2; + break; + } + /* Enable DAC peripheral clock. */ + FCG_Fcg3PeriphClockCmd(u32PClk, ENABLE); +} + +/** + * @brief Init DAC single channel + * @param [in] enUnit The selected DAC unit + * @retval A pointer of DAC handler + */ +static stc_dac_handle_t *DacSingleConversionInit(en_dac_unit_t enUnit) +{ + uint8_t u8Port; + uint16_t u16Pin; + stc_dac_handle_t *pDac; + + if (enUnit == DAC_Unit1) { + pDac = &m_stcDACHandle[DAC_Unit1]; + pDac->pUnit = CM_DAC1; + } else { + pDac = &m_stcDACHandle[DAC_Unit2]; + pDac->pUnit = CM_DAC2; + } + DacPClkEnable(enUnit); + + pDac->enCvtType = E_Dac_Single; +#if (SINGLE_WAVE_DAC_CHN == DAC_CHN1) + pDac->u16Ch = DAC_CH1; +#else + pDac->u16Ch = DAC_CH2; +#endif + + /* Init DAC by default value: source from data register and output enabled*/ + DAC_DeInit(pDac->pUnit); + stc_dac_init_t stInit; + (void)DAC_StructInit(&stInit); + (void)DAC_Init(pDac->pUnit, pDac->u16Ch, &stInit); +#if (DAC_DATA_ALIGN == DAC_DATA_ALIGN_12b_L) + DAC_DataRegAlignConfig(pDac->pUnit, DAC_DATA_ALIGN_L); +#else + DAC_DataRegAlignConfig(pDac->pUnit, DAC_DATA_ALIGN_R); +#endif + + /* Set DAC pin attribute to analog */ + if (enUnit == DAC_Unit1) { + u8Port = DAC_UNIT1_PORT; +#if (SINGLE_WAVE_DAC_CHN == DAC_CHN1) + u16Pin = DAC_UNIT1_CHN1_PIN; +#endif + } + stc_gpio_init_t stcGpioInit; + (void)GPIO_StructInit(&stcGpioInit); + stcGpioInit.u16PinAttr = PIN_ATTR_ANALOG; + (void)GPIO_Init(u8Port, u16Pin, &stcGpioInit); + +#ifdef SUPPORT_ADP + /* Set ADC first */ + /* Enable ADC peripheral clock. */ + FCG_Fcg3PeriphClockCmd(PWC_FCG3_ADC1 | PWC_FCG3_ADC2 | PWC_FCG3_ADC3, ENABLE); + if (CM_ADC1->STR == 0U) { + if (CM_ADC2->STR == 0U) { + if (CM_ADC3->STR == 0U) { + DAC_ADCPrioConfig(pDac->pUnit, DAC_ADP_SELECT_ALL, ENABLE); + DAC_ADCPrioCmd(pDac->pUnit, ENABLE); + } + } + } +#endif + return pDac; +} + +/** + * @brief Start single DAC conversions + * @param [in] pDac A pointer of DAC handler + * @retval None + */ +static void DacStartSingleConversion(const stc_dac_handle_t *pDac) +{ + /* Enalbe AMP */ +#ifdef SUPPORT_AMP + (void)DAC_AMPCmd(pDac->pUnit, pDac->u16Ch, ENABLE); +#endif + + (void)DAC_Start(pDac->pUnit, pDac->u16Ch); + +#ifdef SUPPORT_AMP + /* delay 3us before setting data*/ + DDL_DelayMS(1U); +#endif +} + +/** + * @brief Convert data by single DAC channel + * @param [in] pDac A pointer of DAC handler + * @param [in] pDataTable The data table to be converted + * @param [in] u32count Number of data table items + * @retval None + */ +__STATIC_INLINE void DacSetSingleConversionData(const stc_dac_handle_t *pDac, uint32_t const pDataTable[], uint32_t u32count) +{ + uint32_t i = 0U; + + for (i = 0U; i < u32count; i++) { +#ifdef SUPPORT_ADP + uint32_t u32TryCount = 100U; + while (u32TryCount != 0U) { + u32TryCount--; + if (SET != DAC_GetChConvertState(pDac->pUnit, pDac->u16Ch)) { + break; + } + } +#endif + DAC_SetChData(pDac->pUnit, pDac->u16Ch, (uint16_t)pDataTable[i]); + } +} + +/** + * @brief stop DAC conversion + * @param [in] pDac A pointer of DAC handler + * @retval None + */ +static void DAC_StopConversion(const stc_dac_handle_t *pDac) +{ + if (NULL == pDac) { + DAC_DeInit(CM_DAC1); + DAC_DeInit(CM_DAC2); + } else if (pDac->enCvtType != E_Dac_Dual) { + (void)DAC_Stop(pDac->pUnit, pDac->u16Ch); + } else { + DAC_StopDualCh(pDac->pUnit); + } +} + +static uint32 DacOpen(void *dev) +{ + struct DacHardwareDevice *dac_dev = (struct DacHardwareDevice *)dev; + + /* Init MAU for generating sine data*/ + MauInit(); + /* Init sine data table */ + SinTableInit(gu32SinTable, SINE_DOT_NUMBER); + + /* Init single DAC */ + pSingleDac = DacSingleConversionInit(DAC_Unit1); + + return EOK; +} + +static uint32 DacClose(void *dev) +{ + struct DacHardwareDevice *dac_dev = (struct DacHardwareDevice *)dev; + CM_DAC_TypeDef *DACx = (CM_DAC_TypeDef *)dac_dev->private_data; + + DAC_StopConversion(pSingleDac); + + DAC_DeInit(DACx); + + MauDeinit(); + + memset(gu32SinTable, 0 , sizeof(gu32SinTable)); + + return EOK; +} + +static uint32 DacWrite(void *dev, struct BusBlockWriteParam *write_param) +{ + struct DacHardwareDevice *dac_dev = (struct DacHardwareDevice *)dev; + struct HwDac *dac_cfg = (struct HwDac *)dac_dev->haldev.private_data; + + for (int i = 0; i < dac_cfg->digital_data; i ++) { + DacStartSingleConversion(pSingleDac); + DacSetSingleConversionData(pSingleDac, &gu32SinTable[i], 1U); + if (i > SINE_DOT_NUMBER) { + i = 0; + } + } + + return EOK; +} + +static uint32 DacDrvConfigure(void *drv, struct BusConfigureInfo *configure_info) +{ + NULL_PARAM_CHECK(drv); + NULL_PARAM_CHECK(configure_info); + + x_err_t ret = EOK; + + struct DacDriver *dac_drv = (struct DacDriver *)drv; + struct DacHardwareDevice *dac_dev = (struct DacHardwareDevice *)dac_drv->driver.owner_bus->owner_haldev; + struct HwDac *dac_cfg = (struct HwDac *)dac_dev->haldev.private_data; + + switch (configure_info->configure_cmd) + { + case OPE_CFG: + dac_cfg->digital_data = *(uint16 *)configure_info->private_data; + break; + default: + break; + } + + return ret; +} + +static const struct DacDevDone dev_done = +{ + DacOpen, + DacClose, + DacWrite, + NONE, +}; + +int HwDacInit(void) +{ + x_err_t ret = EOK; + +#ifdef BSP_USING_DAC + static struct DacBus dac_bus; + static struct DacDriver dac_drv; + static struct DacHardwareDevice dac_dev; + static struct HwDac dac_cfg; + + dac_drv.configure = DacDrvConfigure; + + ret = DacBusInit(&dac_bus, DAC_BUS_NAME); + if (ret != EOK) { + KPrintf("DAC bus init error %d\n", ret); + return ERROR; + } + + ret = DacDriverInit(&dac_drv, DAC_DRIVER_NAME); + if (ret != EOK) { + KPrintf("DAC driver init error %d\n", ret); + return ERROR; + } + ret = DacDriverAttachToBus(DAC_DRIVER_NAME, DAC_BUS_NAME); + if (ret != EOK) { + KPrintf("DAC driver attach error %d\n", ret); + return ERROR; + } + + dac_dev.dac_dev_done = &dev_done; + dac_cfg.DACx = CM_DAC1; + dac_cfg.digital_data = 0; + + ret = DacDeviceRegister(&dac_dev, (void *)&dac_cfg, DAC_DEVICE_NAME); + if (ret != EOK) { + KPrintf("DAC device register error %d\n", ret); + return ERROR; + } + ret = DacDeviceAttachToBus(DAC_DEVICE_NAME, DAC_BUS_NAME); + if (ret != EOK) { + KPrintf("DAC device register error %d\n", ret); + return ERROR; + } +#endif + + return ret; +} diff --git a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/ethernet/eth_driver.c b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/ethernet/eth_driver.c index 9ad1468d0..a1e94307c 100644 --- a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/ethernet/eth_driver.c +++ b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/ethernet/eth_driver.c @@ -277,10 +277,7 @@ struct pbuf* low_level_input(struct netif* netif) return p; } -extern void LwipSetIPTest(int argc, char* argv[]); int HwEthInit(void) { - // lwip_config_tcp(0, lwip_ipaddr, lwip_netmask, lwip_gwaddr); - LwipSetIPTest(1, NULL); return EOK; } diff --git a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/ethernet/eth_netdev.c b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/ethernet/eth_netdev.c index 862d80bd8..0f6a8df37 100644 --- a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/ethernet/eth_netdev.c +++ b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/ethernet/eth_netdev.c @@ -76,6 +76,7 @@ static int lwip_netdev_set_addr_info(struct netdev* netdev, ip_addr_t* ip_addr, netif_set_gw((struct netif*)netdev->user_data, ip_2_ip4(gw)); } } + return 0; } #ifdef LWIP_DNS @@ -92,7 +93,7 @@ static int lwip_netdev_set_dns_server(struct netdev* netdev, uint8_t dns_num, ip } #endif -#ifdef LWIP_DHCP +#if LWIP_DHCP static int lwip_netdev_set_dhcp(struct netdev* netdev, bool is_enabled) { netdev_low_level_set_dhcp_status(netdev, is_enabled); @@ -120,7 +121,7 @@ static const struct netdev_ops lwip_netdev_ops = { #ifdef LWIP_DNS .set_dns_server = lwip_netdev_set_dns_server, #endif -#ifdef LWIP_DHCP +#if LWIP_DHCP .set_dhcp = lwip_netdev_set_dhcp, #endif .set_default = lwip_netdev_set_default, @@ -183,9 +184,9 @@ int lwip_netdev_add(struct netif* lwip_netif) netdev->ops = &lwip_netdev_ops; netdev->hwaddr_len = lwip_netif->hwaddr_len; memcpy(netdev->hwaddr, lwip_netif->hwaddr, lwip_netif->hwaddr_len); - netdev->ip_addr = lwip_netif->ip_addr; - netdev->gw = lwip_netif->gw; - netdev->netmask = lwip_netif->netmask; + netdev->ip_addr = &lwip_netif->ip_addr; + netdev->gw = &lwip_netif->gw; + netdev->netmask = &lwip_netif->netmask; return result; } diff --git a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/ethernet/ethernetif.c b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/ethernet/ethernetif.c index 0e1c2a9ed..c5d1309b4 100644 --- a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/ethernet/ethernetif.c +++ b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/ethernet/ethernetif.c @@ -204,7 +204,6 @@ void ethernetif_input(void* netif_arg) /* Move received packet into a new pbuf */ while (1) { sys_arch_sem_wait(get_eth_recv_sem(), WAITING_FOREVER); - KPrintf("%s -->\n", netif->name); while (1) { p = low_level_input(netif); #ifndef ETHERNET_LOOPBACK_TEST diff --git a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/ethernet_wiz/Kconfig b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/ethernet_wiz/Kconfig index 757b85bfb..f32bb08e5 100644 --- a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/ethernet_wiz/Kconfig +++ b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/ethernet_wiz/Kconfig @@ -1,9 +1,5 @@ # Kconfig file -config BSP_WIZ_RST_PIN - int - default 13 - config BSP_WIZ_INT_PIN int - default 14 + default 106 diff --git a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/ethernet_wiz/w5x00_lwip.c b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/ethernet_wiz/w5x00_lwip.c index 2494cdb32..357a9e404 100644 --- a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/ethernet_wiz/w5x00_lwip.c +++ b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/ethernet_wiz/w5x00_lwip.c @@ -113,7 +113,6 @@ void ethernetif_input2(void* netif_arg) struct pbuf* p = NULL; for (;;) { sys_arch_sem_wait(get_eth_recv_sem2(), WAITING_FOREVER); - KPrintf("%s -->\n", netif->name); sys_mutex_lock(&wiz_trans_mtx); while (1) { diff --git a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/i2c/Kconfig b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/i2c/Kconfig new file mode 100644 index 000000000..7808c6abb --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/i2c/Kconfig @@ -0,0 +1,22 @@ +config I2C_BUS_NAME_1 + string "i2c 1 bus name" + default "i2c1" +config I2C_DRV_NAME_1 + string "i2c bus 1 driver name" + default "i2c1_drv" +config I2C_1_DEVICE_NAME_0 + string "i2c bus 1 device 0 name" + default "i2c1_dev0" +config I2C_DEVICE_MODE + bool "choose i2c device mode as master or slave" + default y + choice + prompt "choose i2c mode" + default I2C_DEVICE_MASTER + + config I2C_DEVICE_MASTER + bool "set i2c master" + + config I2C_DEVICE_SLAVE + bool "set i2c slave" + endchoice diff --git a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/i2c/Makefile b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/i2c/Makefile new file mode 100644 index 000000000..4acf3b676 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/i2c/Makefile @@ -0,0 +1,3 @@ +SRC_FILES := connect_i2c.c + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/i2c/connect_i2c.c b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/i2c/connect_i2c.c new file mode 100644 index 000000000..20149f915 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/i2c/connect_i2c.c @@ -0,0 +1,491 @@ +/* + ******************************************************************************* + * Copyright (C) 2022, Xiaohua Semiconductor Co., Ltd. All rights reserved. + * + * This software component is licensed by XHSC under BSD 3-Clause license + * (the "License"); You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ******************************************************************************* + */ + +/** +* @file connect_i2c.c +* @brief support edu-arm32-board i2c function and register to bus framework +* @version 3.0 +* @author AIIT XUOS Lab +* @date 2022-12-05 +*/ + +/************************************************* +File name: connect_i2c.c +Description: support edu-arm32-board i2c configure and i2c bus register function +Others: take projects/ev_hc32f4a0_lqfp176/examples/i2c/i2c_master_polling/source/main.c for references +History: +1. Date: 2022-12-05 +Author: AIIT XUOS Lab +Modification: +1. support edu-arm32-board i2c configure, write and read +2. support edu-arm32-board i2c bus device and driver register +*************************************************/ + +#include + +#define I2C_UNIT (CM_I2C1) +#define I2C_FCG_USE (FCG1_PERIPH_I2C1) + +#define I2C_TIMEOUT (0x40000UL) +#define I2C_BAUDRATE (400000UL) + +/* Define port and pin for SDA and SCL */ +#define I2C_SCL_PORT (GPIO_PORT_D) +#define I2C_SCL_PIN (GPIO_PIN_03) +#define I2C_SDA_PORT (GPIO_PORT_F) +#define I2C_SDA_PIN (GPIO_PIN_10) +#define I2C_GPIO_SCL_FUNC (GPIO_FUNC_49) +#define I2C_GPIO_SDA_FUNC (GPIO_FUNC_48) + +static x_err_t I2cGpioInit(void) +{ + GPIO_SetFunc(I2C_SDA_PORT, I2C_SDA_PIN, I2C_GPIO_SDA_FUNC); + GPIO_SetFunc(I2C_SCL_PORT, I2C_SCL_PIN, I2C_GPIO_SCL_FUNC); + + return EOK; +} + +static uint32 I2cInit(struct I2cDriver *i2c_drv, struct BusConfigureInfo *configure_info) +{ + NULL_PARAM_CHECK(i2c_drv); + + struct I2cHardwareDevice *i2c_dev = (struct I2cHardwareDevice *)i2c_drv->driver.owner_bus->owner_haldev; + + stc_i2c_init_t i2c_init; + (void)I2C_StructInit(&i2c_init); + i2c_init.u32Baudrate = I2C_BAUDRATE; + i2c_init.u32SclTime = 3UL; + i2c_init.u32ClockDiv = I2C_CLK_DIV4; + + if (configure_info->private_data) { + i2c_dev->i2c_dev_addr = *((uint16 *)configure_info->private_data); + } else { + KPrintf("I2cInit need set i2c dev addr\n"); + return ERROR; + } + + /* Configure I2C */ + float32_t f32Error; + int32_t i32Ret = LL_ERR; + I2C_DeInit(I2C_UNIT); + i32Ret = I2C_Init(I2C_UNIT, &i2c_init, &f32Error); + +#ifdef I2C_DEVICE_SLAVE + if (LL_OK == i32Ret) { + /* Set slave address */ + I2C_SlaveAddrConfig(I2C_UNIT, I2C_ADDR0, I2C_ADDR_7BIT, i2c_dev->i2c_dev_addr); + } +#endif + + if(i32Ret != LL_OK) { + return ERROR; + } + + I2C_BusWaitCmd(I2C_UNIT, ENABLE); + + return EOK; +} + +static uint32 I2cDrvConfigure(void *drv, struct BusConfigureInfo *configure_info) +{ + NULL_PARAM_CHECK(drv); + NULL_PARAM_CHECK(configure_info); + + x_err_t ret = EOK; + struct I2cDriver *i2c_drv = (struct I2cDriver *)drv; + + switch (configure_info->configure_cmd) + { + case OPE_INT: + ret = I2cInit(i2c_drv, configure_info); + break; + default: + break; + } + + return ret; +} + +static uint32 I2cMasterWriteData(struct I2cHardwareDevice *i2c_dev, struct I2cDataStandard *msg) +{ + if (msg->len == 0) { + return EOK; + } + uint32 i32Ret; + + I2C_Cmd(I2C_UNIT, ENABLE); + DDL_DelayMS(20UL); + I2C_SWResetCmd(I2C_UNIT, ENABLE); + I2C_SWResetCmd(I2C_UNIT, DISABLE); + DDL_DelayMS(20UL); + i32Ret = I2C_Start(I2C_UNIT, I2C_TIMEOUT); + if (LL_OK == i32Ret) { + i32Ret = I2C_TransAddr(I2C_UNIT, i2c_dev->i2c_dev_addr, I2C_DIR_TX, I2C_TIMEOUT); + + if (i32Ret == LL_OK) { + i32Ret = I2C_TransData(I2C_UNIT, msg->buf, msg->len, I2C_TIMEOUT); + KPrintf("Master Send Success!\n"); + } + } + + (void)I2C_Stop(I2C_UNIT, I2C_TIMEOUT); + I2C_Cmd(I2C_UNIT, DISABLE); + + return i32Ret; +} + +static uint32 I2cMasterReadData(struct I2cHardwareDevice *i2c_dev, struct I2cDataStandard *msg) +{ + uint32 i32Ret; + + I2C_Cmd(I2C_UNIT, ENABLE); + I2C_SWResetCmd(I2C_UNIT, ENABLE); + I2C_SWResetCmd(I2C_UNIT, DISABLE); + i32Ret = I2C_Start(I2C_UNIT, I2C_TIMEOUT); + if (LL_OK == i32Ret) { + if (msg->len == 1U) { + I2C_AckConfig(I2C_UNIT, I2C_NACK); + } + + i32Ret = I2C_TransAddr(I2C_UNIT, i2c_dev->i2c_dev_addr, I2C_DIR_RX, I2C_TIMEOUT); + + if (LL_OK == i32Ret) { + i32Ret = I2C_MasterReceiveDataAndStop(I2C_UNIT, msg->buf, msg->len, I2C_TIMEOUT); + KPrintf("Master Receive Success!\n"); + } + + I2C_AckConfig(I2C_UNIT, I2C_ACK); + } + + if (LL_OK != i32Ret) { + (void)I2C_Stop(I2C_UNIT, I2C_TIMEOUT); + } + I2C_Cmd(I2C_UNIT, DISABLE); + return i32Ret; +} + +static uint32 I2cSlaveWriteData(struct I2cHardwareDevice *i2c_dev, struct I2cDataStandard *msg) { + if (msg->len == 0) { + return EOK; + } + uint32 i32Ret; + + I2C_Cmd(I2C_UNIT, ENABLE); + + /* Clear status */ + I2C_ClearStatus(I2C_UNIT, I2C_CLR_STOPFCLR | I2C_CLR_NACKFCLR); + + /* Wait slave address matched */ + while (RESET == I2C_GetStatus(I2C_UNIT, I2C_FLAG_MATCH_ADDR0)) { + ; + } + + I2C_ClearStatus(I2C_UNIT, I2C_CLR_SLADDR0FCLR); + + if (RESET == I2C_GetStatus(I2C_UNIT, I2C_FLAG_TRA)) { + i32Ret = LL_ERR; + } else { + i32Ret = I2C_TransData(I2C_UNIT, msg->buf, msg->len, I2C_TIMEOUT); + KPrintf("Slave send success!\r\n"); + + if ((LL_OK == i32Ret) || (LL_ERR_TIMEOUT == i32Ret)) { + /* Release SCL pin */ + (void)I2C_ReadData(I2C_UNIT); + + /* Wait stop condition */ + i32Ret = I2C_WaitStatus(I2C_UNIT, I2C_FLAG_STOP, SET, I2C_TIMEOUT); + } + } + + I2C_Cmd(I2C_UNIT, DISABLE); + return i32Ret; +} + +static uint32 I2cSlaveReadData(struct I2cHardwareDevice *i2c_dev, struct I2cDataStandard *msg) { + uint32 i32Ret; + + I2C_Cmd(I2C_UNIT, ENABLE); + + /* Clear status */ + I2C_ClearStatus(I2C_UNIT, I2C_CLR_STOPFCLR | I2C_CLR_NACKFCLR); + + /* Wait slave address matched */ + while (RESET == I2C_GetStatus(I2C_UNIT, I2C_FLAG_MATCH_ADDR0)) { + ; + } + + I2C_ClearStatus(I2C_UNIT, I2C_CLR_SLADDR0FCLR); + + if (RESET == I2C_GetStatus(I2C_UNIT, I2C_FLAG_TRA)) { + /* Slave receive data*/ + i32Ret = I2C_ReceiveData(I2C_UNIT, msg->buf, msg->len, I2C_TIMEOUT); + KPrintf("Slave receive success!\r\n"); + + if ((LL_OK == i32Ret) || (LL_ERR_TIMEOUT == i32Ret)) { + /* Wait stop condition */ + i32Ret = I2C_WaitStatus(I2C_UNIT, I2C_FLAG_STOP, SET, I2C_TIMEOUT); + } + } else { + i32Ret = LL_ERR; + } + + I2C_Cmd(I2C_UNIT, DISABLE); + return i32Ret; +} + + +/* manage the i2c device operations*/ +static const struct I2cDevDone i2c_dev_done = +{ + .dev_open = NONE, + .dev_close = NONE, +#ifdef I2C_DEVICE_SLAVE + .dev_write = I2cSlaveWriteData, + .dev_read = I2cSlaveReadData, +#else + .dev_write = I2cMasterWriteData, + .dev_read = I2cMasterReadData, +#endif +}; + +/* Init i2c bus */ +static int BoardI2cBusInit(struct I2cBus *i2c_bus, struct I2cDriver *i2c_driver) +{ + x_err_t ret = EOK; + + /* Init the i2c bus */ + ret = I2cBusInit(i2c_bus, I2C_BUS_NAME_1); + if (EOK != ret) { + KPrintf("board_i2c_init I2cBusInit error %d\n", ret); + return ERROR; + } + + /* Init the i2c driver*/ + ret = I2cDriverInit(i2c_driver, I2C_DRV_NAME_1); + if (EOK != ret) { + KPrintf("board_i2c_init I2cDriverInit error %d\n", ret); + return ERROR; + } + + /* Attach the i2c driver to the i2c bus*/ + ret = I2cDriverAttachToBus(I2C_DRV_NAME_1, I2C_BUS_NAME_1); + if (EOK != ret) { + KPrintf("board_i2c_init I2cDriverAttachToBus error %d\n", ret); + return ERROR; + } + + return ret; +} + +/* Attach the i2c device to the i2c bus*/ +static int BoardI2cDevBend(void) +{ + x_err_t ret = EOK; + static struct I2cHardwareDevice i2c_device0; + memset(&i2c_device0, 0, sizeof(struct I2cHardwareDevice)); + + i2c_device0.i2c_dev_done = &i2c_dev_done; + + ret = I2cDeviceRegister(&i2c_device0, NONE, I2C_1_DEVICE_NAME_0); + if (EOK != ret) { + KPrintf("board_i2c_init I2cDeviceInit device %s error %d\n", I2C_1_DEVICE_NAME_0, ret); + return ERROR; + } + + ret = I2cDeviceAttachToBus(I2C_1_DEVICE_NAME_0, I2C_BUS_NAME_1); + if (EOK != ret) { + KPrintf("board_i2c_init I2cDeviceAttachToBus device %s error %d\n", I2C_1_DEVICE_NAME_0, ret); + return ERROR; + } + + return ret; +} + +/* EDU-ARM32 BOARD I2C INIT*/ +int HwI2cInit(void) +{ + x_err_t ret = EOK; + static struct I2cBus i2c_bus; + memset(&i2c_bus, 0, sizeof(struct I2cBus)); + + static struct I2cDriver i2c_driver; + memset(&i2c_driver, 0, sizeof(struct I2cDriver)); + + I2cGpioInit(); + + /* Enable I2C Peripheral*/ + FCG_Fcg1PeriphClockCmd(I2C_FCG_USE, ENABLE); + + i2c_driver.configure = I2cDrvConfigure; + + ret = BoardI2cBusInit(&i2c_bus, &i2c_driver); + if (ret != EOK) { + KPrintf("board_i2c_init error ret %u\n", ret); + return ERROR; + } + + ret = BoardI2cDevBend(); + if (EOK != ret) { + KPrintf("board_i2c_init error ret %u\n", ret); + return ERROR; + } + + return ret; +} + +// #define I2C_TEST +#ifdef I2C_TEST + +#define USER_KEY_PORT (GPIO_PORT_I) +#define USER_KEY_PIN (GPIO_PIN_07) + +#define DEVICE_ADDR (0x06U) + +static struct Bus *bus1; +static struct I2cDriver *i2c_drv1; + +void I2cInitTest(void) +{ + x_err_t ret = EOK; + + stc_gpio_init_t stcGpioInit; + + /* KEY initialize */ + (void)GPIO_StructInit(&stcGpioInit); + stcGpioInit.u16PinState = PIN_STAT_RST; + stcGpioInit.u16PinDir = PIN_DIR_IN; + (void)GPIO_Init(USER_KEY_PORT, USER_KEY_PIN, &stcGpioInit); + + bus1 = BusFind(I2C_BUS_NAME_1); + bus1->owner_driver = BusFindDriver(bus1, I2C_DRV_NAME_1); + bus1->owner_haldev = BusFindDevice(bus1, I2C_1_DEVICE_NAME_0); + + struct BusConfigureInfo configure_info; + configure_info.configure_cmd = OPE_INT; + configure_info.private_data = (void *)DEVICE_ADDR; + + ret = I2cDrvConfigure(bus1->owner_driver, &configure_info); + if (ret != EOK) { + KPrintf("initialize %s failed!\n", I2C_UNIT); + return; + } + + i2c_drv1 = (struct I2cDriver *)bus1->owner_driver; + + return; +} +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), +I2cInitTest, I2cInitTest, i2c init); + +void I2cMasterTest(void) +{ + x_err_t ret = EOK; + + struct I2cHardwareDevice *i2c_dev1 = (struct I2cHardwareDevice *)i2c_drv1->driver.owner_bus->owner_haldev; + + struct I2cDataStandard msg; + uint8 u8TxBuf[256U] = {1, 2, 3, 4, 5}; + uint8 u8RxBuf[256U]; + + (void)memset(u8RxBuf, 0, 256U); + + msg.len = 5; + msg.buf = u8TxBuf; + + while (SET == GPIO_ReadInputPins(USER_KEY_PORT, USER_KEY_PIN)) { + ; + } + + KPrintf("I2C send data\n"); + + ret = I2cMasterWriteData(i2c_dev1, &msg); + if (EOK != ret) { + KPrintf("I2C send failed! ret %d\n", ret); + return; + } + + KPrintf("Master send data: "); + + for (uint16 i = 0; i < msg.len; i++) { + KPrintf("%d ", (msg.buf)[i]); + } + + KPrintf("\n"); + + /* 50mS delay for device*/ + DDL_DelayMS(50UL); + + msg.buf = u8RxBuf; + + (void)I2cMasterReadData(i2c_dev1, &msg); + + KPrintf("Master receive data: "); + + for (uint16 i = 0; i < msg.len; i++) { + KPrintf("%d ", (msg.buf)[i]); + } + + KPrintf("\n"); + + return; +} +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), +I2cMasterTest, I2cMasterTest, i2c master send and receive data); + +void I2cSlaveTest(void) +{ + x_err_t ret = EOK; + + struct I2cHardwareDevice *i2c_dev1 = (struct I2cHardwareDevice *)i2c_drv1->driver.owner_bus->owner_haldev; + + struct I2cDataStandard msg; + uint8 u8RxBuf[256U]; + + (void)memset(u8RxBuf, 0, 256U); + + msg.len = 5; + msg.buf = u8RxBuf; + + KPrintf("I2C receive data\n"); + + for (;;) { + ret = I2cSlaveReadData(i2c_dev1, &msg); + if (ret != EOK) { + KPrintf("I2C receive failed!\n"); + break; + } else { + KPrintf("Slave receive data: "); + for (uint16 i = 0; i < msg.len; i++) { + KPrintf("%d ", (msg.buf)[i]); + } + KPrintf("\n"); + } + + ret = I2cSlaveWriteData(i2c_dev1, &msg); + if (ret != EOK) { + KPrintf("I2C send failed!\n"); + break; + } else { + KPrintf("Slave send data: "); + for (uint16 i = 0; i < msg.len; i++) { + KPrintf("%d ", (msg.buf)[i]); + } + KPrintf("\n"); + } + } + + return; +} +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), +I2cSlaveTest, I2cSlaveTest, i2c slave receive and send data); + +#endif diff --git a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/include/connect_adc.h b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/include/connect_adc.h new file mode 100644 index 000000000..d961b5611 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/include/connect_adc.h @@ -0,0 +1,42 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file connect_uart.h +* @brief define edu-arm32-board usart function and struct +* @version 2.0 +* @author AIIT XUOS Lab +* @date 2023-02-09 +*/ + +#include +#include +#include + + +#ifdef __cplusplus +extern "C" { +#endif + +struct HwAdc +{ + CM_ADC_TypeDef *ADCx; + uint8 adc_channel; +}; + +int HwAdcInit(void); + +#ifdef __cplusplus +} +#endif + + diff --git a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/include/connect_can.h b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/include/connect_can.h new file mode 100644 index 000000000..2a7369c42 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/include/connect_can.h @@ -0,0 +1,40 @@ +/* +* Copyright (c) 2021 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file connect_can.h +* @brief define edu-arm32-board can function and struct +* @version 2.0 +* @author AIIT XUOS Lab +* @date 2023-02-21 +*/ + +#ifndef CONNECT_CAN_H +#define CONNECT_CAN_H + +#include +#include +#include +#include +#include + +#ifdef __cplusplus + extern "C" { +#endif + +int HwCanInit(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/include/connect_dac.h b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/include/connect_dac.h new file mode 100644 index 000000000..c99f28010 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/include/connect_dac.h @@ -0,0 +1,43 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file connect_uart.h +* @brief define edu-arm32-board usart function and struct +* @version 2.0 +* @author AIIT XUOS Lab +* @date 2023-02-09 +*/ + +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct HwDac +{ + CM_DAC_TypeDef *DACx; + uint16 digital_data; +}; + +int HwDacInit(void); + +#ifdef __cplusplus +} +#endif + + diff --git a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/include/connect_flash.h b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/include/connect_flash.h new file mode 100644 index 000000000..63d59eb16 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/include/connect_flash.h @@ -0,0 +1,40 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file connect_flash.h +* @brief define edu-arm32-board qspi-flash function and struct +* @version 2.0 +* @author AIIT XUOS Lab +* @date 2022-10-17 +*/ + +#ifndef CONNECT_FLASH_H +#define CONNECT_FLASH_H + +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +int FlashW25qxxSpiDeviceInit(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/include/connect_hwtimer.h b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/include/connect_hwtimer.h new file mode 100644 index 000000000..0ec541003 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/include/connect_hwtimer.h @@ -0,0 +1,40 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file connect_hwtimer.h +* @brief define edu-arm32-board hwtimer function and struct +* @version 2.0 +* @author AIIT XUOS Lab +* @date 2023-02-16 +*/ + +#ifndef CONNECT_HWTIMER_H +#define CONNECT_HWTIMER_H + +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +int HwTimerInit(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/include/connect_i2c.h b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/include/connect_i2c.h new file mode 100644 index 000000000..3b0ab7c45 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/include/connect_i2c.h @@ -0,0 +1,42 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file connect_i2c.h +* @brief define edu-arm32-board i2c function and struct +* @version 3.0 +* @author AIIT XUOS Lab +* @date 2022-12-05 +*/ + +#ifndef CONNECT_I2C_H +#define CONNECT_I2C_H + +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +int HwI2cInit(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/include/connect_rtc.h b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/include/connect_rtc.h new file mode 100644 index 000000000..fc0512bd8 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/include/connect_rtc.h @@ -0,0 +1,37 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file connect_rtc.h +* @brief define edu-arm32-board rtc function and struct +* @version 3.0 +* @author AIIT XUOS Lab +* @date 2023-02-02 +*/ + +#ifndef CONNECT_RTC_H +#define CONNECT_RTC_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +int HwRtcInit(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/include/connect_spi_lora.h b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/include/connect_spi_lora.h new file mode 100644 index 000000000..d696ccf4b --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/include/connect_spi_lora.h @@ -0,0 +1,61 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file connect_spi_lora.h +* @brief define spi lora dev function and struct using bus driver framework +* @version 2.0 +* @author AIIT XUOS Lab +* @date 2022-10-31 +*/ + +#ifndef CONNECT_SPI_LORA_H +#define CONNECT_SPI_LORA_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +//#define SPI_LORA_FREQUENCY 10000000 +#define SPI_LORA_BUFFER_SIZE 256 + +typedef struct SpiLoraDevice *SpiLoraDeviceType; + +struct LoraDevDone +{ + uint32 (*open) (void *dev); + uint32 (*close) (void *dev); + uint32 (*write) (void *dev, struct BusBlockWriteParam *write_param); + uint32 (*read) (void *dev, struct BusBlockReadParam *read_param); +}; + +struct SpiLoraDevice +{ + struct SpiHardwareDevice *spi_dev; + struct SpiHardwareDevice lora_dev; +}; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/include/connect_usb.h b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/include/connect_usb.h new file mode 100644 index 000000000..2d17a181f --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/include/connect_usb.h @@ -0,0 +1,54 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file connect_usb.h +* @brief define edu-arm32-board usb function and struct +* @version 2.0 +* @author AIIT XUOS Lab +* @date 2022-11-07 +*/ + +#ifndef CONNECT_USB_H +#define CONNECT_USB_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(FS_VFS) +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#define USB_HOST_STACK_SIZE 4096 + +#define USB_SINGLE_BLOCK_SIZE 512 + +int HwUsbHostInit(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/include/connect_wdt.h b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/include/connect_wdt.h new file mode 100644 index 000000000..c0c7b3cd6 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/include/connect_wdt.h @@ -0,0 +1,37 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file connect_wdt.h +* @brief define edu-arm32-board watchdog function and struct +* @version 3.0 +* @author AIIT XUOS Lab +* @date 2023-02-02 +*/ + +#ifndef CONNECT_WDT_H +#define CONNECT_WDT_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +int HwWdtInit(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/rtc/Kconfig b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/rtc/Kconfig new file mode 100644 index 000000000..e853dd40a --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/rtc/Kconfig @@ -0,0 +1,11 @@ +if BSP_USING_RTC + config RTC_BUS_NAME + string "rtc bus name" + default "rtc" + config RTC_DRV_NAME + string "rtc bus driver name" + default "rtc_drv" + config RTC_DEVICE_NAME + string "rtc bus device name" + default "rtc_dev" +endif diff --git a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/rtc/Makefile b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/rtc/Makefile new file mode 100644 index 000000000..d30b05a1a --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/rtc/Makefile @@ -0,0 +1,2 @@ +SRC_FILES := connect_rtc.c +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/rtc/connect_rtc.c b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/rtc/connect_rtc.c new file mode 100644 index 000000000..14b7b2378 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/rtc/connect_rtc.c @@ -0,0 +1,185 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file connect_rtc.c +* @brief support aiit-edu-arm32-board rtc function and register to bus framework +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2023-02-02 +*/ + +#include +#include +#include +#include + +static uint32 RtcConfigure(void *drv, struct BusConfigureInfo *configure_info) +{ + NULL_PARAM_CHECK(drv); + + struct RtcDriver *rtc_drv = (struct RtcDriver *)drv; + struct RtcDrvConfigureParam *drv_param = (struct RtcDrvConfigureParam *)configure_info->private_data; + + int cmd = drv_param->rtc_operation_cmd; + time_t *time = drv_param->time; + + switch (cmd) + { + case OPER_RTC_GET_TIME: + { + struct tm ct; + stc_rtc_date_t rtc_date; + stc_rtc_time_t rtc_time; + + // rtc_timer_get(&year, &month, &day, &hour, &minute, &second); + RTC_GetDate(RTC_DATA_FMT_DEC, &rtc_date); + RTC_GetTime(RTC_DATA_FMT_DEC, &rtc_time); + + ct.tm_year = rtc_date.u8Year ; + ct.tm_mon = rtc_date.u8Month ; + ct.tm_mday = rtc_date.u8Day; + ct.tm_wday = rtc_date.u8Weekday; + + ct.tm_hour = rtc_time.u8Hour; + ct.tm_min = rtc_time.u8Minute; + ct.tm_sec = rtc_time.u8Second; + + *time = mktime(&ct); + } + break; + case OPER_RTC_SET_TIME: + { + struct tm *ct; + stc_rtc_date_t rtc_date; + stc_rtc_time_t rtc_time; + x_base lock; + + lock = CriticalAreaLock(); + ct = localtime(time); + rtc_date.u8Year = ct->tm_year ; + rtc_date.u8Month = ct->tm_mon ; + rtc_date.u8Day = ct->tm_mday; + rtc_date.u8Weekday = ct->tm_wday; + rtc_time.u8Hour = ct->tm_hour; + rtc_time.u8Minute = ct->tm_min; + rtc_time.u8Second = ct->tm_sec; + CriticalAreaUnLock(lock); + + RTC_SetDate(RTC_DATA_FMT_DEC, &rtc_date); + RTC_SetTime(RTC_DATA_FMT_DEC, &rtc_time); + } + break; + } + return EOK; +} + +/*manage the rtc device operations*/ +static const struct RtcDevDone dev_done = +{ + .open = NONE, + .close = NONE, + .write = NONE, + .read = NONE, +}; + +static int BoardRtcBusInit(struct RtcBus *rtc_bus, struct RtcDriver *rtc_driver) +{ + x_err_t ret = EOK; + + /*Init the rtc bus */ + ret = RtcBusInit(rtc_bus, RTC_BUS_NAME); + if (EOK != ret) { + KPrintf("HwRtcInit RtcBusInit error %d\n", ret); + return ERROR; + } + + /*Init the rtc driver*/ + ret = RtcDriverInit(rtc_driver, RTC_DRV_NAME); + if (EOK != ret) { + KPrintf("HwRtcInit RtcDriverInit error %d\n", ret); + return ERROR; + } + + /*Attach the rtc driver to the rtc bus*/ + ret = RtcDriverAttachToBus(RTC_DRV_NAME, RTC_BUS_NAME); + if (EOK != ret) { + KPrintf("HwRtcInit RtcDriverAttachToBus error %d\n", ret); + return ERROR; + } + + return ret; +} + +/*Attach the rtc device to the rtc bus*/ +static int BoardRtcDevBend(void) +{ + x_err_t ret = EOK; + + static struct RtcHardwareDevice rtc_device; + memset(&rtc_device, 0, sizeof(struct RtcHardwareDevice)); + + rtc_device.dev_done = &(dev_done); + + ret = RtcDeviceRegister(&rtc_device, NONE, RTC_DEVICE_NAME); + if (EOK != ret) { + KPrintf("HwRtcInit RtcDeviceInit device %s error %d\n", RTC_DEVICE_NAME, ret); + return ERROR; + } + + ret = RtcDeviceAttachToBus(RTC_DEVICE_NAME, RTC_BUS_NAME); + if (EOK != ret) { + KPrintf("HwRtcInit RtcDeviceAttachToBus device %s error %d\n", RTC_DEVICE_NAME, ret); + return ERROR; + } + + return ret; +} + + +int HwRtcInit(void) +{ + x_err_t ret = EOK; + + static struct RtcBus rtc_bus; + memset(&rtc_bus, 0, sizeof(struct RtcBus)); + + static struct RtcDriver rtc_driver; + memset(&rtc_driver, 0, sizeof(struct RtcDriver)); + + rtc_driver.configure = &(RtcConfigure); + + ret = BoardRtcBusInit(&rtc_bus, &rtc_driver); + if (EOK != ret) { + KPrintf("HwRtcInit error ret %u\n", ret); + return ERROR; + } + + ret = BoardRtcDevBend(); + if (EOK != ret) { + KPrintf("HwRtcInit error ret %u\n", ret); + } + + stc_rtc_init_t stcRtcInit; + /* Configure structure initialization */ + (void)RTC_StructInit(&stcRtcInit); + + /* Configuration RTC structure */ + stcRtcInit.u8ClockSrc = RTC_CLK_SRC_XTAL32; + stcRtcInit.u8HourFormat= RTC_HOUR_FMT_24H; + stcRtcInit.u8IntPeriod = RTC_INT_PERIOD_PER_SEC; + (void)RTC_Init(&stcRtcInit); + + RTC_Cmd(LL_RTC_ENABLE); + + return ret; +} diff --git a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/spi/connect_flash.c b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/spi/connect_flash.c new file mode 100644 index 000000000..27fe601ef --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/spi/connect_flash.c @@ -0,0 +1,260 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file connect_flash.c +* @brief support edu-arm32-board qspi-flash function and register to bus framework +* @version 2.0 +* @author AIIT XUOS Lab +* @date 2023-02-16 +*/ +#include + +#define QSPI_DEVICE_SLAVE_ID_0 (0) +#define QSPI_UNIT (CM_QSPI) + +#define QSPI_CS_PORT (GPIO_PORT_C) +#define QSPI_SCK_PORT (GPIO_PORT_C) +#define QSPI_IO0_PORT (GPIO_PORT_D) +#define QSPI_IO1_PORT (GPIO_PORT_D) +#define QSPI_IO2_PORT (GPIO_PORT_D) +#define QSPI_IO3_PORT (GPIO_PORT_D) + +#define QSPI_CS_PIN (GPIO_PIN_07) +#define QSPI_SCK_PIN (GPIO_PIN_06) +#define QSPI_IO0_PIN (GPIO_PIN_08) +#define QSPI_IO1_PIN (GPIO_PIN_09) +#define QSPI_IO2_PIN (GPIO_PIN_10) +#define QSPI_IO3_PIN (GPIO_PIN_11) + +#define QSPI_PIN_FUNC (GPIO_FUNC_18) + +static uint32 QSpiSdkInit(struct SpiDriver *spi_drv) +{ + stc_qspi_init_t stcInit; + + FCG_Fcg1PeriphClockCmd(PWC_FCG1_QSPI, ENABLE); + + (void)QSPI_StructInit(&stcInit); + stcInit.u32ClockDiv = QSPI_CLK_DIV3; + stcInit.u32SpiMode = QSPI_SPI_MD0; + stcInit.u32ReadMode = QSPI_RD_MD_STD_RD; + stcInit.u32DummyCycle = QSPI_DUMMY_CYCLE8; + stcInit.u32AddrWidth = QSPI_ADDR_WIDTH_24BIT; + return QSPI_Init(&stcInit); + +} + +static void QspiPinConfig(void) +{ + stc_gpio_init_t stcGpioInit; + (void)GPIO_StructInit(&stcGpioInit); + stcGpioInit.u16PinState = PIN_STAT_RST; + stcGpioInit.u16PinDir = PIN_DIR_OUT; + (void)GPIO_Init(QSPI_CS_PORT, QSPI_CS_PIN|QSPI_SCK_PIN, &stcGpioInit); + stcGpioInit.u16PinState = PIN_STAT_SET; + (void)GPIO_Init(QSPI_IO0_PORT, QSPI_IO1_PIN|QSPI_IO2_PIN|QSPI_IO3_PIN, &stcGpioInit); + stcGpioInit.u16PinDir = PIN_DIR_IN; + (void)GPIO_Init(QSPI_IO0_PORT, QSPI_IO0_PIN, &stcGpioInit); + + GPIO_ResetPins(QSPI_CS_PORT, QSPI_CS_PIN); + GPIO_SetPins(QSPI_IO0_PORT, QSPI_IO2_PIN|QSPI_IO3_PIN); + + GPIO_SetFunc(QSPI_CS_PORT, QSPI_CS_PIN, QSPI_PIN_FUNC); + GPIO_SetFunc(QSPI_SCK_PORT, QSPI_SCK_PIN, QSPI_PIN_FUNC); + GPIO_SetFunc(QSPI_IO0_PORT, QSPI_IO0_PIN, QSPI_PIN_FUNC); + GPIO_SetFunc(QSPI_IO1_PORT, QSPI_IO1_PIN, QSPI_PIN_FUNC); + GPIO_SetFunc(QSPI_IO2_PORT, QSPI_IO2_PIN, QSPI_PIN_FUNC); + GPIO_SetFunc(QSPI_IO3_PORT, QSPI_IO3_PIN, QSPI_PIN_FUNC); +} + +static uint32 QSpiWriteData(struct SpiHardwareDevice *spi_dev, struct SpiDataStandard *spi_datacfg) +{ + SpiDeviceParam *dev_param = (SpiDeviceParam *)(spi_dev->haldev.private_data); + uint8 cs_gpio_pin = dev_param->spi_slave_param->spi_cs_gpio_pin; + uint8 cs_gpio_port = dev_param->spi_slave_param->spi_cs_gpio_port; + CM_SPI_TypeDef *spi = spi_dev->haldev.owner_bus->private_data; + x_err_t ret = EOK; + if (spi_datacfg->spi_chip_select) { + // GPIO_ResetPins(cs_gpio_port, cs_gpio_pin); + QSPI_EnterDirectCommMode(); + } + if(spi_datacfg->length > 0U && spi_datacfg->tx_buff!=NULL){ + for(int i=0;ilength;i++){ + QSPI_WriteDirectCommValue(spi_datacfg->tx_buff[i]); + } + } + if (spi_datacfg->spi_cs_release) { + // GPIO_SetPins(cs_gpio_port, cs_gpio_pin); + QSPI_ExitDirectCommMode(); + } + return ret; +} + +static uint32 QSpiReadData(struct SpiHardwareDevice *spi_dev, struct SpiDataStandard *spi_datacfg) +{ + SpiDeviceParam *dev_param = (SpiDeviceParam *)(spi_dev->haldev.private_data); + uint8 cs_gpio_pin = dev_param->spi_slave_param->spi_cs_gpio_pin; + uint8 cs_gpio_port = dev_param->spi_slave_param->spi_cs_gpio_port; + CM_SPI_TypeDef *spi = spi_dev->haldev.owner_bus->private_data; + x_err_t ret = EOK; + uint8_t *read_buffer = spi_datacfg->rx_buff; + + if (spi_datacfg->spi_chip_select) { + // GPIO_ResetPins(cs_gpio_port, cs_gpio_pin); + QSPI_EnterDirectCommMode(); + } + if(spi_datacfg->length > 0U && spi_datacfg->rx_buff!=NULL){ + for(int i=0;ilength;i++){ + read_buffer[i] = (uint8_t)QSPI_ReadDirectCommValue(); + } + } + if (spi_datacfg->spi_cs_release) { + // GPIO_SetPins(cs_gpio_port, cs_gpio_pin); + QSPI_ExitDirectCommMode(); + } + return ret; +} + +static uint32 QSpiDrvConfigure(void *drv, struct BusConfigureInfo *configure_info) +{ + NULL_PARAM_CHECK(drv); + NULL_PARAM_CHECK(configure_info); + + x_err_t ret = EOK; + struct SpiDriver *spi_drv = (struct SpiDriver *)drv; + struct SpiMasterParam *spi_param; + + switch (configure_info->configure_cmd) + { + case OPE_INT: + QSpiSdkInit(spi_drv); + QspiPinConfig(); + break; + case OPE_CFG: + spi_param = (struct SpiMasterParam *)configure_info->private_data; + break; + default: + break; + } + + return ret; +} + +/*manage the qspi device operations*/ +static const struct SpiDevDone qspi_dev_done = +{ + .dev_open = NONE, + .dev_close = NONE, + .dev_write = QSpiWriteData, + .dev_read = QSpiReadData, +}; + +static int BoardQSpiDevBend(void) +{ + x_err_t ret = EOK; + + static struct SpiHardwareDevice qspi_device0; + memset(&qspi_device0, 0, sizeof(struct SpiHardwareDevice)); + + static struct SpiSlaveParam qspi_slaveparam0; + memset(&qspi_slaveparam0, 0, sizeof(struct SpiSlaveParam)); + + qspi_slaveparam0.spi_slave_id = QSPI_DEVICE_SLAVE_ID_0; + qspi_slaveparam0.spi_cs_gpio_pin = QSPI_CS_PIN; + qspi_slaveparam0.spi_cs_gpio_port = QSPI_CS_PORT; + + qspi_device0.spi_param.spi_slave_param = &qspi_slaveparam0; + qspi_device0.spi_dev_done = &(qspi_dev_done); + + ret = SpiDeviceRegister(&qspi_device0, (void *)(&qspi_device0.spi_param), QSPI_DEVICE_NAME_0); + if (EOK != ret) { + KPrintf("BoardSpiDevBend SpiDeviceRegister device %s error %d\n", QSPI_DEVICE_NAME_0, ret); + return ERROR; + } + + ret = SpiDeviceAttachToBus(QSPI_DEVICE_NAME_0, QSPI_BUS_NAME); + if (EOK != ret) { + KPrintf("BoardSpiDevBend SpiDeviceAttachToBus device %s error %d\n", QSPI_DEVICE_NAME_0, ret); + return ERROR; + } + + return ret; +} + +static int BoardSpiBusInit(struct SpiBus *spi_bus, struct SpiDriver *spi_driver, const char *bus_name, const char *drv_name) +{ + x_err_t ret = EOK; + + /*Init the spi bus */ + ret = SpiBusInit(spi_bus, bus_name); + if (EOK != ret) { + KPrintf("Board_Spi_init SpiBusInit error %d\n", ret); + return ERROR; + } + + /*Init the spi driver*/ + ret = SpiDriverInit(spi_driver, drv_name); + if (EOK != ret) { + KPrintf("Board_Spi_init SpiDriverInit error %d\n", ret); + return ERROR; + } + + /*Attach the spi driver to the spi bus*/ + ret = SpiDriverAttachToBus(drv_name, bus_name); + if (EOK != ret) { + KPrintf("Board_Spi_init SpiDriverAttachToBus error %d\n", ret); + return ERROR; + } + + return ret; +} + + +int HwQSpiInit(void) +{ + x_err_t ret = EOK; + + static struct SpiBus qspi_bus; + memset(&qspi_bus, 0, sizeof(struct SpiBus)); + + static struct SpiDriver qspi_driver; + memset(&qspi_driver, 0, sizeof(struct SpiDriver)); + + qspi_bus.private_data = QSPI_UNIT; + qspi_driver.configure = QSpiDrvConfigure; + + ret = BoardSpiBusInit(&qspi_bus, &qspi_driver, QSPI_BUS_NAME, QSPI_DRV_NAME); + if (EOK != ret) { + KPrintf("BoardSpiBusInit error ret %u\n", ret); + return ERROR; + } + + ret = BoardQSpiDevBend(); + if (EOK != ret) { + KPrintf("BoardSpiDevBend error ret %u\n", ret); + return ERROR; + } + + return ret; +} + +int FlashW25qxxSpiDeviceInit(void) +{ + HwQSpiInit(); + QSpiSdkInit(NULL); + QspiPinConfig(); + if (NONE == SpiFlashInit(QSPI_BUS_NAME, QSPI_DEVICE_NAME_0, QSPI_DRV_NAME, QSPI_FLASH_DEV_NAME)) { + return ERROR; + } + return EOK; +} diff --git a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/spi/connect_lora_spi.c b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/spi/connect_lora_spi.c new file mode 100644 index 000000000..129455867 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/spi/connect_lora_spi.c @@ -0,0 +1,457 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file connect_lora_spi.c +* @brief support to register spi lora pointer and function +* @version 2.0 +* @author AIIT XUOS Lab +* @date 2022-10-31 +*/ + +#include + +/* RST = PI02 */ +#define LORA_RST_PORT (GPIO_PORT_I) +#define LORA_RST_PIN (GPIO_PIN_02) + +static struct HardwareDev *g_spi_lora_dev; +static tRadioDriver *Radio = NONE; + +void SX1276InitIo(void) +{ + stc_gpio_init_t stcGpioInit; + + (void)GPIO_StructInit(&stcGpioInit); + stcGpioInit.u16PinState = PIN_STAT_RST; + stcGpioInit.u16PinDir = PIN_DIR_OUT; + (void)GPIO_Init(LORA_RST_PORT, LORA_RST_PIN, &stcGpioInit); +} + +inline void SX1276WriteRxTx(uint8_t txEnable) +{ + if (txEnable != 0) { + /*to do*/ + } else { + /*to do*/ + } +} + +void SX1276SetReset(uint8_t state) +{ + if (state == RADIO_RESET_ON) { + GPIO_ResetPins(LORA_RST_PORT, LORA_RST_PIN); + } else { + stc_gpio_init_t stcGpioInit; + (void)GPIO_StructInit(&stcGpioInit); + stcGpioInit.u16PinDir = PIN_DIR_IN; + (void)GPIO_Init(LORA_RST_PORT, LORA_RST_PIN, &stcGpioInit); + } +} + +//Not-necessary Function +uint8_t SX1276ReadDio0(void) +{ + return 1; +} + +uint8_t SX1276ReadDio1(void) +{ + return 1; +} + +uint8_t SX1276ReadDio2(void) +{ + return 1; +} + +uint8_t SX1276ReadDio3(void) +{ + return 1; +} + +uint8_t SX1276ReadDio4(void) +{ + return 1; +} + +uint8_t SX1276ReadDio5(void) +{ + return 1; +} + +void SX1276WriteBuffer(uint8_t addr, uint8_t *buffer, uint8_t size) +{ + struct BusBlockWriteParam write_param; + uint8 write_addr = addr | 0x80; + + BusDevOpen(g_spi_lora_dev); + + write_param.buffer = (void *)&write_addr; + write_param.size = 1; + BusDevWriteData(g_spi_lora_dev, &write_param); + + write_param.buffer = (void *)buffer; + write_param.size = size; + BusDevWriteData(g_spi_lora_dev, &write_param); + + BusDevClose(g_spi_lora_dev); +} + +void SX1276ReadBuffer(uint8_t addr, uint8_t *buffer, uint8_t size) +{ + struct BusBlockWriteParam write_param; + struct BusBlockReadParam read_param; + + uint8 write_addr = addr & 0x7F; + + BusDevOpen(g_spi_lora_dev); + + write_param.buffer = (void *)&write_addr; + write_param.size = 1; + BusDevWriteData(g_spi_lora_dev, &write_param); + + read_param.buffer = (void *)buffer; + read_param.size = size; + BusDevReadData(g_spi_lora_dev, &read_param); + + BusDevClose(g_spi_lora_dev); +} + +void SX1276WriteFifo(uint8_t *buffer, uint8_t size) +{ + SX1276WriteBuffer(0, buffer, size); +} + +void SX1276ReadFifo(uint8_t *buffer, uint8_t size) +{ + SX1276ReadBuffer(0, buffer, size); +} + +void SX1276Write(uint8_t addr, uint8_t data) +{ + SX1276WriteBuffer(addr, &data, 1); +} + +void SX1276Read(uint8_t addr, uint8_t *data) +{ + SX1276ReadBuffer(addr, data, 1); +} + +uint8_t Sx1276SpiCheck(void) +{ + uint8_t test = 0; + + tLoRaSettings settings; + SX1276Read(REG_LR_VERSION, &test); + KPrintf("version code of the chip is 0x%x\n", test); + + settings.RFFrequency = SX1276LoRaGetRFFrequency(); + KPrintf("SX1278 Lora parameters are :\nRFFrequency is %d\n", settings.RFFrequency); + + settings.Power = SX1276LoRaGetRFPower(); + KPrintf("RFPower is %d\n",settings.Power); + + settings.SignalBw = SX1276LoRaGetSignalBandwidth(); + KPrintf("SignalBw is %d\n",settings.SignalBw); + + settings.SpreadingFactor = SX1276LoRaGetSpreadingFactor(); + KPrintf("SpreadingFactor is %d\n",settings.SpreadingFactor); + + /*SPI confirm*/ + SX1276Write(REG_LR_HOPPERIOD, 0x91); + SX1276Read(REG_LR_HOPPERIOD, &test); + if (test != 0x91) { + return 0; + } + return test; +} + +/** + * This function supports to write data to the lora. + * + * @param dev lora dev descriptor + * @param write_param lora dev write datacfg param + */ +static uint32 SpiLoraWrite(void *dev, struct BusBlockWriteParam *write_param) +{ + NULL_PARAM_CHECK(dev); + NULL_PARAM_CHECK(write_param); + + if (write_param->size > 256) { + KPrintf("SpiLoraWrite ERROR:The message is too long!\n"); + return ERROR; + } else { + SX1276SetTx(write_param->buffer, write_param->size); + + KPrintf("SpiLoraWrite success!\n"); + } + + return EOK; +} + +/** + * This function supports to read data from the lora. + * + * @param dev lora dev descriptor + * @param read_param lora dev read datacfg param + */ +static uint32 SpiLoraRead(void *dev, struct BusBlockReadParam *read_param) +{ + NULL_PARAM_CHECK(dev); + NULL_PARAM_CHECK(read_param); + + KPrintf("SpiLoraRead Ready!\n"); + + int ret = SX1276GetRx(read_param->buffer, (uint16 *)&read_param->read_length); + + if (ret < 0) { + return 0; + } + + return read_param->read_length; +} + +static uint32 SpiLoraOpen(void *dev) +{ + NULL_PARAM_CHECK(dev); + + KPrintf("SpiLoraOpen start\n"); + + x_err_t ret = EOK; + static x_bool lora_init_status = RET_FALSE; + + if (RET_TRUE == lora_init_status) { + return EOK; + } + + struct HardwareDev *haldev = (struct HardwareDev *)dev; + + struct SpiHardwareDevice *lora_dev = CONTAINER_OF(haldev, struct SpiHardwareDevice, haldev); + NULL_PARAM_CHECK(lora_dev); + + SpiLoraDeviceType spi_lora_dev = CONTAINER_OF(lora_dev, struct SpiLoraDevice, lora_dev); + NULL_PARAM_CHECK(spi_lora_dev); + + struct Driver *spi_drv = spi_lora_dev->spi_dev->haldev.owner_bus->owner_driver; + + struct BusConfigureInfo configure_info; + struct SpiMasterParam spi_master_param; + spi_master_param.spi_data_bit_width = 8; + spi_master_param.spi_work_mode = SPI_MODE_0 | SPI_MSB; + + configure_info.configure_cmd = OPE_CFG; + configure_info.private_data = (void *)&spi_master_param; + ret = BusDrvConfigure(spi_drv, &configure_info); + if (ret) { + KPrintf("spi drv OPE_CFG error drv %8p cfg %8p\n", spi_drv, &spi_master_param); + return ERROR; + } + + configure_info.configure_cmd = OPE_INT; + ret = BusDrvConfigure(spi_drv, &configure_info); + if (ret) { + KPrintf("spi drv OPE_INT error drv %8p\n", spi_drv); + return ERROR; + } + + SX1276Init(); + + if (0x91 != Sx1276SpiCheck()) { + KPrintf("LoRa check failed!\n!"); + } else { + Radio = RadioDriverInit(); + KPrintf("LoRa check ok!\nNote: The length of the message that can be sent in a single time is 256 characters\n"); + } + + lora_init_status = RET_TRUE; + + return ret; +} + +static uint32 SpiLoraClose(void *dev) +{ + NULL_PARAM_CHECK(dev); + + return EOK; +} + +static const struct LoraDevDone lora_done = +{ + .open = SpiLoraOpen, + .close = SpiLoraClose, + .write = SpiLoraWrite, + .read = SpiLoraRead, +}; + +/** + * This function supports to init spi_lora_dev + * + * @param bus_name spi bus name + * @param dev_name spi dev name + * @param drv_name spi drv name + * @param lora_name lora dev name + */ +SpiLoraDeviceType SpiLoraInit(char *bus_name, char *dev_name, char *drv_name, char *lora_name) +{ + NULL_PARAM_CHECK(dev_name); + NULL_PARAM_CHECK(drv_name); + NULL_PARAM_CHECK(lora_name); + NULL_PARAM_CHECK(bus_name); + + x_err_t ret; + static HardwareDevType haldev; + + haldev = SpiDeviceFind(dev_name, TYPE_SPI_DEV); + if (NONE == haldev) { + KPrintf("SpiLoraInit find spi haldev %s error! \n", dev_name); + return NONE; + } + + SpiLoraDeviceType spi_lora_dev = (SpiLoraDeviceType)malloc(sizeof(struct SpiLoraDevice)); + if (NONE == spi_lora_dev) { + KPrintf("SpiLoraInit malloc spi_lora_dev failed\n"); + free(spi_lora_dev); + return NONE; + } + + memset(spi_lora_dev, 0, sizeof(struct SpiLoraDevice)); + + spi_lora_dev->spi_dev = CONTAINER_OF(haldev, struct SpiHardwareDevice, haldev); + + spi_lora_dev->lora_dev.spi_dev_flag = RET_TRUE; + spi_lora_dev->lora_dev.haldev.dev_done = (struct HalDevDone *)&lora_done; + + struct Driver *spi_driver = SpiDriverFind(drv_name, TYPE_SPI_DRV); + if (NONE == spi_driver) { + KPrintf("SpiLoraInit find spi driver %s error! \n", drv_name); + free(spi_lora_dev); + return NONE; + } + + //spi drv get spi dev param (SpiDeviceParam) + spi_driver->private_data = spi_lora_dev->spi_dev->haldev.private_data; + spi_lora_dev->spi_dev->haldev.owner_bus->owner_driver = spi_driver; + + ret = SpiDeviceRegister(&spi_lora_dev->lora_dev, spi_lora_dev->spi_dev->haldev.private_data, lora_name); + if (EOK != ret) { + KPrintf("SpiLoraInit SpiDeviceRegister device %s error %d\n", lora_name, ret); + free(spi_lora_dev); + return NONE; + } + + ret = SpiDeviceAttachToBus(lora_name, bus_name); + if (EOK != ret) { + KPrintf("SpiLoraInit SpiDeviceAttachToBus device %s error %d\n", lora_name, ret); + free(spi_lora_dev); + return NONE; + } + + g_spi_lora_dev = &spi_lora_dev->spi_dev->haldev; + + return spi_lora_dev; +} + +/** + * This function supports to release spi_lora_dev + * + * @param spi_lora_dev spi lora descriptor + */ +uint32 SpiLoraRelease(SpiLoraDeviceType spi_lora_dev) +{ + NULL_PARAM_CHECK(spi_lora_dev); + + x_err_t ret; + + DeviceDeleteFromBus(spi_lora_dev->lora_dev.haldev.owner_bus, &spi_lora_dev->lora_dev.haldev); + + free(spi_lora_dev); + + return EOK; +} + +int LoraSx12xxSpiDeviceInit(void) +{ +#ifdef BSP_USING_SPI1 + if (NONE == SpiLoraInit(SPI_BUS_NAME_1, SPI_1_DEVICE_NAME_0, SPI_1_DRV_NAME, SX12XX_DEVICE_NAME)) { + return ERROR; + } +#endif + + return EOK; +} + +#define LORA_TEST +#ifdef LORA_TEST +/*Just for lora test*/ +static struct Bus *bus; +static struct HardwareDev *dev; + +void LoraOpen(void) +{ + x_err_t ret = EOK; + + bus = BusFind(SPI_BUS_NAME_1); + dev = BusFindDevice(bus, SX12XX_DEVICE_NAME); + + ret = SpiLoraOpen(dev); + if (EOK != ret) { + KPrintf("LoRa init failed\n"); + return; + } + + KPrintf("LoRa init succeed\n"); + + return; +} +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), + LoraOpen, LoraOpen, open lora device and read parameters ); + +static void LoraReceive(void) +{ + uint32 read_length = 0; + struct BusBlockReadParam read_param; + memset(&read_param, 0, sizeof(struct BusBlockReadParam)); + + read_param.buffer = malloc(SPI_LORA_BUFFER_SIZE); + + read_length = SpiLoraRead(dev, &read_param); + + KPrintf("LoraReceive length %d\n", read_length); + for (int i = 0; i < read_length; i ++) { + KPrintf("i %d data 0x%x\n", i, ((uint8 *)read_param.buffer)[i]); + } + + free(read_param.buffer); +} +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_PARAM_NUM(0), +LoraReceive, LoraReceive, lora wait message ); + +static void LoraSend(int argc, char *argv[]) +{ + char Msg[SPI_LORA_BUFFER_SIZE] = {0}; + struct BusBlockWriteParam write_param; + memset(&write_param, 0, sizeof(struct BusBlockWriteParam)); + + if (argc == 2) { + strncpy(Msg, argv[1], SPI_LORA_BUFFER_SIZE); + write_param.buffer = Msg; + write_param.size = strlen(Msg); + + KPrintf("LoraSend data %s length %d\n", Msg, strlen(Msg)); + + SpiLoraWrite(dev, &write_param); + } +} +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), +LoraSend, LoraSend, lora send message ); +#endif diff --git a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/spi/third_party_spi_lora/Makefile b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/spi/third_party_spi_lora/Makefile new file mode 100644 index 000000000..bd947913d --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/spi/third_party_spi_lora/Makefile @@ -0,0 +1,5 @@ +ifeq ($(CONFIG_RESOURCES_SPI_LORA),y) + SRC_DIR := sx12xx +endif + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/spi/third_party_spi_lora/sx12xx/Makefile b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/spi/third_party_spi_lora/sx12xx/Makefile new file mode 100644 index 000000000..d4ee439ce --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/spi/third_party_spi_lora/sx12xx/Makefile @@ -0,0 +1,3 @@ +SRC_DIR := src + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/spi/third_party_spi_lora/sx12xx/inc/spi_lora_sx12xx.h b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/spi/third_party_spi_lora/sx12xx/inc/spi_lora_sx12xx.h new file mode 100644 index 000000000..df39d277c --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/spi/third_party_spi_lora/sx12xx/inc/spi_lora_sx12xx.h @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file spi_lora_sx12xx.h +* @brief define spi lora driver function +* @version 2.0 +* @author AIIT XUOS Lab +* @date 2022-10-31 +*/ + +#ifndef SPI_LORA_SX12XX_H +#define SPI_LORA_SX12XX_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +uint8_t SX1276ReadDio0(void); +uint8_t SX1276ReadDio1(void); +uint8_t SX1276ReadDio2(void); +uint8_t SX1276ReadDio3(void); +uint8_t SX1276ReadDio4(void); +uint8_t SX1276ReadDio5(void); + +void SX1276Write(uint8_t addr, uint8_t data); +void SX1276Read(uint8_t addr, uint8_t *data); +void SX1276WriteBuffer(uint8_t addr, uint8_t *buffer, uint8_t size); +void SX1276ReadBuffer(uint8_t addr, uint8_t *buffer, uint8_t size); +void SX1276WriteFifo(uint8_t *buffer, uint8_t size); +void SX1276ReadFifo(uint8_t *buffer, uint8_t size); +void SX1276SetReset(uint8_t state); +uint8_t Sx1276SpiCheck(void); +void SX1276WriteRxTx(uint8_t txEnable); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/spi/third_party_spi_lora/sx12xx/src/Makefile b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/spi/third_party_spi_lora/sx12xx/src/Makefile new file mode 100644 index 000000000..ace186b70 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/spi/third_party_spi_lora/sx12xx/src/Makefile @@ -0,0 +1,3 @@ +SRC_DIR := radio + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/Makefile b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/Makefile new file mode 100644 index 000000000..4cc90adb8 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/Makefile @@ -0,0 +1,3 @@ +SRC_FILES := radio.c sx1276-Fsk.c sx1276-FskMisc.c sx1276-LoRa.c sx1276-LoRaMisc.c sx1276.c + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/platform.h b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/platform.h new file mode 100644 index 000000000..cb4bff6d5 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/platform.h @@ -0,0 +1,96 @@ +/* + * THE FOLLOWING FIRMWARE IS PROVIDED: (1) "AS IS" WITH NO WARRANTY; AND + * (2)TO ENABLE ACCESS TO CODING INFORMATION TO GUIDE AND FACILITATE CUSTOMER. + * CONSEQUENTLY, SEMTECH SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR + * CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT + * OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION + * CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * Copyright (C) SEMTECH S.A. + */ +/*! + * \file platform.h + * \brief + * + * \version 1.0 + * \date Nov 21 2012 + * \author Miguel Luis + */ +/************************************************* +File name: platform.h +Description: support aiit board configure and register function +History: +1. Date: 2021-04-25 +Author: AIIT XUOS Lab +Modification: +1. replace original macro and basic date type with AIIT XUOS Lab's own defination +*************************************************/ +#ifndef __PLATFORM_H__ +#define __PLATFORM_H__ + +#ifndef __GNUC__ +#define inline +#endif + +/*! + * Platform definition + */ +#define Bleeper 3 +#define SX1243ska 2 +#define SX12xxEiger 1 +#define SX12000DVK 0 + +/*! + * Platform choice. Please uncoment the PLATFORM define and choose your platform + * or add/change the PLATFORM definition on the compiler Defines option + */ +#define PLATFORM SX12xxEiger + +#if( PLATFORM == SX12xxEiger ) +/*! + * Radio choice. Please uncomment the wanted radio and comment the others + * or add/change wanted radio definition on the compiler Defines option + */ +//#define USE_SX1232_RADIO +//#define USE_SX1272_RADIO +#define USE_SX1276_RADIO +//#define USE_SX1243_RADIO + +/*! + * Module choice. There are three existing module with the SX1276. + * Please set the connected module to the value 1 and set the others to 0 + */ +#ifdef USE_SX1276_RADIO +#define MODULE_SX1276RF1IAS 0 +#define MODULE_SX1276RF1JAS 0 +#define MODULE_SX1276RF1KAS 1 +#endif + +#include +#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__ diff --git a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/radio.c b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/radio.c new file mode 100644 index 000000000..31f8aaebd --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/radio.c @@ -0,0 +1,75 @@ +/* + * THE FOLLOWING FIRMWARE IS PROVIDED: (1) "AS IS" WITH NO WARRANTY; AND + * (2)TO ENABLE ACCESS TO CODING INFORMATION TO GUIDE AND FACILITATE CUSTOMER. + * CONSEQUENTLY, SEMTECH SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR + * CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT + * OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION + * CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * Copyright (C) SEMTECH S.A. + */ +/*! + * \file radio.c + * \brief Generic radio driver ( radio abstraction ) + * + * \version 2.0.0 + * \date Nov 21 2012 + * \author Miguel Luis + * + * Last modified by Gregory Cristian on Apr 25 2013 + */ +/************************************************* +File name: radio.c +Description: support aiit board configure and register function +History: +1. Date: 2021-04-25 +Author: AIIT XUOS Lab +Modification: +1. replace original macro and basic date type with AIIT XUOS Lab's own defination +*************************************************/ +#include +#include "platform.h" +#include "radio.h" + +#if defined( USE_SX1232_RADIO ) + #include "sx1232.h" +#elif defined( USE_SX1272_RADIO ) + #include "sx1272.h" +#elif defined( USE_SX1276_RADIO ) + #include "sx1276.h" +#else + #error "Missing define: USE_XXXXXX_RADIO (ie. USE_SX1272_RADIO)" +#endif + +tRadioDriver RadioDriver; + +tRadioDriver* RadioDriverInit( void ) +{ +#if defined( USE_SX1232_RADIO ) + RadioDriver.Init = SX1232Init; + RadioDriver.Reset = SX1232Reset; + RadioDriver.StartRx = SX1232StartRx; + RadioDriver.GetRxPacket = SX1232GetRxPacket; + RadioDriver.SetTxPacket = SX1232SetTxPacket; + RadioDriver.Process = SX1232Process; +#elif defined( USE_SX1272_RADIO ) + RadioDriver.Init = SX1272Init; + RadioDriver.Reset = SX1272Reset; + RadioDriver.StartRx = SX1272StartRx; + RadioDriver.GetRxPacket = SX1272GetRxPacket; + RadioDriver.SetTxPacket = SX1272SetTxPacket; + RadioDriver.Process = SX1272Process; +#elif defined( USE_SX1276_RADIO ) + RadioDriver.Init = SX1276Init; + RadioDriver.Reset = SX1276Reset; + RadioDriver.StartRx = SX1276StartRx; + RadioDriver.GetRxPacket = SX1276GetRxPacket; + RadioDriver.SetTxPacket = SX1276SetTxPacket; + RadioDriver.Process = SX1276Process; + RadioDriver.ChannelEmpty = SX1276ChannelEmpty; +#else + #error "Missing define: USE_XXXXXX_RADIO (ie. USE_SX1272_RADIO)" +#endif + + return &RadioDriver; +} diff --git a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/radio.h b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/radio.h new file mode 100644 index 000000000..04749ebd5 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/radio.h @@ -0,0 +1,77 @@ +/* + * THE FOLLOWING FIRMWARE IS PROVIDED: (1) "AS IS" WITH NO WARRANTY; AND + * (2)TO ENABLE ACCESS TO CODING INFORMATION TO GUIDE AND FACILITATE CUSTOMER. + * CONSEQUENTLY, SEMTECH SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR + * CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT + * OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION + * CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * Copyright (C) SEMTECH S.A. + */ +/*! + * \file radio.h + * \brief Generic radio driver ( radio abstraction ) + * + * \version 2.0.B2 + * \date Nov 21 2012 + * \author Miguel Luis + * + * Last modified by Gregory Cristian on Apr 25 2013 + */ +/************************************************* +File name: radio.h +Description: support aiit board configure and register function +History: +1. Date: 2021-04-25 +Author: AIIT XUOS Lab +Modification: +1. replace original macro and basic date type with AIIT XUOS Lab's own defination +*************************************************/ + +#ifndef __RADIO_H__ +#define __RADIO_H__ + +/*! + * SX1272 and SX1276 General parameters definition + */ +#define LORA 1 // [0: OFF, 1: ON] + +/*! + * RF process function return codes + */ +typedef enum +{ + RF_IDLE, + RF_BUSY, + RF_RX_DONE, + RF_RX_TIMEOUT, + RF_TX_DONE, + RF_TX_TIMEOUT, + RF_LEN_ERROR, + RF_CHANNEL_EMPTY, + RF_CHANNEL_ACTIVITY_DETECTED, +}tRFProcessReturnCodes; + +/*! + * Radio driver structure defining the different function pointers + */ +typedef struct sRadioDriver +{ + void ( *Init )( void ); + void ( *Reset )( void ); + void ( *StartRx )( void ); + void ( *GetRxPacket )( void *buffer, uint16_t *size ); + void ( *SetTxPacket )( const void *buffer, uint16_t size ); + uint32_t ( *Process )( void ); + uint32_t ( *ChannelEmpty )(void ); +}tRadioDriver; + +/*! + * \brief Initializes the RadioDriver structure with specific radio + * functions. + * + * \retval radioDriver Pointer to the radio driver variable + */ +tRadioDriver* RadioDriverInit( void ); + +#endif // __RADIO_H__ diff --git a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/sx1276-Fsk.c b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/sx1276-Fsk.c new file mode 100644 index 000000000..4d89b60cd --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/sx1276-Fsk.c @@ -0,0 +1,616 @@ +/* + * THE FOLLOWING FIRMWARE IS PROVIDED: (1) "AS IS" WITH NO WARRANTY; AND + * (2)TO ENABLE ACCESS TO CODING INFORMATION TO GUIDE AND FACILITATE CUSTOMER. + * CONSEQUENTLY, SEMTECH SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR + * CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT + * OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION + * CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * Copyright (C) SEMTECH S.A. + */ +/*! + * \file sx1276.c + * \brief SX1276 RF chip driver + * + * \version 2.0.0 + * \date May 6 2013 + * \author Gregory Cristian + * + * Last modified by Miguel Luis on Jun 19 2013 + */ +/************************************************* +File name: sx1276-Fsk.c +Description: support aiit board configure and register function +History: +1. Date: 2021-04-25 +Author: AIIT XUOS Lab +Modification: +1. replace original macro and basic date type with AIIT XUOS Lab's own defination +*************************************************/ + +#include +#include + +#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 diff --git a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/sx1276-Fsk.h b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/sx1276-Fsk.h new file mode 100644 index 000000000..21502bf72 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/sx1276-Fsk.h @@ -0,0 +1,1471 @@ +/* + * 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-Fsk.h + * \brief SX1276 RF chip driver mode FSK + * + * \version 2.0.B2 + * \date May 6 2013 + * \author Gregory Cristian + * + * Last modified by Miguel Luis on Jun 19 2013 + */ +/************************************************* +File name: sx1276-Fsk.h +Description: support aiit board configure and register function +History: +1. Date: 2021-04-25 +Author: AIIT XUOS Lab +Modification: +1. replace original macro and basic date type with AIIT XUOS Lab's own defination +*************************************************/ +#ifndef __SX1276_FSK_H__ +#define __SX1276_FSK_H__ + +#include "stdint.h" +#include "stdbool.h" +/*! + * SX1276 FSK General parameters definition + */ + +typedef struct sFskSettings +{ + uint32_t RFFrequency; + uint32_t Bitrate; + uint32_t Fdev; + int8_t Power; + uint32_t RxBw; + uint32_t RxBwAfc; + bool CrcOn; + bool AfcOn; + uint8_t PayloadLength; +}tFskSettings; + +/*! + * RF packet definition + */ +#define RF_BUFFER_SIZE_MAX 256 +#define RF_BUFFER_SIZE 256 + +/*! + * RF state machine + */ +// FSK +typedef enum +{ + RF_STATE_IDLE, + RF_STATE_RX_INIT, + RF_STATE_RX_SYNC, + RF_STATE_RX_RUNNING, + RF_STATE_RX_DONE, + RF_STATE_RX_TIMEOUT, + RF_STATE_RX_LEN_ERROR, + RF_STATE_TX_INIT, + RF_STATE_TX_READY_WAIT, + RF_STATE_TX_RUNNING, + RF_STATE_TX_DONE, + RF_STATE_TX_TIMEOUT, +}tRFStates; + +/*! + * SX1276 definitions + */ +#define XTAL_FREQ 32000000 +#define FREQ_STEP 61.03515625 + +/*! + * SX1276 Internal registers Address + */ +#define REG_FIFO 0x00 +// Common settings +#define REG_OPMODE 0x01 +#define REG_BITRATEMSB 0x02 +#define REG_BITRATELSB 0x03 +#define REG_FDEVMSB 0x04 +#define REG_FDEVLSB 0x05 +#define REG_FRFMSB 0x06 +#define REG_FRFMID 0x07 +#define REG_FRFLSB 0x08 +// Tx settings +#define REG_PACONFIG 0x09 +#define REG_PARAMP 0x0A +#define REG_OCP 0x0B +// Rx settings +#define REG_LNA 0x0C +#define REG_RXCONFIG 0x0D +#define REG_RSSICONFIG 0x0E +#define REG_RSSICOLLISION 0x0F +#define REG_RSSITHRESH 0x10 +#define REG_RSSIVALUE 0x11 +#define REG_RXBW 0x12 +#define REG_AFCBW 0x13 +#define REG_OOKPEAK 0x14 +#define REG_OOKFIX 0x15 +#define REG_OOKAVG 0x16 +#define REG_RES17 0x17 +#define REG_RES18 0x18 +#define REG_RES19 0x19 +#define REG_AFCFEI 0x1A +#define REG_AFCMSB 0x1B +#define REG_AFCLSB 0x1C +#define REG_FEIMSB 0x1D +#define REG_FEILSB 0x1E +#define REG_PREAMBLEDETECT 0x1F +#define REG_RXTIMEOUT1 0x20 +#define REG_RXTIMEOUT2 0x21 +#define REG_RXTIMEOUT3 0x22 +#define REG_RXDELAY 0x23 +// Oscillator settings +#define REG_OSC 0x24 +// Packet handler settings +#define REG_PREAMBLEMSB 0x25 +#define REG_PREAMBLELSB 0x26 +#define REG_SYNCCONFIG 0x27 +#define REG_SYNCVALUE1 0x28 +#define REG_SYNCVALUE2 0x29 +#define REG_SYNCVALUE3 0x2A +#define REG_SYNCVALUE4 0x2B +#define REG_SYNCVALUE5 0x2C +#define REG_SYNCVALUE6 0x2D +#define REG_SYNCVALUE7 0x2E +#define REG_SYNCVALUE8 0x2F +#define REG_PACKETCONFIG1 0x30 +#define REG_PACKETCONFIG2 0x31 +#define REG_PAYLOADLENGTH 0x32 +#define REG_NODEADRS 0x33 +#define REG_BROADCASTADRS 0x34 +#define REG_FIFOTHRESH 0x35 +// SM settings +#define REG_SEQCONFIG1 0x36 +#define REG_SEQCONFIG2 0x37 +#define REG_TIMERRESOL 0x38 +#define REG_TIMER1COEF 0x39 +#define REG_TIMER2COEF 0x3A +// Service settings +#define REG_IMAGECAL 0x3B +#define REG_TEMP 0x3C +#define REG_LOWBAT 0x3D +// Status +#define REG_IRQFLAGS1 0x3E +#define REG_IRQFLAGS2 0x3F +// I/O settings +#define REG_DIOMAPPING1 0x40 +#define REG_DIOMAPPING2 0x41 +// Version +#define REG_VERSION 0x42 +// Additional settings +#define REG_PLLHOP 0x44 +#define REG_TCXO 0x4B +#define REG_PADAC 0x4D +#define REG_FORMERTEMP 0x5B +#define REG_BITRATEFRAC 0x5D +#define REG_AGCREF 0x61 +#define REG_AGCTHRESH1 0x62 +#define REG_AGCTHRESH2 0x63 +#define REG_AGCTHRESH3 0x64 + + +/*! + * SX1276 FSK bit control definition + */ + +/*! + * RegFifo + */ + +/*! + * RegOpMode + */ +#define RF_OPMODE_LONGRANGEMODE_MASK 0x7F +#define RF_OPMODE_LONGRANGEMODE_OFF 0x00 // Default +#define RF_OPMODE_LONGRANGEMODE_ON 0x80 + +#define RF_OPMODE_MODULATIONTYPE_MASK 0x9F +#define RF_OPMODE_MODULATIONTYPE_FSK 0x00 // Default +#define RF_OPMODE_MODULATIONTYPE_OOK 0x20 + +#define RF_OPMODE_FREQMODE_ACCESS_MASK 0xF7 +#define RF_OPMODE_FREQMODE_ACCESS_LF 0x08 // Default +#define RF_OPMODE_FREQMODE_ACCESS_HF 0x00 + +#define RF_OPMODE_MASK 0xF8 +#define RF_OPMODE_SLEEP 0x00 +#define RF_OPMODE_STANDBY 0x01 // Default +#define RF_OPMODE_SYNTHESIZER_TX 0x02 +#define RF_OPMODE_TRANSMITTER 0x03 +#define RF_OPMODE_SYNTHESIZER_RX 0x04 +#define RF_OPMODE_RECEIVER 0x05 + +/*! + * RegBitRate (bits/sec) + */ +#define RF_BITRATEMSB_1200_BPS 0x68 +#define RF_BITRATELSB_1200_BPS 0x2B +#define RF_BITRATEMSB_2400_BPS 0x34 +#define RF_BITRATELSB_2400_BPS 0x15 +#define RF_BITRATEMSB_4800_BPS 0x1A // Default +#define RF_BITRATELSB_4800_BPS 0x0B // Default +#define RF_BITRATEMSB_9600_BPS 0x0D +#define RF_BITRATELSB_9600_BPS 0x05 +#define RF_BITRATEMSB_15000_BPS 0x08 +#define RF_BITRATELSB_15000_BPS 0x55 +#define RF_BITRATEMSB_19200_BPS 0x06 +#define RF_BITRATELSB_19200_BPS 0x83 +#define RF_BITRATEMSB_38400_BPS 0x03 +#define RF_BITRATELSB_38400_BPS 0x41 +#define RF_BITRATEMSB_76800_BPS 0x01 +#define RF_BITRATELSB_76800_BPS 0xA1 +#define RF_BITRATEMSB_153600_BPS 0x00 +#define RF_BITRATELSB_153600_BPS 0xD0 +#define RF_BITRATEMSB_57600_BPS 0x02 +#define RF_BITRATELSB_57600_BPS 0x2C +#define RF_BITRATEMSB_115200_BPS 0x01 +#define RF_BITRATELSB_115200_BPS 0x16 +#define RF_BITRATEMSB_12500_BPS 0x0A +#define RF_BITRATELSB_12500_BPS 0x00 +#define RF_BITRATEMSB_25000_BPS 0x05 +#define RF_BITRATELSB_25000_BPS 0x00 +#define RF_BITRATEMSB_50000_BPS 0x02 +#define RF_BITRATELSB_50000_BPS 0x80 +#define RF_BITRATEMSB_100000_BPS 0x01 +#define RF_BITRATELSB_100000_BPS 0x40 +#define RF_BITRATEMSB_150000_BPS 0x00 +#define RF_BITRATELSB_150000_BPS 0xD5 +#define RF_BITRATEMSB_200000_BPS 0x00 +#define RF_BITRATELSB_200000_BPS 0xA0 +#define RF_BITRATEMSB_250000_BPS 0x00 +#define RF_BITRATELSB_250000_BPS 0x80 +#define RF_BITRATEMSB_32768_BPS 0x03 +#define RF_BITRATELSB_32768_BPS 0xD1 + +/*! + * RegFdev (Hz) + */ + +#define RF_FDEVMSB_BANDREG_MASK 0x3F +#define RF_FDEVMSB_BANDREG_AUTO 0x00 // Default +#define RF_FDEVMSB_BANDREG_DIV_BY_1 0x40 +#define RF_FDEVMSB_BANDREG_DIV_BY_2 0x80 +#define RF_FDEVMSB_BANDREG_DIV_BY_6 0xC0 + +#define RF_FDEVMSB_FDEV_MASK 0xC0 + +#define RF_FDEVMSB_2000_HZ 0x00 +#define RF_FDEVLSB_2000_HZ 0x21 +#define RF_FDEVMSB_5000_HZ 0x00 // Default +#define RF_FDEVLSB_5000_HZ 0x52 // Default +#define RF_FDEVMSB_10000_HZ 0x00 +#define RF_FDEVLSB_10000_HZ 0xA4 +#define RF_FDEVMSB_15000_HZ 0x00 +#define RF_FDEVLSB_15000_HZ 0xF6 +#define RF_FDEVMSB_20000_HZ 0x01 +#define RF_FDEVLSB_20000_HZ 0x48 +#define RF_FDEVMSB_25000_HZ 0x01 +#define RF_FDEVLSB_25000_HZ 0x9A +#define RF_FDEVMSB_30000_HZ 0x01 +#define RF_FDEVLSB_30000_HZ 0xEC +#define RF_FDEVMSB_35000_HZ 0x02 +#define RF_FDEVLSB_35000_HZ 0x3D +#define RF_FDEVMSB_40000_HZ 0x02 +#define RF_FDEVLSB_40000_HZ 0x8F +#define RF_FDEVMSB_45000_HZ 0x02 +#define RF_FDEVLSB_45000_HZ 0xE1 +#define RF_FDEVMSB_50000_HZ 0x03 +#define RF_FDEVLSB_50000_HZ 0x33 +#define RF_FDEVMSB_55000_HZ 0x03 +#define RF_FDEVLSB_55000_HZ 0x85 +#define RF_FDEVMSB_60000_HZ 0x03 +#define RF_FDEVLSB_60000_HZ 0xD7 +#define RF_FDEVMSB_65000_HZ 0x04 +#define RF_FDEVLSB_65000_HZ 0x29 +#define RF_FDEVMSB_70000_HZ 0x04 +#define RF_FDEVLSB_70000_HZ 0x7B +#define RF_FDEVMSB_75000_HZ 0x04 +#define RF_FDEVLSB_75000_HZ 0xCD +#define RF_FDEVMSB_80000_HZ 0x05 +#define RF_FDEVLSB_80000_HZ 0x1F +#define RF_FDEVMSB_85000_HZ 0x05 +#define RF_FDEVLSB_85000_HZ 0x71 +#define RF_FDEVMSB_90000_HZ 0x05 +#define RF_FDEVLSB_90000_HZ 0xC3 +#define RF_FDEVMSB_95000_HZ 0x06 +#define RF_FDEVLSB_95000_HZ 0x14 +#define RF_FDEVMSB_100000_HZ 0x06 +#define RF_FDEVLSB_100000_HZ 0x66 +#define RF_FDEVMSB_110000_HZ 0x07 +#define RF_FDEVLSB_110000_HZ 0x0A +#define RF_FDEVMSB_120000_HZ 0x07 +#define RF_FDEVLSB_120000_HZ 0xAE +#define RF_FDEVMSB_130000_HZ 0x08 +#define RF_FDEVLSB_130000_HZ 0x52 +#define RF_FDEVMSB_140000_HZ 0x08 +#define RF_FDEVLSB_140000_HZ 0xF6 +#define RF_FDEVMSB_150000_HZ 0x09 +#define RF_FDEVLSB_150000_HZ 0x9A +#define RF_FDEVMSB_160000_HZ 0x0A +#define RF_FDEVLSB_160000_HZ 0x3D +#define RF_FDEVMSB_170000_HZ 0x0A +#define RF_FDEVLSB_170000_HZ 0xE1 +#define RF_FDEVMSB_180000_HZ 0x0B +#define RF_FDEVLSB_180000_HZ 0x85 +#define RF_FDEVMSB_190000_HZ 0x0C +#define RF_FDEVLSB_190000_HZ 0x29 +#define RF_FDEVMSB_200000_HZ 0x0C +#define RF_FDEVLSB_200000_HZ 0xCD + +/*! + * RegFrf (MHz) + */ +#define RF_FRFMSB_863_MHZ 0xD7 +#define RF_FRFMID_863_MHZ 0xC0 +#define RF_FRFLSB_863_MHZ 0x00 +#define RF_FRFMSB_864_MHZ 0xD8 +#define RF_FRFMID_864_MHZ 0x00 +#define RF_FRFLSB_864_MHZ 0x00 +#define RF_FRFMSB_865_MHZ 0xD8 +#define RF_FRFMID_865_MHZ 0x40 +#define RF_FRFLSB_865_MHZ 0x00 +#define RF_FRFMSB_866_MHZ 0xD8 +#define RF_FRFMID_866_MHZ 0x80 +#define RF_FRFLSB_866_MHZ 0x00 +#define RF_FRFMSB_867_MHZ 0xD8 +#define RF_FRFMID_867_MHZ 0xC0 +#define RF_FRFLSB_867_MHZ 0x00 +#define RF_FRFMSB_868_MHZ 0xD9 +#define RF_FRFMID_868_MHZ 0x00 +#define RF_FRFLSB_868_MHZ 0x00 +#define RF_FRFMSB_869_MHZ 0xD9 +#define RF_FRFMID_869_MHZ 0x40 +#define RF_FRFLSB_869_MHZ 0x00 +#define RF_FRFMSB_870_MHZ 0xD9 +#define RF_FRFMID_870_MHZ 0x80 +#define RF_FRFLSB_870_MHZ 0x00 + +#define RF_FRFMSB_902_MHZ 0xE1 +#define RF_FRFMID_902_MHZ 0x80 +#define RF_FRFLSB_902_MHZ 0x00 +#define RF_FRFMSB_903_MHZ 0xE1 +#define RF_FRFMID_903_MHZ 0xC0 +#define RF_FRFLSB_903_MHZ 0x00 +#define RF_FRFMSB_904_MHZ 0xE2 +#define RF_FRFMID_904_MHZ 0x00 +#define RF_FRFLSB_904_MHZ 0x00 +#define RF_FRFMSB_905_MHZ 0xE2 +#define RF_FRFMID_905_MHZ 0x40 +#define RF_FRFLSB_905_MHZ 0x00 +#define RF_FRFMSB_906_MHZ 0xE2 +#define RF_FRFMID_906_MHZ 0x80 +#define RF_FRFLSB_906_MHZ 0x00 +#define RF_FRFMSB_907_MHZ 0xE2 +#define RF_FRFMID_907_MHZ 0xC0 +#define RF_FRFLSB_907_MHZ 0x00 +#define RF_FRFMSB_908_MHZ 0xE3 +#define RF_FRFMID_908_MHZ 0x00 +#define RF_FRFLSB_908_MHZ 0x00 +#define RF_FRFMSB_909_MHZ 0xE3 +#define RF_FRFMID_909_MHZ 0x40 +#define RF_FRFLSB_909_MHZ 0x00 +#define RF_FRFMSB_910_MHZ 0xE3 +#define RF_FRFMID_910_MHZ 0x80 +#define RF_FRFLSB_910_MHZ 0x00 +#define RF_FRFMSB_911_MHZ 0xE3 +#define RF_FRFMID_911_MHZ 0xC0 +#define RF_FRFLSB_911_MHZ 0x00 +#define RF_FRFMSB_912_MHZ 0xE4 +#define RF_FRFMID_912_MHZ 0x00 +#define RF_FRFLSB_912_MHZ 0x00 +#define RF_FRFMSB_913_MHZ 0xE4 +#define RF_FRFMID_913_MHZ 0x40 +#define RF_FRFLSB_913_MHZ 0x00 +#define RF_FRFMSB_914_MHZ 0xE4 +#define RF_FRFMID_914_MHZ 0x80 +#define RF_FRFLSB_914_MHZ 0x00 +#define RF_FRFMSB_915_MHZ 0xE4 // Default +#define RF_FRFMID_915_MHZ 0xC0 // Default +#define RF_FRFLSB_915_MHZ 0x00 // Default +#define RF_FRFMSB_916_MHZ 0xE5 +#define RF_FRFMID_916_MHZ 0x00 +#define RF_FRFLSB_916_MHZ 0x00 +#define RF_FRFMSB_917_MHZ 0xE5 +#define RF_FRFMID_917_MHZ 0x40 +#define RF_FRFLSB_917_MHZ 0x00 +#define RF_FRFMSB_918_MHZ 0xE5 +#define RF_FRFMID_918_MHZ 0x80 +#define RF_FRFLSB_918_MHZ 0x00 +#define RF_FRFMSB_919_MHZ 0xE5 +#define RF_FRFMID_919_MHZ 0xC0 +#define RF_FRFLSB_919_MHZ 0x00 +#define RF_FRFMSB_920_MHZ 0xE6 +#define RF_FRFMID_920_MHZ 0x00 +#define RF_FRFLSB_920_MHZ 0x00 +#define RF_FRFMSB_921_MHZ 0xE6 +#define RF_FRFMID_921_MHZ 0x40 +#define RF_FRFLSB_921_MHZ 0x00 +#define RF_FRFMSB_922_MHZ 0xE6 +#define RF_FRFMID_922_MHZ 0x80 +#define RF_FRFLSB_922_MHZ 0x00 +#define RF_FRFMSB_923_MHZ 0xE6 +#define RF_FRFMID_923_MHZ 0xC0 +#define RF_FRFLSB_923_MHZ 0x00 +#define RF_FRFMSB_924_MHZ 0xE7 +#define RF_FRFMID_924_MHZ 0x00 +#define RF_FRFLSB_924_MHZ 0x00 +#define RF_FRFMSB_925_MHZ 0xE7 +#define RF_FRFMID_925_MHZ 0x40 +#define RF_FRFLSB_925_MHZ 0x00 +#define RF_FRFMSB_926_MHZ 0xE7 +#define RF_FRFMID_926_MHZ 0x80 +#define RF_FRFLSB_926_MHZ 0x00 +#define RF_FRFMSB_927_MHZ 0xE7 +#define RF_FRFMID_927_MHZ 0xC0 +#define RF_FRFLSB_927_MHZ 0x00 +#define RF_FRFMSB_928_MHZ 0xE8 +#define RF_FRFMID_928_MHZ 0x00 +#define RF_FRFLSB_928_MHZ 0x00 + +/*! + * RegPaConfig + */ +#define RF_PACONFIG_PASELECT_MASK 0x7F +#define RF_PACONFIG_PASELECT_PABOOST 0x80 +#define RF_PACONFIG_PASELECT_RFO 0x00 // Default + +#define RF_PACONFIG_MAX_POWER_MASK 0x8F + +#define RF_PACONFIG_OUTPUTPOWER_MASK 0xF0 + +/*! + * RegPaRamp + */ +#define RF_PARAMP_MODULATIONSHAPING_MASK 0x9F +#define RF_PARAMP_MODULATIONSHAPING_00 0x00 // Default +#define RF_PARAMP_MODULATIONSHAPING_01 0x20 +#define RF_PARAMP_MODULATIONSHAPING_10 0x40 +#define RF_PARAMP_MODULATIONSHAPING_11 0x60 + +#define RF_PARAMP_TXBANDFORCE_MASK 0xEF +#define RF_PARAMP_TXBANDFORCE_BAND_SEL 0x10 +#define RF_PARAMP_TXBANDFORCE_AUTO 0x00 // Default + +#define RF_PARAMP_MASK 0xF0 +#define RF_PARAMP_3400_US 0x00 +#define RF_PARAMP_2000_US 0x01 +#define RF_PARAMP_1000_US 0x02 +#define RF_PARAMP_0500_US 0x03 +#define RF_PARAMP_0250_US 0x04 +#define RF_PARAMP_0125_US 0x05 +#define RF_PARAMP_0100_US 0x06 +#define RF_PARAMP_0062_US 0x07 +#define RF_PARAMP_0050_US 0x08 +#define RF_PARAMP_0040_US 0x09 // Default +#define RF_PARAMP_0031_US 0x0A +#define RF_PARAMP_0025_US 0x0B +#define RF_PARAMP_0020_US 0x0C +#define RF_PARAMP_0015_US 0x0D +#define RF_PARAMP_0012_US 0x0E +#define RF_PARAMP_0010_US 0x0F + +/*! + * RegOcp + */ +#define RF_OCP_MASK 0xDF +#define RF_OCP_ON 0x20 // Default +#define RF_OCP_OFF 0x00 + +#define RF_OCP_TRIM_MASK 0xE0 +#define RF_OCP_TRIM_045_MA 0x00 +#define RF_OCP_TRIM_050_MA 0x01 +#define RF_OCP_TRIM_055_MA 0x02 +#define RF_OCP_TRIM_060_MA 0x03 +#define RF_OCP_TRIM_065_MA 0x04 +#define RF_OCP_TRIM_070_MA 0x05 +#define RF_OCP_TRIM_075_MA 0x06 +#define RF_OCP_TRIM_080_MA 0x07 +#define RF_OCP_TRIM_085_MA 0x08 +#define RF_OCP_TRIM_090_MA 0x09 +#define RF_OCP_TRIM_095_MA 0x0A +#define RF_OCP_TRIM_100_MA 0x0B // Default +#define RF_OCP_TRIM_105_MA 0x0C +#define RF_OCP_TRIM_110_MA 0x0D +#define RF_OCP_TRIM_115_MA 0x0E +#define RF_OCP_TRIM_120_MA 0x0F +#define RF_OCP_TRIM_130_MA 0x10 +#define RF_OCP_TRIM_140_MA 0x11 +#define RF_OCP_TRIM_150_MA 0x12 +#define RF_OCP_TRIM_160_MA 0x13 +#define RF_OCP_TRIM_170_MA 0x14 +#define RF_OCP_TRIM_180_MA 0x15 +#define RF_OCP_TRIM_190_MA 0x16 +#define RF_OCP_TRIM_200_MA 0x17 +#define RF_OCP_TRIM_210_MA 0x18 +#define RF_OCP_TRIM_220_MA 0x19 +#define RF_OCP_TRIM_230_MA 0x1A +#define RF_OCP_TRIM_240_MA 0x1B + +/*! + * RegLna + */ +#define RF_LNA_GAIN_MASK 0x1F +#define RF_LNA_GAIN_G1 0x20 // Default +#define RF_LNA_GAIN_G2 0x40 +#define RF_LNA_GAIN_G3 0x60 +#define RF_LNA_GAIN_G4 0x80 +#define RF_LNA_GAIN_G5 0xA0 +#define RF_LNA_GAIN_G6 0xC0 + +#define RF_LNA_BOOST_LF_MASK 0xE7 +#define RF_LNA_BOOST_LF_DEFAULT 0x00 // Default +#define RF_LNA_BOOST_LF_GAIN 0x08 +#define RF_LNA_BOOST_LF_IP3 0x10 +#define RF_LNA_BOOST_LF_BOOST 0x18 + +#define RF_LNA_RXBANDFORCE_MASK 0xFB +#define RF_LNA_RXBANDFORCE_BAND_SEL 0x04 +#define RF_LNA_RXBANDFORCE_AUTO 0x00 // Default + +#define RF_LNA_BOOST_HF_MASK 0xFC +#define RF_LNA_BOOST_HF_OFF 0x00 // Default +#define RF_LNA_BOOST_HF_ON 0x03 + +/*! + * RegRxConfig + */ +#define RF_RXCONFIG_RESTARTRXONCOLLISION_MASK 0x7F +#define RF_RXCONFIG_RESTARTRXONCOLLISION_ON 0x80 +#define RF_RXCONFIG_RESTARTRXONCOLLISION_OFF 0x00 // Default + +#define RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK 0x40 // Write only + +#define RF_RXCONFIG_RESTARTRXWITHPLLLOCK 0x20 // Write only + +#define RF_RXCONFIG_AFCAUTO_MASK 0xEF +#define RF_RXCONFIG_AFCAUTO_ON 0x10 +#define RF_RXCONFIG_AFCAUTO_OFF 0x00 // Default + +#define RF_RXCONFIG_AGCAUTO_MASK 0xF7 +#define RF_RXCONFIG_AGCAUTO_ON 0x08 // Default +#define RF_RXCONFIG_AGCAUTO_OFF 0x00 + +#define RF_RXCONFIG_RXTRIGER_MASK 0xF8 +#define RF_RXCONFIG_RXTRIGER_OFF 0x00 +#define RF_RXCONFIG_RXTRIGER_RSSI 0x01 +#define RF_RXCONFIG_RXTRIGER_PREAMBLEDETECT 0x06 // Default +#define RF_RXCONFIG_RXTRIGER_RSSI_PREAMBLEDETECT 0x07 + +/*! + * RegRssiConfig + */ +#define RF_RSSICONFIG_OFFSET_MASK 0x07 +#define RF_RSSICONFIG_OFFSET_P_00_DB 0x00 // Default +#define RF_RSSICONFIG_OFFSET_P_01_DB 0x08 +#define RF_RSSICONFIG_OFFSET_P_02_DB 0x10 +#define RF_RSSICONFIG_OFFSET_P_03_DB 0x18 +#define RF_RSSICONFIG_OFFSET_P_04_DB 0x20 +#define RF_RSSICONFIG_OFFSET_P_05_DB 0x28 +#define RF_RSSICONFIG_OFFSET_P_06_DB 0x30 +#define RF_RSSICONFIG_OFFSET_P_07_DB 0x38 +#define RF_RSSICONFIG_OFFSET_P_08_DB 0x40 +#define RF_RSSICONFIG_OFFSET_P_09_DB 0x48 +#define RF_RSSICONFIG_OFFSET_P_10_DB 0x50 +#define RF_RSSICONFIG_OFFSET_P_11_DB 0x58 +#define RF_RSSICONFIG_OFFSET_P_12_DB 0x60 +#define RF_RSSICONFIG_OFFSET_P_13_DB 0x68 +#define RF_RSSICONFIG_OFFSET_P_14_DB 0x70 +#define RF_RSSICONFIG_OFFSET_P_15_DB 0x78 +#define RF_RSSICONFIG_OFFSET_M_16_DB 0x80 +#define RF_RSSICONFIG_OFFSET_M_15_DB 0x88 +#define RF_RSSICONFIG_OFFSET_M_14_DB 0x90 +#define RF_RSSICONFIG_OFFSET_M_13_DB 0x98 +#define RF_RSSICONFIG_OFFSET_M_12_DB 0xA0 +#define RF_RSSICONFIG_OFFSET_M_11_DB 0xA8 +#define RF_RSSICONFIG_OFFSET_M_10_DB 0xB0 +#define RF_RSSICONFIG_OFFSET_M_09_DB 0xB8 +#define RF_RSSICONFIG_OFFSET_M_08_DB 0xC0 +#define RF_RSSICONFIG_OFFSET_M_07_DB 0xC8 +#define RF_RSSICONFIG_OFFSET_M_06_DB 0xD0 +#define RF_RSSICONFIG_OFFSET_M_05_DB 0xD8 +#define RF_RSSICONFIG_OFFSET_M_04_DB 0xE0 +#define RF_RSSICONFIG_OFFSET_M_03_DB 0xE8 +#define RF_RSSICONFIG_OFFSET_M_02_DB 0xF0 +#define RF_RSSICONFIG_OFFSET_M_01_DB 0xF8 + +#define RF_RSSICONFIG_SMOOTHING_MASK 0xF8 +#define RF_RSSICONFIG_SMOOTHING_2 0x00 +#define RF_RSSICONFIG_SMOOTHING_4 0x01 +#define RF_RSSICONFIG_SMOOTHING_8 0x02 // Default +#define RF_RSSICONFIG_SMOOTHING_16 0x03 +#define RF_RSSICONFIG_SMOOTHING_32 0x04 +#define RF_RSSICONFIG_SMOOTHING_64 0x05 +#define RF_RSSICONFIG_SMOOTHING_128 0x06 +#define RF_RSSICONFIG_SMOOTHING_256 0x07 + +/*! + * RegRssiCollision + */ +#define RF_RSSICOLISION_THRESHOLD 0x0A // Default + +/*! + * RegRssiThresh + */ +#define RF_RSSITHRESH_THRESHOLD 0xFF // Default + +/*! + * RegRssiValue (Read Only) + */ + +/*! + * RegRxBw + */ +#define RF_RXBW_MANT_MASK 0xE7 +#define RF_RXBW_MANT_16 0x00 +#define RF_RXBW_MANT_20 0x08 +#define RF_RXBW_MANT_24 0x10 // Default + +#define RF_RXBW_EXP_MASK 0xF8 +#define RF_RXBW_EXP_0 0x00 +#define RF_RXBW_EXP_1 0x01 +#define RF_RXBW_EXP_2 0x02 +#define RF_RXBW_EXP_3 0x03 +#define RF_RXBW_EXP_4 0x04 +#define RF_RXBW_EXP_5 0x05 // Default +#define RF_RXBW_EXP_6 0x06 +#define RF_RXBW_EXP_7 0x07 + +/*! + * RegAfcBw + */ +#define RF_AFCBW_MANTAFC_MASK 0xE7 +#define RF_AFCBW_MANTAFC_16 0x00 +#define RF_AFCBW_MANTAFC_20 0x08 // Default +#define RF_AFCBW_MANTAFC_24 0x10 + +#define RF_AFCBW_EXPAFC_MASK 0xF8 +#define RF_AFCBW_EXPAFC_0 0x00 +#define RF_AFCBW_EXPAFC_1 0x01 +#define RF_AFCBW_EXPAFC_2 0x02 +#define RF_AFCBW_EXPAFC_3 0x03 // Default +#define RF_AFCBW_EXPAFC_4 0x04 +#define RF_AFCBW_EXPAFC_5 0x05 +#define RF_AFCBW_EXPAFC_6 0x06 +#define RF_AFCBW_EXPAFC_7 0x07 + +/*! + * RegOokPeak + */ +#define RF_OOKPEAK_BITSYNC_MASK 0xDF // Default +#define RF_OOKPEAK_BITSYNC_ON 0x20 // Default +#define RF_OOKPEAK_BITSYNC_OFF 0x00 + +#define RF_OOKPEAK_OOKTHRESHTYPE_MASK 0xE7 +#define RF_OOKPEAK_OOKTHRESHTYPE_FIXED 0x00 +#define RF_OOKPEAK_OOKTHRESHTYPE_PEAK 0x08 // Default +#define RF_OOKPEAK_OOKTHRESHTYPE_AVERAGE 0x10 + +#define RF_OOKPEAK_OOKPEAKTHRESHSTEP_MASK 0xF8 +#define RF_OOKPEAK_OOKPEAKTHRESHSTEP_0_5_DB 0x00 // Default +#define RF_OOKPEAK_OOKPEAKTHRESHSTEP_1_0_DB 0x01 +#define RF_OOKPEAK_OOKPEAKTHRESHSTEP_1_5_DB 0x02 +#define RF_OOKPEAK_OOKPEAKTHRESHSTEP_2_0_DB 0x03 +#define RF_OOKPEAK_OOKPEAKTHRESHSTEP_3_0_DB 0x04 +#define RF_OOKPEAK_OOKPEAKTHRESHSTEP_4_0_DB 0x05 +#define RF_OOKPEAK_OOKPEAKTHRESHSTEP_5_0_DB 0x06 +#define RF_OOKPEAK_OOKPEAKTHRESHSTEP_6_0_DB 0x07 + +/*! + * RegOokFix + */ +#define RF_OOKFIX_OOKFIXEDTHRESHOLD 0x0C // Default + +/*! + * RegOokAvg + */ +#define RF_OOKAVG_OOKPEAKTHRESHDEC_MASK 0x1F +#define RF_OOKAVG_OOKPEAKTHRESHDEC_000 0x00 // Default +#define RF_OOKAVG_OOKPEAKTHRESHDEC_001 0x20 +#define RF_OOKAVG_OOKPEAKTHRESHDEC_010 0x40 +#define RF_OOKAVG_OOKPEAKTHRESHDEC_011 0x60 +#define RF_OOKAVG_OOKPEAKTHRESHDEC_100 0x80 +#define RF_OOKAVG_OOKPEAKTHRESHDEC_101 0xA0 +#define RF_OOKAVG_OOKPEAKTHRESHDEC_110 0xC0 +#define RF_OOKAVG_OOKPEAKTHRESHDEC_111 0xE0 + +#define RF_OOKAVG_AVERAGEOFFSET_MASK 0xF3 +#define RF_OOKAVG_AVERAGEOFFSET_0_DB 0x00 // Default +#define RF_OOKAVG_AVERAGEOFFSET_2_DB 0x04 +#define RF_OOKAVG_AVERAGEOFFSET_4_DB 0x08 +#define RF_OOKAVG_AVERAGEOFFSET_6_DB 0x0C + +#define RF_OOKAVG_OOKAVERAGETHRESHFILT_MASK 0xFC +#define RF_OOKAVG_OOKAVERAGETHRESHFILT_00 0x00 +#define RF_OOKAVG_OOKAVERAGETHRESHFILT_01 0x01 +#define RF_OOKAVG_OOKAVERAGETHRESHFILT_10 0x02 // Default +#define RF_OOKAVG_OOKAVERAGETHRESHFILT_11 0x03 + +/*! + * RegAfcFei + */ +#define RF_AFCFEI_AGCSTART 0x10 + +#define RF_AFCFEI_AFCCLEAR 0x02 + +#define RF_AFCFEI_AFCAUTOCLEAR_MASK 0xFE +#define RF_AFCFEI_AFCAUTOCLEAR_ON 0x01 +#define RF_AFCFEI_AFCAUTOCLEAR_OFF 0x00 // Default + +/*! + * RegAfcMsb (Read Only) + */ + +/*! + * RegAfcLsb (Read Only) + */ + +/*! + * RegFeiMsb (Read Only) + */ + +/*! + * RegFeiLsb (Read Only) + */ + +/*! + * RegPreambleDetect + */ +#define RF_PREAMBLEDETECT_DETECTOR_MASK 0x7F +#define RF_PREAMBLEDETECT_DETECTOR_ON 0x80 // Default +#define RF_PREAMBLEDETECT_DETECTOR_OFF 0x00 + +#define RF_PREAMBLEDETECT_DETECTORSIZE_MASK 0x9F +#define RF_PREAMBLEDETECT_DETECTORSIZE_1 0x00 +#define RF_PREAMBLEDETECT_DETECTORSIZE_2 0x20 // Default +#define RF_PREAMBLEDETECT_DETECTORSIZE_3 0x40 +#define RF_PREAMBLEDETECT_DETECTORSIZE_4 0x60 + +#define RF_PREAMBLEDETECT_DETECTORTOL_MASK 0xE0 +#define RF_PREAMBLEDETECT_DETECTORTOL_0 0x00 +#define RF_PREAMBLEDETECT_DETECTORTOL_1 0x01 +#define RF_PREAMBLEDETECT_DETECTORTOL_2 0x02 +#define RF_PREAMBLEDETECT_DETECTORTOL_3 0x03 +#define RF_PREAMBLEDETECT_DETECTORTOL_4 0x04 +#define RF_PREAMBLEDETECT_DETECTORTOL_5 0x05 +#define RF_PREAMBLEDETECT_DETECTORTOL_6 0x06 +#define RF_PREAMBLEDETECT_DETECTORTOL_7 0x07 +#define RF_PREAMBLEDETECT_DETECTORTOL_8 0x08 +#define RF_PREAMBLEDETECT_DETECTORTOL_9 0x09 +#define RF_PREAMBLEDETECT_DETECTORTOL_10 0x0A // Default +#define RF_PREAMBLEDETECT_DETECTORTOL_11 0x0B +#define RF_PREAMBLEDETECT_DETECTORTOL_12 0x0C +#define RF_PREAMBLEDETECT_DETECTORTOL_13 0x0D +#define RF_PREAMBLEDETECT_DETECTORTOL_14 0x0E +#define RF_PREAMBLEDETECT_DETECTORTOL_15 0x0F +#define RF_PREAMBLEDETECT_DETECTORTOL_16 0x10 +#define RF_PREAMBLEDETECT_DETECTORTOL_17 0x11 +#define RF_PREAMBLEDETECT_DETECTORTOL_18 0x12 +#define RF_PREAMBLEDETECT_DETECTORTOL_19 0x13 +#define RF_PREAMBLEDETECT_DETECTORTOL_20 0x14 +#define RF_PREAMBLEDETECT_DETECTORTOL_21 0x15 +#define RF_PREAMBLEDETECT_DETECTORTOL_22 0x16 +#define RF_PREAMBLEDETECT_DETECTORTOL_23 0x17 +#define RF_PREAMBLEDETECT_DETECTORTOL_24 0x18 +#define RF_PREAMBLEDETECT_DETECTORTOL_25 0x19 +#define RF_PREAMBLEDETECT_DETECTORTOL_26 0x1A +#define RF_PREAMBLEDETECT_DETECTORTOL_27 0x1B +#define RF_PREAMBLEDETECT_DETECTORTOL_28 0x1C +#define RF_PREAMBLEDETECT_DETECTORTOL_29 0x1D +#define RF_PREAMBLEDETECT_DETECTORTOL_30 0x1E +#define RF_PREAMBLEDETECT_DETECTORTOL_31 0x1F + +/*! + * RegRxTimeout1 + */ +#define RF_RXTIMEOUT1_TIMEOUTRXRSSI 0x00 // Default + +/*! + * RegRxTimeout2 + */ +#define RF_RXTIMEOUT2_TIMEOUTRXPREAMBLE 0x00 // Default + +/*! + * RegRxTimeout3 + */ +#define RF_RXTIMEOUT3_TIMEOUTSIGNALSYNC 0x00 // Default + +/*! + * RegRxDelay + */ +#define RF_RXDELAY_INTERPACKETRXDELAY 0x00 // Default + +/*! + * RegOsc + */ +#define RF_OSC_RCCALSTART 0x08 + +#define RF_OSC_CLKOUT_MASK 0xF8 +#define RF_OSC_CLKOUT_32_MHZ 0x00 +#define RF_OSC_CLKOUT_16_MHZ 0x01 +#define RF_OSC_CLKOUT_8_MHZ 0x02 +#define RF_OSC_CLKOUT_4_MHZ 0x03 +#define RF_OSC_CLKOUT_2_MHZ 0x04 +#define RF_OSC_CLKOUT_1_MHZ 0x05 // Default +#define RF_OSC_CLKOUT_RC 0x06 +#define RF_OSC_CLKOUT_OFF 0x07 + +/*! + * RegPreambleMsb/RegPreambleLsb + */ +#define RF_PREAMBLEMSB_SIZE 0x00 // Default +#define RF_PREAMBLELSB_SIZE 0x03 // Default + +/*! + * RegSyncConfig + */ +#define RF_SYNCCONFIG_AUTORESTARTRXMODE_MASK 0x3F +#define RF_SYNCCONFIG_AUTORESTARTRXMODE_WAITPLL_ON 0x80 // Default +#define RF_SYNCCONFIG_AUTORESTARTRXMODE_WAITPLL_OFF 0x40 +#define RF_SYNCCONFIG_AUTORESTARTRXMODE_OFF 0x00 + + +#define RF_SYNCCONFIG_PREAMBLEPOLARITY_MASK 0xDF +#define RF_SYNCCONFIG_PREAMBLEPOLARITY_55 0x20 +#define RF_SYNCCONFIG_PREAMBLEPOLARITY_AA 0x00 // Default + +#define RF_SYNCCONFIG_SYNC_MASK 0xEF +#define RF_SYNCCONFIG_SYNC_ON 0x10 // Default +#define RF_SYNCCONFIG_SYNC_OFF 0x00 + + +#define RF_SYNCCONFIG_SYNCSIZE_MASK 0xF8 +#define RF_SYNCCONFIG_SYNCSIZE_1 0x00 +#define RF_SYNCCONFIG_SYNCSIZE_2 0x01 +#define RF_SYNCCONFIG_SYNCSIZE_3 0x02 +#define RF_SYNCCONFIG_SYNCSIZE_4 0x03 // Default +#define RF_SYNCCONFIG_SYNCSIZE_5 0x04 +#define RF_SYNCCONFIG_SYNCSIZE_6 0x05 +#define RF_SYNCCONFIG_SYNCSIZE_7 0x06 +#define RF_SYNCCONFIG_SYNCSIZE_8 0x07 + +/*! + * RegSyncValue1-8 + */ +#define RF_SYNCVALUE1_SYNCVALUE 0x01 // Default +#define RF_SYNCVALUE2_SYNCVALUE 0x01 // Default +#define RF_SYNCVALUE3_SYNCVALUE 0x01 // Default +#define RF_SYNCVALUE4_SYNCVALUE 0x01 // Default +#define RF_SYNCVALUE5_SYNCVALUE 0x01 // Default +#define RF_SYNCVALUE6_SYNCVALUE 0x01 // Default +#define RF_SYNCVALUE7_SYNCVALUE 0x01 // Default +#define RF_SYNCVALUE8_SYNCVALUE 0x01 // Default + +/*! + * RegPacketConfig1 + */ +#define RF_PACKETCONFIG1_PACKETFORMAT_MASK 0x7F +#define RF_PACKETCONFIG1_PACKETFORMAT_FIXED 0x00 +#define RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE 0x80 // Default + +#define RF_PACKETCONFIG1_DCFREE_MASK 0x9F +#define RF_PACKETCONFIG1_DCFREE_OFF 0x00 // Default +#define RF_PACKETCONFIG1_DCFREE_MANCHESTER 0x20 +#define RF_PACKETCONFIG1_DCFREE_WHITENING 0x40 + +#define RF_PACKETCONFIG1_CRC_MASK 0xEF +#define RF_PACKETCONFIG1_CRC_ON 0x10 // Default +#define RF_PACKETCONFIG1_CRC_OFF 0x00 + +#define RF_PACKETCONFIG1_CRCAUTOCLEAR_MASK 0xF7 +#define RF_PACKETCONFIG1_CRCAUTOCLEAR_ON 0x00 // Default +#define RF_PACKETCONFIG1_CRCAUTOCLEAR_OFF 0x08 + +#define RF_PACKETCONFIG1_ADDRSFILTERING_MASK 0xF9 +#define RF_PACKETCONFIG1_ADDRSFILTERING_OFF 0x00 // Default +#define RF_PACKETCONFIG1_ADDRSFILTERING_NODE 0x02 +#define RF_PACKETCONFIG1_ADDRSFILTERING_NODEBROADCAST 0x04 + +#define RF_PACKETCONFIG1_CRCWHITENINGTYPE_MASK 0xFE +#define RF_PACKETCONFIG1_CRCWHITENINGTYPE_CCITT 0x00 // Default +#define RF_PACKETCONFIG1_CRCWHITENINGTYPE_IBM 0x01 + +/*! + * RegPacketConfig2 + */ + +#define RF_PACKETCONFIG2_WMBUS_CRC_ENABLE_MASK 0x7F +#define RF_PACKETCONFIG2_WMBUS_CRC_ENABLE 0x80 +#define RF_PACKETCONFIG2_WMBUS_CRC_DISABLE 0x00 // Default + +#define RF_PACKETCONFIG2_DATAMODE_MASK 0xBF +#define RF_PACKETCONFIG2_DATAMODE_CONTINUOUS 0x00 +#define RF_PACKETCONFIG2_DATAMODE_PACKET 0x40 // Default + +#define RF_PACKETCONFIG2_IOHOME_MASK 0xDF +#define RF_PACKETCONFIG2_IOHOME_ON 0x20 +#define RF_PACKETCONFIG2_IOHOME_OFF 0x00 // Default + +#define RF_PACKETCONFIG2_BEACON_MASK 0xF7 +#define RF_PACKETCONFIG2_BEACON_ON 0x08 +#define RF_PACKETCONFIG2_BEACON_OFF 0x00 // Default + +#define RF_PACKETCONFIG2_PAYLOADLENGTH_MSB_MASK 0xF8 + +/*! + * RegPayloadLength + */ +#define RF_PAYLOADLENGTH_LENGTH 0x40 // Default + +/*! + * RegNodeAdrs + */ +#define RF_NODEADDRESS_ADDRESS 0x00 + +/*! + * RegBroadcastAdrs + */ +#define RF_BROADCASTADDRESS_ADDRESS 0x00 + +/*! + * RegFifoThresh + */ +#define RF_FIFOTHRESH_TXSTARTCONDITION_MASK 0x7F +#define RF_FIFOTHRESH_TXSTARTCONDITION_FIFOTHRESH 0x00 // Default +#define RF_FIFOTHRESH_TXSTARTCONDITION_FIFONOTEMPTY 0x80 + +#define RF_FIFOTHRESH_FIFOTHRESHOLD_MASK 0xC0 +#define RF_FIFOTHRESH_FIFOTHRESHOLD_THRESHOLD 0x0F // Default + +/*! + * RegSeqConfig1 + */ +#define RF_SEQCONFIG1_SEQUENCER_START 0x80 + +#define RF_SEQCONFIG1_SEQUENCER_STOP 0x40 + +#define RF_SEQCONFIG1_IDLEMODE_MASK 0xDF +#define RF_SEQCONFIG1_IDLEMODE_SLEEP 0x20 +#define RF_SEQCONFIG1_IDLEMODE_STANDBY 0x00 // Default + +#define RF_SEQCONFIG1_FROMSTART_MASK 0xE7 +#define RF_SEQCONFIG1_FROMSTART_TOLPS 0x00 // Default +#define RF_SEQCONFIG1_FROMSTART_TORX 0x08 +#define RF_SEQCONFIG1_FROMSTART_TOTX 0x10 +#define RF_SEQCONFIG1_FROMSTART_TOTX_ONFIFOLEVEL 0x18 + +#define RF_SEQCONFIG1_LPS_MASK 0xFB +#define RF_SEQCONFIG1_LPS_SEQUENCER_OFF 0x00 // Default +#define RF_SEQCONFIG1_LPS_IDLE 0x04 + +#define RF_SEQCONFIG1_FROMIDLE_MASK 0xFD +#define RF_SEQCONFIG1_FROMIDLE_TOTX 0x00 // Default +#define RF_SEQCONFIG1_FROMIDLE_TORX 0x02 + +#define RF_SEQCONFIG1_FROMTX_MASK 0xFE +#define RF_SEQCONFIG1_FROMTX_TOLPS 0x00 // Default +#define RF_SEQCONFIG1_FROMTX_TORX 0x01 + +/*! + * RegSeqConfig2 + */ +#define RF_SEQCONFIG2_FROMRX_MASK 0x1F +#define RF_SEQCONFIG2_FROMRX_TOUNUSED_000 0x00 // Default +#define RF_SEQCONFIG2_FROMRX_TORXPKT_ONPLDRDY 0x20 +#define RF_SEQCONFIG2_FROMRX_TOLPS_ONPLDRDY 0x40 +#define RF_SEQCONFIG2_FROMRX_TORXPKT_ONCRCOK 0x60 +#define RF_SEQCONFIG2_FROMRX_TOSEQUENCEROFF_ONRSSI 0x80 +#define RF_SEQCONFIG2_FROMRX_TOSEQUENCEROFF_ONSYNC 0xA0 +#define RF_SEQCONFIG2_FROMRX_TOSEQUENCEROFF_ONPREAMBLE 0xC0 +#define RF_SEQCONFIG2_FROMRX_TOUNUSED_111 0xE0 + +#define RF_SEQCONFIG2_FROMRXTIMEOUT_MASK 0xE7 +#define RF_SEQCONFIG2_FROMRXTIMEOUT_TORXRESTART 0x00 // Default +#define RF_SEQCONFIG2_FROMRXTIMEOUT_TOTX 0x08 +#define RF_SEQCONFIG2_FROMRXTIMEOUT_TOLPS 0x10 +#define RF_SEQCONFIG2_FROMRXTIMEOUT_TOSEQUENCEROFF 0x18 + +#define RF_SEQCONFIG2_FROMRXPKT_MASK 0xF8 +#define RF_SEQCONFIG2_FROMRXPKT_TOSEQUENCEROFF 0x00 // Default +#define RF_SEQCONFIG2_FROMRXPKT_TOTX_ONFIFOEMPTY 0x01 +#define RF_SEQCONFIG2_FROMRXPKT_TOLPS 0x02 +#define RF_SEQCONFIG2_FROMRXPKT_TOSYNTHESIZERRX 0x03 +#define RF_SEQCONFIG2_FROMRXPKT_TORX 0x04 + +/*! + * RegTimerResol + */ +#define RF_TIMERRESOL_TIMER1RESOL_MASK 0xF3 +#define RF_TIMERRESOL_TIMER1RESOL_OFF 0x00 // Default +#define RF_TIMERRESOL_TIMER1RESOL_000064_US 0x04 +#define RF_TIMERRESOL_TIMER1RESOL_004100_US 0x08 +#define RF_TIMERRESOL_TIMER1RESOL_262000_US 0x0C + +#define RF_TIMERRESOL_TIMER2RESOL_MASK 0xFC +#define RF_TIMERRESOL_TIMER2RESOL_OFF 0x00 // Default +#define RF_TIMERRESOL_TIMER2RESOL_000064_US 0x01 +#define RF_TIMERRESOL_TIMER2RESOL_004100_US 0x02 +#define RF_TIMERRESOL_TIMER2RESOL_262000_US 0x03 + +/*! + * RegTimer1Coef + */ +#define RF_TIMER1COEF_TIMER1COEFFICIENT 0xF5 // Default + +/*! + * RegTimer2Coef + */ +#define RF_TIMER2COEF_TIMER2COEFFICIENT 0x20 // Default + +/*! + * RegImageCal + */ +#define RF_IMAGECAL_AUTOIMAGECAL_MASK 0x7F +#define RF_IMAGECAL_AUTOIMAGECAL_ON 0x80 +#define RF_IMAGECAL_AUTOIMAGECAL_OFF 0x00 // Default + +#define RF_IMAGECAL_IMAGECAL_MASK 0xBF +#define RF_IMAGECAL_IMAGECAL_START 0x40 + +#define RF_IMAGECAL_IMAGECAL_RUNNING 0x20 +#define RF_IMAGECAL_IMAGECAL_DONE 0x00 // Default + +#define RF_IMAGECAL_TEMPCHANGE_HIGHER 0x08 +#define RF_IMAGECAL_TEMPCHANGE_LOWER 0x00 + +#define RF_IMAGECAL_TEMPTHRESHOLD_MASK 0xF9 +#define RF_IMAGECAL_TEMPTHRESHOLD_05 0x00 +#define RF_IMAGECAL_TEMPTHRESHOLD_10 0x02 // Default +#define RF_IMAGECAL_TEMPTHRESHOLD_15 0x04 +#define RF_IMAGECAL_TEMPTHRESHOLD_20 0x06 + +#define RF_IMAGECAL_TEMPMONITOR_MASK 0xFE +#define RF_IMAGECAL_TEMPMONITOR_ON 0x00 // Default +#define RF_IMAGECAL_TEMPMONITOR_OFF 0x01 + +/*! + * RegTemp (Read Only) + */ + +/*! + * RegLowBat + */ +#define RF_LOWBAT_MASK 0xF7 +#define RF_LOWBAT_ON 0x08 +#define RF_LOWBAT_OFF 0x00 // Default + +#define RF_LOWBAT_TRIM_MASK 0xF8 +#define RF_LOWBAT_TRIM_1695 0x00 +#define RF_LOWBAT_TRIM_1764 0x01 +#define RF_LOWBAT_TRIM_1835 0x02 // Default +#define RF_LOWBAT_TRIM_1905 0x03 +#define RF_LOWBAT_TRIM_1976 0x04 +#define RF_LOWBAT_TRIM_2045 0x05 +#define RF_LOWBAT_TRIM_2116 0x06 +#define RF_LOWBAT_TRIM_2185 0x07 + +/*! + * RegIrqFlags1 + */ +#define RF_IRQFLAGS1_MODEREADY 0x80 + +#define RF_IRQFLAGS1_RXREADY 0x40 + +#define RF_IRQFLAGS1_TXREADY 0x20 + +#define RF_IRQFLAGS1_PLLLOCK 0x10 + +#define RF_IRQFLAGS1_RSSI 0x08 + +#define RF_IRQFLAGS1_TIMEOUT 0x04 + +#define RF_IRQFLAGS1_PREAMBLEDETECT 0x02 + +#define RF_IRQFLAGS1_SYNCADDRESSMATCH 0x01 + +/*! + * RegIrqFlags2 + */ +#define RF_IRQFLAGS2_FIFOFULL 0x80 + +#define RF_IRQFLAGS2_FIFOEMPTY 0x40 + +#define RF_IRQFLAGS2_FIFOLEVEL 0x20 + +#define RF_IRQFLAGS2_FIFOOVERRUN 0x10 + +#define RF_IRQFLAGS2_PACKETSENT 0x08 + +#define RF_IRQFLAGS2_PAYLOADREADY 0x04 + +#define RF_IRQFLAGS2_CRCOK 0x02 + +#define RF_IRQFLAGS2_LOWBAT 0x01 + +/*! + * RegDioMapping1 + */ +#define RF_DIOMAPPING1_DIO0_MASK 0x3F +#define RF_DIOMAPPING1_DIO0_00 0x00 // Default +#define RF_DIOMAPPING1_DIO0_01 0x40 +#define RF_DIOMAPPING1_DIO0_10 0x80 +#define RF_DIOMAPPING1_DIO0_11 0xC0 + +#define RF_DIOMAPPING1_DIO1_MASK 0xCF +#define RF_DIOMAPPING1_DIO1_00 0x00 // Default +#define RF_DIOMAPPING1_DIO1_01 0x10 +#define RF_DIOMAPPING1_DIO1_10 0x20 +#define RF_DIOMAPPING1_DIO1_11 0x30 + +#define RF_DIOMAPPING1_DIO2_MASK 0xF3 +#define RF_DIOMAPPING1_DIO2_00 0x00 // Default +#define RF_DIOMAPPING1_DIO2_01 0x04 +#define RF_DIOMAPPING1_DIO2_10 0x08 +#define RF_DIOMAPPING1_DIO2_11 0x0C + +#define RF_DIOMAPPING1_DIO3_MASK 0xFC +#define RF_DIOMAPPING1_DIO3_00 0x00 // Default +#define RF_DIOMAPPING1_DIO3_01 0x01 +#define RF_DIOMAPPING1_DIO3_10 0x02 +#define RF_DIOMAPPING1_DIO3_11 0x03 + +/*! + * RegDioMapping2 + */ +#define RF_DIOMAPPING2_DIO4_MASK 0x3F +#define RF_DIOMAPPING2_DIO4_00 0x00 // Default +#define RF_DIOMAPPING2_DIO4_01 0x40 +#define RF_DIOMAPPING2_DIO4_10 0x80 +#define RF_DIOMAPPING2_DIO4_11 0xC0 + +#define RF_DIOMAPPING2_DIO5_MASK 0xCF +#define RF_DIOMAPPING2_DIO5_00 0x00 // Default +#define RF_DIOMAPPING2_DIO5_01 0x10 +#define RF_DIOMAPPING2_DIO5_10 0x20 +#define RF_DIOMAPPING2_DIO5_11 0x30 + +#define RF_DIOMAPPING2_MAP_MASK 0xFE +#define RF_DIOMAPPING2_MAP_PREAMBLEDETECT 0x01 +#define RF_DIOMAPPING2_MAP_RSSI 0x00 // Default + +/*! + * RegVersion (Read Only) + */ + +/*! + * RegAgcRef + */ + +/*! + * RegAgcThresh1 + */ + +/*! + * RegAgcThresh2 + */ + +/*! + * RegAgcThresh3 + */ + +/*! + * RegPllHop + */ +#define RF_PLLHOP_FASTHOP_MASK 0x7F +#define RF_PLLHOP_FASTHOP_ON 0x80 +#define RF_PLLHOP_FASTHOP_OFF 0x00 // Default + +/*! + * RegTcxo + */ +#define RF_TCXO_TCXOINPUT_MASK 0xEF +#define RF_TCXO_TCXOINPUT_ON 0x10 +#define RF_TCXO_TCXOINPUT_OFF 0x00 // Default + +/*! + * RegPaDac + */ +#define RF_PADAC_20DBM_MASK 0xF8 +#define RF_PADAC_20DBM_ON 0x07 +#define RF_PADAC_20DBM_OFF 0x04 // Default + +/*! + * RegPll + */ +#define RF_PLL_BANDWIDTH_MASK 0x3F +#define RF_PLL_BANDWIDTH_75 0x00 +#define RF_PLL_BANDWIDTH_150 0x40 +#define RF_PLL_BANDWIDTH_225 0x80 +#define RF_PLL_BANDWIDTH_300 0xC0 // Default + +/*! + * RegPllLowPn + */ +#define RF_PLLLOWPN_BANDWIDTH_MASK 0x3F +#define RF_PLLLOWPN_BANDWIDTH_75 0x00 +#define RF_PLLLOWPN_BANDWIDTH_150 0x40 +#define RF_PLLLOWPN_BANDWIDTH_225 0x80 +#define RF_PLLLOWPN_BANDWIDTH_300 0xC0 // Default + +/*! + * RegFormerTemp + */ + +/*! + * RegBitrateFrac + */ +#define RF_BITRATEFRAC_MASK 0xF0 + +typedef struct sSX1276 +{ + uint8_t RegFifo; // 0x00 + // Common settings + uint8_t RegOpMode; // 0x01 + uint8_t RegBitrateMsb; // 0x02 + uint8_t RegBitrateLsb; // 0x03 + uint8_t RegFdevMsb; // 0x04 + uint8_t RegFdevLsb; // 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 + uint8_t RegRxConfig; // 0x0D + uint8_t RegRssiConfig; // 0x0E + uint8_t RegRssiCollision; // 0x0F + uint8_t RegRssiThresh; // 0x10 + uint8_t RegRssiValue; // 0x11 + uint8_t RegRxBw; // 0x12 + uint8_t RegAfcBw; // 0x13 + uint8_t RegOokPeak; // 0x14 + uint8_t RegOokFix; // 0x15 + uint8_t RegOokAvg; // 0x16 + uint8_t RegRes17; // 0x17 + uint8_t RegRes18; // 0x18 + uint8_t RegRes19; // 0x19 + uint8_t RegAfcFei; // 0x1A + uint8_t RegAfcMsb; // 0x1B + uint8_t RegAfcLsb; // 0x1C + uint8_t RegFeiMsb; // 0x1D + uint8_t RegFeiLsb; // 0x1E + uint8_t RegPreambleDetect; // 0x1F + uint8_t RegRxTimeout1; // 0x20 + uint8_t RegRxTimeout2; // 0x21 + uint8_t RegRxTimeout3; // 0x22 + uint8_t RegRxDelay; // 0x23 + // Oscillator settings + uint8_t RegOsc; // 0x24 + // Packet handler settings + uint8_t RegPreambleMsb; // 0x25 + uint8_t RegPreambleLsb; // 0x26 + uint8_t RegSyncConfig; // 0x27 + uint8_t RegSyncValue1; // 0x28 + uint8_t RegSyncValue2; // 0x29 + uint8_t RegSyncValue3; // 0x2A + uint8_t RegSyncValue4; // 0x2B + uint8_t RegSyncValue5; // 0x2C + uint8_t RegSyncValue6; // 0x2D + uint8_t RegSyncValue7; // 0x2E + uint8_t RegSyncValue8; // 0x2F + uint8_t RegPacketConfig1; // 0x30 + uint8_t RegPacketConfig2; // 0x31 + uint8_t RegPayloadLength; // 0x32 + uint8_t RegNodeAdrs; // 0x33 + uint8_t RegBroadcastAdrs; // 0x34 + uint8_t RegFifoThresh; // 0x35 + // Sequencer settings + uint8_t RegSeqConfig1; // 0x36 + uint8_t RegSeqConfig2; // 0x37 + uint8_t RegTimerResol; // 0x38 + uint8_t RegTimer1Coef; // 0x39 + uint8_t RegTimer2Coef; // 0x3A + // Service settings + uint8_t RegImageCal; // 0x3B + uint8_t RegTemp; // 0x3C + uint8_t RegLowBat; // 0x3D + // Status + uint8_t RegIrqFlags1; // 0x3E + uint8_t RegIrqFlags2; // 0x3F + // I/O settings + uint8_t RegDioMapping1; // 0x40 + uint8_t RegDioMapping2; // 0x41 + // Version + uint8_t RegVersion; // 0x42 + // Additional settings + uint8_t RegAgcRef; // 0x43 + uint8_t RegAgcThresh1; // 0x44 + uint8_t RegAgcThresh2; // 0x45 + uint8_t RegAgcThresh3; // 0x46 + // Test + uint8_t RegTestReserved47[0x4B - 0x47]; // 0x47-0x4A + // Additional settings + uint8_t RegPllHop; // 0x4B + uint8_t RegTestReserved4C; // 0x4C + uint8_t RegPaDac; // 0x4D + // Test + uint8_t RegTestReserved4E[0x58-0x4E]; // 0x4E-0x57 + // Additional settings + uint8_t RegTcxo; // 0x58 + // Test + uint8_t RegTestReserved59; // 0x59 + // Test + uint8_t RegTestReserved5B; // 0x5B + // Additional settings + uint8_t RegPll; // 0x5C + // Test + uint8_t RegTestReserved5D; // 0x5D + // Additional settings + uint8_t RegPllLowPn; // 0x5E + // Test + uint8_t RegTestReserved5F[0x6C - 0x5F]; // 0x5F-0x6B + // Additional settings + uint8_t RegFormerTemp; // 0x6C + // Test + uint8_t RegTestReserved6D[0x70 - 0x6D]; // 0x6D-0x6F + // Additional settings + uint8_t RegBitrateFrac; // 0x70 +}tSX1276; + +extern tSX1276* SX1276; + +/*! + * \brief Initializes the SX1276 + */ +void SX1276FskInit( void ); + +/*! + * \brief Sets the SX1276 to datasheet default values + */ +void SX1276FskSetDefaults( void ); + +/*! + * \brief Resets the SX1276 + */ +void SX1276FskReset( void ); + +/*! + * \brief Enables/Disables the LoRa modem + * + * \param [IN]: enable [true, false] + */ +void SX1276FskSetLoRaOn( bool enable ); + +/*! + * \brief Sets the SX1276 operating mode + * + * \param [IN] opMode New operating mode + */ +void SX1276FskSetOpMode( uint8_t opMode ); + +/*! + * \brief Gets the SX1276 operating mode + * + * \retval opMode Current operating mode + */ +uint8_t SX1276FskGetOpMode( void ); + +/*! + * \brief Trigs and reads the FEI + * + * \retval feiValue Frequency error value. + */ +int32_t SX1276FskReadFei( void ); + +/*! + * \brief Reads the current AFC value + * + * \retval afcValue Frequency offset value. + */ +int32_t SX1276FskReadAfc( void ); + +/*! + * \brief Reads the current Rx gain setting + * + * \retval rxGain Current gain setting + */ +uint8_t SX1276FskReadRxGain( void ); + +/*! + * \brief Trigs and reads the current RSSI value + * + * \retval rssiValue Current RSSI value in [dBm] + */ +double SX1276FskReadRssi( void ); + +/*! + * \brief Gets the Rx gain value measured while receiving the packet + * + * \retval rxGainValue Current Rx gain value + */ +uint8_t SX1276FskGetPacketRxGain( void ); + +/*! + * \brief Gets the RSSI value measured while receiving the packet + * + * \retval rssiValue Current RSSI value in [dBm] + */ +double SX1276FskGetPacketRssi( void ); + +/*! + * \brief Gets the AFC value measured while receiving the packet + * + * \retval afcValue Current AFC value in [Hz] + */ +uint32_t SX1276FskGetPacketAfc( void ); + +/*! + * \brief Sets the radio in Rx mode. Waiting for a packet + */ +void SX1276FskStartRx( void ); + +/*! + * \brief Gets a copy of the current received buffer + * + * \param [IN]: buffer Buffer pointer + * \param [IN]: size Buffer size + */ +void SX1276FskGetRxPacket( void *buffer, uint16_t *size ); + +/*! + * \brief Sets a copy of the buffer to be transmitted and starts the + * transmission + * + * \param [IN]: buffer Buffer pointer + * \param [IN]: size Buffer size + */ +void SX1276FskSetTxPacket( 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 SX1276FskGetRFState( void ); + +/*! + * \brief Sets the new state of the RF state machine + * + * \param [IN]: state New RF state machine state + */ +void SX1276FskSetRFState( uint8_t state ); + +/*! + * \brief Process the FSK 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 SX1276FskProcess( void ); + +#endif //__SX1276_FSK_H__ diff --git a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/sx1276-FskMisc.c b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/sx1276-FskMisc.c new file mode 100644 index 000000000..4e6eca88b --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/sx1276-FskMisc.c @@ -0,0 +1,532 @@ +/* + * THE FOLLOWING FIRMWARE IS PROVIDED: (1) "AS IS" WITH NO WARRANTY; AND + * (2)TO ENABLE ACCESS TO CODING INFORMATION TO GUIDE AND FACILITATE CUSTOMER. + * CONSEQUENTLY, SEMTECH SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR + * CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT + * OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION + * CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * Copyright (C) SEMTECH S.A. + */ +/*! + * \file sx1276-FskMisc.c + * \brief SX1276 RF chip high level functions driver + * + * \remark Optional support functions. + * These functions are defined only to easy the change of the + * parameters. + * For a final firmware the radio parameters will be known so + * there is no need to support all possible parameters. + * Removing these functions will greatly reduce the final firmware + * size. + * + * \version 2.0.0 + * \date May 6 2013 + * \author Gregory Cristian + * + * Last modified by Miguel Luis on Jun 19 2013 + */ +/************************************************* +File name: sx1276-FskMisc.c +Description: support aiit board configure and register function +History: +1. Date: 2021-04-25 +Author: AIIT XUOS Lab +Modification: +1. replace original macro and basic date type with AIIT XUOS Lab's own defination +*************************************************/ + +#include + +#include "platform.h" + +#if defined( USE_SX1276_RADIO ) + +#include "sx1276-Hal.h" +#include "sx1276.h" + +#include "sx1276-Fsk.h" +#include "sx1276-FskMisc.h" + +extern tFskSettings FskSettings; + +void SX1276FskSetRFFrequency( uint32_t freq ) +{ + FskSettings.RFFrequency = freq; + + freq = ( uint32_t )( ( double )freq / ( double )FREQ_STEP ); + SX1276->RegFrfMsb = ( uint8_t )( ( freq >> 16 ) & 0xFF ); + SX1276->RegFrfMid = ( uint8_t )( ( freq >> 8 ) & 0xFF ); + SX1276->RegFrfLsb = ( uint8_t )( freq & 0xFF ); + SX1276WriteBuffer( REG_FRFMSB, &SX1276->RegFrfMsb, 3 ); +} + +uint32_t SX1276FskGetRFFrequency( void ) +{ + SX1276ReadBuffer( REG_FRFMSB, &SX1276->RegFrfMsb, 3 ); + FskSettings.RFFrequency = ( ( uint32_t )SX1276->RegFrfMsb << 16 ) | ( ( uint32_t )SX1276->RegFrfMid << 8 ) | ( ( uint32_t )SX1276->RegFrfLsb ); + FskSettings.RFFrequency = ( uint32_t )( ( double )FskSettings.RFFrequency * ( double )FREQ_STEP ); + + return FskSettings.RFFrequency; +} + +void SX1276FskRxCalibrate( void ) +{ + // the function RadioRxCalibrate is called just after the reset so all register are at their default values + uint8_t regPaConfigInitVal; + uint32_t initialFreq; + + // save register values; + SX1276Read( REG_PACONFIG, ®PaConfigInitVal ); + initialFreq = SX1276FskGetRFFrequency( ); + + // Cut the PA just in case + SX1276->RegPaConfig = 0x00; // RFO output, power = -1 dBm + SX1276Write( REG_PACONFIG, SX1276->RegPaConfig ); + + // Set Frequency in HF band + SX1276FskSetRFFrequency( 860000000 ); + + // Rx chain re-calibration workaround + SX1276Read( REG_IMAGECAL, &SX1276->RegImageCal ); + SX1276->RegImageCal = ( SX1276->RegImageCal & RF_IMAGECAL_IMAGECAL_MASK ) | RF_IMAGECAL_IMAGECAL_START; + SX1276Write( REG_IMAGECAL, SX1276->RegImageCal ); + + SX1276Read( REG_IMAGECAL, &SX1276->RegImageCal ); + // rx_cal_run goes low when calibration in finished + while( ( SX1276->RegImageCal & RF_IMAGECAL_IMAGECAL_RUNNING ) == RF_IMAGECAL_IMAGECAL_RUNNING ) + { + SX1276Read( REG_IMAGECAL, &SX1276->RegImageCal ); + } + + // reload saved values into the registers + SX1276->RegPaConfig = regPaConfigInitVal; + SX1276Write( REG_PACONFIG, SX1276->RegPaConfig ); + + SX1276FskSetRFFrequency( initialFreq ); + +} + +void SX1276FskSetBitrate( uint32_t bitrate ) +{ + FskSettings.Bitrate = bitrate; + + bitrate = ( uint16_t )( ( double )XTAL_FREQ / ( double )bitrate ); + SX1276->RegBitrateMsb = ( uint8_t )( bitrate >> 8 ); + SX1276->RegBitrateLsb = ( uint8_t )( bitrate & 0xFF ); + SX1276WriteBuffer( REG_BITRATEMSB, &SX1276->RegBitrateMsb, 2 ); +} + +uint32_t SX1276FskGetBitrate( void ) +{ + SX1276ReadBuffer( REG_BITRATEMSB, &SX1276->RegBitrateMsb, 2 ); + FskSettings.Bitrate = ( ( ( uint32_t )SX1276->RegBitrateMsb << 8 ) | ( ( uint32_t )SX1276->RegBitrateLsb ) ); + FskSettings.Bitrate = ( uint16_t )( ( double )XTAL_FREQ / ( double )FskSettings.Bitrate ); + + return FskSettings.Bitrate; +} + +void SX1276FskSetFdev( uint32_t fdev ) +{ + FskSettings.Fdev = fdev; + + SX1276Read( REG_FDEVMSB, &SX1276->RegFdevMsb ); + + fdev = ( uint16_t )( ( double )fdev / ( double )FREQ_STEP ); + SX1276->RegFdevMsb = ( ( SX1276->RegFdevMsb & RF_FDEVMSB_FDEV_MASK ) | ( ( ( uint8_t )( fdev >> 8 ) ) & ~RF_FDEVMSB_FDEV_MASK ) ); + SX1276->RegFdevLsb = ( uint8_t )( fdev & 0xFF ); + SX1276WriteBuffer( REG_FDEVMSB, &SX1276->RegFdevMsb, 2 ); +} + +uint32_t SX1276FskGetFdev( void ) +{ + SX1276ReadBuffer( REG_FDEVMSB, &SX1276->RegFdevMsb, 2 ); + FskSettings.Fdev = ( ( ( uint32_t )( ( SX1276->RegFdevMsb << 8 ) & ~RF_FDEVMSB_FDEV_MASK ) ) | ( ( uint32_t )SX1276->RegFdevLsb ) ); + FskSettings.Fdev = ( uint16_t )( ( double )FskSettings.Fdev * ( double )FREQ_STEP ); + + return FskSettings.Fdev; +} + +void SX1276FskSetRFPower( int8_t power ) +{ + SX1276Read( REG_PACONFIG, &SX1276->RegPaConfig ); + SX1276Read( REG_PADAC, &SX1276->RegPaDac ); + + if( ( SX1276->RegPaConfig & RF_PACONFIG_PASELECT_PABOOST ) == RF_PACONFIG_PASELECT_PABOOST ) + { + if( ( SX1276->RegPaDac & 0x87 ) == 0x87 ) + { + if( power < 5 ) + { + power = 5; + } + if( power > 20 ) + { + power = 20; + } + SX1276->RegPaConfig = ( SX1276->RegPaConfig & RF_PACONFIG_MAX_POWER_MASK ) | 0x70; + SX1276->RegPaConfig = ( SX1276->RegPaConfig & RF_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power - 5 ) & 0x0F ); + } + else + { + if( power < 2 ) + { + power = 2; + } + if( power > 17 ) + { + power = 17; + } + SX1276->RegPaConfig = ( SX1276->RegPaConfig & RF_PACONFIG_MAX_POWER_MASK ) | 0x70; + SX1276->RegPaConfig = ( SX1276->RegPaConfig & RF_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power - 2 ) & 0x0F ); + } + } + else + { + if( power < -1 ) + { + power = -1; + } + if( power > 14 ) + { + power = 14; + } + SX1276->RegPaConfig = ( SX1276->RegPaConfig & RF_PACONFIG_MAX_POWER_MASK ) | 0x70; + SX1276->RegPaConfig = ( SX1276->RegPaConfig & RF_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power + 1 ) & 0x0F ); + } + SX1276Write( REG_PACONFIG, SX1276->RegPaConfig ); + FskSettings.Power = power; +} + +int8_t SX1276FskGetRFPower( void ) +{ + SX1276Read( REG_PACONFIG, &SX1276->RegPaConfig ); + SX1276Read( REG_PADAC, &SX1276->RegPaDac ); + + if( ( SX1276->RegPaConfig & RF_PACONFIG_PASELECT_PABOOST ) == RF_PACONFIG_PASELECT_PABOOST ) + { + if( ( SX1276->RegPaDac & 0x07 ) == 0x07 ) + { + FskSettings.Power = 5 + ( SX1276->RegPaConfig & ~RF_PACONFIG_OUTPUTPOWER_MASK ); + } + else + { + FskSettings.Power = 2 + ( SX1276->RegPaConfig & ~RF_PACONFIG_OUTPUTPOWER_MASK ); + } + } + else + { + FskSettings.Power = -1 + ( SX1276->RegPaConfig & ~RF_PACONFIG_OUTPUTPOWER_MASK ); + } + return FskSettings.Power; +} + +/*! + * \brief Computes the Rx bandwidth with the mantisse and exponent + * + * \param [IN] mantisse Mantisse of the bandwidth value + * \param [IN] exponent Exponent of the bandwidth value + * \retval bandwidth Computed bandwidth + */ +static uint32_t SX1276FskComputeRxBw( uint8_t mantisse, uint8_t exponent ) +{ + // rxBw + if( ( SX1276->RegOpMode & RF_OPMODE_MODULATIONTYPE_FSK ) == RF_OPMODE_MODULATIONTYPE_FSK ) + { + return ( uint32_t )( ( double )XTAL_FREQ / ( mantisse * ( double )pow( 2, exponent + 2 ) ) ); + } + else + { + return ( uint32_t )( ( double )XTAL_FREQ / ( mantisse * ( double )pow( 2, exponent + 3 ) ) ); + } +} + +/*! + * \brief Computes the mantisse and exponent from the bandwitdh value + * + * \param [IN] rxBwValue Bandwidth value + * \param [OUT] mantisse Mantisse of the bandwidth value + * \param [OUT] exponent Exponent of the bandwidth value + */ +static void SX1276FskComputeRxBwMantExp( uint32_t rxBwValue, uint8_t* mantisse, uint8_t* exponent ) +{ + uint8_t tmpExp = 0; + uint8_t tmpMant = 0; + + double tmpRxBw = 0; + double rxBwMin = 10e6; + + for( tmpExp = 0; tmpExp < 8; tmpExp++ ) + { + for( tmpMant = 16; tmpMant <= 24; tmpMant += 4 ) + { + if( ( SX1276->RegOpMode & RF_OPMODE_MODULATIONTYPE_FSK ) == RF_OPMODE_MODULATIONTYPE_FSK ) + { + tmpRxBw = ( double )XTAL_FREQ / ( tmpMant * ( double )pow( 2, tmpExp + 2 ) ); + } + else + { + tmpRxBw = ( double )XTAL_FREQ / ( tmpMant * ( double )pow( 2, tmpExp + 3 ) ); + } + if( fabs( tmpRxBw - rxBwValue ) < rxBwMin ) + { + rxBwMin = fabs( tmpRxBw - rxBwValue ); + *mantisse = tmpMant; + *exponent = tmpExp; + } + } + } +} + +void SX1276FskSetDccBw( uint8_t* reg, uint32_t dccValue, uint32_t rxBwValue ) +{ + uint8_t mantisse = 0; + uint8_t exponent = 0; + + if( reg == &SX1276->RegRxBw ) + { + *reg = ( uint8_t )dccValue & 0x60; + } + else + { + *reg = 0; + } + + SX1276FskComputeRxBwMantExp( rxBwValue, &mantisse, &exponent ); + + switch( mantisse ) + { + case 16: + *reg |= ( uint8_t )( 0x00 | ( exponent & 0x07 ) ); + break; + case 20: + *reg |= ( uint8_t )( 0x08 | ( exponent & 0x07 ) ); + break; + case 24: + *reg |= ( uint8_t )( 0x10 | ( exponent & 0x07 ) ); + break; + default: + // Something went terribely wrong + break; + } + + if( reg == &SX1276->RegRxBw ) + { + SX1276Write( REG_RXBW, *reg ); + FskSettings.RxBw = rxBwValue; + } + else + { + SX1276Write( REG_AFCBW, *reg ); + FskSettings.RxBwAfc = rxBwValue; + } +} + +uint32_t SX1276FskGetBw( uint8_t* reg ) +{ + uint32_t rxBwValue = 0; + uint8_t mantisse = 0; + switch( ( *reg & 0x18 ) >> 3 ) + { + case 0: + mantisse = 16; + break; + case 1: + mantisse = 20; + break; + case 2: + mantisse = 24; + break; + default: + break; + } + rxBwValue = SX1276FskComputeRxBw( mantisse, ( uint8_t )*reg & 0x07 ); + if( reg == &SX1276->RegRxBw ) + { + return FskSettings.RxBw = rxBwValue; + } + else + { + return FskSettings.RxBwAfc = rxBwValue; + } +} + +void SX1276FskSetPacketCrcOn( bool enable ) +{ + SX1276Read( REG_PACKETCONFIG1, &SX1276->RegPacketConfig1 ); + SX1276->RegPacketConfig1 = ( SX1276->RegPacketConfig1 & RF_PACKETCONFIG1_CRC_MASK ) | ( enable << 4 ); + SX1276Write( REG_PACKETCONFIG1, SX1276->RegPacketConfig1 ); + FskSettings.CrcOn = enable; +} + +bool SX1276FskGetPacketCrcOn( void ) +{ + SX1276Read( REG_PACKETCONFIG1, &SX1276->RegPacketConfig1 ); + FskSettings.CrcOn = ( SX1276->RegPacketConfig1 & RF_PACKETCONFIG1_CRC_ON ) >> 4; + return FskSettings.CrcOn; +} + +void SX1276FskSetAfcOn( bool enable ) +{ + SX1276Read( REG_RXCONFIG, &SX1276->RegRxConfig ); + SX1276->RegRxConfig = ( SX1276->RegRxConfig & RF_RXCONFIG_AFCAUTO_MASK ) | ( enable << 4 ); + SX1276Write( REG_RXCONFIG, SX1276->RegRxConfig ); + FskSettings.AfcOn = enable; +} + +bool SX1276FskGetAfcOn( void ) +{ + SX1276Read( REG_RXCONFIG, &SX1276->RegRxConfig ); + FskSettings.AfcOn = ( SX1276->RegRxConfig & RF_RXCONFIG_AFCAUTO_ON ) >> 4; + return FskSettings.AfcOn; +} + +void SX1276FskSetPayloadLength( uint8_t value ) +{ + SX1276->RegPayloadLength = value; + SX1276Write( REG_PAYLOADLENGTH, SX1276->RegPayloadLength ); + FskSettings.PayloadLength = value; +} + +uint8_t SX1276FskGetPayloadLength( void ) +{ + SX1276Read( REG_PAYLOADLENGTH, &SX1276->RegPayloadLength ); + FskSettings.PayloadLength = SX1276->RegPayloadLength; + return FskSettings.PayloadLength; +} + +void SX1276FskSetPa20dBm( bool enale ) +{ + SX1276Read( REG_PADAC, &SX1276->RegPaDac ); + SX1276Read( REG_PACONFIG, &SX1276->RegPaConfig ); + + if( ( SX1276->RegPaConfig & RF_PACONFIG_PASELECT_PABOOST ) == RF_PACONFIG_PASELECT_PABOOST ) + { + if( enale == true ) + { + SX1276->RegPaDac = 0x87; + } + } + else + { + SX1276->RegPaDac = 0x84; + } + SX1276Write( REG_PADAC, SX1276->RegPaDac ); +} + +bool SX1276FskGetPa20dBm( void ) +{ + SX1276Read( REG_PADAC, &SX1276->RegPaDac ); + + return ( ( SX1276->RegPaDac & 0x07 ) == 0x07 ) ? true : false; +} + +void SX1276FskSetPAOutput( uint8_t outputPin ) +{ + SX1276Read( REG_PACONFIG, &SX1276->RegPaConfig ); + SX1276->RegPaConfig = (SX1276->RegPaConfig & RF_PACONFIG_PASELECT_MASK ) | outputPin; + SX1276Write( REG_PACONFIG, SX1276->RegPaConfig ); +} + +uint8_t SX1276FskGetPAOutput( void ) +{ + SX1276Read( REG_PACONFIG, &SX1276->RegPaConfig ); + return SX1276->RegPaConfig & ~RF_PACONFIG_PASELECT_MASK; +} + + +void SX1276FskSetPaRamp( uint8_t value ) +{ + SX1276Read( REG_PARAMP, &SX1276->RegPaRamp ); + SX1276->RegPaRamp = ( SX1276->RegPaRamp & RF_PARAMP_MASK ) | ( value & ~RF_PARAMP_MASK ); + SX1276Write( REG_PARAMP, SX1276->RegPaRamp ); +} + +uint8_t SX1276FskGetPaRamp( void ) +{ + SX1276Read( REG_PARAMP, &SX1276->RegPaRamp ); + return SX1276->RegPaRamp & ~RF_PARAMP_MASK; +} + +void SX1276FskSetRssiOffset( int8_t offset ) +{ + SX1276Read( REG_RSSICONFIG, &SX1276->RegRssiConfig ); + if( offset < 0 ) + { + offset = ( ~offset & 0x1F ); + offset += 1; + offset = -offset; + } + SX1276->RegRssiConfig |= ( uint8_t )( ( offset & 0x1F ) << 3 ); + SX1276Write( REG_RSSICONFIG, SX1276->RegRssiConfig ); +} + +int8_t SX1276FskGetRssiOffset( void ) +{ + int8_t offset; + SX1276Read( REG_RSSICONFIG, &SX1276->RegRssiConfig ); + offset = SX1276->RegRssiConfig >> 3; + if( ( offset & 0x10 ) == 0x10 ) + { + offset = ( ~offset & 0x1F ); + offset += 1; + offset = -offset; + } + return offset; +} + +int8_t SX1276FskGetRawTemp( void ) +{ + int8_t temp = 0; + uint8_t previousOpMode; + uint32_t startTick; + + // Enable Temperature reading + SX1276Read( REG_IMAGECAL, &SX1276->RegImageCal ); + SX1276->RegImageCal = ( SX1276->RegImageCal & RF_IMAGECAL_TEMPMONITOR_MASK ) | RF_IMAGECAL_TEMPMONITOR_ON; + SX1276Write( REG_IMAGECAL, SX1276->RegImageCal ); + + // save current Op Mode + SX1276Read( REG_OPMODE, &SX1276->RegOpMode ); + previousOpMode = SX1276->RegOpMode; + + // put device in FSK RxSynth + SX1276->RegOpMode = RF_OPMODE_SYNTHESIZER_RX; + SX1276Write( REG_OPMODE, SX1276->RegOpMode ); + + // Wait 1ms + startTick = GET_TICK_COUNT( ); + while( ( GET_TICK_COUNT( ) - startTick ) < TICK_RATE_MS( 1 ) ); + + // Disable Temperature reading + SX1276Read( REG_IMAGECAL, &SX1276->RegImageCal ); + SX1276->RegImageCal = ( SX1276->RegImageCal & RF_IMAGECAL_TEMPMONITOR_MASK ) | RF_IMAGECAL_TEMPMONITOR_OFF; + SX1276Write( REG_IMAGECAL, SX1276->RegImageCal ); + + // Read temperature + SX1276Read( REG_TEMP, &SX1276->RegTemp ); + + temp = SX1276->RegTemp & 0x7F; + + if( ( SX1276->RegTemp & 0x80 ) == 0x80 ) + { + temp *= -1; + } + + // Reload previous Op Mode + SX1276Write( REG_OPMODE, previousOpMode ); + + return temp; +} + +int8_t SX1276FskCalibreateTemp( int8_t actualTemp ) +{ + return actualTemp - SX1276FskGetRawTemp( ); +} + +int8_t SX1276FskGetTemp( int8_t compensationFactor ) +{ + return SX1276FskGetRawTemp( ) + compensationFactor; +} + +#endif // USE_SX1276_RADIO diff --git a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/sx1276-FskMisc.h b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/sx1276-FskMisc.h new file mode 100644 index 000000000..583264bca --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/sx1276-FskMisc.h @@ -0,0 +1,251 @@ +/* + * THE FOLLOWING FIRMWARE IS PROVIDED: (1) "AS IS" WITH NO WARRANTY; AND + * (2)TO ENABLE ACCESS TO CODING INFORMATION TO GUIDE AND FACILITATE CUSTOMER. + * CONSEQUENTLY, SEMTECH SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR + * CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT + * OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION + * CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * Copyright (C) SEMTECH S.A. + */ +/*! + * \file sx1276-FskMisc.h + * \brief SX1276 RF chip high level functions driver + * + * \remark Optional support functions. + * These functions are defined only to easy the change of the + * parameters. + * For a final firmware the radio parameters will be known so + * there is no need to support all possible parameters. + * Removing these functions will greatly reduce the final firmware + * size. + * + * \version 2.0.B2 + * \date May 6 2013 + * \author Gregory Cristian + * + * Last modified by Miguel Luis on Jun 19 2013 + */ +/************************************************* +File name: sx1276-FskMisc.h +Description: support aiit board configure and register function +History: +1. Date: 2021-04-25 +Author: AIIT XUOS Lab +Modification: +1. replace original macro and basic date type with AIIT XUOS Lab's own defination +*************************************************/ + +#ifndef __SX1276_FSK_MISC_H__ +#define __SX1276_FSK_MISC_H__ + +/*! + * \brief Writes the new RF frequency value + * + * \param [IN] freq New RF frequency value in [Hz] + */ +void SX1276FskSetRFFrequency( uint32_t freq ); + +/*! + * \brief Reads the current RF frequency value + * + * \retval freq Current RF frequency value in [Hz] + */ +uint32_t SX1276FskGetRFFrequency( void ); + +/*! + * \brief Calibrate RSSI and I/Q mismatch for HF + * + * \retval none + */ +void SX1276FskRxCalibrate( void ); + +/*! + * \brief Writes the new bitrate value + * + * \param [IN] bitrate New bitrate value in [bps] + */ +void SX1276FskSetBitrate( uint32_t bitrate ); + +/*! + * \brief Reads the current bitrate value + * + * \retval bitrate Current bitrate value in [bps] + */ +uint32_t SX1276FskGetBitrate( void ); + +/*! + * \brief Writes the new frequency deviation value + * + * \param [IN] fdev New frequency deviation value in [Hz] + */ +void SX1276FskSetFdev( uint32_t fdev ); + +/*! + * \brief Reads the current frequency deviation value + * + * \retval fdev Current frequency deviation value in [Hz] + */ +uint32_t SX1276FskGetFdev( void ); + +/*! + * \brief Writes the new RF output power value + * + * \param [IN] power New output power value in [dBm] + */ +void SX1276FskSetRFPower( int8_t power ); + +/*! + * \brief Reads the current RF output power value + * + * \retval power Current output power value in [dBm] + */ +int8_t SX1276FskGetRFPower( void ); + +/*! + * \brief Writes the DC offset canceller and Rx bandwidth values + * + * \remark For SX1276 there is no DCC setting. dccValue should be 0 + * ie: SX1276SetDccBw( &SX1276.RegRxBw, 0, 62500 ); + * + * \param [IN] reg Register pointer to either SX1231.RegRxBw or SX1231.RegAfcBw + * \param [IN] dccValue New DC offset canceller value in [Hz] ( SX1231 only ) + * \param [IN] rxBwValue New Rx bandwidth value in [Hz] + */ +void SX1276FskSetDccBw( uint8_t* reg, uint32_t dccValue, uint32_t rxBwValue ); + +/*! + * \brief Reads the current bandwidth setting + * + * \param [IN] reg Register pointer to either SX1231.RegRxBw or SX1231.RegAfcBw + * + * \retval bandwidth Bandwidth value + */ +uint32_t SX1276FskGetBw( uint8_t* reg ); + +/*! + * \brief Enables/Disables CRC + * + * \param [IN] enable CRC enable/disable + */ +void SX1276FskSetPacketCrcOn( bool enable ); + +/*! + * \brief Reads the current CRC Enable/Disbale value + * + * \retval enable Current CRC Enable/Disbale value + */ +bool SX1276FskGetPacketCrcOn( void ); + +/*! + * \brief Enables/Disables AFC + * + * \param [IN] enable AFC enable/disable + */ +void SX1276FskSetAfcOn( bool enable ); + +/*! + * \brief Reads the current AFC Enable/Disbale value + * + * \retval enable Current AFC Enable/Disbale value + */ +bool SX1276FskGetAfcOn( void ); + +/*! + * \brief Writes the new payload length value + * + * \param [IN] value New payload length value + */ +void SX1276FskSetPayloadLength( uint8_t value ); + +/*! + * \brief Reads the current payload length value + * + * \retval value Current payload length value + */ +uint8_t SX1276FskGetPayloadLength( void ); + +/*! + * \brief Enables/Disables the 20 dBm PA + * + * \param [IN] enable [true, false] + */ +void SX1276FskSetPa20dBm( bool enale ); + +/*! + * \brief Gets the current 20 dBm PA status + * + * \retval enable [true, false] + */ +bool SX1276FskGetPa20dBm( void ); + +/*! + * \brief Set the RF Output pin + * + * \param [IN] RF_PACONFIG_PASELECT_PABOOST or RF_PACONFIG_PASELECT_RFO + */ +void SX1276FskSetPAOutput( uint8_t outputPin ); + +/*! + * \brief Gets the used RF Ouptu pin + * + * \retval RF_PACONFIG_PASELECT_PABOOST or RF_PACONFIG_PASELECT_RFO + */ +uint8_t SX1276FskGetPAOutput( void ); + +/*! + * \brief Writes the new PA rise/fall time of ramp up/down value + * + * \param [IN] value New PaRamp value + */ +void SX1276FskSetPaRamp( uint8_t value ); + +/*! + * \brief Reads the current PA rise/fall time of ramp up/down value + * + * \retval value Current PaRamp value + */ +uint8_t SX1276FskGetPaRamp( void ); + +/*! + * \brief Applies an offset to the RSSI. Compensates board components + * + * \param [IN] offset Offset to be applied (+/-) + */ +void SX1276FskSetRssiOffset( int8_t offset ); + +/*! + * \brief Gets the current RSSI offset. + * + * \retval offset Current offset (+/-) + */ +int8_t SX1276FskGetRssiOffset( void ); + +/*! + * \brief Writes the new value for the preamble size + * + * \param [IN] size New value of pramble size + */ +void SX1276FskSetPreambleSize( uint16_t size ); + +/*! + * Reads the raw temperature + * \retval temperature New raw temperature reading in 2's complement format + */ +int8_t SX1276FskGetRawTemp( void ); + +/*! + * Computes the temperature compensation factor + * \param [IN] actualTemp Actual temperature measured by an external device + * \retval compensationFactor Computed compensation factor + */ +int8_t SX1276FskCalibreateTemp( int8_t actualTemp ); + +/*! + * Gets the actual compensated temperature + * \param [IN] compensationFactor Return value of the calibration function + * \retval New compensated temperature value + */ +int8_t SX1276FskGetTemp( int8_t compensationFactor ); + +#endif //__SX1276_FSK_MISC_H__ diff --git a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/sx1276-Hal.h b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/sx1276-Hal.h new file mode 100644 index 000000000..cc21c3b54 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/sx1276-Hal.h @@ -0,0 +1,170 @@ +/* + * THE FOLLOWING FIRMWARE IS PROVIDED: (1) "AS IS" WITH NO WARRANTY; AND + * (2)TO ENABLE ACCESS TO CODING INFORMATION TO GUIDE AND FACILITATE CUSTOMER. + * CONSEQUENTLY, SEMTECH SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR + * CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT + * OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION + * CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * Copyright (C) SEMTECH S.A. + */ +/*! + * \file sx1276-Hal.h + * \brief SX1276 Hardware Abstraction Layer + * + * \version 2.0.B2 + * \date Nov 21 2012 + * \author Miguel Luis + * + * Last modified by Miguel Luis on Jun 19 2013 + */ +/************************************************* +File name: sx1276-Hal.h +Description: support aiit board configure and register function +History: +1. Date: 2021-04-25 +Author: AIIT XUOS Lab +Modification: +1. replace original macro and basic date type with AIIT XUOS Lab's own defination +*************************************************/ + +#ifndef __SX1276_HAL_H__ +#define __SX1276_HAL_H__ +#include "platform.h" + +/*! + * DIO state read functions mapping + */ +#define DIO0 SX1276ReadDio0( ) +#define DIO1 SX1276ReadDio1( ) +#define DIO2 SX1276ReadDio2( ) +#define DIO3 SX1276ReadDio3( ) +#define DIO4 SX1276ReadDio4( ) +#define DIO5 SX1276ReadDio5( ) + +// RXTX pin control see errata note +#define RXTX( txEnable ) SX1276WriteRxTx( txEnable ); + +#define GET_TICK_COUNT( ) CurrentTicksGain() +#define TICK_RATE_MS( ms ) ( ms ) + +typedef enum +{ + RADIO_RESET_OFF, + RADIO_RESET_ON, +}tRadioResetState; + +/*! + * \brief Initializes the radio interface I/Os + */ +void SX1276InitIo( void ); + +/*! + * \brief Set the radio reset pin state + * + * \param state New reset pin state + */ +void SX1276SetReset( uint8_t state ); + +/*! + * \brief Writes the radio register at the specified address + * + * \param [IN]: addr Register address + * \param [IN]: data New register value + */ +void SX1276Write( uint8_t addr, uint8_t data ); + +/*! + * \brief Reads the radio register at the specified address + * + * \param [IN]: addr Register address + * \param [OUT]: data Register value + */ +void SX1276Read( uint8_t addr, uint8_t *data ); + +/*! + * \brief Writes multiple radio registers starting at address + * + * \param [IN] addr First Radio register address + * \param [IN] buffer Buffer containing the new register's values + * \param [IN] size Number of registers to be written + */ +void SX1276WriteBuffer( uint8_t addr, uint8_t *buffer, uint8_t size ); + +/*! + * \brief Reads multiple radio registers starting at address + * + * \param [IN] addr First Radio register address + * \param [OUT] buffer Buffer where to copy the registers data + * \param [IN] size Number of registers to be read + */ +void SX1276ReadBuffer( uint8_t addr, uint8_t *buffer, uint8_t size ); + +/*! + * \brief Writes the buffer contents to the radio FIFO + * + * \param [IN] buffer Buffer containing data to be put on the FIFO. + * \param [IN] size Number of bytes to be written to the FIFO + */ +void SX1276WriteFifo( uint8_t *buffer, uint8_t size ); + +/*! + * \brief Reads the contents of the radio FIFO + * + * \param [OUT] buffer Buffer where to copy the FIFO read data. + * \param [IN] size Number of bytes to be read from the FIFO + */ +void SX1276ReadFifo( uint8_t *buffer, uint8_t size ); + +/*! + * \brief Gets the SX1276 DIO0 hardware pin status + * + * \retval status Current hardware pin status [1, 0] + */ +inline uint8_t SX1276ReadDio0( void ); + +/*! + * \brief Ge// USE_SX1276_RADIOts the SX1276 DIO1 hardware pin status + * + * \retval status Current hardware pin status [1, 0] + */ +inline uint8_t SX1276ReadDio1( void ); + +/*! + * \brief Gets the SX1276 DIO2 hardware pin status + * + * \retval status Current hardware pin status [1, 0] + */ +inline uint8_t SX1276ReadDio2( void ); + +/*! + * \brief Gets the SX1276 DIO3 hardware pin status + * + * \retval status Current hardware pin status [1, 0] + */ +inline uint8_t SX1276ReadDio3( void ); + +/*! + * \brief Gets the SX1276 DIO4 hardware pin status + * + * \retval status Current hardware pin status [1, 0] + */ +inline uint8_t SX1276ReadDio4( void ); + +/*! + * \brief Gets the SX1276 DIO5 hardware pin status + * + * \retval status Current hardware pin status [1, 0] + */ +inline uint8_t SX1276ReadDio5( void ); + +/*! + * \brief Writes the external RxTx pin value + * + * \remark see errata note + * + * \param [IN] txEnable [1: Tx, 0: Rx] + */ +inline void SX1276WriteRxTx( uint8_t txEnable ); + +#endif //__SX1276_HAL_H__ diff --git a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/sx1276-LoRa.c b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/sx1276-LoRa.c new file mode 100644 index 000000000..60d9b5e61 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/sx1276-LoRa.c @@ -0,0 +1,723 @@ +/* + * THE FOLLOWING FIRMWARE IS PROVIDED: (1) "AS IS" WITH NO WARRANTY; AND + * (2)TO ENABLE ACCESS TO CODING INFORMATION TO GUIDE AND FACILITATE CUSTOMER. + * CONSEQUENTLY, SEMTECH SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR + * CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT + * OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION + * CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * Original Copyright (C) SEMTECH S.A. + * Modified Copyright (C) 2020 AIIT XUOS Lab + */ +/*! + * \file sx1276-LoRa.c + * \brief SX1276 RF chip driver mode LoRa + * + * \version 2.0.0 + * \date Nov 21 2012 + * \author Miguel Luis + * + * Last modified by Miguel Luis on Jun 19 2013 + */ +/************************************************* +File name: sx1276-LoRa.c +Description: support aiit board configure and register function +History: +1. Date: 2021-04-25 +Author: AIIT XUOS Lab +Modification: +1. replace original macro and basic date type with AIIT XUOS Lab's own defination +*************************************************/ + +#include + +#include "platform.h" + +#if defined( USE_SX1276_RADIO ) +#include "radio.h" +#include "sx1276-Hal.h" +#include "sx1276.h" +#include "sx1276-LoRaMisc.h" +#include "sx1276-LoRa.h" + +#define LoRa_FREQENCY 433000000 + +#define RSSI_OFFSET_LF -155.0 +#define RSSI_OFFSET_HF -150.0 + +#define NOISE_ABSOLUTE_ZERO -174.0 +#define NOISE_FIGURE_LF 4.0 +#define NOISE_FIGURE_HF 6.0 + +volatile uint32 TickCounter = 0; + +uint32 Tx_Time_Start,Tx_Time_End; +uint32 Rx_Time_Start,Rx_Time_End; +//Signal bandwidth, used to calculate RSSI +const double SignalBwLog[] = +{ + 3.8927900303521316335038277369285, // 7.8 kHz + 4.0177301567005500940384239336392, // 10.4 kHz + 4.193820026016112828717566631653, // 15.6 kHz + 4.31875866931372901183597627752391, // 20.8 kHz + 4.4948500216800940239313055263775, // 31.2 kHz + 4.6197891057238405255051280399961, // 41.6 kHz + 4.795880017344075219145044421102, // 62.5 kHz + 5.0969100130080564143587833158265, // 125 kHz + 5.397940008672037609572522210551, // 250 kHz + 5.6989700043360188047862611052755 // 500 kHz +}; + +//These values need testing +const double RssiOffsetLF[] = +{ + -155.0, + -155.0, + -155.0, + -155.0, + -155.0, + -155.0, + -155.0, + -155.0, + -155.0, + -155.0, +}; + +//These values need testing +const double RssiOffsetHF[] = +{ + -150.0, + -150.0, + -150.0, + -150.0, + -150.0, + -150.0, + -150.0, + -150.0, + -150.0, + -150.0, +}; + +/*! + * Frequency hopping frequencies table + */ +const int32_t HoppingFrequencies[] = +{ + 916500000, + 923500000, + 906500000, + 917500000, + 917500000, + 909000000, + 903000000, + 916000000, + 912500000, + 926000000, + 925000000, + 909500000, + 913000000, + 918500000, + 918500000, + 902500000, + 911500000, + 926500000, + 902500000, + 922000000, + 924000000, + 903500000, + 913000000, + 922000000, + 926000000, + 910000000, + 920000000, + 922500000, + 911000000, + 922000000, + 909500000, + 926000000, + 922000000, + 918000000, + 925500000, + 908000000, + 917500000, + 926500000, + 908500000, + 916000000, + 905500000, + 916000000, + 903000000, + 905000000, + 915000000, + 913000000, + 907000000, + 910000000, + 926500000, + 925500000, + 911000000, +}; + +// Default settings +tLoRaSettings LoRaSettings = +{ + LoRa_FREQENCY , // RFFrequency + 20, // Power + 9, // SignalBw [0: 125 kHz, 1: 250 kHz, 2: 500 kHz, 3: Reserved] + 12, // SpreadingFactor [6: 64, 7: 128, 8: 256, 9: 512, 10: 1024, 11: 2048, 12: 4096 chips] + 2, // ErrorCoding [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8] + true, // CrcOn [0: OFF, 1: ON] + false, // ImplicitHeaderOn [0: OFF, 1: ON] + 0, // RxSingleOn [0: Continuous, 1 Single] + 0, // FreqHopOn [0: OFF, 1: ON] + 4, // HopPeriod Hops every frequency hopping period symbols + 1000, // TxPacketTimeout + 1000, // RxPacketTimeout + 128, // PayloadLength (used for implicit header mode) +}; + +/*! + * SX1276 LoRa registers variable + */ +tSX1276LR* SX1276LR; + +/*! + * Local RF buffer for communication support + */ +static uint8_t RFBuffer[RF_BUFFER_SIZE]; +static uint8_t TFBuffer[RF_BUFFER_SIZE]; + +/*! + * RF state machine variable + */ +static uint8_t RFLRState = RFLR_STATE_IDLE; + +/*! + * Rx management support variables + */ +static uint16_t RxPacketSize = 0; +static int8_t RxPacketSnrEstimate; +static double RxPacketRssiValue; +static uint8_t RxGain = 1; +static uint32_t RxTimeoutTimer = 0; + +/*! + * PacketTimeout Stores the Rx window time value for packet reception + */ +static uint32_t PacketTimeout; + +/*! + * Tx management support variables + */ +static uint16_t TxPacketSize = 0; + + +void SX1276LoRaInit( void ) +{ + RFLRState = RFLR_STATE_IDLE; + + SX1276LoRaSetDefaults(); + + SX1276ReadBuffer( REG_LR_OPMODE, SX1276Regs + 1, 0x70 - 1 ); + + //SX1276LoRaSetOpMode( RFLR_OPMODE_SLEEP ); + + SX1276LR->RegLna = RFLR_LNA_GAIN_G1; + SX1276WriteBuffer( REG_LR_OPMODE, SX1276Regs + 1, 0x70 - 1 ); + + // set the RF settings + SX1276LoRaSetRFFrequency( LoRaSettings.RFFrequency ); + SX1276LoRaSetSpreadingFactor( LoRaSettings.SpreadingFactor ); + SX1276LoRaSetErrorCoding( LoRaSettings.ErrorCoding ); + SX1276LoRaSetPacketCrcOn( LoRaSettings.CrcOn ); + SX1276LoRaSetSignalBandwidth( LoRaSettings.SignalBw ); + SX1276LoRaSetImplicitHeaderOn( LoRaSettings.ImplicitHeaderOn ); + + SX1276LoRaSetSymbTimeout(0x3FF); + SX1276LoRaSetPayloadLength( LoRaSettings.PayloadLength ); + SX1276LoRaSetLowDatarateOptimize( true ); + + #if( ( MODULE_SX1276RF1IAS == 1 ) || ( MODULE_SX1276RF1KAS == 1 ) ) + if( LoRaSettings.RFFrequency > 860000000 ) + { + SX1276LoRaSetPAOutput( RFLR_PACONFIG_PASELECT_RFO ); + SX1276LoRaSetPa20dBm( false ); + LoRaSettings.Power = 14; + SX1276LoRaSetRFPower( LoRaSettings.Power ); + } + else + { + //SX1276Write( REG_LR_OCP, 0x3f ); + SX1276LoRaSetPAOutput( RFLR_PACONFIG_PASELECT_PABOOST ); + SX1276LoRaSetPa20dBm( true ); + LoRaSettings.Power = 20; + SX1276LoRaSetRFPower( LoRaSettings.Power ); + } + #elif( MODULE_SX1276RF1JAS == 1 ) + if( LoRaSettings.RFFrequency > 380000000 ) + { + SX1276LoRaSetPAOutput( RFLR_PACONFIG_PASELECT_PABOOST ); + SX1276LoRaSetPa20dBm( true ); + LoRaSettings.Power = 20; + SX1276LoRaSetRFPower( LoRaSettings.Power ); + } + else + { + SX1276LoRaSetPAOutput( RFLR_PACONFIG_PASELECT_RFO ); + SX1276LoRaSetPa20dBm( false ); + LoRaSettings.Power = 14; + SX1276LoRaSetRFPower( LoRaSettings.Power ); + } + #endif + SX1276LoRaSetOpMode( RFLR_OPMODE_STANDBY ); + + SX1276ReadBuffer( REG_LR_OPMODE, SX1276Regs + 1, 0x70 - 1 ); +} + +void SX1276LoRaSetDefaults( void ) +{ + // REMARK: See SX1276 datasheet for modified default values. + + // Sets IF frequency selection manual + SX1276Read( REG_LR_VERSION, &SX1276LR->RegVersion ); +} + +void SX1276LoRaReset( void ) +{ + uint32_t startTick; + + SX1276SetReset( RADIO_RESET_ON ); + + // Wait 1ms + startTick = GET_TICK_COUNT( ); + while( ( GET_TICK_COUNT( ) - startTick ) < TICK_RATE_MS( 1 ) ); + + SX1276SetReset( RADIO_RESET_OFF ); + + // Wait 6ms + startTick = GET_TICK_COUNT( ); + while( ( GET_TICK_COUNT( ) - startTick ) < TICK_RATE_MS( 6 ) ); +} + +void SX1276LoRaSetOpMode( uint8_t opMode ) +{ + static uint8_t opModePrev = RFLR_OPMODE_STANDBY; + static bool antennaSwitchTxOnPrev = true; + bool antennaSwitchTxOn = false; + opModePrev = SX1276LR->RegOpMode & ~RFLR_OPMODE_MASK; + if( opMode != opModePrev ) + { + if( opMode == RFLR_OPMODE_TRANSMITTER ) + { + antennaSwitchTxOn = true; + } + else + { + antennaSwitchTxOn = false; + } + if( antennaSwitchTxOn != antennaSwitchTxOnPrev ) + { + antennaSwitchTxOnPrev = antennaSwitchTxOn; // Antenna switch control + RXTX( antennaSwitchTxOn ); + } + SX1276LR->RegOpMode = ( SX1276LR->RegOpMode & RFLR_OPMODE_MASK ) | opMode | RFLR_OPMODE_FREQMODE_ACCESS_LF; + + SX1276Write( REG_LR_OPMODE, SX1276LR->RegOpMode ); + } +} + +uint8_t SX1276LoRaGetOpMode( void ) +{ + SX1276Read( REG_LR_OPMODE, &SX1276LR->RegOpMode ); + + return SX1276LR->RegOpMode & ~RFLR_OPMODE_MASK; +} + +uint8_t SX1276LoRaReadRxGain( void ) +{ + + SX1276Read( REG_LR_LNA, &SX1276LR->RegLna ); + return( SX1276LR->RegLna >> 5 ) & 0x07; +} + +double SX1276LoRaReadRssi( void ) +{ + // Reads the RSSI value + SX1276Read( REG_LR_RSSIVALUE, &SX1276LR->RegRssiValue ); + + if( LoRaSettings.RFFrequency < 860000000 ) + { + return RssiOffsetLF[LoRaSettings.SignalBw] + ( double )SX1276LR->RegRssiValue; + } + else + { + return RssiOffsetHF[LoRaSettings.SignalBw] + ( double )SX1276LR->RegRssiValue; + } +} + +uint8_t SX1276LoRaGetPacketRxGain( void ) +{ + return RxGain; +} + +int8_t SX1276LoRaGetPacketSnr( void ) +{ + return RxPacketSnrEstimate; +} + +double SX1276LoRaGetPacketRssi( void ) +{ + return RxPacketRssiValue; +} + +void SX1276LoRaStartRx( void ) +{ + SX1276LoRaSetRFState( RFLR_STATE_RX_INIT ); +} + +void SX1276LoRaGetRxPacket( void *buffer, uint16_t *size ) +{ + *size = RxPacketSize; + RxPacketSize = 0; + memcpy( (void*)buffer, (void*)RFBuffer, (size_t)*size ); +} + +void SX1276LoRaSetTxPacket( const void *buffer, uint16_t size ) +{ + if( LoRaSettings.FreqHopOn == false ) + { + TxPacketSize = size; + } + else + { + TxPacketSize = 255; + } + memcpy( ( void * )TFBuffer, buffer, ( size_t )TxPacketSize ); + + RFLRState = RFLR_STATE_TX_INIT; +} + +uint8_t SX1276LoRaGetRFState( void ) +{ + return RFLRState; +} + +void SX1276LoRaSetRFState( uint8_t state ) +{ + RFLRState = state; +} + +/*! + * \brief Process the LoRa modem Rx and Tx state machines depending on the + * SX1276 operating mode. + * + * \retval rfState Current RF state [RF_IDLE, RF_BUSY, + * RF_RX_DONE, RF_RX_TIMEOUT, + * RF_TX_DONE, RF_TX_TIMEOUT] + */ +uint32_t SX1276LoRaProcess( void ) +{ + uint32_t result = RF_BUSY; + uint8_t regValue = 0; + + switch( RFLRState ) + { + case RFLR_STATE_IDLE: + break; + case RFLR_STATE_RX_INIT: + SX1276LoRaSetOpMode(RFLR_OPMODE_STANDBY); + SX1276LR->RegIrqFlagsMask = RFLR_IRQFLAGS_RXTIMEOUT | + //RFLR_IRQFLAGS_RXDONE | + RFLR_IRQFLAGS_PAYLOADCRCERROR | + RFLR_IRQFLAGS_VALIDHEADER | + RFLR_IRQFLAGS_TXDONE | + RFLR_IRQFLAGS_CADDONE | + RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL | + RFLR_IRQFLAGS_CADDETECTED; + SX1276Write( REG_LR_IRQFLAGSMASK, SX1276LR->RegIrqFlagsMask ); + + if(LoRaSettings.FreqHopOn == true ) + { + SX1276LR->RegHopPeriod = LoRaSettings.HopPeriod; + + SX1276Read( REG_LR_HOPCHANNEL, &SX1276LR->RegHopChannel ); + SX1276LoRaSetRFFrequency( HoppingFrequencies[SX1276LR->RegHopChannel & RFLR_HOPCHANNEL_CHANNEL_MASK] ); + } + else + { + SX1276LR->RegHopPeriod = 255; + } + + SX1276Write( REG_LR_HOPPERIOD, SX1276LR->RegHopPeriod ); + + if( LoRaSettings.RxSingleOn == true ) // Rx single mode + { + SX1276LoRaSetOpMode( RFLR_OPMODE_RECEIVER_SINGLE ); + } + else // Rx continuous mode + { + SX1276LR->RegFifoAddrPtr = SX1276LR->RegFifoRxBaseAddr; + + SX1276Write( REG_LR_FIFOADDRPTR, SX1276LR->RegFifoAddrPtr ); + SX1276LoRaSetOpMode( RFLR_OPMODE_RECEIVER ); + } + memset( RFBuffer, 0, ( size_t )RF_BUFFER_SIZE ); + Rx_Time_Start=TickCounter; + PacketTimeout = LoRaSettings.RxPacketTimeout; + RxTimeoutTimer = GET_TICK_COUNT( ); + RFLRState = RFLR_STATE_RX_RUNNING; + break; + case RFLR_STATE_RX_RUNNING: + SX1276Read(0x12, ®Value); + // RxDone + if(regValue & (1<<6)) + { + RxTimeoutTimer = GET_TICK_COUNT( ); + if( LoRaSettings.FreqHopOn == true ) + { + SX1276Read( REG_LR_HOPCHANNEL, &SX1276LR->RegHopChannel ); + SX1276LoRaSetRFFrequency( HoppingFrequencies[SX1276LR->RegHopChannel & RFLR_HOPCHANNEL_CHANNEL_MASK] ); + } + // Clear Irq + SX1276Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_RXDONE ); + RFLRState = RFLR_STATE_RX_DONE; + } + // FHSS Changed Channel + if(regValue & (1<<1)) + { + RxTimeoutTimer = GET_TICK_COUNT( ); + if( LoRaSettings.FreqHopOn == true ) + { + SX1276Read( REG_LR_HOPCHANNEL, &SX1276LR->RegHopChannel ); + SX1276LoRaSetRFFrequency( HoppingFrequencies[SX1276LR->RegHopChannel & RFLR_HOPCHANNEL_CHANNEL_MASK] ); + } + // Clear Irq + SX1276Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL ); + //RxGain = SX1276LoRaReadRxGain( ); + } + if( LoRaSettings.RxSingleOn == true ) // Rx single mode + { + if( ( GET_TICK_COUNT( ) - RxTimeoutTimer ) > PacketTimeout ) + { + RFLRState = RFLR_STATE_RX_TIMEOUT; + } + } + break; + case RFLR_STATE_RX_DONE: + SX1276Read( REG_LR_IRQFLAGS, &SX1276LR->RegIrqFlags ); + if( ( SX1276LR->RegIrqFlags & RFLR_IRQFLAGS_PAYLOADCRCERROR ) == RFLR_IRQFLAGS_PAYLOADCRCERROR ) + { + // Clear Irq + SX1276Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_PAYLOADCRCERROR ); + if( LoRaSettings.RxSingleOn == true ) // Rx single mode + { + RFLRState = RFLR_STATE_RX_INIT; + } + else + { + RFLRState = RFLR_STATE_RX_RUNNING; + } + break; + } + + if( LoRaSettings.RxSingleOn == true ) // Rx single mode + { + SX1276LR->RegFifoAddrPtr = SX1276LR->RegFifoRxBaseAddr; + SX1276Write( REG_LR_FIFOADDRPTR, SX1276LR->RegFifoAddrPtr ); + if( LoRaSettings.ImplicitHeaderOn == true ) + { + RxPacketSize = SX1276LR->RegPayloadLength; + SX1276ReadFifo( RFBuffer, SX1276LR->RegPayloadLength ); + } + else + { + SX1276Read( REG_LR_NBRXBYTES, &SX1276LR->RegNbRxBytes ); + RxPacketSize = SX1276LR->RegNbRxBytes; + SX1276ReadFifo( RFBuffer, SX1276LR->RegNbRxBytes ); + } + } + else // Rx continuous mode + { + SX1276Read( REG_LR_FIFORXCURRENTADDR, &SX1276LR->RegFifoRxCurrentAddr ); + if( LoRaSettings.ImplicitHeaderOn == true ) + { + RxPacketSize = SX1276LR->RegPayloadLength; + SX1276LR->RegFifoAddrPtr = SX1276LR->RegFifoRxCurrentAddr; + SX1276Write( REG_LR_FIFOADDRPTR, SX1276LR->RegFifoAddrPtr ); + SX1276ReadFifo( RFBuffer, SX1276LR->RegPayloadLength ); + } + else + { + SX1276Read( REG_LR_NBRXBYTES, &SX1276LR->RegNbRxBytes ); + RxPacketSize = SX1276LR->RegNbRxBytes; + SX1276LR->RegFifoAddrPtr = SX1276LR->RegFifoRxCurrentAddr; + SX1276Write( REG_LR_FIFOADDRPTR, SX1276LR->RegFifoAddrPtr ); + SX1276ReadFifo( RFBuffer, SX1276LR->RegNbRxBytes ); + } + } + if( LoRaSettings.RxSingleOn == true ) // Rx single mode + { + RFLRState = RFLR_STATE_RX_INIT; + } + else // Rx continuous mode + { + RFLRState = RFLR_STATE_RX_RUNNING; + } + Rx_Time_End=TickCounter; + result = RF_RX_DONE; + break; + case RFLR_STATE_RX_TIMEOUT: + RFLRState = RFLR_STATE_RX_INIT; + result = RF_RX_TIMEOUT; + break; + case RFLR_STATE_TX_INIT: + Tx_Time_Start = TickCounter; + + // Initializes the payload size + SX1276LR->RegPayloadLength = TxPacketSize; + SX1276Write( REG_LR_PAYLOADLENGTH, SX1276LR->RegPayloadLength ); + + SX1276LR->RegFifoTxBaseAddr = 0x00; // Full buffer used for Tx + SX1276Write( REG_LR_FIFOTXBASEADDR, SX1276LR->RegFifoTxBaseAddr ); + + SX1276LR->RegFifoAddrPtr = SX1276LR->RegFifoTxBaseAddr; + SX1276Write( REG_LR_FIFOADDRPTR, SX1276LR->RegFifoAddrPtr ); + + SX1276LoRaSetOpMode( RFLR_OPMODE_STANDBY ); + + // Write payload buffer to LORA modem + SX1276WriteFifo( TFBuffer, SX1276LR->RegPayloadLength ); + + if( LoRaSettings.FreqHopOn == true ) + { + SX1276LR->RegIrqFlagsMask = RFLR_IRQFLAGS_RXTIMEOUT | + RFLR_IRQFLAGS_RXDONE | + RFLR_IRQFLAGS_PAYLOADCRCERROR | + RFLR_IRQFLAGS_VALIDHEADER | + //RFLR_IRQFLAGS_TXDONE | + RFLR_IRQFLAGS_CADDONE | + RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL | + RFLR_IRQFLAGS_CADDETECTED; + SX1276LR->RegHopPeriod = LoRaSettings.HopPeriod; + SX1276Read( REG_LR_HOPCHANNEL, &SX1276LR->RegHopChannel ); + SX1276LoRaSetRFFrequency( HoppingFrequencies[SX1276LR->RegHopChannel & RFLR_HOPCHANNEL_CHANNEL_MASK] ); + } + else + { + SX1276LR->RegIrqFlagsMask = RFLR_IRQFLAGS_RXTIMEOUT | + RFLR_IRQFLAGS_RXDONE | + RFLR_IRQFLAGS_PAYLOADCRCERROR | + RFLR_IRQFLAGS_VALIDHEADER | + //RFLR_IRQFLAGS_TXDONE | + RFLR_IRQFLAGS_CADDONE | + RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL | + RFLR_IRQFLAGS_CADDETECTED; + SX1276LR->RegHopPeriod = 0; + } + SX1276Write( REG_LR_HOPPERIOD, SX1276LR->RegHopPeriod ); + SX1276Write( REG_LR_IRQFLAGSMASK, SX1276LR->RegIrqFlagsMask ); + + SX1276Write( REG_LR_DIOMAPPING1, ( regValue & RFLR_DIOMAPPING1_DIO0_MASK ) | RFLR_DIOMAPPING1_DIO0_01 );//DIO0设置为TXdone中断 + + SX1276LoRaSetOpMode( RFLR_OPMODE_TRANSMITTER ); + + RFLRState = RFLR_STATE_TX_RUNNING; + break; + case RFLR_STATE_TX_RUNNING: + SX1276Read(0x12, ®Value); + if(regValue & (1<<3)) + { + // Clear Irq + SX1276Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_TXDONE ); + RFLRState = RFLR_STATE_TX_DONE; + } + // FHSS Changed Channel + if(regValue & (1<<3)) + { + if( LoRaSettings.FreqHopOn == true ) + { + SX1276Read( REG_LR_HOPCHANNEL, &SX1276LR->RegHopChannel ); + SX1276LoRaSetRFFrequency( HoppingFrequencies[SX1276LR->RegHopChannel & RFLR_HOPCHANNEL_CHANNEL_MASK] ); + } + // Clear Irq + SX1276Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL ); + } + break; + case RFLR_STATE_TX_DONE: + Tx_Time_End=TickCounter; + SX1276LoRaSetOpMode( RFLR_OPMODE_STANDBY ); + RFLRState = RFLR_STATE_IDLE; + result = RF_TX_DONE; + break; + case RFLR_STATE_CAD_INIT: + // optimize the power consumption by switching off the transmitter as soon as the packet has been sent + SX1276LoRaSetOpMode( RFLR_OPMODE_STANDBY ); + SX1276LR->RegIrqFlagsMask = RFLR_IRQFLAGS_RXTIMEOUT | + RFLR_IRQFLAGS_RXDONE | + RFLR_IRQFLAGS_PAYLOADCRCERROR | + RFLR_IRQFLAGS_VALIDHEADER | + RFLR_IRQFLAGS_TXDONE | + //RFLR_IRQFLAGS_CADDONE | + RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL; + //RFLR_IRQFLAGS_CADDETECTED; + SX1276Write( REG_LR_IRQFLAGSMASK, SX1276LR->RegIrqFlagsMask ); + + SX1276LoRaSetOpMode( RFLR_OPMODE_CAD ); + RFLRState = RFLR_STATE_CAD_RUNNING; + + break; + case RFLR_STATE_CAD_RUNNING: + SX1276Read(0x12,®Value); + int cad_done = regValue & (1<<2); + int cad_detected = regValue & (1<<0); + + if( cad_done ) //CAD Done interrupt + { + SX1276Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_CADDONE ); + if( cad_detected ) // CAD Detected interrupt + { + SX1276Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_CADDETECTED ); + //CAD detected, we have a LoRa preamble + RFLRState = RFLR_STATE_RX_INIT; + result = RF_CHANNEL_ACTIVITY_DETECTED; + } + else + { + // The device goes in Standby Mode automatically + RFLRState = RFLR_STATE_IDLE; + result = RF_CHANNEL_EMPTY; + } + } + break; + default: + break; + } + return result; +} + +uint32_t SX1276LoraChannelEmpty( void ) +{ + uint32_t result = 0; + RFLRState = RFLR_STATE_CAD_INIT; + SX1276LoRaProcess(); + while(RFLRState == RFLR_STATE_CAD_RUNNING) + { + //KPrintf("\nLora--SX1276LoRaProcess()"); + result = SX1276LoRaProcess(); + } + + if(result == RF_CHANNEL_EMPTY) + { + KPrintf("\nLora--RF_CHANNEL_EMPTY\n"); + return 0; + } + else if(result == RF_CHANNEL_ACTIVITY_DETECTED) + { + KPrintf("\nLora--RF_CHANNEL_ACTIVITY_DETECTED\n"); + return 1; + } + else + { + return 2; + } +} + +#endif // USE_SX1276_RADIO \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/sx1276-LoRa.h b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/sx1276-LoRa.h new file mode 100644 index 000000000..76400e6b8 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/sx1276-LoRa.h @@ -0,0 +1,820 @@ +/* + * THE FOLLOWING FIRMWARE IS PROVIDED: (1) "AS IS" WITH NO WARRANTY; AND + * (2)TO ENABLE ACCESS TO CODING INFORMATION TO GUIDE AND FACILITATE CUSTOMER. + * CONSEQUENTLY, SEMTECH SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR + * CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT + * OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION + * CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * Original Copyright (C) SEMTECH S.A. + * Modified Copyright (C) 2020 AIIT XUOS Lab + */ +/*! + * \file sx1276-LoRa.h + * \brief SX1276 RF chip driver mode LoRa + * + * \version 2.0.0 + * \date Nov 21 2012 + * \author Miguel Luis + * + * Last modified by Miguel Luis on Jun 19 2013 + */ +/************************************************* +File name: sx1276-LoRa.h +Description: support aiit board configure and register function +History: +1. Date: 2021-04-25 +Author: AIIT XUOS Lab +Modification: +1. replace original macro and basic date type with AIIT XUOS Lab's own defination +*************************************************/ + +#ifndef __SX1276_LORA_H__ +#define __SX1276_LORA_H__ + +#include "stdint.h" +#include "stdbool.h" + + +//SX1276一些配置参数设置 +typedef struct sLoRaSettings +{ + uint32_t RFFrequency; //无线通信频率 + int8_t Power; //功率 + uint8_t SignalBw; //LORA 带宽[0: 7.8 kHz, 1: 10.4 kHz, 2: 15.6 kHz, 3: 20.8 kHz, 4: 31.2 kHz, + //5: 41.6 kHz, 6: 62.5 kHz, 7: 125 kHz, 8: 250 kHz, 9: 500 kHz, other: Reserved] + uint8_t SpreadingFactor; //扩频因子 LORA [6: 64, 7: 128, 8: 256, 9: 512, 10: 1024, 11: 2048, 12: 4096 chips] + uint8_t ErrorCoding; //LORA 纠错码 [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8] + bool CrcOn; //CRC效验开关 [0: OFF, 1: ON] + bool ImplicitHeaderOn; //隐藏头部信息开关 [0: OFF, 1: ON] + bool RxSingleOn; //接收单次模式\连续模式配置[0: Continuous, 1 Single] + bool FreqHopOn; //跳频模式开关 [0: OFF, 1: ON] + uint8_t HopPeriod; //跳频之间的周期长度 Hops every frequency hopping period symbols + uint32_t TxPacketTimeout; //最大发送时间 + uint32_t RxPacketTimeout; //最大接收时间 + uint8_t PayloadLength; //数据长度 +}tLoRaSettings; + +//RF数据包大小(模块配备了256Byte的RAM缓存,该缓存仅能通过LoRa模式访问) +#define RF_BUFFER_SIZE_MAX 256 +#define RF_BUFFER_SIZE 256 + + +//LoRa的返回值 +typedef enum +{ + RFLR_STATE_IDLE, + RFLR_STATE_RX_INIT, + RFLR_STATE_RX_RUNNING, + RFLR_STATE_RX_DONE, + RFLR_STATE_RX_TIMEOUT, + RFLR_STATE_TX_INIT, + RFLR_STATE_TX_RUNNING, + RFLR_STATE_TX_DONE, + RFLR_STATE_TX_TIMEOUT, + RFLR_STATE_CAD_INIT, + RFLR_STATE_CAD_RUNNING, +}tRFLRStates; + + +//SX1276 definitions +#define XTAL_FREQ 32000000 +#define FREQ_STEP 61.03515625 + +/*LoRa模式寄存器映射*/ +//SX1276内部寄存器地址 +#define REG_LR_FIFO 0x00 //FIFO 数据输入/输出。当器件处于睡眠模式时,FIFO被清零,无法访问。 + +//通用寄存器 +#define REG_LR_OPMODE 0x01 //关于模式选择相关的寄存器 +#define REG_LR_BANDSETTING 0x04 +#define REG_LR_FRFMSB 0x06 //RF 载波频率最高有效位 +#define REG_LR_FRFMID 0x07 //RF 载波频率中间有效位 +#define REG_LR_FRFLSB 0x08 //RF 载波频率最低有效位 + +//RF模块寄存器 +#define REG_LR_PACONFIG 0x09 +#define REG_LR_PARAMP 0x0A +#define REG_LR_OCP 0x0B +#define REG_LR_LNA 0x0C + +//LoRa页面寄存器 +#define REG_LR_FIFOADDRPTR 0x0D +#define REG_LR_FIFOTXBASEADDR 0x0E +#define REG_LR_FIFORXBASEADDR 0x0F +#define REG_LR_FIFORXCURRENTADDR 0x10 +#define REG_LR_IRQFLAGSMASK 0x11 //IAQ标志屏蔽 +#define REG_LR_IRQFLAGS 0x12 +#define REG_LR_NBRXBYTES 0x13 +#define REG_LR_RXHEADERCNTVALUEMSB 0x14 +#define REG_LR_RXHEADERCNTVALUELSB 0x15 +#define REG_LR_RXPACKETCNTVALUEMSB 0x16 +#define REG_LR_RXPACKETCNTVALUELSB 0x17 +#define REG_LR_MODEMSTAT 0x18 +#define REG_LR_PKTSNRVALUE 0x19 +#define REG_LR_PKTRSSIVALUE 0x1A +#define REG_LR_RSSIVALUE 0x1B +#define REG_LR_HOPCHANNEL 0x1C +#define REG_LR_MODEMCONFIG1 0x1D +#define REG_LR_MODEMCONFIG2 0x1E +#define REG_LR_SYMBTIMEOUTLSB 0x1F +#define REG_LR_PREAMBLEMSB 0x20 +#define REG_LR_PREAMBLELSB 0x21 +#define REG_LR_PAYLOADLENGTH 0x22 +#define REG_LR_PAYLOADMAXLENGTH 0x23 +#define REG_LR_HOPPERIOD 0x24 +#define REG_LR_FIFORXBYTEADDR 0x25 +#define REG_LR_MODEMCONFIG3 0x26 +/*以上是LoRa模式寄存器映射*/ + +//IO控制寄存器(关于DI00-DI05的映射设置) +#define REG_LR_DIOMAPPING1 0x40 +#define REG_LR_DIOMAPPING2 0x41 + +//版本寄存器 +#define REG_LR_VERSION 0x42 + +//附加寄存器 +#define REG_LR_PLLHOP 0x44 +#define REG_LR_TCXO 0x4B +#define REG_LR_PADAC 0x4D +#define REG_LR_FORMERTEMP 0x5B +#define REG_LR_BITRATEFRAC 0x5D +#define REG_LR_AGCREF 0x61 +#define REG_LR_AGCTHRESH1 0x62 +#define REG_LR_AGCTHRESH2 0x63 +#define REG_LR_AGCTHRESH3 0x64 + +//与模式选择相关的宏定义 RegOpMode(寄存器地址0X01) +#define RFLR_OPMODE_LONGRANGEMODE_MASK 0x7F +#define RFLR_OPMODE_LONGRANGEMODE_OFF 0x00 // Default +#define RFLR_OPMODE_LONGRANGEMODE_ON 0x80 + +#define RFLR_OPMODE_ACCESSSHAREDREG_MASK 0xBF +#define RFLR_OPMODE_ACCESSSHAREDREG_ENABLE 0x40 +#define RFLR_OPMODE_ACCESSSHAREDREG_DISABLE 0x00 // Default + +#define RFLR_OPMODE_FREQMODE_ACCESS_MASK 0xF7 +#define RFLR_OPMODE_FREQMODE_ACCESS_LF 0x08 // Default +#define RFLR_OPMODE_FREQMODE_ACCESS_HF 0x00 + +#define RFLR_OPMODE_MASK 0xF8 +#define RFLR_OPMODE_SLEEP 0x00 //睡眠模式 +#define RFLR_OPMODE_STANDBY 0x01 //待机模式 +#define RFLR_OPMODE_SYNTHESIZER_TX 0x02 //频率合成器转换至Tx频率 +#define RFLR_OPMODE_TRANSMITTER 0x03 //发送模式 +#define RFLR_OPMODE_SYNTHESIZER_RX 0x04 //频率合成器转换至Rx频率 +#define RFLR_OPMODE_RECEIVER 0x05 //接收模式 + +#define RFLR_OPMODE_RECEIVER_SINGLE 0x06 //单次接收模式 +#define RFLR_OPMODE_CAD 0x07 //CAD模式 + +//与位带操作相关的宏定义 +#define RFLR_BANDSETTING_MASK 0x3F +#define RFLR_BANDSETTING_AUTO 0x00 // Default +#define RFLR_BANDSETTING_DIV_BY_1 0x40 +#define RFLR_BANDSETTING_DIV_BY_2 0x80 +#define RFLR_BANDSETTING_DIV_BY_6 0xC0 + +//射频载波频率设置相关宏定义 RegFrf (MHz)(寄存器地址0x06,0x07,0x08) +#define RFLR_FRFMSB_434_MHZ 0x6C // Default +#define RFLR_FRFMID_434_MHZ 0x80 // Default +#define RFLR_FRFLSB_434_MHZ 0x00 // Default + +#define RFLR_FRFMSB_470_MHZ 0x73 // Default +#define RFLR_FRFMID_470_MHZ 0xBB // Default +#define RFLR_FRFLSB_470_MHZ 0xBB // Default + +#define RFLR_FRFMSB_863_MHZ 0xD7 +#define RFLR_FRFMID_863_MHZ 0xC0 +#define RFLR_FRFLSB_863_MHZ 0x00 +#define RFLR_FRFMSB_864_MHZ 0xD8 +#define RFLR_FRFMID_864_MHZ 0x00 +#define RFLR_FRFLSB_864_MHZ 0x00 +#define RFLR_FRFMSB_865_MHZ 0xD8 +#define RFLR_FRFMID_865_MHZ 0x40 +#define RFLR_FRFLSB_865_MHZ 0x00 +#define RFLR_FRFMSB_866_MHZ 0xD8 +#define RFLR_FRFMID_866_MHZ 0x80 +#define RFLR_FRFLSB_866_MHZ 0x00 +#define RFLR_FRFMSB_867_MHZ 0xD8 +#define RFLR_FRFMID_867_MHZ 0xC0 +#define RFLR_FRFLSB_867_MHZ 0x00 +#define RFLR_FRFMSB_868_MHZ 0xD9 +#define RFLR_FRFMID_868_MHZ 0x00 +#define RFLR_FRFLSB_868_MHZ 0x00 +#define RFLR_FRFMSB_869_MHZ 0xD9 +#define RFLR_FRFMID_869_MHZ 0x40 +#define RFLR_FRFLSB_869_MHZ 0x00 +#define RFLR_FRFMSB_870_MHZ 0xD9 +#define RFLR_FRFMID_870_MHZ 0x80 +#define RFLR_FRFLSB_870_MHZ 0x00 + +#define RFLR_FRFMSB_902_MHZ 0xE1 +#define RFLR_FRFMID_902_MHZ 0x80 +#define RFLR_FRFLSB_902_MHZ 0x00 +#define RFLR_FRFMSB_903_MHZ 0xE1 +#define RFLR_FRFMID_903_MHZ 0xC0 +#define RFLR_FRFLSB_903_MHZ 0x00 +#define RFLR_FRFMSB_904_MHZ 0xE2 +#define RFLR_FRFMID_904_MHZ 0x00 +#define RFLR_FRFLSB_904_MHZ 0x00 +#define RFLR_FRFMSB_905_MHZ 0xE2 +#define RFLR_FRFMID_905_MHZ 0x40 +#define RFLR_FRFLSB_905_MHZ 0x00 +#define RFLR_FRFMSB_906_MHZ 0xE2 +#define RFLR_FRFMID_906_MHZ 0x80 +#define RFLR_FRFLSB_906_MHZ 0x00 +#define RFLR_FRFMSB_907_MHZ 0xE2 +#define RFLR_FRFMID_907_MHZ 0xC0 +#define RFLR_FRFLSB_907_MHZ 0x00 +#define RFLR_FRFMSB_908_MHZ 0xE3 +#define RFLR_FRFMID_908_MHZ 0x00 +#define RFLR_FRFLSB_908_MHZ 0x00 +#define RFLR_FRFMSB_909_MHZ 0xE3 +#define RFLR_FRFMID_909_MHZ 0x40 +#define RFLR_FRFLSB_909_MHZ 0x00 +#define RFLR_FRFMSB_910_MHZ 0xE3 +#define RFLR_FRFMID_910_MHZ 0x80 +#define RFLR_FRFLSB_910_MHZ 0x00 +#define RFLR_FRFMSB_911_MHZ 0xE3 +#define RFLR_FRFMID_911_MHZ 0xC0 +#define RFLR_FRFLSB_911_MHZ 0x00 +#define RFLR_FRFMSB_912_MHZ 0xE4 +#define RFLR_FRFMID_912_MHZ 0x00 +#define RFLR_FRFLSB_912_MHZ 0x00 +#define RFLR_FRFMSB_913_MHZ 0xE4 +#define RFLR_FRFMID_913_MHZ 0x40 +#define RFLR_FRFLSB_913_MHZ 0x00 +#define RFLR_FRFMSB_914_MHZ 0xE4 +#define RFLR_FRFMID_914_MHZ 0x80 +#define RFLR_FRFLSB_914_MHZ 0x00 +#define RFLR_FRFMSB_915_MHZ 0xE4 // Default +#define RFLR_FRFMID_915_MHZ 0xC0 // Default +#define RFLR_FRFLSB_915_MHZ 0x00 // Default +#define RFLR_FRFMSB_916_MHZ 0xE5 +#define RFLR_FRFMID_916_MHZ 0x00 +#define RFLR_FRFLSB_916_MHZ 0x00 +#define RFLR_FRFMSB_917_MHZ 0xE5 +#define RFLR_FRFMID_917_MHZ 0x40 +#define RFLR_FRFLSB_917_MHZ 0x00 +#define RFLR_FRFMSB_918_MHZ 0xE5 +#define RFLR_FRFMID_918_MHZ 0x80 +#define RFLR_FRFLSB_918_MHZ 0x00 +#define RFLR_FRFMSB_919_MHZ 0xE5 +#define RFLR_FRFMID_919_MHZ 0xC0 +#define RFLR_FRFLSB_919_MHZ 0x00 +#define RFLR_FRFMSB_920_MHZ 0xE6 +#define RFLR_FRFMID_920_MHZ 0x00 +#define RFLR_FRFLSB_920_MHZ 0x00 +#define RFLR_FRFMSB_921_MHZ 0xE6 +#define RFLR_FRFMID_921_MHZ 0x40 +#define RFLR_FRFLSB_921_MHZ 0x00 +#define RFLR_FRFMSB_922_MHZ 0xE6 +#define RFLR_FRFMID_922_MHZ 0x80 +#define RFLR_FRFLSB_922_MHZ 0x00 +#define RFLR_FRFMSB_923_MHZ 0xE6 +#define RFLR_FRFMID_923_MHZ 0xC0 +#define RFLR_FRFLSB_923_MHZ 0x00 +#define RFLR_FRFMSB_924_MHZ 0xE7 +#define RFLR_FRFMID_924_MHZ 0x00 +#define RFLR_FRFLSB_924_MHZ 0x00 +#define RFLR_FRFMSB_925_MHZ 0xE7 +#define RFLR_FRFMID_925_MHZ 0x40 +#define RFLR_FRFLSB_925_MHZ 0x00 +#define RFLR_FRFMSB_926_MHZ 0xE7 +#define RFLR_FRFMID_926_MHZ 0x80 +#define RFLR_FRFLSB_926_MHZ 0x00 +#define RFLR_FRFMSB_927_MHZ 0xE7 +#define RFLR_FRFMID_927_MHZ 0xC0 +#define RFLR_FRFLSB_927_MHZ 0x00 +#define RFLR_FRFMSB_928_MHZ 0xE8 +#define RFLR_FRFMID_928_MHZ 0x00 +#define RFLR_FRFLSB_928_MHZ 0x00 + +//PA(功率放大器) 选择和输出功率控制设置相关宏定义 RegPaConfig(寄存器地址0X09) +#define RFLR_PACONFIG_PASELECT_MASK 0x7F +#define RFLR_PACONFIG_PASELECT_PABOOST 0x80 +#define RFLR_PACONFIG_PASELECT_RFO 0x00 // Default + +#define RFLR_PACONFIG_MAX_POWER_MASK 0x8F + +#define RFLR_PACONFIG_OUTPUTPOWER_MASK 0xF0 + +//PA(功率放大器) 斜升/斜降时间和低相噪设置相关定义 RegPaRamp(寄存器地址0X0A) +#define RFLR_PARAMP_TXBANDFORCE_MASK 0xEF +#define RFLR_PARAMP_TXBANDFORCE_BAND_SEL 0x10 +#define RFLR_PARAMP_TXBANDFORCE_AUTO 0x00 // Default + +#define RFLR_PARAMP_MASK 0xF0 +#define RFLR_PARAMP_3400_US 0x00 +#define RFLR_PARAMP_2000_US 0x01 +#define RFLR_PARAMP_1000_US 0x02 +#define RFLR_PARAMP_0500_US 0x03 +#define RFLR_PARAMP_0250_US 0x04 +#define RFLR_PARAMP_0125_US 0x05 +#define RFLR_PARAMP_0100_US 0x06 +#define RFLR_PARAMP_0062_US 0x07 +#define RFLR_PARAMP_0050_US 0x08 +#define RFLR_PARAMP_0040_US 0x09 // Default +#define RFLR_PARAMP_0031_US 0x0A +#define RFLR_PARAMP_0025_US 0x0B +#define RFLR_PARAMP_0020_US 0x0C +#define RFLR_PARAMP_0015_US 0x0D +#define RFLR_PARAMP_0012_US 0x0E +#define RFLR_PARAMP_0010_US 0x0F + +//过流保护控制设置相关宏定义 RegOcp(寄存器地址0X0B) +#define RFLR_OCP_MASK 0xDF +#define RFLR_OCP_ON 0x20 // Default +#define RFLR_OCP_OFF 0x00 + +#define RFLR_OCP_TRIM_MASK 0xE0 +#define RFLR_OCP_TRIM_045_MA 0x00 +#define RFLR_OCP_TRIM_050_MA 0x01 +#define RFLR_OCP_TRIM_055_MA 0x02 +#define RFLR_OCP_TRIM_060_MA 0x03 +#define RFLR_OCP_TRIM_065_MA 0x04 +#define RFLR_OCP_TRIM_070_MA 0x05 +#define RFLR_OCP_TRIM_075_MA 0x06 +#define RFLR_OCP_TRIM_080_MA 0x07 +#define RFLR_OCP_TRIM_085_MA 0x08 +#define RFLR_OCP_TRIM_090_MA 0x09 +#define RFLR_OCP_TRIM_095_MA 0x0A +#define RFLR_OCP_TRIM_100_MA 0x0B // Default +#define RFLR_OCP_TRIM_105_MA 0x0C +#define RFLR_OCP_TRIM_110_MA 0x0D +#define RFLR_OCP_TRIM_115_MA 0x0E +#define RFLR_OCP_TRIM_120_MA 0x0F +#define RFLR_OCP_TRIM_130_MA 0x10 +#define RFLR_OCP_TRIM_140_MA 0x11 +#define RFLR_OCP_TRIM_150_MA 0x12 +#define RFLR_OCP_TRIM_160_MA 0x13 +#define RFLR_OCP_TRIM_170_MA 0x14 +#define RFLR_OCP_TRIM_180_MA 0x15 +#define RFLR_OCP_TRIM_190_MA 0x16 +#define RFLR_OCP_TRIM_200_MA 0x17 +#define RFLR_OCP_TRIM_210_MA 0x18 +#define RFLR_OCP_TRIM_220_MA 0x19 +#define RFLR_OCP_TRIM_230_MA 0x1A +#define RFLR_OCP_TRIM_240_MA 0x1B + +//LNA(低噪声放大器 )设置相关宏定义 RegLna(寄存器地址0X0C) +#define RFLR_LNA_GAIN_MASK 0x1F +#define RFLR_LNA_GAIN_G1 0x20 // Default +#define RFLR_LNA_GAIN_G2 0x40 +#define RFLR_LNA_GAIN_G3 0x60 +#define RFLR_LNA_GAIN_G4 0x80 +#define RFLR_LNA_GAIN_G5 0xA0 +#define RFLR_LNA_GAIN_G6 0xC0 + +#define RFLR_LNA_BOOST_LF_MASK 0xE7 +#define RFLR_LNA_BOOST_LF_DEFAULT 0x00 // Default +#define RFLR_LNA_BOOST_LF_GAIN 0x08 +#define RFLR_LNA_BOOST_LF_IP3 0x10 +#define RFLR_LNA_BOOST_LF_BOOST 0x18 + +#define RFLR_LNA_RXBANDFORCE_MASK 0xFB +#define RFLR_LNA_RXBANDFORCE_BAND_SEL 0x04 +#define RFLR_LNA_RXBANDFORCE_AUTO 0x00 // Default + +#define RFLR_LNA_BOOST_HF_MASK 0xFC +#define RFLR_LNA_BOOST_HF_OFF 0x00 // Default +#define RFLR_LNA_BOOST_HF_ON 0x03 + + +//FIFO 数据缓冲区中 SPI 接口地址指针(寄存器地址0X0D) +#define RFLR_FIFOADDRPTR 0x00 // Default + +//发送信息的起始位置 +#define RFLR_FIFOTXBASEADDR 0x80 // Default + +//接收信息的起始位置 +#define RFLR_FIFORXBASEADDR 0x00 // Default + +/*! + * RegFifoRxCurrentAddr (Read Only) + */ + +//关于中断屏蔽相关的宏定义 +#define RFLR_IRQFLAGS_RXTIMEOUT_MASK 0x80 +#define RFLR_IRQFLAGS_RXDONE_MASK 0x40 +#define RFLR_IRQFLAGS_PAYLOADCRCERROR_MASK 0x20 +#define RFLR_IRQFLAGS_VALIDHEADER_MASK 0x10 +#define RFLR_IRQFLAGS_TXDONE_MASK 0x08 +#define RFLR_IRQFLAGS_CADDONE_MASK 0x04 +#define RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL_MASK 0x02 +#define RFLR_IRQFLAGS_CADDETECTED_MASK 0x01 + +//关于中断打开相关的宏定义 +#define RFLR_IRQFLAGS_RXTIMEOUT 0x80 +#define RFLR_IRQFLAGS_RXDONE 0x40 +#define RFLR_IRQFLAGS_PAYLOADCRCERROR 0x20 +#define RFLR_IRQFLAGS_VALIDHEADER 0x10 +#define RFLR_IRQFLAGS_TXDONE 0x08 +#define RFLR_IRQFLAGS_CADDONE 0x04 +#define RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL 0x02 +#define RFLR_IRQFLAGS_CADDETECTED 0x01 + + + +/*! + * RegFifoRxNbBytes (Read Only) // + */ + + + /*! + * RegRxHeaderCntValueMsb (Read Only) // + */ + + + /*! + * RegRxHeaderCntValueLsb (Read Only) // + */ + + +/*! + * RegRxPacketCntValueMsb (Read Only) // + */ + + + /*! + * RegRxPacketCntValueLsb (Read Only) // + */ + + + /*! + * RegModemStat (Read Only) // + */ +#define RFLR_MODEMSTAT_RX_CR_MASK 0x1F +#define RFLR_MODEMSTAT_MODEM_STATUS_MASK 0xE0 + +/*! + * RegPktSnrValue (Read Only) // + */ + + + /*! + * RegPktRssiValue (Read Only) // + */ + + +/*! + * RegRssiValue (Read Only) // + */ + + +//与信号宽度,纠错编码率,是否显示报头有关宏定义(寄存器位置0X1D) +#define RFLR_MODEMCONFIG1_BW_MASK 0x0F + +#define RFLR_MODEMCONFIG1_BW_7_81_KHZ 0x00 +#define RFLR_MODEMCONFIG1_BW_10_41_KHZ 0x10 +#define RFLR_MODEMCONFIG1_BW_15_62_KHZ 0x20 +#define RFLR_MODEMCONFIG1_BW_20_83_KHZ 0x30 +#define RFLR_MODEMCONFIG1_BW_31_25_KHZ 0x40 +#define RFLR_MODEMCONFIG1_BW_41_66_KHZ 0x50 +#define RFLR_MODEMCONFIG1_BW_62_50_KHZ 0x60 +#define RFLR_MODEMCONFIG1_BW_125_KHZ 0x70 // Default +#define RFLR_MODEMCONFIG1_BW_250_KHZ 0x80 +#define RFLR_MODEMCONFIG1_BW_500_KHZ 0x90 + +#define RFLR_MODEMCONFIG1_CODINGRATE_MASK 0xF1 +#define RFLR_MODEMCONFIG1_CODINGRATE_4_5 0x02 +#define RFLR_MODEMCONFIG1_CODINGRATE_4_6 0x04 // Default +#define RFLR_MODEMCONFIG1_CODINGRATE_4_7 0x06 +#define RFLR_MODEMCONFIG1_CODINGRATE_4_8 0x08 + +#define RFLR_MODEMCONFIG1_IMPLICITHEADER_MASK 0xFE +#define RFLR_MODEMCONFIG1_IMPLICITHEADER_ON 0x01 +#define RFLR_MODEMCONFIG1_IMPLICITHEADER_OFF 0x00 // Default + +//与扩频因子,接收模式,发送CRC开启,RX超时相关宏定义 +#define RFLR_MODEMCONFIG2_SF_MASK 0x0F +#define RFLR_MODEMCONFIG2_SF_6 0x60 +#define RFLR_MODEMCONFIG2_SF_7 0x70 // Default +#define RFLR_MODEMCONFIG2_SF_8 0x80 +#define RFLR_MODEMCONFIG2_SF_9 0x90 +#define RFLR_MODEMCONFIG2_SF_10 0xA0 +#define RFLR_MODEMCONFIG2_SF_11 0xB0 +#define RFLR_MODEMCONFIG2_SF_12 0xC0 + +#define RFLR_MODEMCONFIG2_TXCONTINUOUSMODE_MASK 0xF7 +#define RFLR_MODEMCONFIG2_TXCONTINUOUSMODE_ON 0x08 +#define RFLR_MODEMCONFIG2_TXCONTINUOUSMODE_OFF 0x00 + +#define RFLR_MODEMCONFIG2_RXPAYLOADCRC_MASK 0xFB +#define RFLR_MODEMCONFIG2_RXPAYLOADCRC_ON 0x04 +#define RFLR_MODEMCONFIG2_RXPAYLOADCRC_OFF 0x00 // Default + +#define RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB_MASK 0xFC +#define RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB 0x00 // Default + + +/*! + * RegHopChannel (Read Only) + */ +#define RFLR_HOPCHANNEL_PLL_LOCK_TIMEOUT_MASK 0x7F +#define RFLR_HOPCHANNEL_PLL_LOCK_FAIL 0x80 +#define RFLR_HOPCHANNEL_PLL_LOCK_SUCCEED 0x00 // Default + +#define RFLR_HOPCHANNEL_PAYLOAD_CRC16_MASK 0xBF +#define RFLR_HOPCHANNEL_PAYLOAD_CRC16_ON 0x40 +#define RFLR_HOPCHANNEL_PAYLOAD_CRC16_OFF 0x00 // Default + +#define RFLR_HOPCHANNEL_CHANNEL_MASK 0x3F + + +/*! + * RegSymbTimeoutLsb + */ +#define RFLR_SYMBTIMEOUTLSB_SYMBTIMEOUT 0x64 // Default + +/*! + * RegPreambleLengthMsb + */ +#define RFLR_PREAMBLELENGTHMSB 0x00 // Default + +/*! + * RegPreambleLengthLsb + */ +#define RFLR_PREAMBLELENGTHLSB 0x08 // Default + +/*! + * RegPayloadLength + */ +#define RFLR_PAYLOADLENGTH 0x0E // Default + +/*! + * RegPayloadMaxLength + */ +#define RFLR_PAYLOADMAXLENGTH 0xFF // Default + +/*! + * RegHopPeriod + */ +#define RFLR_HOPPERIOD_FREQFOPPINGPERIOD 0x00 // Default + + +/*! + * RegDioMapping1 + */ +#define RFLR_DIOMAPPING1_DIO0_MASK 0x3F +#define RFLR_DIOMAPPING1_DIO0_00 0x00 // Default +#define RFLR_DIOMAPPING1_DIO0_01 0x40 +#define RFLR_DIOMAPPING1_DIO0_10 0x80 +#define RFLR_DIOMAPPING1_DIO0_11 0xC0 + +#define RFLR_DIOMAPPING1_DIO1_MASK 0xCF +#define RFLR_DIOMAPPING1_DIO1_00 0x00 // Default +#define RFLR_DIOMAPPING1_DIO1_01 0x10 +#define RFLR_DIOMAPPING1_DIO1_10 0x20 +#define RFLR_DIOMAPPING1_DIO1_11 0x30 + +#define RFLR_DIOMAPPING1_DIO2_MASK 0xF3 +#define RFLR_DIOMAPPING1_DIO2_00 0x00 // Default +#define RFLR_DIOMAPPING1_DIO2_01 0x04 +#define RFLR_DIOMAPPING1_DIO2_10 0x08 +#define RFLR_DIOMAPPING1_DIO2_11 0x0C + +#define RFLR_DIOMAPPING1_DIO3_MASK 0xFC +#define RFLR_DIOMAPPING1_DIO3_00 0x00 // Default +#define RFLR_DIOMAPPING1_DIO3_01 0x01 +#define RFLR_DIOMAPPING1_DIO3_10 0x02 +#define RFLR_DIOMAPPING1_DIO3_11 0x03 + +/*! + * RegDioMapping2 + */ +#define RFLR_DIOMAPPING2_DIO4_MASK 0x3F +#define RFLR_DIOMAPPING2_DIO4_00 0x00 // Default +#define RFLR_DIOMAPPING2_DIO4_01 0x40 +#define RFLR_DIOMAPPING2_DIO4_10 0x80 +#define RFLR_DIOMAPPING2_DIO4_11 0xC0 + +#define RFLR_DIOMAPPING2_DIO5_MASK 0xCF +#define RFLR_DIOMAPPING2_DIO5_00 0x00 // Default +#define RFLR_DIOMAPPING2_DIO5_01 0x10 +#define RFLR_DIOMAPPING2_DIO5_10 0x20 +#define RFLR_DIOMAPPING2_DIO5_11 0x30 + +#define RFLR_DIOMAPPING2_MAP_MASK 0xFE +#define RFLR_DIOMAPPING2_MAP_PREAMBLEDETECT 0x01 +#define RFLR_DIOMAPPING2_MAP_RSSI 0x00 // Default + +/*! + * RegVersion (Read Only) + */ + +/*! + * RegAgcRef + */ + +/*! + * RegAgcThresh1 + */ + +/*! + * RegAgcThresh2 + */ + +/*! + * RegAgcThresh3 + */ + +/*! + * RegFifoRxByteAddr (Read Only) + */ + +/*! + * RegPllHop + */ +#define RFLR_PLLHOP_FASTHOP_MASK 0x7F +#define RFLR_PLLHOP_FASTHOP_ON 0x80 +#define RFLR_PLLHOP_FASTHOP_OFF 0x00 // Default + +/*! + * RegTcxo + */ +#define RFLR_TCXO_TCXOINPUT_MASK 0xEF +#define RFLR_TCXO_TCXOINPUT_ON 0x10 +#define RFLR_TCXO_TCXOINPUT_OFF 0x00 // Default + +/*! + * RegPaDac + */ +#define RFLR_PADAC_20DBM_MASK 0xF8 +#define RFLR_PADAC_20DBM_ON 0x07 +#define RFLR_PADAC_20DBM_OFF 0x04 // Default + +/*! + * RegPll + */ +#define RFLR_PLL_BANDWIDTH_MASK 0x3F +#define RFLR_PLL_BANDWIDTH_75 0x00 +#define RFLR_PLL_BANDWIDTH_150 0x40 +#define RFLR_PLL_BANDWIDTH_225 0x80 +#define RFLR_PLL_BANDWIDTH_300 0xC0 // Default + +/*! + * RegPllLowPn + */ +#define RFLR_PLLLOWPN_BANDWIDTH_MASK 0x3F +#define RFLR_PLLLOWPN_BANDWIDTH_75 0x00 +#define RFLR_PLLLOWPN_BANDWIDTH_150 0x40 +#define RFLR_PLLLOWPN_BANDWIDTH_225 0x80 +#define RFLR_PLLLOWPN_BANDWIDTH_300 0xC0 // Default + +/*! + * RegModemConfig3 + */ +#define RFLR_MODEMCONFIG3_LOWDATARATEOPTIMIZE_MASK 0xF7 +#define RFLR_MODEMCONFIG3_LOWDATARATEOPTIMIZE_ON 0x08 +#define RFLR_MODEMCONFIG3_LOWDATARATEOPTIMIZE_OFF 0x00 // Default + +#define RFLR_MODEMCONFIG3_AGCAUTO_MASK 0xFB +#define RFLR_MODEMCONFIG3_AGCAUTO_ON 0x04 // Default +#define RFLR_MODEMCONFIG3_AGCAUTO_OFF 0x00 + +/*! + * RegFormerTemp + */ + +typedef struct sSX1276LR +{ + uint8_t RegFifo; // 0x00 + // Common settings + uint8_t RegOpMode; // 0x01 + uint8_t RegRes02; // 0x02 + uint8_t RegRes03; // 0x03 + uint8_t RegBandSetting; // 0x04 + uint8_t RegRes05; // 0x05 + uint8_t RegFrfMsb; // 0x06 + uint8_t RegFrfMid; // 0x07 + uint8_t RegFrfLsb; // 0x08 + // Tx settings + uint8_t RegPaConfig; // 0x09 + uint8_t RegPaRamp; // 0x0A + uint8_t RegOcp; // 0x0B + // Rx settings + uint8_t RegLna; // 0x0C + // LoRa registers + uint8_t RegFifoAddrPtr; // 0x0D + uint8_t RegFifoTxBaseAddr; // 0x0E + uint8_t RegFifoRxBaseAddr; // 0x0F + uint8_t RegFifoRxCurrentAddr; // 0x10 + uint8_t RegIrqFlagsMask; // 0x11 + uint8_t RegIrqFlags; // 0x12 + uint8_t RegNbRxBytes; // 0x13 + uint8_t RegRxHeaderCntValueMsb; // 0x14 + uint8_t RegRxHeaderCntValueLsb; // 0x15 + uint8_t RegRxPacketCntValueMsb; // 0x16 + uint8_t RegRxPacketCntValueLsb; // 0x17 + uint8_t RegModemStat; // 0x18 + uint8_t RegPktSnrValue; // 0x19 + uint8_t RegPktRssiValue; // 0x1A + uint8_t RegRssiValue; // 0x1B + uint8_t RegHopChannel; // 0x1C + uint8_t RegModemConfig1; // 0x1D + uint8_t RegModemConfig2; // 0x1E + uint8_t RegSymbTimeoutLsb; // 0x1F + uint8_t RegPreambleMsb; // 0x20 + uint8_t RegPreambleLsb; // 0x21 + uint8_t RegPayloadLength; // 0x22 + uint8_t RegMaxPayloadLength; // 0x23 + uint8_t RegHopPeriod; // 0x24 跳频周期 + uint8_t RegFifoRxByteAddr; // 0x25 + uint8_t RegModemConfig3; // 0x26 + uint8_t RegTestReserved27[0x30 - 0x27]; // 0x27-0x30 + uint8_t RegTestReserved31; // 0x31 + uint8_t RegTestReserved32[0x40 - 0x32]; // 0x32-0x40 + // I/O settings + uint8_t RegDioMapping1; // 0x40 + uint8_t RegDioMapping2; // 0x41 + // Version + uint8_t RegVersion; // 0x42 + // Additional settings + uint8_t RegAgcRef; // 0x43 + uint8_t RegAgcThresh1; // 0x44 + uint8_t RegAgcThresh2; // 0x45 + uint8_t RegAgcThresh3; // 0x46 + // Test + uint8_t RegTestReserved47[0x4B - 0x47]; // 0x47-0x4A + // Additional settings + uint8_t RegPllHop; // 0x4B + uint8_t RegTestReserved4C; // 0x4C + uint8_t RegPaDac; // 0x4D + // Test + uint8_t RegTestReserved4E[0x58-0x4E]; // 0x4E-0x57 + // Additional settings + uint8_t RegTcxo; // 0x58 + // Test + uint8_t RegTestReserved59; // 0x59 + // Test + uint8_t RegTestReserved5B; // 0x5B + // Additional settings + uint8_t RegPll; // 0x5C + // Test + uint8_t RegTestReserved5D; // 0x5D + // Additional settings + uint8_t RegPllLowPn; // 0x5E + // Test + uint8_t RegTestReserved5F[0x6C - 0x5F]; // 0x5F-0x6B + // Additional settings + uint8_t RegFormerTemp; // 0x6C + // Test + uint8_t RegTestReserved6D[0x71 - 0x6D]; // 0x6D-0x70 +}tSX1276LR; + +extern tSX1276LR* SX1276LR; + +//初始化SX1276LoRa模式 +void SX1276LoRaInit( void ); + +//读SX1276的版本号 +void SX1276LoRaSetDefaults( void ); + +//启用/禁用LoRa模式 +void SX1276LoRaSetLoRaOn( bool enable ); + +//设置SX1276操作模式 +void SX1276LoRaSetOpMode( uint8_t opMode ); + +//获取SX1276操作模式 +uint8_t SX1276LoRaGetOpMode( void ); + +//读取SX1276低噪声放大器(信号放大)的增益, +uint8_t SX1276LoRaReadRxGain( void ); + +//读取lora模式下无线信号强度 +double SX1276LoRaReadRssi( void ); + +//获取数据时的增益值 +uint8_t SX1276LoRaGetPacketRxGain( void ); + +//获取数据时的信噪比值,信号和噪声的比值,信噪比越高,说明信号干扰越小。 +int8_t SX1276LoRaGetPacketSnr( void ); + +//获取数据时的无线信号强度 +double SX1276LoRaGetPacketRssi( void ); + +//开始接收 +void SX1276LoRaStartRx( void ); + +//接收数据 +void SX1276LoRaGetRxPacket( void *buffer, uint16_t *size ); + +//发送数据 +void SX1276LoRaSetTxPacket( const void *buffer, uint16_t size ); + +//得到RFLRState状态 +uint8_t SX1276LoRaGetRFState( void ); + +//设置RFLRState状态,RFLRState的值决定了下面的函数处理哪一步的代码 +void SX1276LoRaSetRFState( uint8_t state ); + +//SX1276模块接发收数据的处理函数 +uint32_t SX1276LoRaProcess( void ); + +uint32_t SX1276LoraChannelEmpty( void ); + +#endif diff --git a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/sx1276-LoRaMisc.c b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/sx1276-LoRaMisc.c new file mode 100644 index 000000000..6a472f8c7 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/sx1276-LoRaMisc.c @@ -0,0 +1,420 @@ +/* + * THE FOLLOWING FIRMWARE IS PROVIDED: (1) "AS IS" WITH NO WARRANTY; AND + * (2)TO ENABLE ACCESS TO CODING INFORMATION TO GUIDE AND FACILITATE CUSTOMER. + * CONSEQUENTLY, SEMTECH SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR + * CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT + * OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION + * CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * Copyright (C) SEMTECH S.A. + */ +/*! + * \file sx1276-LoRaMisc.c + * \brief SX1276 RF chip high level functions driver + * + * \remark Optional support functions. + * These functions are defined only to easy the change of the + * parameters. + * For a final firmware the radio parameters will be known so + * there is no need to support all possible parameters. + * Removing these functions will greatly reduce the final firmware + * size. + * + * \version 2.0.0 + * \date May 6 2013 + * \author Gregory Cristian + * + * Last modified by Miguel Luis on Jun 19 2013 + */ +/************************************************* +File name: sx1276-LoRaMisc.c +Description: support aiit board configure and register function +History: +1. Date: 2021-04-25 +Author: AIIT XUOS Lab +Modification: +1. replace original macro and basic date type with AIIT XUOS Lab's own defination +*************************************************/ +#include "platform.h" + +#if defined( USE_SX1276_RADIO ) + +#include "sx1276-Hal.h" +#include "sx1276.h" + +#include "sx1276-LoRa.h" +#include "sx1276-LoRaMisc.h" + +/*! + * SX1276 definitions + */ +#define XTAL_FREQ 32000000 +#define FREQ_STEP 61.03515625 + +extern tLoRaSettings LoRaSettings; + +void SX1276LoRaSetRFFrequency( uint32_t freq ) +{ + LoRaSettings.RFFrequency = freq; + + freq = ( uint32_t )( ( double )freq / ( double )FREQ_STEP ); + SX1276LR->RegFrfMsb = ( uint8_t )( ( freq >> 16 ) & 0xFF ); + SX1276LR->RegFrfMid = ( uint8_t )( ( freq >> 8 ) & 0xFF ); + SX1276LR->RegFrfLsb = ( uint8_t )( freq & 0xFF ); + SX1276WriteBuffer( REG_LR_FRFMSB, &SX1276LR->RegFrfMsb, 3 ); +} + +uint32_t SX1276LoRaGetRFFrequency( void ) +{ + SX1276ReadBuffer( REG_LR_FRFMSB, &SX1276LR->RegFrfMsb, 3 ); + LoRaSettings.RFFrequency = ( ( uint32_t )SX1276LR->RegFrfMsb << 16 ) | ( ( uint32_t )SX1276LR->RegFrfMid << 8 ) | ( ( uint32_t )SX1276LR->RegFrfLsb ); + LoRaSettings.RFFrequency = ( uint32_t )( ( double )LoRaSettings.RFFrequency * ( double )FREQ_STEP ); + + return LoRaSettings.RFFrequency; +} + +void SX1276LoRaSetRFPower( int8_t power ) +{ + SX1276Read( REG_LR_PACONFIG, &SX1276LR->RegPaConfig ); + SX1276Read( REG_LR_PADAC, &SX1276LR->RegPaDac ); + + if( ( SX1276LR->RegPaConfig & RFLR_PACONFIG_PASELECT_PABOOST ) == RFLR_PACONFIG_PASELECT_PABOOST ) + { + if( ( SX1276LR->RegPaDac & 0x87 ) == 0x87 ) + { + if( power < 5 ) + { + power = 5; + } + if( power > 20 ) + { + power = 20; + } + SX1276LR->RegPaConfig = ( SX1276LR->RegPaConfig & RFLR_PACONFIG_MAX_POWER_MASK ) | 0x70; + SX1276LR->RegPaConfig = ( SX1276LR->RegPaConfig & RFLR_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power - 5 ) & 0x0F ); + } + else + { + if( power < 2 ) + { + power = 2; + } + if( power > 17 ) + { + power = 17; + } + SX1276LR->RegPaConfig = ( SX1276LR->RegPaConfig & RFLR_PACONFIG_MAX_POWER_MASK ) | 0x70; + SX1276LR->RegPaConfig = ( SX1276LR->RegPaConfig & RFLR_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power - 2 ) & 0x0F ); + } + } + else + { + if( power < -1 ) + { + power = -1; + } + if( power > 14 ) + { + power = 14; + } + SX1276LR->RegPaConfig = ( SX1276LR->RegPaConfig & RFLR_PACONFIG_MAX_POWER_MASK ) | 0x70; + SX1276LR->RegPaConfig = ( SX1276LR->RegPaConfig & RFLR_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power + 1 ) & 0x0F ); + } + SX1276Write( REG_LR_PACONFIG, SX1276LR->RegPaConfig ); + LoRaSettings.Power = power; +} + +int8_t SX1276LoRaGetRFPower( void ) +{ + SX1276Read( REG_LR_PACONFIG, &SX1276LR->RegPaConfig ); + SX1276Read( REG_LR_PADAC, &SX1276LR->RegPaDac ); + + if( ( SX1276LR->RegPaConfig & RFLR_PACONFIG_PASELECT_PABOOST ) == RFLR_PACONFIG_PASELECT_PABOOST ) + { + if( ( SX1276LR->RegPaDac & 0x07 ) == 0x07 ) + { + LoRaSettings.Power = 5 + ( SX1276LR->RegPaConfig & ~RFLR_PACONFIG_OUTPUTPOWER_MASK ); + } + else + { + LoRaSettings.Power = 2 + ( SX1276LR->RegPaConfig & ~RFLR_PACONFIG_OUTPUTPOWER_MASK ); + } + } + else + { + LoRaSettings.Power = -1 + ( SX1276LR->RegPaConfig & ~RFLR_PACONFIG_OUTPUTPOWER_MASK ); + } + return LoRaSettings.Power; +} + +void SX1276LoRaSetSignalBandwidth( uint8_t bw ) +{ + SX1276Read( REG_LR_MODEMCONFIG1, &SX1276LR->RegModemConfig1 ); + SX1276LR->RegModemConfig1 = ( SX1276LR->RegModemConfig1 & RFLR_MODEMCONFIG1_BW_MASK ) | ( bw << 4 ); + SX1276Write( REG_LR_MODEMCONFIG1, SX1276LR->RegModemConfig1 ); + LoRaSettings.SignalBw = bw; +} + +uint8_t SX1276LoRaGetSignalBandwidth( void ) +{ + SX1276Read( REG_LR_MODEMCONFIG1, &SX1276LR->RegModemConfig1 ); + LoRaSettings.SignalBw = ( SX1276LR->RegModemConfig1 & ~RFLR_MODEMCONFIG1_BW_MASK ) >> 4; + return LoRaSettings.SignalBw; +} + +void SX1276LoRaSetSpreadingFactor( uint8_t factor ) +{ + + if( factor > 12 ) + { + factor = 12; + } + else if( factor < 6 ) + { + factor = 6; + } + + if( factor == 6 ) + { + SX1276LoRaSetNbTrigPeaks( 5 ); + } + else + { + SX1276LoRaSetNbTrigPeaks( 3 ); + } + + SX1276Read( REG_LR_MODEMCONFIG2, &SX1276LR->RegModemConfig2 ); + SX1276LR->RegModemConfig2 = ( SX1276LR->RegModemConfig2 & RFLR_MODEMCONFIG2_SF_MASK ) | ( factor << 4 ); + SX1276Write( REG_LR_MODEMCONFIG2, SX1276LR->RegModemConfig2 ); + LoRaSettings.SpreadingFactor = factor; +} + +uint8_t SX1276LoRaGetSpreadingFactor( void ) +{ + SX1276Read( REG_LR_MODEMCONFIG2, &SX1276LR->RegModemConfig2 ); + LoRaSettings.SpreadingFactor = ( SX1276LR->RegModemConfig2 & ~RFLR_MODEMCONFIG2_SF_MASK ) >> 4; + return LoRaSettings.SpreadingFactor; +} + +void SX1276LoRaSetErrorCoding( uint8_t value ) +{ + SX1276Read( REG_LR_MODEMCONFIG1, &SX1276LR->RegModemConfig1 ); + SX1276LR->RegModemConfig1 = ( SX1276LR->RegModemConfig1 & RFLR_MODEMCONFIG1_CODINGRATE_MASK ) | ( value << 1 ); + SX1276Write( REG_LR_MODEMCONFIG1, SX1276LR->RegModemConfig1 ); + LoRaSettings.ErrorCoding = value; +} + +uint8_t SX1276LoRaGetErrorCoding( void ) +{ + SX1276Read( REG_LR_MODEMCONFIG1, &SX1276LR->RegModemConfig1 ); + LoRaSettings.ErrorCoding = ( SX1276LR->RegModemConfig1 & ~RFLR_MODEMCONFIG1_CODINGRATE_MASK ) >> 1; + return LoRaSettings.ErrorCoding; +} + +void SX1276LoRaSetPacketCrcOn( bool enable ) +{ + SX1276Read( REG_LR_MODEMCONFIG2, &SX1276LR->RegModemConfig2 ); + SX1276LR->RegModemConfig2 = ( SX1276LR->RegModemConfig2 & RFLR_MODEMCONFIG2_RXPAYLOADCRC_MASK ) | ( enable << 2 ); + SX1276Write( REG_LR_MODEMCONFIG2, SX1276LR->RegModemConfig2 ); + LoRaSettings.CrcOn = enable; +} + +void SX1276LoRaSetPreambleLength( uint16_t value ) +{ + SX1276ReadBuffer( REG_LR_PREAMBLEMSB, &SX1276LR->RegPreambleMsb, 2 ); + + SX1276LR->RegPreambleMsb = ( value >> 8 ) & 0x00FF; + SX1276LR->RegPreambleLsb = value & 0xFF; + SX1276WriteBuffer( REG_LR_PREAMBLEMSB, &SX1276LR->RegPreambleMsb, 2 ); +} + +uint16_t SX1276LoRaGetPreambleLength( void ) +{ + SX1276ReadBuffer( REG_LR_PREAMBLEMSB, &SX1276LR->RegPreambleMsb, 2 ); + return ( ( SX1276LR->RegPreambleMsb & 0x00FF ) << 8 ) | SX1276LR->RegPreambleLsb; +} + +bool SX1276LoRaGetPacketCrcOn( void ) +{ + SX1276Read( REG_LR_MODEMCONFIG2, &SX1276LR->RegModemConfig2 ); + LoRaSettings.CrcOn = ( SX1276LR->RegModemConfig2 & RFLR_MODEMCONFIG2_RXPAYLOADCRC_ON ) >> 1; + return LoRaSettings.CrcOn; +} + +void SX1276LoRaSetImplicitHeaderOn( bool enable ) +{ + SX1276Read( REG_LR_MODEMCONFIG1, &SX1276LR->RegModemConfig1 ); + SX1276LR->RegModemConfig1 = ( SX1276LR->RegModemConfig1 & RFLR_MODEMCONFIG1_IMPLICITHEADER_MASK ) | ( enable ); + SX1276Write( REG_LR_MODEMCONFIG1, SX1276LR->RegModemConfig1 ); + LoRaSettings.ImplicitHeaderOn = enable; +} + +bool SX1276LoRaGetImplicitHeaderOn( void ) +{ + SX1276Read( REG_LR_MODEMCONFIG1, &SX1276LR->RegModemConfig1 ); + LoRaSettings.ImplicitHeaderOn = ( SX1276LR->RegModemConfig1 & RFLR_MODEMCONFIG1_IMPLICITHEADER_ON ); + return LoRaSettings.ImplicitHeaderOn; +} + +void SX1276LoRaSetRxSingleOn( bool enable ) +{ + LoRaSettings.RxSingleOn = enable; +} + +bool SX1276LoRaGetRxSingleOn( void ) +{ + return LoRaSettings.RxSingleOn; +} + +void SX1276LoRaSetFreqHopOn( bool enable ) +{ + LoRaSettings.FreqHopOn = enable; +} + +bool SX1276LoRaGetFreqHopOn( void ) +{ + return LoRaSettings.FreqHopOn; +} + +void SX1276LoRaSetHopPeriod( uint8_t value ) +{ + SX1276LR->RegHopPeriod = value; + SX1276Write( REG_LR_HOPPERIOD, SX1276LR->RegHopPeriod ); + LoRaSettings.HopPeriod = value; +} + +uint8_t SX1276LoRaGetHopPeriod( void ) +{ + SX1276Read( REG_LR_HOPPERIOD, &SX1276LR->RegHopPeriod ); + LoRaSettings.HopPeriod = SX1276LR->RegHopPeriod; + return LoRaSettings.HopPeriod; +} + +void SX1276LoRaSetTxPacketTimeout( uint32_t value ) +{ + LoRaSettings.TxPacketTimeout = value; +} + +uint32_t SX1276LoRaGetTxPacketTimeout( void ) +{ + return LoRaSettings.TxPacketTimeout; +} + +void SX1276LoRaSetRxPacketTimeout( uint32_t value ) +{ + LoRaSettings.RxPacketTimeout = value; +} + +uint32_t SX1276LoRaGetRxPacketTimeout( void ) +{ + return LoRaSettings.RxPacketTimeout; +} + +void SX1276LoRaSetPayloadLength( uint8_t value ) +{ + SX1276LR->RegPayloadLength = value; + SX1276Write( REG_LR_PAYLOADLENGTH, SX1276LR->RegPayloadLength ); + LoRaSettings.PayloadLength = value; +} + +uint8_t SX1276LoRaGetPayloadLength( void ) +{ + SX1276Read( REG_LR_PAYLOADLENGTH, &SX1276LR->RegPayloadLength ); + LoRaSettings.PayloadLength = SX1276LR->RegPayloadLength; + return LoRaSettings.PayloadLength; +} + +void SX1276LoRaSetPa20dBm( bool enale ) +{ + SX1276Read( REG_LR_PADAC, &SX1276LR->RegPaDac ); + SX1276Read( REG_LR_PACONFIG, &SX1276LR->RegPaConfig ); + + if( ( SX1276LR->RegPaConfig & RFLR_PACONFIG_PASELECT_PABOOST ) == RFLR_PACONFIG_PASELECT_PABOOST ) + { + if( enale == true ) + { + SX1276LR->RegPaDac = 0x87; + } + } + else + { + SX1276LR->RegPaDac = 0x84; + } + SX1276Write( REG_LR_PADAC, SX1276LR->RegPaDac ); +} + +bool SX1276LoRaGetPa20dBm( void ) +{ + SX1276Read( REG_LR_PADAC, &SX1276LR->RegPaDac ); + + return ( ( SX1276LR->RegPaDac & 0x07 ) == 0x07 ) ? true : false; +} + +void SX1276LoRaSetPAOutput( uint8_t outputPin ) +{ + SX1276Read( REG_LR_PACONFIG, &SX1276LR->RegPaConfig ); + SX1276LR->RegPaConfig = (SX1276LR->RegPaConfig & RFLR_PACONFIG_PASELECT_MASK ) | outputPin; + SX1276Write( REG_LR_PACONFIG, SX1276LR->RegPaConfig ); +} + +uint8_t SX1276LoRaGetPAOutput( void ) +{ + SX1276Read( REG_LR_PACONFIG, &SX1276LR->RegPaConfig ); + return SX1276LR->RegPaConfig & ~RFLR_PACONFIG_PASELECT_MASK; +} + +void SX1276LoRaSetPaRamp( uint8_t value ) +{ + SX1276Read( REG_LR_PARAMP, &SX1276LR->RegPaRamp ); + SX1276LR->RegPaRamp = ( SX1276LR->RegPaRamp & RFLR_PARAMP_MASK ) | ( value & ~RFLR_PARAMP_MASK ); + SX1276Write( REG_LR_PARAMP, SX1276LR->RegPaRamp ); +} + +uint8_t SX1276LoRaGetPaRamp( void ) +{ + SX1276Read( REG_LR_PARAMP, &SX1276LR->RegPaRamp ); + return SX1276LR->RegPaRamp & ~RFLR_PARAMP_MASK; +} + +void SX1276LoRaSetSymbTimeout( uint16_t value ) +{ + SX1276ReadBuffer( REG_LR_MODEMCONFIG2, &SX1276LR->RegModemConfig2, 2 ); + + SX1276LR->RegModemConfig2 = ( SX1276LR->RegModemConfig2 & RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB_MASK ) | ( ( value >> 8 ) & ~RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB_MASK ); + SX1276LR->RegSymbTimeoutLsb = value & 0xFF; + SX1276WriteBuffer( REG_LR_MODEMCONFIG2, &SX1276LR->RegModemConfig2, 2 ); +} + +uint16_t SX1276LoRaGetSymbTimeout( void ) +{ + SX1276ReadBuffer( REG_LR_MODEMCONFIG2, &SX1276LR->RegModemConfig2, 2 ); + return ( ( SX1276LR->RegModemConfig2 & ~RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB_MASK ) << 8 ) | SX1276LR->RegSymbTimeoutLsb; +} + +void SX1276LoRaSetLowDatarateOptimize( bool enable ) +{ + SX1276Read( REG_LR_MODEMCONFIG3, &SX1276LR->RegModemConfig3 ); + SX1276LR->RegModemConfig3 = ( SX1276LR->RegModemConfig3 & RFLR_MODEMCONFIG3_LOWDATARATEOPTIMIZE_MASK ) | ( enable << 3 ); + SX1276Write( REG_LR_MODEMCONFIG3, SX1276LR->RegModemConfig3 ); +} + +bool SX1276LoRaGetLowDatarateOptimize( void ) +{ + SX1276Read( REG_LR_MODEMCONFIG3, &SX1276LR->RegModemConfig3 ); + return ( ( SX1276LR->RegModemConfig3 & RFLR_MODEMCONFIG3_LOWDATARATEOPTIMIZE_ON ) >> 3 ); +} + +void SX1276LoRaSetNbTrigPeaks( uint8_t value ) +{ + SX1276Read( 0x31, &SX1276LR->RegTestReserved31 ); + SX1276LR->RegTestReserved31 = ( SX1276LR->RegTestReserved31 & 0xF8 ) | value;//数据包长度最高有效位 0x31 bit2 1 0 + SX1276Write( 0x31, SX1276LR->RegTestReserved31 ); +} + +uint8_t SX1276LoRaGetNbTrigPeaks( void ) +{ + SX1276Read( 0x31, &SX1276LR->RegTestReserved31 ); + return ( SX1276LR->RegTestReserved31 & 0x07 ); +} + +#endif // USE_SX1276_RADIO diff --git a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/sx1276-LoRaMisc.h b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/sx1276-LoRaMisc.h new file mode 100644 index 000000000..b6bc148c9 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/sx1276-LoRaMisc.h @@ -0,0 +1,324 @@ +/* + * THE FOLLOWING FIRMWARE IS PROVIDED: (1) "AS IS" WITH NO WARRANTY; AND + * (2)TO ENABLE ACCESS TO CODING INFORMATION TO GUIDE AND FACILITATE CUSTOMER. + * CONSEQUENTLY, SEMTECH SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR + * CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT + * OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION + * CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * Copyright (C) SEMTECH S.A. + */ +/*! + * \file sx1276-LoRaMisc.h + * \brief SX1276 RF chip high level functions driver + * + * \remark Optional support functions. + * These functions are defined only to easy the change of the + * parameters. + * For a final firmware the radio parameters will be known so + * there is no need to support all possible parameters. + * Removing these functions will greatly reduce the final firmware + * size. + * + * \version 2.0.0 + * \date May 6 2013 + * \author Gregory Cristian + * + * Last modified by Miguel Luis on Jun 19 2013 + */ +/************************************************* +File name: sx1276-LoRaMisc.h +Description: support aiit board configure and register function +History: +1. Date: 2021-04-25 +Author: AIIT XUOS Lab +Modification: +1. replace original macro and basic date type with AIIT XUOS Lab's own defination +*************************************************/ +#ifndef __SX1276_LORA_MISC_H__ +#define __SX1276_LORA_MISC_H__ +#include "stdint.h" +#include "stdbool.h" +/*! + * \brief Writes the new RF frequency value + * + * \param [IN] freq New RF frequency value in [Hz] + */ +void SX1276LoRaSetRFFrequency( uint32_t freq ); + +/*! + * \brief Reads the current RF frequency value + * + * \retval freq Current RF frequency value in [Hz] + */ +uint32_t SX1276LoRaGetRFFrequency( void ); + +/*! + * \brief Writes the new RF output power value + * + * \param [IN] power New output power value in [dBm] + */ +void SX1276LoRaSetRFPower( int8_t power ); + +/*! + * \brief Reads the current RF output power value + * + * \retval power Current output power value in [dBm] + */ +int8_t SX1276LoRaGetRFPower( void ); + +/*! + * \brief Writes the new Signal Bandwidth value + * + * \remark This function sets the IF frequency according to the datasheet + * + * \param [IN] factor New Signal Bandwidth value [0: 125 kHz, 1: 250 kHz, 2: 500 kHz] + */ +void SX1276LoRaSetSignalBandwidth( uint8_t bw ); + +/*! + * \brief Reads the current Signal Bandwidth value + * + * \retval factor Current Signal Bandwidth value [0: 125 kHz, 1: 250 kHz, 2: 500 kHz] + */ +uint8_t SX1276LoRaGetSignalBandwidth( void ); + +/*! + * \brief Writes the new Spreading Factor value + * + * \param [IN] factor New Spreading Factor value [7, 8, 9, 10, 11, 12] + */ +void SX1276LoRaSetSpreadingFactor( uint8_t factor ); + +/*! + * \brief Reads the current Spreading Factor value + * + * \retval factor Current Spreading Factor value [7, 8, 9, 10, 11, 12] + */ +uint8_t SX1276LoRaGetSpreadingFactor( void ); + +/*! + * \brief Writes the new Error Coding value + * + * \param [IN] value New Error Coding value [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8] + */ +void SX1276LoRaSetErrorCoding( uint8_t value ); + +/*! + * \brief Reads the current Error Coding value + * + * \retval value Current Error Coding value [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8] + */ +uint8_t SX1276LoRaGetErrorCoding( void ); + +/*! + * \brief Enables/Disables the packet CRC generation + * + * \param [IN] enaable [true, false] + */ +void SX1276LoRaSetPacketCrcOn( bool enable ); + +/*! + * \brief Reads the current packet CRC generation status + * + * \retval enable [true, false] + */ +bool SX1276LoRaGetPacketCrcOn( void ); + +/*! + * \brief Enables/Disables the Implicit Header mode in LoRa + * + * \param [IN] enable [true, false] + */ +void SX1276LoRaSetImplicitHeaderOn( bool enable ); + +/*! + * \brief Check if implicit header mode in LoRa in enabled or disabled + * + * \retval enable [true, false] + */ +bool SX1276LoRaGetImplicitHeaderOn( void ); + +/*! + * \brief Enables/Disables Rx single instead of Rx continuous + * + * \param [IN] enable [true, false] + */ +void SX1276LoRaSetRxSingleOn( bool enable ); + +/*! + * \brief Check if LoRa is in Rx Single mode + * + * \retval enable [true, false] + */ +bool SX1276LoRaGetRxSingleOn( void ); + +/*! + * \brief Enables/Disables the frequency hopping + * + * \param [IN] enable [true, false] + */ + +void SX1276LoRaSetFreqHopOn( bool enable ); + +/*! + * \brief Get the frequency hopping status + * + * \param [IN] enable [true, false] + */ +bool SX1276LoRaGetFreqHopOn( void ); + +/*! + * \brief Set symbol period between frequency hops + * + * \param [IN] value + */ +void SX1276LoRaSetHopPeriod( uint8_t value ); + +/*! + * \brief Get symbol period between frequency hops + * + * \retval value symbol period between frequency hops + */ +uint8_t SX1276LoRaGetHopPeriod( void ); + +/*! + * \brief Set timeout Tx packet (based on MCU timer, timeout between Tx Mode entry Tx Done IRQ) + * + * \param [IN] value timeout (ms) + */ +void SX1276LoRaSetTxPacketTimeout( uint32_t value ); + +/*! + * \brief Get timeout between Tx packet (based on MCU timer, timeout between Tx Mode entry Tx Done IRQ) + * + * \retval value timeout (ms) + */ +uint32_t SX1276LoRaGetTxPacketTimeout( void ); + +/*! + * \brief Set timeout Rx packet (based on MCU timer, timeout between Rx Mode entry and Rx Done IRQ) + * + * \param [IN] value timeout (ms) + */ +void SX1276LoRaSetRxPacketTimeout( uint32_t value ); + +/*! + * \brief Get timeout Rx packet (based on MCU timer, timeout between Rx Mode entry and Rx Done IRQ) + * + * \retval value timeout (ms) + */ +uint32_t SX1276LoRaGetRxPacketTimeout( void ); + +/*! + * \brief Set payload length + * + * \param [IN] value payload length + */ +void SX1276LoRaSetPayloadLength( uint8_t value ); + +/*! + * \brief Get payload length + * + * \retval value payload length + */ +uint8_t SX1276LoRaGetPayloadLength( void ); + +/*! + * \brief Enables/Disables the 20 dBm PA + * + * \param [IN] enable [true, false] + */ +void SX1276LoRaSetPa20dBm( bool enale ); + +/*! + * \brief Gets the current 20 dBm PA status + * + * \retval enable [true, false] + */ +bool SX1276LoRaGetPa20dBm( void ); + +/*! + * \brief Set the RF Output pin + * + * \param [IN] RF_PACONFIG_PASELECT_PABOOST or RF_PACONFIG_PASELECT_RFO + */ +void SX1276LoRaSetPAOutput( uint8_t outputPin ); + +/*! + * \brief Gets the used RF Ouptut pin + * + * \retval RF_PACONFIG_PASELECT_PABOOST or RF_PACONFIG_PASELECT_RFO + */ +uint8_t SX1276LoRaGetPAOutput( void ); + +/*! + * \brief Writes the new PA rise/fall time of ramp up/down value + * + * \param [IN] value New PaRamp value + */ +void SX1276LoRaSetPaRamp( uint8_t value ); + +/*! + * \brief Reads the current PA rise/fall time of ramp up/down value + * + * \retval freq Current PaRamp value + */ +uint8_t SX1276LoRaGetPaRamp( void ); + +/*! + * \brief Set Symbol Timeout based on symbol length + * + * \param [IN] value number of symbol + */ +void SX1276LoRaSetSymbTimeout( uint16_t value ); + +/*! + * \brief Get Symbol Timeout based on symbol length + * + * \retval value number of symbol + */ +uint16_t SX1276LoRaGetSymbTimeout( void ); + +/*! + * \brief Configure the device to optimize low datarate transfers + * + * \param [IN] enable Enables/Disables the low datarate optimization + */ +void SX1276LoRaSetLowDatarateOptimize( bool enable ); + +/*! + * \brief Get the status of optimize low datarate transfers + * + * \retval LowDatarateOptimize enable or disable + */ +bool SX1276LoRaGetLowDatarateOptimize( void ); + +/*! + * \brief Get the preamble length + * + * \retval value preamble length + */ +uint16_t SX1276LoRaGetPreambleLength( void ); + +/*! + * \brief Set the preamble length + * + * \param [IN] value preamble length + */ +void SX1276LoRaSetPreambleLength( uint16_t value ); + +/*! + * \brief Set the number or rolling preamble symbol needed for detection + * + * \param [IN] value number of preamble symbol + */ +void SX1276LoRaSetNbTrigPeaks( uint8_t value ); + +/*! + * \brief Get the number or rolling preamble symbol needed for detection + * + * \retval value number of preamble symbol + */ +uint8_t SX1276LoRaGetNbTrigPeaks( void ); +#endif diff --git a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/sx1276.c b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/sx1276.c new file mode 100644 index 000000000..19e9bd528 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/sx1276.c @@ -0,0 +1,327 @@ +/* + * THE FOLLOWING FIRMWARE IS PROVIDED: (1) "AS IS" WITH NO WARRANTY; AND + * (2)TO ENABLE ACCESS TO CODING INFORMATION TO GUIDE AND FACILITATE CUSTOMER. + * CONSEQUENTLY, SEMTECH SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR + * CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT + * OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION + * CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * Copyright (C) SEMTECH S.A. + */ +/*! + * \file sx1276.c + * \brief SX1276 RF chip high level functions driver + * + * \remark Optional support functions. + * These functions are defined only to easy the change of the + * parameters. + * For a final firmware the radio parameters will be known so + * there is no need to support all possible parameters. + * Removing these functions will greatly reduce the final firmware + * size. + * + * \version 2.0.0 + * \date May 6 2013 + * \author Gregory Cristian + * + * Last modified by Miguel Luis on Jun 19 2013 + */ +/************************************************* +File name: sx1276.c +Description: support aiit board configure and register function +History: +1. Date: 2021-04-25 +Author: AIIT XUOS Lab +Modification: +1. replace original macro and basic date type with AIIT XUOS Lab's own defination +*************************************************/ + +#include "platform.h" +#include "radio.h" + +#if defined(USE_SX1276_RADIO) +#include "sx1276.h" +#include "sx1276-Hal.h" +#include "sx1276-Fsk.h" +#include "sx1276-LoRa.h" + +uint8_t SX1276Regs[0x70]; + +static bool LoRaOn = true; +static bool LoRaOnState = false; + +static int sx1276_tx_sem, sx1276_rx_sem; +static int sx1276_radio_task; + +void SX1276Reset(void) +{ + uint32_t startTick; + + SX1276SetReset(RADIO_RESET_ON); + + DDL_DelayMS(1); + + SX1276SetReset(RADIO_RESET_OFF); + + DDL_DelayMS(6); +} + +void SX1276_SetLoRaOn(bool enable) +{ + if(LoRaOnState == enable) { + return; + } + + LoRaOnState = enable; + LoRaOn = enable; + + if(LoRaOn == true) { + SX1276LoRaSetOpMode(RFLR_OPMODE_SLEEP); + + SX1276LR->RegOpMode = (SX1276LR->RegOpMode & RFLR_OPMODE_LONGRANGEMODE_MASK) | RFLR_OPMODE_LONGRANGEMODE_ON; + SX1276Write(REG_LR_OPMODE, SX1276LR->RegOpMode); + + SX1276LoRaSetOpMode(RFLR_OPMODE_STANDBY); + + // RxDone RxTimeout FhssChangeChannel CadDone + SX1276LR->RegDioMapping1 = RFLR_DIOMAPPING1_DIO0_00 | RFLR_DIOMAPPING1_DIO1_00 | RFLR_DIOMAPPING1_DIO2_00 | RFLR_DIOMAPPING1_DIO3_00; + // CadDetected ModeReady + SX1276LR->RegDioMapping2 = RFLR_DIOMAPPING2_DIO4_00 | RFLR_DIOMAPPING2_DIO5_00; + SX1276WriteBuffer(REG_LR_DIOMAPPING1, &SX1276LR->RegDioMapping1, 2); + + SX1276ReadBuffer(REG_LR_OPMODE, SX1276Regs + 1, 0x70 - 1); + } else { + SX1276LoRaSetOpMode(RFLR_OPMODE_SLEEP); + + SX1276LR->RegOpMode = (SX1276LR->RegOpMode & RFLR_OPMODE_LONGRANGEMODE_MASK) | RFLR_OPMODE_LONGRANGEMODE_OFF; + SX1276Write(REG_LR_OPMODE, SX1276LR->RegOpMode); + + SX1276LoRaSetOpMode(RFLR_OPMODE_STANDBY); + + SX1276ReadBuffer(REG_OPMODE, SX1276Regs + 1, 0x70 - 1); + } +} + +bool SX1276_GetLoRaOn(void) +{ + return LoRaOn; +} + +void SX1276SetOpMode(uint8_t opMode) +{ + if(LoRaOn == false) { + SX1276FskSetOpMode(opMode); + } else { + SX1276LoRaSetOpMode(opMode); + } +} + +uint8_t SX1276_GetOpMode(void) +{ + if(LoRaOn == false) { + return SX1276FskGetOpMode(); + } else { + return SX1276LoRaGetOpMode(); + } +} + +double SX1276ReadRssi(void) +{ + if(LoRaOn == false) { + return SX1276FskReadRssi(); + } else { + return SX1276LoRaReadRssi(); + } +} + +uint8_t SX1276_ReadRxGain(void) +{ + if(LoRaOn == false) { + return SX1276FskReadRxGain(); + } else { + return SX1276LoRaReadRxGain(); + } +} + +uint8_t SX1276_GetPacketRxGain(void) +{ + if(LoRaOn == false) { + return SX1276FskGetPacketRxGain(); + } else { + return SX1276LoRaGetPacketRxGain(); + } +} + +int8_t SX1276_GetPacketSnr(void) +{ + if(LoRaOn == false) { + while(1) { + // Useless in FSK mode + // Block program here + } + } else { + return SX1276LoRaGetPacketSnr(); + } +} + +double SX1276_GetPacketRssi(void) +{ + if(LoRaOn == false) { + return SX1276FskGetPacketRssi(); + } else { + return SX1276LoRaGetPacketRssi(); + } +} + +uint32_t SX1276GetPacketAfc(void) +{ + if(LoRaOn == false) { + return SX1276FskGetPacketAfc(); + } else { + while(1) { + // Useless in LoRa mode + // Block program here + } + } +} + +void SX1276StartRx(void) +{ + if(LoRaOn == false) { + SX1276FskSetRFState(RF_STATE_RX_INIT); + } else { + SX1276LoRaSetRFState(RFLR_STATE_RX_INIT); + } +} + +void SX1276GetRxPacket(void *buffer, uint16_t *size) +{ + if(LoRaOn == false) { + SX1276FskGetRxPacket(buffer, size); + } else { + SX1276LoRaGetRxPacket(buffer, size); + } +} + +int SX1276GetRx(void *buffer, uint16_t *size) +{ + int ret = -1; + SX1276StartRx(); + + //receive timeout 10s + ret = KSemaphoreObtain(sx1276_rx_sem, 10000); + if (0 == ret) { + SX1276LoRaSetRFState(RFLR_STATE_IDLE); + SX1276GetRxPacket(buffer, size); + } + return ret; +} + +void SX1276SetTxPacket(const void *buffer, uint16_t size) +{ + if(LoRaOn == false) { + SX1276FskSetTxPacket(buffer, size); + } else { + SX1276LoRaSetTxPacket(buffer, size); + } +} + +void SX1276SetTx(const void *buffer, uint16_t size) +{ + SX1276SetTxPacket(buffer, size); + + KSemaphoreObtain(sx1276_tx_sem, WAITING_FOREVER); + SX1276StartRx(); +} + +uint8_t SX1276GetRFState(void) +{ + if(LoRaOn == false) { + return SX1276FskGetRFState(); + } else { + return SX1276LoRaGetRFState(); + } +} + +void SX1276SetRFState(uint8_t state) +{ + if(LoRaOn == false) { + SX1276FskSetRFState(state); + } else { + SX1276LoRaSetRFState(state); + } +} + +uint32_t SX1276Process(void) +{ + if(LoRaOn == false) { + return SX1276FskProcess(); + } else { + return SX1276LoRaProcess(); + } +} + +static void Sx1276RadioEntry(void *parameter) +{ + uint32_t result; + while(1) { + result = SX1276Process(); + if (RF_RX_DONE == result) { + KSemaphoreAbandon(sx1276_rx_sem); + } + if (RF_TX_DONE == result) { + KSemaphoreAbandon(sx1276_tx_sem); + } + } +} + +uint32_t SX1276ChannelEmpty(void) +{ + if(LoRaOn == false) { + return true; + } else { + SX1276LoraChannelEmpty(); + } +} + +void SX1276Init(void) +{ + uint8_t TempReg; + + SX1276 = (tSX1276 *)SX1276Regs; + SX1276LR = (tSX1276LR *)SX1276Regs; + + SX1276InitIo(); + + SX1276Reset(); + + SX1276Read(0x06, &TempReg); + + if(TempReg != 0x6C) { + KPrintf("Hard SPI Err!\r\n"); + } + + SX1276Read(0x42, &TempReg); + + if(TempReg != 0x12) { + KPrintf("Hard SPI Err! version 0x%x\r\n", TempReg); + } + + #if (LORA == 0) + LoRaOn = false; + SX1276_SetLoRaOn(LoRaOn); + SX1276FskInit(); + #else + LoRaOn = true; + SX1276_SetLoRaOn(LoRaOn); + SX1276LoRaInit(); + #endif + + sx1276_rx_sem = KSemaphoreCreate(0); + sx1276_tx_sem = KSemaphoreCreate(0); + + sx1276_radio_task = KTaskCreate("radio", Sx1276RadioEntry , NONE, 2048, 20); + StartupKTask(sx1276_radio_task); +} + +#endif diff --git a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/sx1276.h b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/sx1276.h new file mode 100644 index 000000000..44699274e --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio/sx1276.h @@ -0,0 +1,97 @@ +/* + * THE FOLLOWING FIRMWARE IS PROVIDED: (1) "AS IS" WITH NO WARRANTY; AND + * (2)TO ENABLE ACCESS TO CODING INFORMATION TO GUIDE AND FACILITATE CUSTOMER. + * CONSEQUENTLY, SEMTECH SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR + * CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT + * OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION + * CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + * Copyright (C) SEMTECH S.A. + */ +/*! + * \file sx1276.h + * \brief SX1276 RF chip high level functions driver + * + * \remark Optional support functions. + * These functions are defined only to easy the change of the + * parameters. + * For a final firmware the radio parameters will be known so + * there is no need to support all possible parameters. + * Removing these functions will greatly reduce the final firmware + * size. + * + * \version 2.0.0 + * \date May 6 2013 + * \author Gregory Cristian + * + * Last modified by Miguel Luis on Jun 19 2013 + */ +/************************************************* +File name: sx1276.h +Description: support aiit board configure and register function +History: +1. Date: 2021-04-25 +Author: AIIT XUOS Lab +Modification: +1. replace original macro and basic date type with AIIT XUOS Lab's own defination +*************************************************/ + + +#ifndef __SX1276_H__ +#define __SX1276_H__ + +#include +#include + +extern uint8_t SX1276Regs[0x70]; //SX1276寄存器数组 + +void SX1276Init( void ); //初始化SX1276 + +void SX1276Reset( void ); //重置SX1276 + +/*以下函数都没有被使用到,因为在sx1276-LoRa.h里面又定义了一系列与下面作用相同的函数*/ +void SX1276_SetLoRaOn( bool enable ); //启用LoRa调制解调器或FSK调制解调器 + +bool SX1276_GetLoRaOn( void ); //获取LoRa调制解调器状态 + +void SX1276SetOpMode( uint8_t opMode ); //设置SX1276操作模式 + +uint8_t SX1276_GetOpMode( void ); //获取SX1276操作模式 + +uint8_t SX1276_ReadRxGain( void ); //读取当前Rx增益设置 + +double SX1276ReadRssi( void ); //读取无线信号强度 + +uint8_t SX1276_GetPacketRxGain( void ); //获取数据时的增益值 + +int8_t SX1276_GetPacketSnr( void ); //获取数据时的信噪比值,信号和噪声的比值,信噪比越高,说明信号干扰越小。 + +double SX1276_GetPacketRssi( void ); //获取数据是的无线信号强度 + +/*! + * \brief Gets the AFC value measured while receiving the packet + * + * \retval afcValue Current AFC value in [Hz] + */ +uint32_t SX1276GetPacketAfc( void ); //此函数不知道作用 + + +void SX1276StartRx( void ); //开始接收 + +void SX1276GetRxPacket( void *buffer, uint16_t *size ); //得到接收的数据 + +int SX1276GetRx(void *buffer, uint16_t *size); //应用接收数据,无数据时阻塞 + +void SX1276SetTxPacket( const void *buffer, uint16_t size ); //发送数据 + +void SX1276SetTx( const void *buffer, uint16_t size ); //应用发送数据 + +uint8_t SX1276GetRFState( void ); //得到RFLRState状态 + +void SX1276SetRFState( uint8_t state ); //设置RFLRState状态,RFLRState的值决定了下面的函数处理哪一步的代码 + +uint32_t SX1276Process( void ); //SX1276模块接发收数据的处理函数 + +uint32_t SX1276ChannelEmpty( void ); + +#endif diff --git a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/timer/Kconfig b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/timer/Kconfig new file mode 100644 index 000000000..2ec110cac --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/timer/Kconfig @@ -0,0 +1,16 @@ +menuconfig BSP_USING_HWTIMER + bool "Using hwtimer" + default y + select RESOURCES_HWTIMER + +if BSP_USING_HWTIMER + config HWTIMER_BUS_NAME_0 + string "timer 0 bus 0 name" + default "timer0" + config HWTIMER_0_DEVICE_NAME_0 + string "timer 0 bus 0 device 0 name" + default "timer0_dev0" + config HWTIMER_DRIVER_NAME_0 + string "timer 0 bus 0 driver name" + default "timer0_drv" +endif diff --git a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/timer/Makefile b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/timer/Makefile new file mode 100644 index 000000000..df3718568 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/timer/Makefile @@ -0,0 +1,3 @@ +SRC_FILES := connect_hwtimer.c + +include $(KERNEL_ROOT)/compiler.mk \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/timer/connect_hwtimer.c b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/timer/connect_hwtimer.c new file mode 100644 index 000000000..dec5de52e --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/timer/connect_hwtimer.c @@ -0,0 +1,189 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file connect_hwtimer.c +* @brief support edu-arm32-board hwtimer function and register to bus framework +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2021-04-25 +*/ + +#include + +#define TMR0_CMP_VAL 1000 +#define TMR0x ((CM_TMR0_TypeDef *)CM_TMR0_1_BASE) +#define TMR0_CH_x (TMR0_CH_A) +#define INTSEL_REG ((uint32_t)(&CM_INTC->SEL0)) +#define TIMER0_IRQn (18) + + +void (*callback_function)(void *) ; + +static void Timer0Callback(int vector, void *param) +{ + TMR0_SetCountValue(TMR0x, TMR0_CH_x, 0); + if (callback_function) { + callback_function(param); + } + +} + +static uint32 HwtimerOpen(void *dev) +{ + struct HwtimerHardwareDevice *hwtimer_dev = dev; + stc_tmr0_init_t stcTmr0Init; + /* Enable timer0 peripheral clock */ + FCG_Fcg2PeriphClockCmd(PWC_FCG2_TMR0_1, ENABLE); + + /* TIMER0 basetimer function initialize */ + (void)TMR0_StructInit(&stcTmr0Init); + stcTmr0Init.u32ClockDiv = TMR0_CLK_DIV128; /* Config clock division */ + stcTmr0Init.u32ClockSrc = TMR0_CLK_SRC_INTERN_CLK; /* Chose clock source */ + stcTmr0Init.u32Func = TMR0_FUNC_CMP; /* Timer0 compare mode */ + stcTmr0Init.u16CompareValue = TMR0_CMP_VAL; /* Set compare register data */ + (void)TMR0_Init(TMR0x, TMR0_CH_x, &stcTmr0Init); + + // DelayKTask(1); + // /* Set internal hardware capture source */ + // TMR0_SetTriggerSrc(EVT_PORT_EIRQ0); + + // DelayKTask(1); + + return EOK; +} + +static uint32 HwtimerClose(void *dev) +{ + /* Timer0 interrupt function Disable */ + TMR0_IntCmd(TMR0x, TMR0_INT_CMP_A, DISABLE); + return EOK; +} + +/*manage the hwtimer device operations*/ +static const struct HwtimerDevDone dev_done = +{ + .open = HwtimerOpen, + .close = HwtimerClose, + .write = NONE, + .read = NONE, +}; + +static uint32 HwtimerDrvConfigure(void *drv, struct BusConfigureInfo *configure_info) +{ + NULL_PARAM_CHECK(drv); + NULL_PARAM_CHECK(configure_info); + + x_err_t ret = EOK; + __IO uint32_t *INTC_SELx; + + switch (configure_info->configure_cmd) + { + case OPE_INT: + INTC_SELx = (__IO uint32_t *)(INTSEL_REG+ 4U * (uint32_t)(TIMER0_IRQn)); + WRITE_REG32(*INTC_SELx, EVT_SRC_TMR0_1_CMP_A); + callback_function = (void (*)(void *param))configure_info->private_data; + isrManager.done->registerIrq(TIMER0_IRQn+16,Timer0Callback,NULL); + isrManager.done->enableIrq(TIMER0_IRQn); + TMR0_IntCmd(TMR0x, TMR0_INT_CMP_A, ENABLE); + break; + case OPE_CFG: + TMR0_ClearStatus(TMR0x, TMR0_FLAG_CMP_A); + TMR0_SetCompareValue(TMR0x, TMR0_CH_x, *((int *)configure_info->private_data) ); + /* Timer0 interrupt function Enable */ + TMR0_SetCountValue(TMR0x, TMR0_CH_x, 0x0000); + TMR0_Start(TMR0x, TMR0_CH_x); + break; + default: + break; + } + return ret; +} + +/*Init hwtimer bus*/ +static int BoardHwtimerBusInit(struct HwtimerBus *hwtimer_bus, struct HwtimerDriver *hwtimer_driver) +{ + x_err_t ret = EOK; + + /*Init the hwtimer bus */ + ret = HwtimerBusInit(hwtimer_bus, HWTIMER_BUS_NAME_0); + if (EOK != ret) { + KPrintf("board_hwtimer_init HwtimerBusInit error %d\n", ret); + return ERROR; + } + + /*Init the hwtimer driver*/ + hwtimer_driver->configure = &(HwtimerDrvConfigure); + ret = HwtimerDriverInit(hwtimer_driver, HWTIMER_DRIVER_NAME_0); + if (EOK != ret) { + KPrintf("board_hwtimer_init HwtimerDriverInit error %d\n", ret); + return ERROR; + } + + /*Attach the hwtimer driver to the hwtimer bus*/ + ret = HwtimerDriverAttachToBus(HWTIMER_DRIVER_NAME_0, HWTIMER_BUS_NAME_0); + if (EOK != ret) { + KPrintf("board_hwtimer_init USEDriverAttachToBus error %d\n", ret); + return ERROR; + } + + return ret; +} + +/*Attach the hwtimer device to the hwtimer bus*/ +static int BoardHwtimerDevBend(void) +{ + x_err_t ret = EOK; + static struct HwtimerHardwareDevice hwtimer_device_0; + memset(&hwtimer_device_0, 0, sizeof(struct HwtimerHardwareDevice)); + + hwtimer_device_0.dev_done = &dev_done; + + ret = HwtimerDeviceRegister(&hwtimer_device_0, NONE, HWTIMER_0_DEVICE_NAME_0); + if (EOK != ret) { + KPrintf("BoardHwtimerDevBend HwtimerDeviceRegister device %s error %d\n", HWTIMER_0_DEVICE_NAME_0, ret); + return ERROR; + } + + ret = HwtimerDeviceAttachToBus(HWTIMER_0_DEVICE_NAME_0, HWTIMER_BUS_NAME_0); + if (EOK != ret) { + KPrintf("BoardHwtimerDevBend HwtimerDeviceAttachToBus device %s error %d\n", HWTIMER_0_DEVICE_NAME_0, ret); + return ERROR; + } + + return ret; +} + +/*EDU-ARM32 BOARD HWTIMER INIT*/ +int HwTimerInit(void) +{ + x_err_t ret = EOK; + static struct HwtimerBus hwtimer_bus; + memset(&hwtimer_bus, 0, sizeof(struct HwtimerBus)); + + static struct HwtimerDriver hwtimer_driver; + memset(&hwtimer_driver, 0, sizeof(struct HwtimerDriver)); + + ret = BoardHwtimerBusInit(&hwtimer_bus, &hwtimer_driver); + if (EOK != ret) { + KPrintf("board_hwtimer_Init error ret %u\n", ret); + return ERROR; + } + + ret = BoardHwtimerDevBend(); + if (EOK != ret) { + KPrintf("board_hwtimer_Init error ret %u\n", ret); + return ERROR; + } + + return ret; +} diff --git a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/watchdog/Kconfig b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/watchdog/Kconfig new file mode 100644 index 000000000..b47dd9f77 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/watchdog/Kconfig @@ -0,0 +1,15 @@ +if BSP_USING_WDT + config WDT_BUS_NAME_0 + string "watchdog bus 0 name" + default "wdt0" + + config WDT_DRIVER_NAME_0 + string "watchdog driver 0 name" + default "wdt0_drv" + + config WDT_0_DEVICE_NAME_0 + string "watchdog device 0 name" + default "wdt0_dev0" +endif + + diff --git a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/watchdog/Makefile b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/watchdog/Makefile new file mode 100644 index 000000000..9be59f003 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/watchdog/Makefile @@ -0,0 +1,3 @@ +SRC_FILES := connect_wdt.c + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/watchdog/connect_wdt.c b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/watchdog/connect_wdt.c new file mode 100644 index 000000000..afb8d68d7 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xishutong-arm32/third_party_driver/watchdog/connect_wdt.c @@ -0,0 +1,145 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file connect_wdt.c +* @brief support edu-arm32-board watchdog function and register to bus framework +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2023-02-02 +*/ + +#include + +#define WDT_COUNT_CYCLE 65536U + +static uint32 WdtOpen(void *dev) +{ + NULL_PARAM_CHECK(dev); + + stc_wdt_init_t stcWdtInit; + stcWdtInit.u32CountPeriod = WDT_CNT_PERIOD65536; + stcWdtInit.u32ClockDiv = WDT_CLK_DIV1024; + stcWdtInit.u32RefreshRange = WDT_RANGE_0TO25PCT; + stcWdtInit.u32LPMCount = WDT_LPM_CNT_STOP; + stcWdtInit.u32ExceptionType = WDT_EXP_TYPE_RST; + (void)WDT_Init(&stcWdtInit); + return EOK; +} + +static uint32 WdtConfigure(void *drv, struct BusConfigureInfo *args) +{ + NULL_PARAM_CHECK(drv); + NULL_PARAM_CHECK(args); + + stc_wdt_init_t stcWdtInit; + + int period_option = *((int*)args->private_data); + if(period_option<=256){ + period_option = WDT_CNT_PERIOD256; + }else if(period_option<=4096){ + period_option = WDT_CNT_PERIOD4096; + }else if(period_option<=16384){ + period_option = WDT_CNT_PERIOD16384; + }else{ + period_option = WDT_CNT_PERIOD65536; + } + + switch (args->configure_cmd) + { + case OPER_WDT_SET_TIMEOUT: + stcWdtInit.u32CountPeriod = period_option; + stcWdtInit.u32ClockDiv = WDT_CLK_DIV1024; + stcWdtInit.u32RefreshRange = WDT_RANGE_0TO25PCT; + stcWdtInit.u32LPMCount = WDT_LPM_CNT_STOP; + stcWdtInit.u32ExceptionType = WDT_EXP_TYPE_RST; + if (WDT_Init(&stcWdtInit) != 0) { + return ERROR; + } + /* the chip SDK's feature:to start up watchdog counter, feed dog first after initialization*/ + WDT_FeedDog(); + break; + case OPER_WDT_KEEPALIVE: + /* must wait for count lower than 25%(division by 4) for a feed as RefreshRange is set as 0TO25PCT*/ + if (WDT_GetCountValue() < WDT_COUNT_CYCLE/4){ + WDT_FeedDog(); + } + break; + default: + return ERROR; + } + return EOK; +} + +static const struct WdtDevDone dev_done = +{ + WdtOpen, + NONE, + NONE, + NONE, +}; + +/** + * @description: Watchdog function + * @return success: EOK, failure: other + */ +int StartWatchdog(void) +{ + //add feed watchdog task function + + return EOK; +} + +int HwWdtInit(void) +{ + x_err_t ret = EOK; + + static struct WdtBus wdt0; + + ret = WdtBusInit(&wdt0, WDT_BUS_NAME_0); + if (ret != EOK) { + KPrintf("Watchdog bus init error %d\n", ret); + return ERROR; + } + + static struct WdtDriver drv0; + drv0.configure = WdtConfigure; + + ret = WdtDriverInit(&drv0, WDT_DRIVER_NAME_0); + if (ret != EOK) { + KPrintf("Watchdog driver init error %d\n", ret); + return ERROR; + } + + ret = WdtDriverAttachToBus(WDT_DRIVER_NAME_0, WDT_BUS_NAME_0); + if (ret != EOK) { + KPrintf("Watchdog driver attach error %d\n", ret); + return ERROR; + } + + static struct WdtHardwareDevice dev0; + dev0.dev_done = &dev_done; + + ret = WdtDeviceRegister(&dev0, WDT_0_DEVICE_NAME_0); + if (ret != EOK) { + KPrintf("Watchdog device register error %d\n", ret); + return ERROR; + } + + ret = WdtDeviceAttachToBus(WDT_0_DEVICE_NAME_0, WDT_BUS_NAME_0); + if (ret != EOK) { + KPrintf("Watchdog device register error %d\n", ret); + return ERROR; + } + + return ret; +} diff --git a/Ubiquitous/XiZi_IIoT/board/xiwangtong-arm32/third_party_driver/ethernet/eth_netdev.c b/Ubiquitous/XiZi_IIoT/board/xiwangtong-arm32/third_party_driver/ethernet/eth_netdev.c index 03ca27594..09957b854 100644 --- a/Ubiquitous/XiZi_IIoT/board/xiwangtong-arm32/third_party_driver/ethernet/eth_netdev.c +++ b/Ubiquitous/XiZi_IIoT/board/xiwangtong-arm32/third_party_driver/ethernet/eth_netdev.c @@ -76,6 +76,7 @@ static int lwip_netdev_set_addr_info(struct netdev* netdev, ip_addr_t* ip_addr, netif_set_gw((struct netif*)netdev->user_data, ip_2_ip4(gw)); } } + return 0; } #ifdef LWIP_DNS @@ -92,7 +93,7 @@ static int lwip_netdev_set_dns_server(struct netdev* netdev, uint8_t dns_num, ip } #endif -#ifdef LWIP_DHCP +#if LWIP_DHCP static int lwip_netdev_set_dhcp(struct netdev* netdev, bool is_enabled) { netdev_low_level_set_dhcp_status(netdev, is_enabled); @@ -120,7 +121,7 @@ static const struct netdev_ops lwip_netdev_ops = { #ifdef LWIP_DNS .set_dns_server = lwip_netdev_set_dns_server, #endif -#ifdef LWIP_DHCP +#if LWIP_DHCP .set_dhcp = lwip_netdev_set_dhcp, #endif .set_default = lwip_netdev_set_default, @@ -180,9 +181,9 @@ int lwip_netdev_add(struct netif* lwip_netif) netdev->ops = &lwip_netdev_ops; netdev->hwaddr_len = lwip_netif->hwaddr_len; memcpy(netdev->hwaddr, lwip_netif->hwaddr, lwip_netif->hwaddr_len); - netdev->ip_addr = lwip_netif->ip_addr; - netdev->gw = lwip_netif->gw; - netdev->netmask = lwip_netif->netmask; + netdev->ip_addr = &lwip_netif->ip_addr; + netdev->gw = &lwip_netif->gw; + netdev->netmask = &lwip_netif->netmask; return result; } diff --git a/Ubiquitous/XiZi_IIoT/compiler.mk b/Ubiquitous/XiZi_IIoT/compiler.mk index 87aba0280..4a91b1ba0 100644 --- a/Ubiquitous/XiZi_IIoT/compiler.mk +++ b/Ubiquitous/XiZi_IIoT/compiler.mk @@ -2,6 +2,8 @@ ifeq ($(COMPILE_TYPE), COMPILE_MUSL) SRC_DIR_TEMP := $(MUSL_DIR) else ifeq ($(COMPILE_TYPE), COMPILE_LWIP) SRC_DIR_TEMP := $(LWIP_DIR) +else ifeq ($(COMPILE_TYPE), COMPILE_MONGOOSE) +SRC_DIR_TEMP := $(MONGOOSE_DIR) else SRC_DIR_TEMP := $(SRC_DIR) endif @@ -9,6 +11,7 @@ endif SRC_DIR := MUSL_DIR := LWIP_DIR := +MONGOOSE_DIR := ifeq ($(USE_APP_INCLUDEPATH), y) include $(KERNEL_ROOT)/path_app.mk diff --git a/Ubiquitous/XiZi_IIoT/fs/shared/include/iot-vfs_posix.h b/Ubiquitous/XiZi_IIoT/fs/shared/include/iot-vfs_posix.h index 00f67aaee..80df49507 100644 --- a/Ubiquitous/XiZi_IIoT/fs/shared/include/iot-vfs_posix.h +++ b/Ubiquitous/XiZi_IIoT/fs/shared/include/iot-vfs_posix.h @@ -15,7 +15,8 @@ #include -typedef void DIR; +#include +// typedef void void; #if defined(LIB_NEWLIB) && defined(_EXFUN) _READ_WRITE_RETURN_TYPE _EXFUN(read, (int __fd, void *__buf, size_t __nbyte)); @@ -39,15 +40,15 @@ int fsync(int fd); int ftruncate(int fd, off_t length); int mkdir(const char *path, mode_t mode); -DIR *opendir(const char *path); -int closedir(DIR *dirp); -struct dirent *readdir(DIR *dirp); +void* opendir(const char* path); +int closedir(void* dirp); +struct dirent* readdir(void* dirp); int rmdir(const char *path); int chdir(const char *path); char *getcwd(char *buf, size_t size); -long telldir(DIR *dirp); -void seekdir(DIR *dirp, off_t offset); -void rewinddir(DIR *dirp); +long telldir(void* dirp); +void seekdir(void* dirp, off_t offset); +void rewinddir(void* dirp); int statfs(const char *path, struct statfs *buf); diff --git a/Ubiquitous/XiZi_IIoT/fs/shared/src/iot-vfs.c b/Ubiquitous/XiZi_IIoT/fs/shared/src/iot-vfs.c index 2d3421d1a..e8835ef94 100644 --- a/Ubiquitous/XiZi_IIoT/fs/shared/src/iot-vfs.c +++ b/Ubiquitous/XiZi_IIoT/fs/shared/src/iot-vfs.c @@ -906,7 +906,7 @@ err: return 0; } -DIR *opendir(const char *path) +void* opendir(const char* path) { struct FileDescriptor *fdp; struct MountPoint *mp; @@ -968,7 +968,7 @@ err: return fdp; } -int closedir(DIR *dirp) +int closedir(void* dirp) { struct FileDescriptor *fdp = dirp; int ret; @@ -999,7 +999,7 @@ int closedir(DIR *dirp) } static struct dirent dirent; -struct dirent *readdir(DIR *dirp) +struct dirent* readdir(void* dirp) { struct FileDescriptor *fdp = dirp; int ret; @@ -1036,7 +1036,7 @@ int rmdir(const char *path) int chdir(const char *path) { char *abspath; - DIR *dirp; + void* dirp; if (path == NULL) { SYS_ERR("%s: invalid path\n", __func__); @@ -1074,7 +1074,7 @@ char *getcwd(char *buf, size_t size) return buf; } -void seekdir(DIR *dirp, off_t offset) +void seekdir(void* dirp, off_t offset) { struct FileDescriptor *fdp = dirp; @@ -1093,7 +1093,7 @@ void seekdir(DIR *dirp, off_t offset) fdp->mntp->fs->seekdir(fdp, offset); } -void rewinddir(DIR *dirp) +void rewinddir(void* dirp) { struct FileDescriptor *fdp = dirp; diff --git a/Ubiquitous/XiZi_IIoT/kernel/include/xs_kdbg.h b/Ubiquitous/XiZi_IIoT/kernel/include/xs_kdbg.h index afd6dd617..c4cf2c162 100644 --- a/Ubiquitous/XiZi_IIoT/kernel/include/xs_kdbg.h +++ b/Ubiquitous/XiZi_IIoT/kernel/include/xs_kdbg.h @@ -44,15 +44,16 @@ extern "C" { #define MSGQUEUE_DEBUG 0 #define FILESYS_DEBUG 0 -#define NETDEV_DEBUG 0 +#define NETDEV_DEBUG 1 #define WEBNET_DEBUG 0 #define WIZNET_DEBUG 0 -#define SYS_KDEBUG_LOG(section, information) \ - do { \ - if (section) { \ - KPrintf information; \ - } \ +#define SYS_KDEBUG_LOG(section, information) \ + do { \ + if (section) { \ + KPrintf("[%s:%d] ", __func__, __LINE__); \ + KPrintf information; \ + } \ } while (0) #define KDYN_NONE 0 diff --git a/Ubiquitous/XiZi_IIoT/link.mk b/Ubiquitous/XiZi_IIoT/link.mk index a2bdd07d4..09e643226 100644 --- a/Ubiquitous/XiZi_IIoT/link.mk +++ b/Ubiquitous/XiZi_IIoT/link.mk @@ -3,7 +3,7 @@ OBJS := $(shell cat make.obj) $(TARGET): $(OBJS) @echo ------------------------------------------------ @echo link $(TARGET) - @$(CROSS_COMPILE)g++ -o $@ $($(LINK_FLAGS)) $(OBJS) $(LINK_LWIP) $(LINK_MUSLLIB) $(LIBCC) + @$(CROSS_COMPILE)g++ -o $@ $($(LINK_FLAGS)) $(OBJS) $(LINK_LWIP) $(LINK_MUSLLIB) $(LINK_MONGOOSE) $(LIBCC) @echo ------------------------------------------------ @$(CROSS_COMPILE)objcopy -O binary $@ XiZi-$(BOARD)$(COMPILE_TYPE).bin @$(CROSS_COMPILE)objdump -S $@ > XiZi-$(BOARD)$(COMPILE_TYPE).asm diff --git a/Ubiquitous/XiZi_IIoT/link_mongoose.mk b/Ubiquitous/XiZi_IIoT/link_mongoose.mk new file mode 100644 index 000000000..568c910b0 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/link_mongoose.mk @@ -0,0 +1,9 @@ +OBJS := $(shell cat make.obj) + +$(TARGET): $(OBJS) + @echo ------------------------------------------------ + @echo link $(TARGET) + @$(CROSS_COMPILE)ar -r $@ $(OBJS) + @echo ------------------------------------------------ + @$(CROSS_COMPILE)objcopy $@ $(TARGET) + @$(CROSS_COMPILE)size $@ \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/api/sockets.c b/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/api/sockets.c index 3ddd778f5..5f458d8f0 100644 --- a/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/api/sockets.c +++ b/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/api/sockets.c @@ -640,7 +640,8 @@ lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen) LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d)...\n", s)); sock = get_socket(s); if (!sock) { - return -1; + KPrintf("sock = get_socket(s);\n"); + return -1; } /* wait for a new connection */ @@ -655,6 +656,7 @@ lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen) sock_set_errno(sock, err_to_errno(err)); } done_socket(sock); + KPrintf("err = netconn_accept(sock->conn, &newconn);\n"); return -1; } LWIP_ASSERT("newconn != NULL", newconn != NULL); @@ -664,6 +666,7 @@ lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen) netconn_delete(newconn); sock_set_errno(sock, ENFILE); done_socket(sock); + KPrintf("newsock = alloc_socket(newconn, 1);\n"); return -1; } LWIP_ASSERT("invalid socket index", (newsock >= LWIP_SOCKET_OFFSET) && (newsock < NUM_SOCKETS + LWIP_SOCKET_OFFSET)); @@ -701,6 +704,7 @@ lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen) free_socket(nsock, 1); sock_set_errno(sock, err_to_errno(err)); done_socket(sock); + KPrintf("err = netconn_peer(newconn, &naddr, &port);\n"); return -1; } @@ -1242,6 +1246,8 @@ lwip_recvfrom(int s, void *mem, size_t len, int flags, if (err != ERR_OK) { LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom[UDP/RAW](%d): buf == NULL, error is \"%s\"!\n", s, lwip_strerr(err))); + KPrintf("lwip_recvfrom[UDP/RAW](%d): buf == NULL, error is \"%s\"!\n", + s, lwip_strerr(err)); sock_set_errno(sock, err_to_errno(err)); done_socket(sock); return -1; diff --git a/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/arch/lwipopts.h b/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/arch/lwipopts.h index 72106e022..ffbb51d74 100644 --- a/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/arch/lwipopts.h +++ b/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/arch/lwipopts.h @@ -36,6 +36,7 @@ #ifndef LWIP_DEBUG #define LWIP_DEBUG 1 // #define LWIP_SOCKET_DEBUG +// #define LWIP_SOCKETS_DEBUG // #define LWIP_TCPIP_DEBUG // #define LWIP_MEMP_DEBUG // #define LWIP_PBUF_DEBUG @@ -271,13 +272,16 @@ a lot of data that needs to be copied, this should be set high. */ #define MEMP_NUM_PBUF 32 /* MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One per active UDP "connection". */ -#define MEMP_NUM_UDP_PCB 4 +#define MEMP_NUM_UDP_PCB 32 /* MEMP_NUM_TCP_PCB: the number of simulatenously active TCP connections. */ -#define MEMP_NUM_TCP_PCB 64 +#define MEMP_NUM_TCP_PCB 32 +#define MEMP_NUM_RAW_PCB 32 +#define MEMP_NUM_REASSDATA 32 +#define MEMP_NUM_NETCONN 32 /* MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP connections. */ -#define MEMP_NUM_TCP_PCB_LISTEN 2 +#define MEMP_NUM_TCP_PCB_LISTEN 32 /* MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP segments. */ #define MEMP_NUM_TCP_SEG 256 @@ -383,12 +387,6 @@ a lot of data that needs to be copied, this should be set high. */ /* ---------- ICMP options ---------- */ #define LWIP_ICMP 1 -/* ---------- DHCP options ---------- */ -/* Define LWIP_DHCP to 1 if you want DHCP configuration of - interfaces. DHCP is not implemented in lwIP 0.5.1, however, so - turning this on does currently not work. */ -#define LWIP_DHCP 1 - /* ---------- UDP options ---------- */ #define LWIP_UDP 1 #define UDP_TTL 255 @@ -412,7 +410,7 @@ The STM32F4x7 allows computing and verifying the IP, UDP, TCP and ICMP checksums - To use this feature let the following define uncommented. - To disable it and process by CPU comment the the checksum. */ -#define CHECKSUM_BY_HARDWARE +// #define CHECKSUM_BY_HARDWARE #ifdef CHECKSUM_BY_HARDWARE /* CHECKSUM_GEN_IP==0: Generate checksums by hardware for outgoing IP packets.*/ @@ -520,7 +518,7 @@ The STM32F4x7 allows computing and verifying the IP, UDP, TCP and ICMP checksums /* ---------- DHCP options ---------- */ /* Define LWIP_DHCP to 1 if you want DHCP configuration of interfaces. */ -#define LWIP_DHCP 1 +#define LWIP_DHCP 0 /* 1 if you want to do an ARP check on the offered address (recommended). */ diff --git a/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/arch/sys_arch.c b/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/arch/sys_arch.c index 99b1c8579..788e7e3e3 100644 --- a/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/arch/sys_arch.c +++ b/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/arch/sys_arch.c @@ -76,9 +76,9 @@ char lwip_eth0_ipaddr[20] = { 192, 168, 130, 77 }; char lwip_eth0_netmask[20] = { 255, 255, 254, 0 }; char lwip_eth0_gwaddr[20] = { 192, 168, 130, 1 }; -char lwip_eth1_ipaddr[20] = { 192, 168, 130, 99 }; +char lwip_eth1_ipaddr[20] = { 192, 168, 131, 88 }; char lwip_eth1_netmask[20] = { 255, 255, 254, 0 }; -char lwip_eth1_gwaddr[20] = { 192, 168, 130, 23 }; +char lwip_eth1_gwaddr[20] = { 192, 168, 130, 1 }; char lwip_flag = 0; @@ -93,6 +93,13 @@ sys_sem_t* get_eth_recv_sem() return &g_recv_sem; } +struct netif gnetif2; +sys_sem_t* get_eth_recv_sem2() +{ + static sys_sem_t g_recv_sem = 0; + return &g_recv_sem; +} + void sys_init(void) { // do nothing @@ -332,136 +339,104 @@ ip4_addr_t ipaddr; ip4_addr_t netmask; ip4_addr_t gw; -void lwip_config_input(struct netif* net) +void lwip_config_input(int eport, struct netif* net) { sys_thread_t th_id = 0; - th_id = sys_thread_new("eth_input", ethernetif_input, net, LWIP_TASK_STACK_SIZE, 30); - - // if (th_id >= 0) { - // lw_print("%s %d successfully!\n", __func__, th_id); - // } else { - // lw_print("%s failed!\n", __func__); - // } + if (eport == 0) { + th_id = sys_thread_new("eth_input", ethernetif_input, net, LWIP_TASK_STACK_SIZE, 30); + } else if (eport == 1) { +#ifdef NETIF_ENET1_INIT_FUNC + th_id = sys_thread_new("eth_input2", ethernetif_input2, net, LWIP_TASK_STACK_SIZE, 30); +#endif + } } void lwip_config_tcp(uint8_t enet_port, char* ip, char* mask, char* gw) { - static char is_init = 0; - if (is_init != 0) { - return; + static char is_init_0 = 0; + static char is_init_1 = 0; + if (is_init_0 == 0 && is_init_1 == 0) { + sys_sem_new(get_eth_recv_sem(), 0); + sys_sem_new(get_eth_recv_sem2(), 0); + + if (chk_lwip_bit(LWIP_INIT_FLAG)) { + lw_print("lw: [%s] already ...\n", __func__); + } + + set_lwip_bit(LWIP_INIT_FLAG); + + tcpip_init(NULL, NULL); } - is_init = 1; - - sys_sem_new(get_eth_recv_sem(), 0); - - ip4_addr_t net_ipaddr, net_netmask, net_gw; - char* eth_cfg; - - eth_cfg = ethernetif_config_enet_set(enet_port); - - if (chk_lwip_bit(LWIP_INIT_FLAG)) { - lw_print("lw: [%s] already ...\n", __func__); - return; - } - - set_lwip_bit(LWIP_INIT_FLAG); - - tcpip_init(NULL, NULL); lw_print("lw: [%s] start ...\n", __func__); + char* eth_cfg = ethernetif_config_enet_set(enet_port); + ip4_addr_t net_ipaddr, net_netmask, net_gw; IP4_ADDR(&net_ipaddr, ip[0], ip[1], ip[2], ip[3]); IP4_ADDR(&net_netmask, mask[0], mask[1], mask[2], mask[3]); IP4_ADDR(&net_gw, gw[0], gw[1], gw[2], gw[3]); if (0 == enet_port) { + if (is_init_0 == 1) { + return; + } +#ifndef NETIF_ENET0_INIT_FUNC + lw_print("Not Netif driver for Eport 0\n"); + return; +#endif #ifdef NETIF_ENET0_INIT_FUNC + lw_print("Add netif eport 0\n"); netif_add(&gnetif, &net_ipaddr, &net_netmask, &net_gw, eth_cfg, NETIF_ENET0_INIT_FUNC, tcpip_input); -#endif - } else if (1 == enet_port) { -#ifdef NETIF_ENET1_INIT_FUNC - netif_add(&gnetif, &net_ipaddr, &net_netmask, &net_gw, eth_cfg, NETIF_ENET1_INIT_FUNC, - tcpip_input); -#endif - } - netif_set_default(&gnetif); - netif_set_up(&gnetif); - - lw_print("\r\n************************************************\r\n"); - lw_print(" Network Configuration\r\n"); - lw_print("************************************************\r\n"); - lw_print(" IPv4 Address : %u.%u.%u.%u\r\n", ((u8_t*)&net_ipaddr)[0], ((u8_t*)&net_ipaddr)[1], - ((u8_t*)&net_ipaddr)[2], ((u8_t*)&net_ipaddr)[3]); - lw_print(" IPv4 Subnet mask : %u.%u.%u.%u\r\n", ((u8_t*)&net_netmask)[0], ((u8_t*)&net_netmask)[1], - ((u8_t*)&net_netmask)[2], ((u8_t*)&net_netmask)[3]); - lw_print(" IPv4 Gateway : %u.%u.%u.%u\r\n", ((u8_t*)&net_gw)[0], ((u8_t*)&net_gw)[1], - ((u8_t*)&net_gw)[2], ((u8_t*)&net_gw)[3]); - lw_print("************************************************\r\n"); - - lwip_config_input(&gnetif); -} - -void lwip_config_net(uint8_t enet_port, char* ip, char* mask, char* gw) -{ - ip4_addr_t net_ipaddr, net_netmask, net_gw; - char* eth_cfg; - - eth_cfg = ethernetif_config_enet_set(enet_port); - - if (chk_lwip_bit(LWIP_INIT_FLAG)) { - lw_print("lw: [%s] already ...\n", __func__); - - IP4_ADDR(&net_ipaddr, ip[0], ip[1], ip[2], ip[3]); - IP4_ADDR(&net_netmask, mask[0], mask[1], mask[2], mask[3]); - IP4_ADDR(&net_gw, gw[0], gw[1], gw[2], gw[3]); - - // update ip addr - netif_set_down(&gnetif); - netif_set_gw(&gnetif, &net_gw); - netif_set_netmask(&gnetif, &net_netmask); - netif_set_ipaddr(&gnetif, &net_ipaddr); + netif_set_default(&gnetif); netif_set_up(&gnetif); - return; - } - set_lwip_bit(LWIP_INIT_FLAG); - lw_print("lw: [%s] start ...\n", __func__); - - IP4_ADDR(&net_ipaddr, ip[0], ip[1], ip[2], ip[3]); - IP4_ADDR(&net_netmask, mask[0], mask[1], mask[2], mask[3]); - IP4_ADDR(&net_gw, gw[0], gw[1], gw[2], gw[3]); - - lwip_init(); - - if (0 == enet_port) { -#ifdef NETIF_ENET0_INIT_FUNC - netif_add(&gnetif, &net_ipaddr, &net_netmask, &net_gw, eth_cfg, NETIF_ENET0_INIT_FUNC, - ethernet_input); -#endif - } else if (1 == enet_port) { -#ifdef NETIF_ENET1_INIT_FUNC - netif_add(&gnetif, &net_ipaddr, &net_netmask, &net_gw, eth_cfg, NETIF_ENET1_INIT_FUNC, - ethernet_input); -#endif - } - - netif_set_default(&gnetif); - netif_set_up(&gnetif); - - if (chk_lwip_bit(LWIP_PRINT_FLAG)) { - lw_notice("\r\n************************************************\r\n"); - lw_notice(" Network Configuration\r\n"); - lw_notice("************************************************\r\n"); - lw_notice(" IPv4 Address : %u.%u.%u.%u\r\n", ((u8_t*)&net_ipaddr)[0], ((u8_t*)&net_ipaddr)[1], + lw_print("\r\n************************************************\r\n"); + lw_print(" Network Configuration\r\n"); + lw_print("************************************************\r\n"); + lw_print(" IPv4 Address : %u.%u.%u.%u\r\n", ((u8_t*)&net_ipaddr)[0], ((u8_t*)&net_ipaddr)[1], ((u8_t*)&net_ipaddr)[2], ((u8_t*)&net_ipaddr)[3]); - lw_notice(" IPv4 Subnet mask : %u.%u.%u.%u\r\n", ((u8_t*)&net_netmask)[0], ((u8_t*)&net_netmask)[1], + lw_print(" IPv4 Subnet mask : %u.%u.%u.%u\r\n", ((u8_t*)&net_netmask)[0], ((u8_t*)&net_netmask)[1], ((u8_t*)&net_netmask)[2], ((u8_t*)&net_netmask)[3]); - lw_notice(" IPv4 Gateway : %u.%u.%u.%u\r\n", ((u8_t*)&net_gw)[0], ((u8_t*)&net_gw)[1], + lw_print(" IPv4 Gateway : %u.%u.%u.%u\r\n", ((u8_t*)&net_gw)[0], ((u8_t*)&net_gw)[1], ((u8_t*)&net_gw)[2], ((u8_t*)&net_gw)[3]); - lw_notice("************************************************\r\n"); + lw_print("************************************************\r\n"); + + lwip_config_input(enet_port, &gnetif); + is_init_0 = 1; +#endif + + } else if (1 == enet_port) { + if (is_init_1 == 1) { + return; + } +#ifndef NETIF_ENET1_INIT_FUNC + lw_print("Not Netif driver for Eport 1\n"); + return; +#endif +#ifdef NETIF_ENET1_INIT_FUNC + lw_print("Add netif eport 1\n"); + netif_add(&gnetif2, &net_ipaddr, &net_netmask, &net_gw, eth_cfg, NETIF_ENET1_INIT_FUNC, + tcpip_input); + + // netif_set_default(&gnetif2); + netif_set_up(&gnetif2); + + lw_print("\r\n************************************************\r\n"); + lw_print(" Network Configuration\r\n"); + lw_print("************************************************\r\n"); + lw_print(" IPv4 Address : %u.%u.%u.%u\r\n", ((u8_t*)&net_ipaddr)[0], ((u8_t*)&net_ipaddr)[1], + ((u8_t*)&net_ipaddr)[2], ((u8_t*)&net_ipaddr)[3]); + lw_print(" IPv4 Subnet mask : %u.%u.%u.%u\r\n", ((u8_t*)&net_netmask)[0], ((u8_t*)&net_netmask)[1], + ((u8_t*)&net_netmask)[2], ((u8_t*)&net_netmask)[3]); + lw_print(" IPv4 Gateway : %u.%u.%u.%u\r\n", ((u8_t*)&net_gw)[0], ((u8_t*)&net_gw)[1], + ((u8_t*)&net_gw)[2], ((u8_t*)&net_gw)[3]); + lw_print("************************************************\r\n"); + + lwip_config_input(enet_port, &gnetif2); + is_init_1 = 1; +#endif } - lwip_config_input(&gnetif); -} +} \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/arch/sys_arch.h b/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/arch/sys_arch.h index 384b85b1a..bbcef28ac 100644 --- a/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/arch/sys_arch.h +++ b/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/arch/sys_arch.h @@ -101,6 +101,8 @@ extern char lwip_eth1_gwaddr[]; extern struct netif gnetif; extern sys_sem_t* get_eth_recv_sem(); +extern struct netif gnetif2; +extern sys_sem_t* get_eth_recv_sem2(); void lwip_tcp_init(void); void lwip_config_net(uint8_t enet_port, char *ip, char *mask, char *gw); diff --git a/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/core/ipv4/ip4.c b/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/core/ipv4/ip4.c index 036457afe..3cb0ca16f 100644 --- a/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/core/ipv4/ip4.c +++ b/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/core/ipv4/ip4.c @@ -228,6 +228,95 @@ ip4_route(const ip4_addr_t *dest) return netif_default; } +/** + * Finds the appropriate network interface for a given IP address. It + * searches the list of network interfaces linearly. A match is found + * if the masked IP address of the network interface equals the masked + * IP address given to the function. + * + * @param dest the destination IP address for which to find the route + * @return the netif on which to send to reach dest + */ +struct netif* +ip4_route2(const ip4_addr_t* src, const ip4_addr_t* dest) +{ +#if !LWIP_SINGLE_NETIF + struct netif* netif; + LWIP_ASSERT_CORE_LOCKED(); + +#if LWIP_MULTICAST_TX_OPTIONS + /* Use administratively selected interface for multicast by default */ + if (ip4_addr_ismulticast(dest) && ip4_default_multicast_netif) { + return ip4_default_multicast_netif; + } +#endif /* LWIP_MULTICAST_TX_OPTIONS */ + + /* bug #54569: in case LWIP_SINGLE_NETIF=1 and LWIP_DEBUGF() disabled, the following loop is optimized away */ + LWIP_UNUSED_ARG(dest); + + /* iterate through netifs */ + NETIF_FOREACH(netif) + { + /* is the netif up, does it have a link and a valid address? */ + if (netif_is_up(netif) && netif_is_link_up(netif) && !ip4_addr_isany_val(*netif_ip4_addr(netif))) { + + /* network mask matches? */ + // if (ip4_addr_netcmp(dest, netif_ip4_addr(netif), netif_ip4_netmask(netif))) { + if (ip4_addr_cmp(src, netif_ip4_addr(netif))) { + /* return netif on which to forward IP packet */ + return netif; + } + /* gateway matches on a non broadcast interface? (i.e. peer in a point to point interface) */ + if (((netif->flags & NETIF_FLAG_BROADCAST) == 0) && ip4_addr_cmp(dest, netif_ip4_gw(netif))) { + /* return netif on which to forward IP packet */ + return netif; + } + } + } + +#if LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF + /* loopif is disabled, looopback traffic is passed through any netif */ + if (ip4_addr_isloopback(dest)) { + /* don't check for link on loopback traffic */ + if (netif_default != NULL && netif_is_up(netif_default)) { + return netif_default; + } + /* default netif is not up, just use any netif for loopback traffic */ + NETIF_FOREACH(netif) + { + if (netif_is_up(netif)) { + return netif; + } + } + return NULL; + } +#endif /* LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF */ + +#ifdef LWIP_HOOK_IP4_ROUTE_SRC + netif = LWIP_HOOK_IP4_ROUTE_SRC(NULL, dest); + if (netif != NULL) { + return netif; + } +#elif defined(LWIP_HOOK_IP4_ROUTE) + netif = LWIP_HOOK_IP4_ROUTE(dest); + if (netif != NULL) { + return netif; + } +#endif +#endif /* !LWIP_SINGLE_NETIF */ + + if ((netif_default == NULL) || !netif_is_up(netif_default) || !netif_is_link_up(netif_default) || ip4_addr_isany_val(*netif_ip4_addr(netif_default)) || ip4_addr_isloopback(dest)) { + /* No matching netif found and default netif is not usable. + If this is not good enough for you, use LWIP_HOOK_IP4_ROUTE() */ + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip4_route: No route to %" U16_F ".%" U16_F ".%" U16_F ".%" U16_F "\n", ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest))); + IP_STATS_INC(ip.rterr); + MIB2_STATS_INC(mib2.ipoutnoroutes); + return NULL; + } + + return netif_default; +} + #if IP_FORWARD /** * Determine whether an IP address is in a reserved set of addresses diff --git a/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/include/lwip/ip4.h b/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/include/lwip/ip4.h index fd35a3369..d3789a9be 100644 --- a/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/include/lwip/ip4.h +++ b/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/include/lwip/ip4.h @@ -63,39 +63,41 @@ extern "C" { #define ip_init() /* Compatibility define, no init needed. */ struct netif *ip4_route(const ip4_addr_t *dest); +struct netif* ip4_route2(const ip4_addr_t* src, const ip4_addr_t* dest); #if LWIP_IPV4_SRC_ROUTING -struct netif *ip4_route_src(const ip4_addr_t *src, const ip4_addr_t *dest); +struct netif* ip4_route_src(const ip4_addr_t* src, const ip4_addr_t* dest); #else /* LWIP_IPV4_SRC_ROUTING */ -#define ip4_route_src(src, dest) ip4_route(dest) +// #define ip4_route_src(src, dest) ip4_route(dest) +#define ip4_route_src(src, dest) ip4_route2(src, dest) #endif /* LWIP_IPV4_SRC_ROUTING */ -err_t ip4_input(struct pbuf *p, struct netif *inp); -err_t ip4_output(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, - u8_t ttl, u8_t tos, u8_t proto); -err_t ip4_output_if(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, - u8_t ttl, u8_t tos, u8_t proto, struct netif *netif); -err_t ip4_output_if_src(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, - u8_t ttl, u8_t tos, u8_t proto, struct netif *netif); +err_t ip4_input(struct pbuf* p, struct netif* inp); +err_t ip4_output(struct pbuf* p, const ip4_addr_t* src, const ip4_addr_t* dest, + u8_t ttl, u8_t tos, u8_t proto); +err_t ip4_output_if(struct pbuf* p, const ip4_addr_t* src, const ip4_addr_t* dest, + u8_t ttl, u8_t tos, u8_t proto, struct netif* netif); +err_t ip4_output_if_src(struct pbuf* p, const ip4_addr_t* src, const ip4_addr_t* dest, + u8_t ttl, u8_t tos, u8_t proto, struct netif* netif); #if LWIP_NETIF_USE_HINTS -err_t ip4_output_hinted(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, - u8_t ttl, u8_t tos, u8_t proto, struct netif_hint *netif_hint); + err_t ip4_output_hinted(struct pbuf* p, const ip4_addr_t* src, const ip4_addr_t* dest, + u8_t ttl, u8_t tos, u8_t proto, struct netif_hint* netif_hint); #endif /* LWIP_NETIF_USE_HINTS */ #if IP_OPTIONS_SEND -err_t ip4_output_if_opt(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, - u8_t ttl, u8_t tos, u8_t proto, struct netif *netif, void *ip_options, - u16_t optlen); -err_t ip4_output_if_opt_src(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, - u8_t ttl, u8_t tos, u8_t proto, struct netif *netif, void *ip_options, - u16_t optlen); + err_t ip4_output_if_opt(struct pbuf* p, const ip4_addr_t* src, const ip4_addr_t* dest, + u8_t ttl, u8_t tos, u8_t proto, struct netif* netif, void* ip_options, + u16_t optlen); + err_t ip4_output_if_opt_src(struct pbuf* p, const ip4_addr_t* src, const ip4_addr_t* dest, + u8_t ttl, u8_t tos, u8_t proto, struct netif* netif, void* ip_options, + u16_t optlen); #endif /* IP_OPTIONS_SEND */ #if LWIP_MULTICAST_TX_OPTIONS -void ip4_set_default_multicast_netif(struct netif* default_multicast_netif); + void ip4_set_default_multicast_netif(struct netif* default_multicast_netif); #endif /* LWIP_MULTICAST_TX_OPTIONS */ #define ip4_netif_get_local_ip(netif) (((netif) != NULL) ? netif_ip_addr4(netif) : NULL) #if IP_DEBUG -void ip4_debug_print(struct pbuf *p); + void ip4_debug_print(struct pbuf* p); #else #define ip4_debug_print(p) #endif /* IP_DEBUG */ diff --git a/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/include/lwip/opt.h b/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/include/lwip/opt.h index a304c67c2..55c840233 100644 --- a/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/include/lwip/opt.h +++ b/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/include/lwip/opt.h @@ -521,7 +521,7 @@ * (only needed if you use the sequential API, like api_lib.c) */ #if !defined MEMP_NUM_NETBUF || defined __DOXYGEN__ -#define MEMP_NUM_NETBUF 2 +#define MEMP_NUM_NETBUF 8 #endif /** @@ -529,7 +529,7 @@ * (only needed if you use the sequential API, like api_lib.c) */ #if !defined MEMP_NUM_NETCONN || defined __DOXYGEN__ -#define MEMP_NUM_NETCONN 4 +#define MEMP_NUM_NETCONN 8 #endif /** @@ -538,7 +538,7 @@ * In that case, you need one per thread calling lwip_select.) */ #if !defined MEMP_NUM_SELECT_CB || defined __DOXYGEN__ -#define MEMP_NUM_SELECT_CB 4 +#define MEMP_NUM_SELECT_CB 4 #endif /** @@ -547,7 +547,7 @@ * (only needed if you use tcpip.c) */ #if !defined MEMP_NUM_TCPIP_MSG_API || defined __DOXYGEN__ -#define MEMP_NUM_TCPIP_MSG_API 8 +#define MEMP_NUM_TCPIP_MSG_API 8 #endif /** @@ -556,7 +556,7 @@ * (only needed if you use tcpip.c) */ #if !defined MEMP_NUM_TCPIP_MSG_INPKT || defined __DOXYGEN__ -#define MEMP_NUM_TCPIP_MSG_INPKT 8 +#define MEMP_NUM_TCPIP_MSG_INPKT 8 #endif /** @@ -564,7 +564,7 @@ * (before freeing the corresponding memory using lwip_freeaddrinfo()). */ #if !defined MEMP_NUM_NETDB || defined __DOXYGEN__ -#define MEMP_NUM_NETDB 1 +#define MEMP_NUM_NETDB 2 #endif /** @@ -572,7 +572,7 @@ * if DNS_LOCAL_HOSTLIST_IS_DYNAMIC==1. */ #if !defined MEMP_NUM_LOCALHOSTLIST || defined __DOXYGEN__ -#define MEMP_NUM_LOCALHOSTLIST 1 +#define MEMP_NUM_LOCALHOSTLIST 2 #endif /** diff --git a/Ubiquitous/XiZi_IIoT/resources/ethernet/cmd_lwip/Makefile b/Ubiquitous/XiZi_IIoT/resources/ethernet/cmd_lwip/Makefile index 5cb85ac11..a10fe9679 100755 --- a/Ubiquitous/XiZi_IIoT/resources/ethernet/cmd_lwip/Makefile +++ b/Ubiquitous/XiZi_IIoT/resources/ethernet/cmd_lwip/Makefile @@ -1,4 +1,4 @@ # SRC_FILES := ping.c lwip_ping_demo.c lwip_config_demo.c lwip_dhcp_demo.c iperf.c http_test.c -SRC_FILES := ping.c lwip_ping_demo.c lwip_udp_demo.c tcpecho_raw.c lwip_config_demo.c lwip_dhcp_demo.c +SRC_FILES := ping.c lwip_ping_demo.c tcpecho_raw.c lwip_config_demo.c include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/resources/ethernet/cmd_lwip/lwip_config_demo.c b/Ubiquitous/XiZi_IIoT/resources/ethernet/cmd_lwip/lwip_config_demo.c index b1b145648..1d6aa94e8 100755 --- a/Ubiquitous/XiZi_IIoT/resources/ethernet/cmd_lwip/lwip_config_demo.c +++ b/Ubiquitous/XiZi_IIoT/resources/ethernet/cmd_lwip/lwip_config_demo.c @@ -25,104 +25,145 @@ #include #include -#include +#include "argparse.h" + +#include "inet.h" +#include "netdev.h" /******************************************************************************/ -uint8_t enet_id = 0; -static void LwipSetIPTask(void* param) -{ - uint8_t enet_port = *(uint8_t*)param; ///< test enet port - printf("lw: [%s] config netport id[%d]\n", __func__, enet_port); - // lwip_config_net(enet_port, lwip_ipaddr, lwip_netmask, lwip_gwaddr); - lwip_config_tcp(enet_port, lwip_ipaddr, lwip_netmask, lwip_gwaddr); -} +enum NETWORK_ACTIVE_E { + LWIP_ACTIVE = 'e', + LWIP_ACTIVE_ALL = 'a', +}; -void LwipSetIPTest(int argc, char* argv[]) +void LwipNetworkActive(int argc, char* argv[]) { - if (argc >= 4) { - printf("lw: [%s] ip %s mask %s gw %s netport %s\n", __func__, argv[1], argv[2], argv[3], argv[4]); - sscanf(argv[1], "%hhd.%hhd.%hhd.%hhd", &lwip_ipaddr[0], &lwip_ipaddr[1], &lwip_ipaddr[2], &lwip_ipaddr[3]); - sscanf(argv[2], "%hhd.%hhd.%hhd.%hhd", &lwip_netmask[0], &lwip_netmask[1], &lwip_netmask[2], &lwip_netmask[3]); - sscanf(argv[3], "%hhd.%hhd.%hhd.%hhd", &lwip_gwaddr[0], &lwip_gwaddr[1], &lwip_gwaddr[2], &lwip_gwaddr[3]); - sscanf(argv[4], "%hhd", &enet_id); + static char usage_info[] = "select a eport to start."; + static char program_info[] = "Active lwip network function."; + static const char* const net_active_usages[] = { + "LwipNetworkActive -e 0", + "LwipNetworkActive -e 1", + "LwipNetworkActive -a", + }; - if (0 == enet_id) { - printf("save eth0 info\n"); - memcpy(lwip_eth0_ipaddr, lwip_ipaddr, 20); - memcpy(lwip_eth0_netmask, lwip_netmask, 20); - memcpy(lwip_eth0_gwaddr, lwip_gwaddr, 20); - } else if (1 == enet_id) { - printf("save eth1 info\n"); - memcpy(lwip_eth1_ipaddr, lwip_ipaddr, 20); - memcpy(lwip_eth1_netmask, lwip_netmask, 20); - memcpy(lwip_eth1_gwaddr, lwip_gwaddr, 20); - } - } else if (argc == 2) { - printf("lw: [%s] set eth0 ipaddr %s \n", __func__, argv[1]); - sscanf(argv[1], "%hhd.%hhd.%hhd.%hhd", &lwip_ipaddr[0], &lwip_ipaddr[1], &lwip_ipaddr[2], &lwip_ipaddr[3]); - memcpy(lwip_eth0_ipaddr, lwip_ipaddr, strlen(lwip_ipaddr)); + int eport = -1; + bool all = false; + bool is_help = false; + struct argparse_option options[] = { + OPT_HELP(&is_help), + OPT_INTEGER(LWIP_ACTIVE, "eport", &eport, "eport to start network.", NULL, 0, 0), + OPT_BIT(LWIP_ACTIVE_ALL, "all", &all, "start network at both eport 0 and 1.", NULL, true, 0), + OPT_END(), + }; + + struct argparse argparse; + argparse_init(&argparse, options, net_active_usages, 0); + argparse_describe(&argparse, usage_info, program_info); + argc = argparse_parse(&argparse, argc, (const char**)argv); + if (is_help) { + return; } - // sys_thread_new("SET ip address", LwipSetIPTask, &enet_id, LWIP_TASK_STACK_SIZE, LWIP_DEMO_TASK_PRIO); - LwipSetIPTask(&enet_id); -} + if (all) { + lwip_config_tcp(0, lwip_eth0_ipaddr, lwip_eth0_netmask, lwip_eth0_gwaddr); + lwip_config_tcp(1, lwip_eth1_ipaddr, lwip_eth1_netmask, lwip_eth1_gwaddr); + return; + } + + if (eport != 0 && eport != 1) { + printf("[%s] Err: Support only eport 0 and eport 1.\n", __func__); + } + + if (eport == 0) { + lwip_config_tcp(0, lwip_eth0_ipaddr, lwip_eth0_netmask, lwip_eth0_gwaddr); + } else if (eport == 1) { + lwip_config_tcp(1, lwip_eth1_ipaddr, lwip_eth1_netmask, lwip_eth1_gwaddr); + } +} SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(5), - setip, LwipSetIPTest, setip[IP][Netmask][Gateway][port]); + LwipNetworkActive, LwipNetworkActive, start lwip); -void LwipShowIPTask(int argc, char* argv[]) +enum NETWORK_CONFIG_E { + NETWORK_DEV = 'd', + NETWORK_IP = 'i', + NETWORK_NM = 'n', + NETWORK_GW = 'g', +}; + +void LwipSetNetwork(int argc, char* argv[]) { -#ifdef configMAC_ADDR - char mac_addr0[] = configMAC_ADDR; -#endif + static char usage_info[] = "config network information."; + static char program_info[] = "set network ip, netmask, gateway"; + static const char* const net_set_usages[] = { + "LwipSetNetwork -d [dev] -i [ip]", + "LwipSetNetwork -d [dev] -n [netmask]", + "LwipSetNetwork -d [dev] -g [gw]", + "LwipSetNetwork -d [dev] -i [ip] -n [netmask] -g [gw]", + }; - // find default netdev - struct netdev* netdev = netdev_get_by_name("en\0"); + char* dev_ptr = NULL; + char* ip_ptr = NULL; + char* nm_ptr = NULL; + char* gw_ptr = NULL; + bool is_help = false; + struct argparse_option options[] = { + OPT_HELP(&is_help), + OPT_GROUP("Param Options"), + OPT_STRING(NETWORK_DEV, "dev", &dev_ptr, "netdev", NULL, 0, 0), + OPT_STRING(NETWORK_IP, "ip", &ip_ptr, "change ip", NULL, 0, 0), + OPT_STRING(NETWORK_NM, "nm", &nm_ptr, "change netmask", NULL, 0, 0), + OPT_STRING(NETWORK_GW, "gw", &gw_ptr, "change gateway", NULL, 0, 0), + OPT_END(), + }; + + struct argparse argparse; + argparse_init(&argparse, options, net_set_usages, 0); + argparse_describe(&argparse, usage_info, program_info); + argc = argparse_parse(&argparse, argc, (const char**)argv); + /* help task */ + if (is_help) { + return; + } + + if (dev_ptr == NULL) { + printf("[%s] Err: must given a netdev name.\n", __func__); + return; + } + struct netdev* netdev = netdev_get_by_name(dev_ptr); if (netdev == NULL) { - lw_notice("[%s] Netdev not found by name en\n"); - struct netdev* default_netdev = NETDEV_DEFAULT; + printf("[%s] Err: Netdev not found by name: %s\n", __func__, dev_ptr); + return; } - lw_notice("\r\n************************************************\r\n"); - lw_notice(" Network Configuration\r\n"); - lw_notice("************************************************\r\n"); - // lw_notice(" ETH0 IPv4 Address : %u.%u.%u.%u\r\n", ((u8_t*)&lwip_eth0_ipaddr)[0], ((u8_t*)&lwip_eth0_ipaddr)[1], - // ((u8_t*)&lwip_eth0_ipaddr)[2], ((u8_t*)&lwip_eth0_ipaddr)[3]); - // lw_notice(" ETH0 IPv4 Subnet mask : %u.%u.%u.%u\r\n", ((u8_t*)&lwip_eth0_netmask)[0], ((u8_t*)&lwip_eth0_netmask)[1], - // ((u8_t*)&lwip_eth0_netmask)[2], ((u8_t*)&lwip_eth0_netmask)[3]); - // lw_notice(" ETH0 IPv4 Gateway : %u.%u.%u.%u\r\n", ((u8_t*)&lwip_gwaddr)[0], ((u8_t*)&lwip_eth0_gwaddr)[1], - // ((u8_t*)&lwip_eth0_gwaddr)[2], ((u8_t*)&lwip_eth0_gwaddr)[3]); - // #ifdef configMAC_ADDR - // lw_notice(" ETH0 MAC Address : %x:%x:%x:%x:%x:%x\r\n", mac_addr0[0], mac_addr0[1], mac_addr0[2], - // mac_addr0[3], mac_addr0[4], mac_addr0[5]); - // #endif - - lw_notice(" ETH0 IPv4 Address : %u.%u.%u.%u\r\n", ((u8_t*)&lwip_eth0_ipaddr)[0], ((u8_t*)&lwip_eth0_ipaddr)[1], - ((u8_t*)&lwip_eth0_ipaddr)[2], ((u8_t*)&lwip_eth0_ipaddr)[3]); - lw_notice(" ETH0 IPv4 Subnet mask : %u.%u.%u.%u\r\n", ((u8_t*)&lwip_eth0_netmask)[0], ((u8_t*)&lwip_eth0_netmask)[1], - ((u8_t*)&lwip_eth0_netmask)[2], ((u8_t*)&lwip_eth0_netmask)[3]); - lw_notice(" ETH0 IPv4 Gateway : %u.%u.%u.%u\r\n", ((u8_t*)&lwip_gwaddr)[0], ((u8_t*)&lwip_eth0_gwaddr)[1], - ((u8_t*)&lwip_eth0_gwaddr)[2], ((u8_t*)&lwip_eth0_gwaddr)[3]); -#ifdef configMAC_ADDR - lw_notice(" ETH0 MAC Address : %x:%x:%x:%x:%x:%x\r\n", mac_addr0[0], mac_addr0[1], mac_addr0[2], - mac_addr0[3], mac_addr0[4], mac_addr0[5]); -#endif - -#ifdef BOARD_NET_COUNT - if (BOARD_NET_COUNT > 1) { - char mac_addr1[] = configMAC_ADDR_ETH1; - lw_notice("\r\n"); - lw_notice(" ETH1 IPv4 Address : %u.%u.%u.%u\r\n", ((u8_t*)&lwip_eth1_ipaddr)[0], ((u8_t*)&lwip_eth1_ipaddr)[1], - ((u8_t*)&lwip_eth1_ipaddr)[2], ((u8_t*)&lwip_eth1_ipaddr)[3]); - lw_notice(" ETH1 IPv4 Subnet mask : %u.%u.%u.%u\r\n", ((u8_t*)&lwip_eth1_netmask)[0], ((u8_t*)&lwip_eth1_netmask)[1], - ((u8_t*)&lwip_eth1_netmask)[2], ((u8_t*)&lwip_eth1_netmask)[3]); - lw_notice(" ETH1 IPv4 Gateway : %u.%u.%u.%u\r\n", ((u8_t*)&lwip_eth1_gwaddr)[0], ((u8_t*)&lwip_eth1_gwaddr)[1], - ((u8_t*)&lwip_eth1_gwaddr)[2], ((u8_t*)&lwip_eth1_gwaddr)[3]); - lw_notice(" ETH1 MAC Address : %x:%x:%x:%x:%x:%x\r\n", mac_addr1[0], mac_addr1[1], mac_addr1[2], - mac_addr1[3], mac_addr1[4], mac_addr1[5]); + ip_addr_t ipaddr, maskaddr, gwaddr; + if (ip_ptr != NULL) { + inet_aton(ip_ptr, &ipaddr); + if (0 != netdev_set_ipaddr(netdev, &ipaddr)) { + printf("[%s] Err: set ip: %s failed.\n", __func__, ip_ptr); + } } -#endif - lw_notice("************************************************\r\n"); + if (nm_ptr != NULL) { + inet_aton(nm_ptr, &maskaddr); + if (0 != netdev_set_netmask(netdev, &maskaddr)) { + printf("[%s] Err: set netmask: %s failed.\n", __func__, nm_ptr); + } + } + if (gw_ptr != NULL) { + inet_aton(gw_ptr, &gwaddr); + if (0 != netdev_set_gw(netdev, &gwaddr)) { + printf("[%s] Err: set gateway: %s failed.\n", __func__, gw_ptr); + } + } +} + +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(11), + LwipSetNetwork, LwipSetNetwork, config lwip); + +void LwipShowNetwork(int argc, char* argv[]) +{ + extern void netdev_list_dev(); + netdev_list_dev(); } SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(0), - showip, LwipShowIPTask, GetIp[IP][Netmask][Gateway]); + LwipShowNetwork, LwipShowNetwork, show lwip network configuration); diff --git a/Ubiquitous/XiZi_IIoT/resources/ethernet/netdev/netdev_lowlevel.c b/Ubiquitous/XiZi_IIoT/resources/ethernet/netdev/netdev_lowlevel.c index c1d4e0fa4..8cd2b0fde 100644 --- a/Ubiquitous/XiZi_IIoT/resources/ethernet/netdev/netdev_lowlevel.c +++ b/Ubiquitous/XiZi_IIoT/resources/ethernet/netdev/netdev_lowlevel.c @@ -43,8 +43,8 @@ void netdev_low_level_set_ipaddr(struct netdev* netdev, const ip_addr_t* ip_addr { CHECK(ip_addr); - if (netdev && ip_addr_cmp(&(netdev->ip_addr), ip_addr) == 0) { - ip_addr_copy(netdev->ip_addr, *ip_addr); + if (netdev && ip_addr_cmp((netdev->ip_addr), ip_addr) == 0) { + ip_addr_copy(*netdev->ip_addr, *ip_addr); /* execute IP address change callback function */ if (netdev->addr_callback) { @@ -64,8 +64,8 @@ void netdev_low_level_set_netmask(struct netdev* netdev, const ip_addr_t* netmas { CHECK(netmask); - if (netdev && ip_addr_cmp(&(netdev->netmask), netmask) == 0) { - ip_addr_copy(netdev->netmask, *netmask); + if (netdev && ip_addr_cmp((netdev->netmask), netmask) == 0) { + ip_addr_copy(*netdev->netmask, *netmask); /* execute netmask address change callback function */ if (netdev->addr_callback) { @@ -85,8 +85,8 @@ void netdev_low_level_set_gw(struct netdev* netdev, const ip_addr_t* gw) { CHECK(gw); - if (netdev && ip_addr_cmp(&(netdev->gw), gw) == 0) { - ip_addr_copy(netdev->gw, *gw); + if (netdev && ip_addr_cmp((netdev->gw), gw) == 0) { + ip_addr_copy(*netdev->gw, *gw); /* execute gateway address change callback function */ if (netdev->addr_callback) { diff --git a/Ubiquitous/XiZi_IIoT/resources/ethernet/netdev/netdev_manipulate.c b/Ubiquitous/XiZi_IIoT/resources/ethernet/netdev/netdev_manipulate.c index 97e15d3a1..283261a1b 100644 --- a/Ubiquitous/XiZi_IIoT/resources/ethernet/netdev/netdev_manipulate.c +++ b/Ubiquitous/XiZi_IIoT/resources/ethernet/netdev/netdev_manipulate.c @@ -28,8 +28,12 @@ Modification: 1. support net dev set-ip, set-netmask, set-gw, set-addr-callback, set-status-callback, set-up and set-down *************************************************/ +#include + #include #include + +#include #include #include @@ -273,7 +277,7 @@ struct netdev* netdev_get_by_ipaddr(ip_addr_t* ip_addr) struct netdev* current_dev = NETDEV_LISTHEAD; SINGLE_LINKLIST_FOR_EACH_ENTRY(current_dev, &(NETDEV_LISTHEAD->list), list) { - if (NULL != current_dev && ip_addr_cmp(&(current_dev->ip_addr), ip_addr)) { + if (NULL != current_dev && ip_addr_cmp((current_dev->ip_addr), ip_addr)) { ENABLE_INTERRUPT(lock); return current_dev; } @@ -298,6 +302,8 @@ struct netdev* netdev_get_by_name(const char* name) return NULL; } + uint32_t search_name_len = strlen(name); + SYS_KDEBUG_LOG(NETDEV_DEBUG, ("Netdev search name: %s, len: %d\n", name, search_name_len)); // get netdev from list x_base lock = DISABLE_INTERRUPT(); struct netdev* current_dev = NETDEV_LISTHEAD; @@ -306,8 +312,10 @@ struct netdev* netdev_get_by_name(const char* name) if (NULL == current_dev) { continue; } + uint32_t name_len = strlen(current_dev->name); - if (NULL != current_dev && (strncmp(current_dev->name, name, strlen(current_dev->name) < NAME_NUM_MAX ? strlen(current_dev->name) : NAME_NUM_MAX) == 0)) { + SYS_KDEBUG_LOG(NETDEV_DEBUG, ("Netdev current dev name: %s, len: %d\n", current_dev->name, name_len)); + if (NULL != current_dev && name_len == search_name_len && 0 == strncmp(current_dev->name, name, name_len)) { ENABLE_INTERRUPT(lock); return current_dev; } @@ -316,3 +324,35 @@ struct netdev* netdev_get_by_name(const char* name) return NULL; } + +void netdev_list_dev() +{ + if (NETDEV_LISTHEAD == NULL) { + return; + } + + char ip[IP4ADDR_STRLEN_MAX], netmask[IP4ADDR_STRLEN_MAX], gw[IP4ADDR_STRLEN_MAX], dns[IP4ADDR_STRLEN_MAX]; + + // get netdev from list + x_base lock = DISABLE_INTERRUPT(); + struct netdev* current_dev = NETDEV_LISTHEAD; + SINGLE_LINKLIST_FOR_EACH_ENTRY(current_dev, &(NETDEV_LISTHEAD->list), list) + { + if (NULL == current_dev) { + continue; + } + + strncpy(ip, inet_ntoa(*current_dev->ip_addr), IP4ADDR_STRLEN_MAX); + strncpy(netmask, inet_ntoa(*current_dev->netmask), IP4ADDR_STRLEN_MAX); + strncpy(gw, inet_ntoa(*current_dev->gw), IP4ADDR_STRLEN_MAX); + strncpy(dns, inet_ntoa(current_dev->dns_servers[0]), IP4ADDR_STRLEN_MAX); + KPrintf("Netdev %s: ip: %s, mask: %s, gw: %s, dns: %s\n", + current_dev->name, + ip, netmask, gw, dns); + } + ENABLE_INTERRUPT(lock); + + return; +} +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(5), + netdev_list, netdev_list_dev, list sys netdev); \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/resources/ethernet/netdev/netdev_register.c b/Ubiquitous/XiZi_IIoT/resources/ethernet/netdev/netdev_register.c index 73ef0ed88..e6196feb6 100644 --- a/Ubiquitous/XiZi_IIoT/resources/ethernet/netdev/netdev_register.c +++ b/Ubiquitous/XiZi_IIoT/resources/ethernet/netdev/netdev_register.c @@ -38,7 +38,16 @@ Modification: struct netdev** get_netdev_listhead() { - static struct netdev* netdev_listhead = NULL; + static bool init = false; + static struct netdev* netdev_listhead; + if (!init) { + static struct netdev netdev_guard; + strncpy(netdev_guard.name, "guard\0", 6); + InitSingleLinkList(&(netdev_guard.list)); + netdev_listhead = &netdev_guard; + } + init = true; + return &netdev_listhead; } struct netdev** get_default_netdev() @@ -56,17 +65,13 @@ int netdev_register(struct netdev* netdev, const char* name, void* user_data) // set flag mask, assert network is down uint16_t flag_mask = 0; - flag_mask = NETDEV_FLAG_UP | NETDEV_FLAG_LINK_UP | NETDEV_FLAG_INTERNET_UP | NETDEV_FLAG_DHCP; + flag_mask = NETDEV_FLAG_UP | NETDEV_FLAG_LINK_UP | NETDEV_FLAG_INTERNET_UP; netdev->flags &= ~flag_mask; // clear dev setting - ip_addr_set_zero(&(netdev->ip_addr)); - ip_addr_set_zero(&(netdev->netmask)); - ip_addr_set_zero(&(netdev->gw)); - - IP_SET_TYPE_VAL(netdev->ip_addr, IPADDR_TYPE_V4); - IP_SET_TYPE_VAL(netdev->netmask, IPADDR_TYPE_V4); - IP_SET_TYPE_VAL(netdev->gw, IPADDR_TYPE_V4); + netdev->ip_addr = NULL; + netdev->netmask = NULL; + netdev->gw = NULL; #if NETDEV_IPV6 for (index = 0; index < NETDEV_IPV6_NUM_ADDRESSES; index++) { @@ -78,7 +83,6 @@ int netdev_register(struct netdev* netdev, const char* name, void* user_data) // clear DNS servers for (uint16_t idx = 0; idx < NETDEV_DNS_SERVERS_NUM; idx++) { ip_addr_set_zero(&(netdev->dns_servers[idx])); - IP_SET_TYPE_VAL(netdev->ip_addr, IPADDR_TYPE_V4); } // clear callback fn netdev->addr_callback = NULL; @@ -87,7 +91,8 @@ int netdev_register(struct netdev* netdev, const char* name, void* user_data) // validate name uint32_t name_len = strlen(name); if (name_len < NAME_NUM_MAX) { - strncpy(netdev->name, name, name_len); + SYS_KDEBUG_LOG(NETDEV_DEBUG, ("Register Netdev %s, name len: %d.\n", name, name_len)); + strncpy(netdev->name, name, (name_len > 31 ? 31 : name_len)); netdev->name[name_len] = '\0'; } else { SYS_KDEBUG_LOG(NETDEV_DEBUG, ("[%s] name too long.\n", __func__)); @@ -103,6 +108,7 @@ int netdev_register(struct netdev* netdev, const char* name, void* user_data) x_base lock = DISABLE_INTERRUPT(); if (NETDEV_LISTHEAD == NULL) { NETDEV_LISTHEAD = netdev; + } else { SingleLinkListNodeInsert(&(NETDEV_LISTHEAD->list), &(netdev->list)); } @@ -110,7 +116,7 @@ int netdev_register(struct netdev* netdev, const char* name, void* user_data) if (NETDEV_DEFAULT == NULL) { // set first met netdev to default netdev - netdev_set_default(NETDEV_LISTHEAD); + netdev_set_default(netdev); } if (g_netdev_register_callback) { diff --git a/Ubiquitous/XiZi_IIoT/resources/include/netdev/netdev.h b/Ubiquitous/XiZi_IIoT/resources/include/netdev/netdev.h index e3007fd9e..468a1a68e 100644 --- a/Ubiquitous/XiZi_IIoT/resources/include/netdev/netdev.h +++ b/Ubiquitous/XiZi_IIoT/resources/include/netdev/netdev.h @@ -93,9 +93,9 @@ struct netdev { SysSingleLinklistType list; char name[NAME_NUM_MAX]; /* network interface device name */ - ip_addr_t ip_addr; /* IP address */ - ip_addr_t netmask; /* subnet mask */ - ip_addr_t gw; /* gateway */ + ip_addr_t* ip_addr; /* IP address */ + ip_addr_t* netmask; /* subnet mask */ + ip_addr_t* gw; /* gateway */ #if NETDEV_IPV6 ip_addr_t ip6_addr[NETDEV_IPV6_NUM_ADDRESSES]; /* array of IPv6 addresses */ #endif /* NETDEV_IPV6 */