forked from xuos/xiuos
support OK1052-C ADC SPI I2C RTC codes ; support PLC control framework from Wang_linyu
This commit is contained in:
commit
73d10380ea
|
@ -56,5 +56,6 @@ void test_adc()
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN),
|
|
||||||
// test_adc, test_adc, read 3.3 voltage data from adc);
|
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN),
|
||||||
|
adc, test_adc, read 3.3 voltage data from adc);
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
* @author AIIT XUOS Lab
|
* @author AIIT XUOS Lab
|
||||||
* @date 2021-05-29
|
* @date 2021-05-29
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <transform.h>
|
#include <transform.h>
|
||||||
#include <xizi.h>
|
#include <xizi.h>
|
||||||
#include "board.h"
|
#include "board.h"
|
||||||
|
@ -24,27 +25,13 @@
|
||||||
#include <lwip/sockets.h>
|
#include <lwip/sockets.h>
|
||||||
#include "lwip/sys.h"
|
#include "lwip/sys.h"
|
||||||
|
|
||||||
/*******************************************************************************
|
#define TCP_DEMO_BUF_SIZE 65535
|
||||||
* Definitions
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
* Prototypes
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
* Variables
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
char tcp_socket_ip[] = {192, 168, 250, 252};
|
char tcp_socket_ip[] = {192, 168, 250, 252};
|
||||||
|
|
||||||
#define TCP_DEMO_BUF_SIZE 65535
|
/******************************************************************************/
|
||||||
|
|
||||||
/*******************************************************************************
|
static void TCPSocketRecvTask(void *arg)
|
||||||
* Code
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
static void tcp_recv_demo(void *arg)
|
|
||||||
{
|
{
|
||||||
int fd = -1, clientfd;
|
int fd = -1, clientfd;
|
||||||
int recv_len;
|
int recv_len;
|
||||||
|
@ -80,7 +67,7 @@ static void tcp_recv_demo(void *arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
lw_print("tcp bind success, start to receive.\n");
|
lw_print("tcp bind success, start to receive.\n");
|
||||||
lw_print("\n\nLocal Port:%d\n\n", LWIP_LOCAL_PORT);
|
lw_pr_info("\n\nLocal Port:%d\n\n", LWIP_LOCAL_PORT);
|
||||||
|
|
||||||
// setup socket fd as listening mode
|
// setup socket fd as listening mode
|
||||||
if (listen(fd, 5) != 0 )
|
if (listen(fd, 5) != 0 )
|
||||||
|
@ -91,7 +78,7 @@ static void tcp_recv_demo(void *arg)
|
||||||
|
|
||||||
// accept client connection
|
// accept client connection
|
||||||
clientfd = accept(fd, (struct sockaddr *)&tcp_addr, (socklen_t*)&addr_len);
|
clientfd = accept(fd, (struct sockaddr *)&tcp_addr, (socklen_t*)&addr_len);
|
||||||
lw_print("client %s connected\n", inet_ntoa(tcp_addr.sin_addr));
|
lw_pr_info("client %s connected\n", inet_ntoa(tcp_addr.sin_addr));
|
||||||
|
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
|
@ -114,7 +101,7 @@ static void tcp_recv_demo(void *arg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void tcp_socket_recv_run(int argc, char *argv[])
|
void TCPSocketRecvTest(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int result = 0;
|
int result = 0;
|
||||||
pthread_t th_id;
|
pthread_t th_id;
|
||||||
|
@ -126,15 +113,14 @@ void tcp_socket_recv_run(int argc, char *argv[])
|
||||||
sscanf(argv[1], "%d.%d.%d.%d", &tcp_socket_ip[0], &tcp_socket_ip[1], &tcp_socket_ip[2], &tcp_socket_ip[3]);
|
sscanf(argv[1], "%d.%d.%d.%d", &tcp_socket_ip[0], &tcp_socket_ip[1], &tcp_socket_ip[2], &tcp_socket_ip[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
ETH_BSP_Config();
|
|
||||||
lwip_config_tcp(lwip_ipaddr, lwip_netmask, lwip_gwaddr);
|
lwip_config_tcp(lwip_ipaddr, lwip_netmask, lwip_gwaddr);
|
||||||
sys_thread_new("tcp_recv_demo", tcp_recv_demo, NULL, LWIP_TASK_STACK_SIZE, LWIP_DEMO_TASK_PRIO);
|
sys_thread_new("TCPSocketRecvTask", TCPSocketRecvTask, NULL, LWIP_TASK_STACK_SIZE, LWIP_DEMO_TASK_PRIO);
|
||||||
}
|
}
|
||||||
|
|
||||||
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(3),
|
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(3),
|
||||||
TCPSocketRecv, tcp_socket_recv_run, TCP recv echo);
|
TCPSocketRecv, TCPSocketRecvTest, TCP recv echo);
|
||||||
|
|
||||||
static void tcp_send_demo(void *arg)
|
static void TCPSocketSendTask(void *arg)
|
||||||
{
|
{
|
||||||
int cnt = LWIP_DEMO_TIMES;
|
int cnt = LWIP_DEMO_TIMES;
|
||||||
int fd = -1;
|
int fd = -1;
|
||||||
|
@ -163,7 +149,7 @@ static void tcp_send_demo(void *arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
lw_print("tcp connect success, start to send.\n");
|
lw_print("tcp connect success, start to send.\n");
|
||||||
lw_pr_info("\n\nTarget Port:%d\n\n", tcp_sock.sin_port);
|
lw_pr_info("\n\nTarget Port:%d\n\n", LWIP_TARGET_PORT);
|
||||||
|
|
||||||
while (cnt --)
|
while (cnt --)
|
||||||
{
|
{
|
||||||
|
@ -182,7 +168,7 @@ __exit:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void tcp_socket_send_run(int argc, char *argv[])
|
void TCPSocketSendTest(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
if(argc == 2)
|
if(argc == 2)
|
||||||
{
|
{
|
||||||
|
@ -190,11 +176,10 @@ void tcp_socket_send_run(int argc, char *argv[])
|
||||||
sscanf(argv[1], "%d.%d.%d.%d", &tcp_socket_ip[0], &tcp_socket_ip[1], &tcp_socket_ip[2], &tcp_socket_ip[3]);
|
sscanf(argv[1], "%d.%d.%d.%d", &tcp_socket_ip[0], &tcp_socket_ip[1], &tcp_socket_ip[2], &tcp_socket_ip[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
ETH_BSP_Config();
|
|
||||||
lwip_config_tcp(lwip_ipaddr, lwip_netmask, tcp_socket_ip);
|
lwip_config_tcp(lwip_ipaddr, lwip_netmask, tcp_socket_ip);
|
||||||
sys_thread_new("tcp socket", tcp_send_demo, NULL, LWIP_TASK_STACK_SIZE, LWIP_DEMO_TASK_PRIO);
|
sys_thread_new("tcp socket", TCPSocketSendTask, NULL, LWIP_TASK_STACK_SIZE, LWIP_DEMO_TASK_PRIO);
|
||||||
}
|
}
|
||||||
|
|
||||||
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(0),
|
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(0),
|
||||||
TCPSocketSend, tcp_socket_send_run, TCP send demo);
|
TCPSocketSend, TCPSocketSendTest, TCP send demo);
|
||||||
|
|
||||||
|
|
|
@ -23,36 +23,20 @@
|
||||||
#include "sys_arch.h"
|
#include "sys_arch.h"
|
||||||
#include "lwip/udp.h"
|
#include "lwip/udp.h"
|
||||||
#include "lwip/opt.h"
|
#include "lwip/opt.h"
|
||||||
|
#include <lwip/sockets.h>
|
||||||
|
#include "lwip/sys.h"
|
||||||
|
|
||||||
/*******************************************************************************
|
#define UDP_BUF_SIZE 65536
|
||||||
* Definitions
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
* Prototypes
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
* Variables
|
|
||||||
******************************************************************************/
|
|
||||||
extern char udp_target[];
|
extern char udp_target[];
|
||||||
static struct udp_pcb *udpecho_raw_pcb;
|
static struct udp_pcb *udpecho_raw_pcb;
|
||||||
char udp_socket_ip[] = {192, 168, 250, 252};
|
char udp_socket_ip[] = {192, 168, 250, 252};
|
||||||
|
|
||||||
/*******************************************************************************
|
/******************************************************************************/
|
||||||
* Code
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
#include <lwip/sockets.h>
|
static void UdpSocketRecvTask(void *arg)
|
||||||
#include "lwip/sys.h"
|
|
||||||
|
|
||||||
#define LWIP_UDP_TASK_STACK 4096
|
|
||||||
#define LWIP_UDP_TASK_PRIO 25
|
|
||||||
#define UDP_BUF_SIZE 1024
|
|
||||||
|
|
||||||
static void udp_recv_demo(void *arg)
|
|
||||||
{
|
{
|
||||||
lw_print("udp_recv_demo start.\n");
|
lw_print("UdpSocketRecvTask start.\n");
|
||||||
|
|
||||||
int socket_fd = -1;
|
int socket_fd = -1;
|
||||||
char *recv_buf;
|
char *recv_buf;
|
||||||
|
@ -63,14 +47,14 @@ static void udp_recv_demo(void *arg)
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
recv_buf = (char *)malloc(UDP_BUF_SIZE);
|
recv_buf = (char *)malloc(UDP_BUF_SIZE);
|
||||||
if (recv_buf == NULL)
|
if(recv_buf == NULL)
|
||||||
{
|
{
|
||||||
lw_print("No memory\n");
|
lw_print("No memory\n");
|
||||||
goto __exit;
|
goto __exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
socket_fd = socket(AF_INET, SOCK_DGRAM, 0);
|
socket_fd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
if (socket_fd < 0)
|
if(socket_fd < 0)
|
||||||
{
|
{
|
||||||
lw_print("Socket error\n");
|
lw_print("Socket error\n");
|
||||||
goto __exit;
|
goto __exit;
|
||||||
|
@ -81,7 +65,7 @@ static void udp_recv_demo(void *arg)
|
||||||
udp_addr.sin_port = htons(LWIP_LOCAL_PORT);
|
udp_addr.sin_port = htons(LWIP_LOCAL_PORT);
|
||||||
memset(&(udp_addr.sin_zero), 0, sizeof(udp_addr.sin_zero));
|
memset(&(udp_addr.sin_zero), 0, sizeof(udp_addr.sin_zero));
|
||||||
|
|
||||||
if (bind(socket_fd, (struct sockaddr *)&udp_addr, sizeof(struct sockaddr)) == -1)
|
if(bind(socket_fd, (struct sockaddr *)&udp_addr, sizeof(struct sockaddr)) == -1)
|
||||||
{
|
{
|
||||||
lw_print("Unable to bind\n");
|
lw_print("Unable to bind\n");
|
||||||
goto __exit;
|
goto __exit;
|
||||||
|
@ -94,28 +78,25 @@ static void udp_recv_demo(void *arg)
|
||||||
{
|
{
|
||||||
memset(recv_buf, 0, UDP_BUF_SIZE);
|
memset(recv_buf, 0, UDP_BUF_SIZE);
|
||||||
recv_len = recvfrom(socket_fd, recv_buf, UDP_BUF_SIZE, 0, (struct sockaddr *)&server_addr, &addr_len);
|
recv_len = recvfrom(socket_fd, recv_buf, UDP_BUF_SIZE, 0, (struct sockaddr *)&server_addr, &addr_len);
|
||||||
lw_print("Receive from : %s\n", inet_ntoa(server_addr.sin_addr));
|
lw_pr_info("Receive from : %s\n", inet_ntoa(server_addr.sin_addr));
|
||||||
lw_print("Receive data : %s\n\n", recv_buf);
|
lw_pr_info("Receive data : %s\n\n", recv_buf);
|
||||||
sendto(socket_fd, recv_buf, recv_len, 0, (struct sockaddr*)&server_addr, addr_len);
|
sendto(socket_fd, recv_buf, recv_len, 0, (struct sockaddr*)&server_addr, addr_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
__exit:
|
__exit:
|
||||||
if (socket_fd >= 0)
|
if(socket_fd >= 0)
|
||||||
|
{
|
||||||
closesocket(socket_fd);
|
closesocket(socket_fd);
|
||||||
|
}
|
||||||
|
|
||||||
if (recv_buf)
|
if(recv_buf)
|
||||||
|
{
|
||||||
free(recv_buf);
|
free(recv_buf);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void udp_recv_demo_thread(void* param)
|
void UdpSocketRecvTask(int argc, char *argv[])
|
||||||
{
|
|
||||||
ETH_BSP_Config();
|
|
||||||
lwip_config_tcp(lwip_ipaddr, lwip_netmask, lwip_gwaddr);
|
|
||||||
sys_thread_new("udp_recv_demo", udp_recv_demo, NULL, LWIP_UDP_TASK_STACK, LWIP_UDP_TASK_PRIO);
|
|
||||||
}
|
|
||||||
|
|
||||||
void udp_socket_recv_run(int argc, char *argv[])
|
|
||||||
{
|
{
|
||||||
int result = 0;
|
int result = 0;
|
||||||
pthread_t th_id;
|
pthread_t th_id;
|
||||||
|
@ -127,24 +108,25 @@ void udp_socket_recv_run(int argc, char *argv[])
|
||||||
sscanf(argv[1], "%d.%d.%d.%d", &udp_socket_ip[0], &udp_socket_ip[1], &udp_socket_ip[2], &udp_socket_ip[3]);
|
sscanf(argv[1], "%d.%d.%d.%d", &udp_socket_ip[0], &udp_socket_ip[1], &udp_socket_ip[2], &udp_socket_ip[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
sys_thread_new("udp socket send", udp_recv_demo_thread, NULL, 4096, 15);
|
lwip_config_tcp(lwip_ipaddr, lwip_netmask, lwip_gwaddr);
|
||||||
|
sys_thread_new("UdpSocketRecvTask", UdpSocketRecvTask, NULL, LWIP_TASK_STACK_SIZE, LWIP_DEMO_TASK_PRIO);
|
||||||
}
|
}
|
||||||
|
|
||||||
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(3),
|
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(3),
|
||||||
UDPSocketRecv, udp_socket_recv_run, UDP recv echo);
|
UDPSocketRecv, UdpSocketRecvTask, UDP recv echo);
|
||||||
|
|
||||||
static void udp_send_demo(void *arg)
|
static void UdpSocketSendTask(void *arg)
|
||||||
{
|
{
|
||||||
int cnt = LWIP_DEMO_TIMES;
|
int cnt = LWIP_DEMO_TIMES;
|
||||||
char send_str[128];
|
char send_str[128];
|
||||||
|
|
||||||
lw_print("udp_send_demo start.\n");
|
lw_print("UdpSocketSendTask start.\n");
|
||||||
|
|
||||||
int socket_fd = -1;
|
int socket_fd = -1;
|
||||||
memset(send_str, 0, sizeof(send_str));
|
memset(send_str, 0, sizeof(send_str));
|
||||||
|
|
||||||
socket_fd = socket(AF_INET, SOCK_DGRAM, 0);
|
socket_fd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
if (socket_fd < 0)
|
if(socket_fd < 0)
|
||||||
{
|
{
|
||||||
lw_print("Socket error\n");
|
lw_print("Socket error\n");
|
||||||
goto __exit;
|
goto __exit;
|
||||||
|
@ -153,10 +135,10 @@ static void udp_send_demo(void *arg)
|
||||||
struct sockaddr_in udp_sock;
|
struct sockaddr_in udp_sock;
|
||||||
udp_sock.sin_family = AF_INET;
|
udp_sock.sin_family = AF_INET;
|
||||||
udp_sock.sin_port = htons(LWIP_TARGET_PORT);
|
udp_sock.sin_port = htons(LWIP_TARGET_PORT);
|
||||||
udp_sock.sin_addr.s_addr = PP_HTONL(LWIP_MAKEU32(udp_target[0],udp_target[1],udp_target[2],udp_target[3]));
|
udp_sock.sin_addr.s_addr = PP_HTONL(LWIP_MAKEU32(udp_target[0], udp_target[1], udp_target[2], udp_target[3]));
|
||||||
memset(&(udp_sock.sin_zero), 0, sizeof(udp_sock.sin_zero));
|
memset(&(udp_sock.sin_zero), 0, sizeof(udp_sock.sin_zero));
|
||||||
|
|
||||||
if (connect(socket_fd, (struct sockaddr *)&udp_sock, sizeof(struct sockaddr)))
|
if(connect(socket_fd, (struct sockaddr *)&udp_sock, sizeof(struct sockaddr)))
|
||||||
{
|
{
|
||||||
lw_print("Unable to connect\n");
|
lw_print("Unable to connect\n");
|
||||||
goto __exit;
|
goto __exit;
|
||||||
|
@ -174,7 +156,7 @@ static void udp_send_demo(void *arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
__exit:
|
__exit:
|
||||||
if (socket_fd >= 0)
|
if(socket_fd >= 0)
|
||||||
{
|
{
|
||||||
closesocket(socket_fd);
|
closesocket(socket_fd);
|
||||||
}
|
}
|
||||||
|
@ -182,14 +164,7 @@ __exit:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void udp_send_demo_thread(void* param)
|
void UdpSocketSendTest(int argc, char *argv[])
|
||||||
{
|
|
||||||
ETH_BSP_Config();
|
|
||||||
lwip_config_tcp(lwip_ipaddr, lwip_netmask, lwip_gwaddr);
|
|
||||||
sys_thread_new("udp_send_demo", udp_send_demo, NULL, LWIP_UDP_TASK_STACK, LWIP_UDP_TASK_PRIO);
|
|
||||||
}
|
|
||||||
|
|
||||||
void udp_socket_send_run(int argc, char *argv[])
|
|
||||||
{
|
{
|
||||||
int result = 0;
|
int result = 0;
|
||||||
pthread_t th_id;
|
pthread_t th_id;
|
||||||
|
@ -201,9 +176,10 @@ void udp_socket_send_run(int argc, char *argv[])
|
||||||
sscanf(argv[1], "%d.%d.%d.%d", &udp_socket_ip[0], &udp_socket_ip[1], &udp_socket_ip[2], &udp_socket_ip[3]);
|
sscanf(argv[1], "%d.%d.%d.%d", &udp_socket_ip[0], &udp_socket_ip[1], &udp_socket_ip[2], &udp_socket_ip[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
sys_thread_new("udp socket send", udp_send_demo_thread, NULL, 4096, 15);
|
lwip_config_tcp(lwip_ipaddr, lwip_netmask, lwip_gwaddr);
|
||||||
|
sys_thread_new("UdpSocketSendTask", UdpSocketSendTask, NULL, LWIP_TASK_STACK_SIZE, LWIP_DEMO_TASK_PRIO);
|
||||||
}
|
}
|
||||||
|
|
||||||
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(3),
|
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(3),
|
||||||
UDPSocketSend, udp_socket_send_run, UDP send echo);
|
UDPSocketSend, UdpSocketSendTest, UDP send echo);
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ SRC_DIR :=
|
||||||
ifeq ($(CONFIG_RESOURCES_LWIP),y)
|
ifeq ($(CONFIG_RESOURCES_LWIP),y)
|
||||||
|
|
||||||
ifeq ($(CONFIG_USING_CONTROL_PLC_OPCUA), y)
|
ifeq ($(CONFIG_USING_CONTROL_PLC_OPCUA), y)
|
||||||
SRC_DIR += opcua_demo
|
SRC_DIR += opcua_demo plc_demo
|
||||||
endif
|
endif
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -31,6 +31,8 @@
|
||||||
|
|
||||||
#define TCP_LOCAL_PORT 4840
|
#define TCP_LOCAL_PORT 4840
|
||||||
#define UA_URL_SIZE 100
|
#define UA_URL_SIZE 100
|
||||||
|
#define UA_STACK_SIZE 4096
|
||||||
|
#define UA_TASK_PRIO 15
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Prototypes
|
* Prototypes
|
||||||
|
@ -40,80 +42,71 @@
|
||||||
* Variables
|
* Variables
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
char test_ua_ip[] = {192, 168, 250, 5};
|
char test_ua_ip[] = {192, 168, 250, 2};
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Code
|
* Code
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
static void test_ua_connect(void *arg)
|
static void UaConnectTestTask(void* arg)
|
||||||
{
|
{
|
||||||
struct netif net;
|
struct netif net;
|
||||||
UA_StatusCode retval;
|
UA_StatusCode retval;
|
||||||
char ua_uri[UA_URL_SIZE];
|
char ua_uri[UA_URL_SIZE];
|
||||||
|
|
||||||
memset(ua_uri, 0, sizeof(ua_uri));
|
memset(ua_uri, 0, sizeof(ua_uri));
|
||||||
|
UA_Client* client = UA_Client_new();
|
||||||
|
|
||||||
UA_Client *client = UA_Client_new();
|
if(client == NULL)
|
||||||
|
|
||||||
if (client == NULL)
|
|
||||||
{
|
{
|
||||||
ua_print("ua: [%s] tcp client null\n", __func__);
|
ua_print("ua: [%s] tcp client null\n", __func__);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
UA_ClientConfig *config = UA_Client_getConfig(client);
|
UA_ClientConfig* config = UA_Client_getConfig(client);
|
||||||
UA_ClientConfig_setDefault(config);
|
UA_ClientConfig_setDefault(config);
|
||||||
|
snprintf(ua_uri, sizeof(ua_uri), "opc.tcp://%d.%d.%d.%d:4840",
|
||||||
snprintf(ua_uri, UA_URL_SIZE, "opc.tcp://%d.%d.%d.%d:4840",
|
|
||||||
test_ua_ip[0], test_ua_ip[1], test_ua_ip[2], test_ua_ip[3]);
|
test_ua_ip[0], test_ua_ip[1], test_ua_ip[2], test_ua_ip[3]);
|
||||||
|
ua_pr_info("ua uri: %d %s\n", strlen(ua_uri), ua_uri);
|
||||||
|
retval = UA_Client_connect(client,ua_uri);
|
||||||
|
|
||||||
retval = UA_Client_connect(client, ua_uri);
|
if(retval != UA_STATUSCODE_GOOD)
|
||||||
if (retval != UA_STATUSCODE_GOOD)
|
|
||||||
{
|
{
|
||||||
ua_print("ua: [%s] ret %x\n", __func__, retval);
|
ua_pr_info("ua: [%s] connected failed %x\n", __func__, retval);
|
||||||
|
UA_Client_delete(client);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ua_print("ua: [%s] start Ua Test!\n", __func__);
|
ua_pr_info("ua: [%s] connected ok!\n", __func__);
|
||||||
UA_Client_disconnect(client);
|
UA_Client_disconnect(client);
|
||||||
UA_Client_delete(client);
|
UA_Client_delete(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_ua_connect_thr(void *arg)
|
void UaConnectTest(void* arg)
|
||||||
{
|
{
|
||||||
ETH_BSP_Config();
|
|
||||||
lwip_config_tcp(lwip_ipaddr, lwip_netmask, test_ua_ip);
|
lwip_config_tcp(lwip_ipaddr, lwip_netmask, test_ua_ip);
|
||||||
test_ua_connect(NULL);
|
sys_thread_new("ua test", UaConnectTestTask, NULL, UA_STACK_SIZE, UA_TASK_PRIO);
|
||||||
}
|
|
||||||
|
|
||||||
void test_sh_ua_connect(void)
|
|
||||||
{
|
|
||||||
int result = 0;
|
|
||||||
pthread_t th_id;
|
|
||||||
pthread_attr_t attr;
|
|
||||||
sys_thread_new("ua test", test_ua_connect_thr, NULL, 4096, 15);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(0),
|
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(0),
|
||||||
UaConnect, test_sh_ua_connect, Test Opc UA connection);
|
UaConnect, UaConnectTest, Test Opc UA connection);
|
||||||
|
|
||||||
void test_ua_browser_objects(void *param)
|
void UaBrowserObjectsTestTask(void* param)
|
||||||
{
|
{
|
||||||
UA_Client *client = UA_Client_new();
|
UA_Client* client = UA_Client_new();
|
||||||
|
|
||||||
ua_pr_info("ua: [%s] start ...\n", __func__);
|
ua_pr_info("ua: [%s] start ...\n", __func__);
|
||||||
|
|
||||||
if (client == NULL)
|
if(client == NULL)
|
||||||
{
|
{
|
||||||
ua_print("ua: [%s] tcp client null\n", __func__);
|
ua_print("ua: [%s] tcp client null\n", __func__);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
UA_ClientConfig *config = UA_Client_getConfig(client);
|
UA_ClientConfig* config = UA_Client_getConfig(client);
|
||||||
UA_ClientConfig_setDefault(config);
|
UA_ClientConfig_setDefault(config);
|
||||||
|
UA_StatusCode retval = UA_Client_connect(client, opc_server_url);
|
||||||
|
|
||||||
UA_StatusCode retval = UA_Client_connect(client, OPC_SERVER);
|
if(retval != UA_STATUSCODE_GOOD)
|
||||||
if(retval != UA_STATUSCODE_GOOD) {
|
{
|
||||||
ua_print("ua: [%s] connect failed %#x\n", __func__, retval);
|
ua_print("ua: [%s] connect failed %#x\n", __func__, retval);
|
||||||
UA_Client_delete(client);
|
UA_Client_delete(client);
|
||||||
return;
|
return;
|
||||||
|
@ -121,18 +114,15 @@ void test_ua_browser_objects(void *param)
|
||||||
|
|
||||||
ua_print("ua: [%s] connect ok!\n", __func__);
|
ua_print("ua: [%s] connect ok!\n", __func__);
|
||||||
ua_pr_info("--- start read time ---\n", __func__);
|
ua_pr_info("--- start read time ---\n", __func__);
|
||||||
|
|
||||||
ua_read_time(client);
|
ua_read_time(client);
|
||||||
|
|
||||||
ua_pr_info("--- get server info ---\n", __func__);
|
ua_pr_info("--- get server info ---\n", __func__);
|
||||||
ua_browser_objects(client);
|
ua_test_browser_objects(client);
|
||||||
|
|
||||||
/* Clean up */
|
/* Clean up */
|
||||||
UA_Client_disconnect(client);
|
UA_Client_disconnect(client);
|
||||||
UA_Client_delete(client); /* Disconnects the client internally */
|
UA_Client_delete(client); /* Disconnects the client internally */
|
||||||
}
|
}
|
||||||
|
|
||||||
void *test_sh_ua_brower_objects(int argc, char *argv[])
|
void* UaBrowserObjectsTest(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
if(argc == 2)
|
if(argc == 2)
|
||||||
{
|
{
|
||||||
|
@ -146,47 +136,45 @@ void *test_sh_ua_brower_objects(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ETH_BSP_Config();
|
|
||||||
lwip_config_tcp(lwip_ipaddr, lwip_netmask, test_ua_ip);
|
lwip_config_tcp(lwip_ipaddr, lwip_netmask, test_ua_ip);
|
||||||
sys_thread_new("ua object", test_ua_browser_objects, NULL, 4096, 15);
|
sys_thread_new("ua object", UaBrowserObjectsTestTask, NULL, UA_STACK_SIZE, UA_TASK_PRIO);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(3),
|
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(3),
|
||||||
UaObj, test_sh_ua_brower_objects, UaObj [IP]);
|
UaObj, UaBrowserObjectsTest, UaObj [IP]);
|
||||||
|
|
||||||
void test_ua_get_info(void *param)
|
void UaGetInfoTestTask(void* param)
|
||||||
{
|
{
|
||||||
UA_Client *client = UA_Client_new();
|
UA_Client* client = UA_Client_new();
|
||||||
|
|
||||||
ua_pr_info("ua: [%s] start ...\n", __func__);
|
ua_pr_info("ua: [%s] start ...\n", __func__);
|
||||||
|
|
||||||
if (client == NULL)
|
if(client == NULL)
|
||||||
{
|
{
|
||||||
ua_print("ua: [%s] tcp client null\n", __func__);
|
ua_print("ua: [%s] tcp client null\n", __func__);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
UA_ClientConfig *config = UA_Client_getConfig(client);
|
UA_ClientConfig* config = UA_Client_getConfig(client);
|
||||||
UA_ClientConfig_setDefault(config);
|
UA_ClientConfig_setDefault(config);
|
||||||
|
UA_StatusCode retval = UA_Client_connect(client, opc_server_url);
|
||||||
|
|
||||||
UA_StatusCode retval = UA_Client_connect(client, OPC_SERVER);
|
if(retval != UA_STATUSCODE_GOOD)
|
||||||
if(retval != UA_STATUSCODE_GOOD) {
|
{
|
||||||
ua_print("ua: [%s] connect failed %#x\n", __func__, retval);
|
ua_print("ua: [%s] connect failed %#x\n", __func__, retval);
|
||||||
UA_Client_delete(client);
|
UA_Client_delete(client);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ua_print("ua: [%s] connect ok!\n", __func__);
|
ua_print("ua: [%s] connect ok!\n", __func__);
|
||||||
ua_pr_info("--- get server info ---\n", __func__);
|
ua_pr_info("--- interactive server ---\n", __func__);
|
||||||
ua_get_server_info(client);
|
ua_test_interact_server(client);
|
||||||
|
|
||||||
/* Clean up */
|
/* Clean up */
|
||||||
UA_Client_disconnect(client);
|
UA_Client_disconnect(client);
|
||||||
UA_Client_delete(client); /* Disconnects the client internally */
|
UA_Client_delete(client); /* Disconnects the client internally */
|
||||||
}
|
}
|
||||||
|
|
||||||
void *test_sh_ua_get_info(int argc, char *argv[])
|
void* UaGetInfoTest(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
if(argc == 2)
|
if(argc == 2)
|
||||||
{
|
{
|
||||||
|
@ -200,12 +188,63 @@ void *test_sh_ua_get_info(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ETH_BSP_Config();
|
|
||||||
lwip_config_tcp(lwip_ipaddr, lwip_netmask, test_ua_ip);
|
lwip_config_tcp(lwip_ipaddr, lwip_netmask, test_ua_ip);
|
||||||
sys_thread_new("ua object", test_ua_browser_objects, NULL, 4096, 15);
|
sys_thread_new("ua info", UaGetInfoTestTask, NULL, UA_STACK_SIZE, UA_TASK_PRIO);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(3),
|
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(3),
|
||||||
UaInfo, test_sh_ua_get_info, UaInfo [IP]);
|
UaInfo, UaGetInfoTest, UaInfo [IP]);
|
||||||
|
|
||||||
|
void UaAddNodesTask(void* param)
|
||||||
|
{
|
||||||
|
UA_Client* client = UA_Client_new();
|
||||||
|
ua_pr_info("ua: [%s] start ...\n", __func__);
|
||||||
|
|
||||||
|
if(client == NULL)
|
||||||
|
{
|
||||||
|
ua_print("ua: [%s] tcp client null\n", __func__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
UA_ClientConfig* config = UA_Client_getConfig(client);
|
||||||
|
UA_ClientConfig_setDefault(config);
|
||||||
|
UA_StatusCode retval = UA_Client_connect(client, opc_server_url);
|
||||||
|
|
||||||
|
if(retval != UA_STATUSCODE_GOOD)
|
||||||
|
{
|
||||||
|
ua_print("ua: [%s] connect failed %#x\n", __func__, retval);
|
||||||
|
UA_Client_delete(client);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ua_print("ua: [%s] connect ok!\n", __func__);
|
||||||
|
ua_pr_info("--- add nodes ---\n", __func__);
|
||||||
|
ua_add_nodes(client);
|
||||||
|
/* Clean up */
|
||||||
|
UA_Client_disconnect(client);
|
||||||
|
UA_Client_delete(client); /* Disconnects the client internally */
|
||||||
|
}
|
||||||
|
|
||||||
|
void* UaAddNodesTest(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
if(argc == 2)
|
||||||
|
{
|
||||||
|
if(isdigit(argv[1][0]))
|
||||||
|
{
|
||||||
|
if(sscanf(argv[1], "%d.%d.%d.%d", &test_ua_ip[0], &test_ua_ip[1], &test_ua_ip[2], &test_ua_ip[3]) == EOF)
|
||||||
|
{
|
||||||
|
lw_pr_info("input wrong ip\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lwip_config_tcp(lwip_ipaddr, lwip_netmask, test_ua_ip);
|
||||||
|
sys_thread_new("ua add nodes", UaAddNodesTask, NULL, UA_STACK_SIZE, UA_TASK_PRIO);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(3),
|
||||||
|
UaAdd, UaAddNodesTest, UA Add Nodes);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
SRC_FILES := plc_show_demo.c plc_control_demo.c
|
||||||
|
|
||||||
|
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -0,0 +1,221 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 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 plc_control_demo.c
|
||||||
|
* @brief Demo for PLC control
|
||||||
|
* @version 1.0
|
||||||
|
* @author AIIT XUOS Lab
|
||||||
|
* @date 2022.2.22
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "transform.h"
|
||||||
|
#include "open62541.h"
|
||||||
|
#include "ua_api.h"
|
||||||
|
#include "sys_arch.h"
|
||||||
|
#include "plc_demo.h"
|
||||||
|
|
||||||
|
#define PLC_NS_FORMAT "n%d,%s"
|
||||||
|
|
||||||
|
struct PlcChannel plc_demo_ch;
|
||||||
|
struct PlcDriver plc_demo_drv;
|
||||||
|
struct PlcDevice plc_demo_dev;
|
||||||
|
|
||||||
|
PlcCtrlParamType plc_ctrl_param;
|
||||||
|
|
||||||
|
UA_NodeId test_nodeid = {4, UA_NODEIDTYPE_NUMERIC, 5};
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
void PlcDemoChannelDrvInit(void)
|
||||||
|
{
|
||||||
|
static uint8_t init_flag = 0;
|
||||||
|
if(init_flag)
|
||||||
|
return;
|
||||||
|
init_flag = 1;
|
||||||
|
|
||||||
|
lwip_config_tcp(lwip_ipaddr, lwip_netmask, test_ua_ip);
|
||||||
|
PlcChannelInit(&plc_demo_ch, PLC_CH_NAME);
|
||||||
|
if(PlcDriverInit(&plc_demo_drv, PLC_DRV_NAME) == EOK)
|
||||||
|
{
|
||||||
|
PlcDriverAttachToChannel(PLC_DRV_NAME, PLC_CH_NAME);
|
||||||
|
}
|
||||||
|
memset(&plc_demo_dev, 0, sizeof(plc_demo_dev));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void PlcCtrlDemoInit(void)
|
||||||
|
{
|
||||||
|
static uint8_t init_flag = 0;
|
||||||
|
|
||||||
|
PlcDemoChannelDrvInit();
|
||||||
|
// register plc device
|
||||||
|
plc_demo_dev.state = CHDEV_INIT;
|
||||||
|
strcpy(plc_demo_dev.name, "UA Demo");
|
||||||
|
plc_demo_dev.info.product = "CPU 1215C";
|
||||||
|
plc_demo_dev.info.vendor = "SIEMENS";
|
||||||
|
plc_demo_dev.info.model = "S7-1200";
|
||||||
|
plc_demo_dev.info.id = 123;
|
||||||
|
plc_demo_dev.net = PLC_IND_ENET_OPCUA;
|
||||||
|
|
||||||
|
// register UA parameter
|
||||||
|
if(!plc_demo_dev.priv_data)
|
||||||
|
{
|
||||||
|
plc_demo_dev.priv_data = (UaParamType*)malloc(sizeof(UaParamType));
|
||||||
|
}
|
||||||
|
UaParamType* ua_ptr = plc_demo_dev.priv_data;
|
||||||
|
memset(ua_ptr, 0, sizeof(UaParamType));
|
||||||
|
strcpy(ua_ptr->ua_remote_ip, opc_server_url);
|
||||||
|
ua_ptr->act = UA_ACT_ATTR;
|
||||||
|
memcpy(&ua_ptr->ua_id, &test_nodeid, sizeof(test_nodeid));
|
||||||
|
|
||||||
|
if(init_flag)
|
||||||
|
return;
|
||||||
|
init_flag = 1;
|
||||||
|
|
||||||
|
if(PlcDevRegister(&plc_demo_dev, NULL, plc_demo_dev.name) != EOK)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
PlcDeviceAttachToChannel(plc_demo_dev.name, PLC_CH_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlcReadUATask(void* arg)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
struct PlcOps* ops = NULL;
|
||||||
|
char buf[PLC_BUF_SIZE];
|
||||||
|
memset(buf, 0, sizeof(buf));
|
||||||
|
PlcCtrlDemoInit();
|
||||||
|
ops = plc_demo_dev.ops;
|
||||||
|
ret = ops->open(&plc_demo_dev);
|
||||||
|
|
||||||
|
if(EOK != ret)
|
||||||
|
{
|
||||||
|
plc_print("plc: [%s] open failed %#x\n", __func__, ret);
|
||||||
|
// free(plc_demo_dev.priv_data);
|
||||||
|
// plc_demo_dev.priv_data = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = ops->read(&plc_demo_dev, buf, PLC_BUF_SIZE);
|
||||||
|
|
||||||
|
if(EOK != ret)
|
||||||
|
{
|
||||||
|
plc_print("plc: [%s] read failed %x\n", __func__, ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
ops->close(&plc_demo_dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlcReadTest(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
static char node_str[UA_NODE_LEN];
|
||||||
|
memset(node_str, 0, sizeof(node_str));
|
||||||
|
|
||||||
|
if(argc > 1)
|
||||||
|
{
|
||||||
|
plc_print("plc: arg %s\n", argv[1]);
|
||||||
|
|
||||||
|
if(sscanf(argv[1], PLC_NS_FORMAT, &test_nodeid.namespaceIndex, node_str) != EOF)
|
||||||
|
{
|
||||||
|
if(isdigit(node_str[0]))
|
||||||
|
{
|
||||||
|
test_nodeid.identifierType = UA_NODEIDTYPE_NUMERIC;
|
||||||
|
test_nodeid.identifier.numeric = atoi(node_str);
|
||||||
|
plc_print("ns %d num %d\n", test_nodeid.namespaceIndex, test_nodeid.identifier.numeric);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
test_nodeid.identifierType = UA_NODEIDTYPE_STRING;
|
||||||
|
test_nodeid.identifier.string.length = strlen(node_str);
|
||||||
|
test_nodeid.identifier.string.data = node_str;
|
||||||
|
plc_print("ns %d str %s\n", test_nodeid.namespaceIndex, test_nodeid.identifier.string.data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sys_thread_new("plc read", PlcReadUATask, NULL, PLC_STACK_SIZE, PLC_TASK_PRIO);
|
||||||
|
}
|
||||||
|
|
||||||
|
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(3),
|
||||||
|
PlcRead, PlcReadTest, Read PLC);
|
||||||
|
|
||||||
|
void PlcWriteUATask(void* arg)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
struct PlcOps* ops = NULL;
|
||||||
|
char buf[PLC_BUF_SIZE];
|
||||||
|
memset(buf, 0, sizeof(buf));
|
||||||
|
|
||||||
|
PlcCtrlDemoInit();
|
||||||
|
ops = plc_demo_dev.ops;
|
||||||
|
ret = ops->open(&plc_demo_dev);
|
||||||
|
|
||||||
|
if(EOK != ret)
|
||||||
|
{
|
||||||
|
plc_print("plc: [%s] open failed %#x\n", __func__, ret);
|
||||||
|
// free(plc_demo_dev.priv_data);
|
||||||
|
// plc_demo_dev.priv_data = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = ops->write(&plc_demo_dev, arg, PLC_BUF_SIZE);
|
||||||
|
|
||||||
|
if(EOK != ret)
|
||||||
|
{
|
||||||
|
plc_print("plc: [%s] read failed\n", __func__);
|
||||||
|
}
|
||||||
|
|
||||||
|
ops->close(&plc_demo_dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlcWriteTest(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
static char node_str[UA_NODE_LEN];
|
||||||
|
static char val_param[UA_NODE_LEN];
|
||||||
|
memset(node_str, 0, sizeof(node_str));
|
||||||
|
memset(val_param, 0, sizeof(val_param));
|
||||||
|
|
||||||
|
if(argc > 1)
|
||||||
|
{
|
||||||
|
plc_print("plc: arg %s\n", argv[1]);
|
||||||
|
|
||||||
|
if(sscanf(argv[1], PLC_NS_FORMAT, &test_nodeid.namespaceIndex, node_str) != EOF)
|
||||||
|
{
|
||||||
|
if(isdigit(node_str[0]))
|
||||||
|
{
|
||||||
|
test_nodeid.identifierType = UA_NODEIDTYPE_NUMERIC;
|
||||||
|
test_nodeid.identifier.numeric = atoi(node_str);
|
||||||
|
plc_print("ns %d num %d\n", test_nodeid.namespaceIndex, test_nodeid.identifier.numeric);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
test_nodeid.identifierType = UA_NODEIDTYPE_STRING;
|
||||||
|
test_nodeid.identifier.string.length = strlen(node_str);
|
||||||
|
test_nodeid.identifier.string.data = node_str;
|
||||||
|
plc_print("ns %d str %s\n", test_nodeid.namespaceIndex, test_nodeid.identifier.string.data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(argc > 2)
|
||||||
|
{
|
||||||
|
strcpy(val_param, argv[2]);
|
||||||
|
plc_print("write value %s\n", val_param);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sys_thread_new("plc write", PlcWriteUATask, val_param, PLC_STACK_SIZE, PLC_TASK_PRIO);
|
||||||
|
}
|
||||||
|
|
||||||
|
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(3),
|
||||||
|
PlcWrite, PlcWriteTest, Read PLC);
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 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 plc_show_demo.c
|
||||||
|
* @brief Demo for PLC information show
|
||||||
|
* @version 1.0
|
||||||
|
* @author AIIT XUOS Lab
|
||||||
|
* @date 2022.02.24
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __PLC_DEMO_H_
|
||||||
|
#define __PLC_DEMO_H_
|
||||||
|
|
||||||
|
#include "plc_channel.h"
|
||||||
|
#include "plc_device.h"
|
||||||
|
|
||||||
|
#define PLC_CH_NAME "PLC"
|
||||||
|
#define PLC_DRV_NAME "OPCUA"
|
||||||
|
|
||||||
|
#define PLC_BUF_SIZE 128
|
||||||
|
|
||||||
|
#define PLC_STACK_SIZE 4096
|
||||||
|
#define PLC_TASK_PRIO 15
|
||||||
|
|
||||||
|
extern struct PlcChannel plc_demo_ch;
|
||||||
|
extern struct PlcDriver plc_demo_drv;
|
||||||
|
extern struct PlcDevice plc_demo_dev;
|
||||||
|
|
||||||
|
void PlcDemoChannelDrvInit(void);
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,257 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 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 plc_show_demo.c
|
||||||
|
* @brief Demo for PLC information show
|
||||||
|
* @version 1.0
|
||||||
|
* @author AIIT XUOS Lab
|
||||||
|
* @date 2022.02.24
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "transform.h"
|
||||||
|
#include "list.h"
|
||||||
|
|
||||||
|
#include "open62541.h"
|
||||||
|
#include "ua_api.h"
|
||||||
|
#include "sys_arch.h"
|
||||||
|
#include "plc_demo.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define PLC_DEMO_NUM 5
|
||||||
|
|
||||||
|
struct PlcDevice plc_demo_array[PLC_DEMO_NUM];
|
||||||
|
|
||||||
|
typedef struct PlcShowParam
|
||||||
|
{
|
||||||
|
int id;
|
||||||
|
char* vector;
|
||||||
|
char* model;
|
||||||
|
char* product;
|
||||||
|
} PlcShowParamType;
|
||||||
|
|
||||||
|
PlcShowParamType plc_demo_param[PLC_NAME_SIZE] =
|
||||||
|
{
|
||||||
|
{1, "SIEMENS", "S7-1500", "CPU 1512SP-1PN"},
|
||||||
|
{2, "SIEMENS", "S7-1200", "CPU 1215C"},
|
||||||
|
{3, "SIEMSNS", "S7-200", "CPU SR60"},
|
||||||
|
{4, "B&R", "X20", "X20 CP1586"},
|
||||||
|
{5, "B&R", "X20", "X20 CP1381"}
|
||||||
|
};
|
||||||
|
|
||||||
|
static char* const channel_type_str[] =
|
||||||
|
{
|
||||||
|
"PLC_Channel",
|
||||||
|
"Unknown"
|
||||||
|
};
|
||||||
|
|
||||||
|
extern DoublelistType plcdev_list;
|
||||||
|
extern DoublelistType ch_linklist;
|
||||||
|
|
||||||
|
/**********************************************************************************************************************/
|
||||||
|
|
||||||
|
void PlcShowTitle(const char* item_array[])
|
||||||
|
{
|
||||||
|
int i = 0, max_len = 65;
|
||||||
|
KPrintf(" %-15s%-15s%-15s%-15s%-20s\n", item_array[0], item_array[1], item_array[2], item_array[3], item_array[4]);
|
||||||
|
|
||||||
|
while(i < max_len)
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
|
||||||
|
if(max_len == i)
|
||||||
|
{
|
||||||
|
KPrintf("-\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
KPrintf("-");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static ChDrvType ShowChannelFindDriver(struct Channel* ch)
|
||||||
|
{
|
||||||
|
struct ChDrv* driver = NONE;
|
||||||
|
DoublelistType* node = NONE;
|
||||||
|
DoublelistType* head = &ch->ch_drvlink;
|
||||||
|
|
||||||
|
for(node = head->node_next; node != head; node = node->node_next)
|
||||||
|
{
|
||||||
|
driver = DOUBLE_LIST_ENTRY(node, struct ChDrv, driver_link);
|
||||||
|
return driver;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void PlcShowDemoInit(void)
|
||||||
|
{
|
||||||
|
static uint8_t init_flag = 0;
|
||||||
|
int i;
|
||||||
|
PlcDemoChannelDrvInit();
|
||||||
|
|
||||||
|
for(i = 0; i < PLC_DEMO_NUM; i++)
|
||||||
|
{
|
||||||
|
// register plc device
|
||||||
|
plc_demo_array[i].state = CHDEV_INIT;
|
||||||
|
snprintf(plc_demo_array[i].name, PLC_NAME_SIZE, "PLC Demo %d", i);
|
||||||
|
plc_demo_array[i].info.vendor = plc_demo_param[i].vector;
|
||||||
|
plc_demo_array[i].info.model = plc_demo_param[i].model;
|
||||||
|
plc_demo_array[i].info.id = plc_demo_param[i].id;
|
||||||
|
plc_demo_array[i].info.product = plc_demo_param[i].product;
|
||||||
|
plc_demo_array[i].net = PLC_IND_ENET_OPCUA;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(init_flag)
|
||||||
|
return;
|
||||||
|
init_flag = 1;
|
||||||
|
|
||||||
|
for(i = 0; i < PLC_DEMO_NUM; i++)
|
||||||
|
{
|
||||||
|
if(PlcDevRegister(&plc_demo_array[i], NULL, plc_demo_array[i].name) == EOK)
|
||||||
|
{
|
||||||
|
PlcDeviceAttachToChannel(plc_demo_array[i].name, PLC_CH_NAME);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlcShowChannel(void)
|
||||||
|
{
|
||||||
|
ChannelType ch;
|
||||||
|
ChDrvType driver;
|
||||||
|
ChDevType device;
|
||||||
|
int dev_cnt;
|
||||||
|
DoublelistType* ch_node = NONE;
|
||||||
|
DoublelistType* ch_head = &ch_linklist;
|
||||||
|
const char* item_array[] = {"ch_type", "ch_name", "drv_name", "dev_name", "cnt"};
|
||||||
|
PlcShowDemoInit();
|
||||||
|
PlcShowTitle(item_array);
|
||||||
|
ch_node = ch_head->node_next;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
ch = DOUBLE_LIST_ENTRY(ch_node, struct Channel, ch_link);
|
||||||
|
|
||||||
|
if((ch) && (ch->ch_type == CH_PLC_TYPE))
|
||||||
|
{
|
||||||
|
KPrintf("%s", " ");
|
||||||
|
KPrintf("%-15s%-15s",
|
||||||
|
channel_type_str[ch->ch_type],
|
||||||
|
ch->ch_name);
|
||||||
|
|
||||||
|
driver = ShowChannelFindDriver(ch);
|
||||||
|
|
||||||
|
if(driver)
|
||||||
|
{
|
||||||
|
KPrintf("%-15s", driver->drv_name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
KPrintf("%-15s", "nil");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ch->haldev_cnt)
|
||||||
|
{
|
||||||
|
DoublelistType* dev_node = NONE;
|
||||||
|
DoublelistType* dev_head = &ch->ch_devlink;
|
||||||
|
dev_node = dev_head->node_next;
|
||||||
|
dev_cnt = 1;
|
||||||
|
|
||||||
|
while(dev_node != dev_head)
|
||||||
|
{
|
||||||
|
device = DOUBLE_LIST_ENTRY(dev_node, struct ChDev, dev_link);
|
||||||
|
|
||||||
|
if(1 == dev_cnt)
|
||||||
|
{
|
||||||
|
if(device)
|
||||||
|
{
|
||||||
|
KPrintf("%-16s%-4d\n", device->dev_name, dev_cnt);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
KPrintf("%-16s%-4d\n", "nil", dev_cnt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
KPrintf("%46s", " ");
|
||||||
|
|
||||||
|
if(device)
|
||||||
|
{
|
||||||
|
KPrintf("%-16s%-4d\n", device->dev_name, dev_cnt);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
KPrintf("%-16s%-4d\n", "nil", dev_cnt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dev_cnt++;
|
||||||
|
dev_node = dev_node->node_next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
KPrintf("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ch_node = ch_node->node_next;
|
||||||
|
}
|
||||||
|
while(ch_node != ch_head);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(3),
|
||||||
|
ShowChannel, PlcShowChannel, Show PLC information);
|
||||||
|
|
||||||
|
void PlcShowDev(void)
|
||||||
|
{
|
||||||
|
PlcDeviceType* plc_dev;
|
||||||
|
ChDrvType driver;
|
||||||
|
ChDevType device;
|
||||||
|
DoublelistType* plc_node = NONE;
|
||||||
|
DoublelistType* plc_head = &plcdev_list;
|
||||||
|
const char* item_array[] = {"device", "vendor", "model", "product", "id"};
|
||||||
|
PlcShowDemoInit();
|
||||||
|
PlcShowTitle(item_array);
|
||||||
|
plc_node = plc_head->node_next;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
plc_dev = DOUBLE_LIST_ENTRY(plc_node, struct PlcDevice, link);
|
||||||
|
|
||||||
|
if(plc_dev)
|
||||||
|
{
|
||||||
|
KPrintf("%s", " ");
|
||||||
|
KPrintf("%-15s%-15s%-15s%-15s%-20d",
|
||||||
|
plc_dev->name,
|
||||||
|
plc_dev->info.vendor,
|
||||||
|
plc_dev->info.model,
|
||||||
|
plc_dev->info.product,
|
||||||
|
plc_dev->info.id);
|
||||||
|
KPrintf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
plc_node = plc_node->node_next;
|
||||||
|
}
|
||||||
|
while(plc_node != plc_head);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(3),
|
||||||
|
ShowPlc, PlcShowDev, Show PLC information);
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
SRC_FILES := ua_data.c open62541.c ua_client.c ua_server.c
|
SRC_FILES := ua_data.c open62541.c ua_client.c ua_server.c ua_api.c ua_test.c
|
||||||
|
|
||||||
include $(KERNEL_ROOT)/compiler.mk
|
include $(KERNEL_ROOT)/compiler.mk
|
||||||
|
|
|
@ -15,18 +15,6 @@
|
||||||
* A PARTICULAR PURPOSE.
|
* A PARTICULAR PURPOSE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
* 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 open62541.c
|
* @file open62541.c
|
||||||
* @brief Support OPCUA protocol
|
* @brief Support OPCUA protocol
|
||||||
|
@ -44256,7 +44244,7 @@ UA_Client_run_iterate(UA_Client *client, UA_UInt32 timeout) {
|
||||||
client->sessionState < UA_SESSIONSTATE_ACTIVATED) {
|
client->sessionState < UA_SESSIONSTATE_ACTIVATED) {
|
||||||
retval = connectIterate(client, timeout);
|
retval = connectIterate(client, timeout);
|
||||||
notifyClientState(client);
|
notifyClientState(client);
|
||||||
lw_print("lw: [%s] ret %d timeout %d state %d ch %d\n", __func__, retval, timeout,
|
ua_print("lw: [%s] ret %d timeout %d state %d ch %d\n", __func__, retval, timeout,
|
||||||
client->sessionState, client->channel.state);
|
client->sessionState, client->channel.state);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
@ -45299,7 +45287,7 @@ connectIterate(UA_Client *client, UA_UInt32 timeout) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
lw_print("lw: [%s] sess %d conn %d\n", __func__, client->sessionState, client->connectStatus);
|
ua_print("ua: [%s] sess %d conn %d\n", __func__, client->sessionState, client->connectStatus);
|
||||||
return client->connectStatus;
|
return client->connectStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,98 @@
|
||||||
|
/*
|
||||||
|
* 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 ua_api.c
|
||||||
|
* @brief Demo for OpcUa function
|
||||||
|
* @version 1.0
|
||||||
|
* @author AIIT XUOS Lab
|
||||||
|
* @date 2021.11.11
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "open62541.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "ua_api.h"
|
||||||
|
|
||||||
|
int ua_open(void *dev)
|
||||||
|
{
|
||||||
|
UaParamType *param = (UaParamType *)dev;
|
||||||
|
|
||||||
|
param->client = UA_Client_new();
|
||||||
|
|
||||||
|
ua_pr_info("ua: [%s] start ...\n", __func__);
|
||||||
|
|
||||||
|
if (param->client == NULL)
|
||||||
|
{
|
||||||
|
ua_print("ua: [%s] tcp client null\n", __func__);
|
||||||
|
return EEMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
UA_ClientConfig *config = UA_Client_getConfig(param->client);
|
||||||
|
UA_ClientConfig_setDefault(config);
|
||||||
|
|
||||||
|
ua_pr_info("ua: [%s] %d %s\n", __func__, strlen(param->ua_remote_ip), param->ua_remote_ip);
|
||||||
|
|
||||||
|
UA_StatusCode retval = UA_Client_connect(param->client, param->ua_remote_ip);
|
||||||
|
if(retval != UA_STATUSCODE_GOOD) {
|
||||||
|
ua_pr_info("ua: [%s] deleted ret %x!\n", __func__, retval);
|
||||||
|
return (int)retval;
|
||||||
|
}
|
||||||
|
return EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ua_close(void *dev)
|
||||||
|
{
|
||||||
|
UaParamType *param = (UaParamType *)dev;
|
||||||
|
UA_Client_disconnect(param->client);
|
||||||
|
UA_Client_delete(param->client); /* Disconnects the client internally */
|
||||||
|
}
|
||||||
|
|
||||||
|
int ua_read(void *dev, void *buf, size_t len)
|
||||||
|
{
|
||||||
|
UaParamType *param = (UaParamType *)dev;
|
||||||
|
switch(param->act)
|
||||||
|
{
|
||||||
|
case UA_ACT_ATTR:
|
||||||
|
ua_read_nodeid_value(param->client, param->ua_id, buf);
|
||||||
|
break;
|
||||||
|
case UA_ACT_OBJ:
|
||||||
|
ua_test_browser_objects(param->client);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ua_write(void *dev, const void *buf, size_t len)
|
||||||
|
{
|
||||||
|
UaParamType *param = (UaParamType *)dev;
|
||||||
|
|
||||||
|
switch(param->act)
|
||||||
|
{
|
||||||
|
case UA_ACT_ATTR:
|
||||||
|
ua_write_nodeid_value(param->client, param->ua_id, (char *)buf);
|
||||||
|
break;
|
||||||
|
case UA_ACT_OBJ:
|
||||||
|
ua_test_browser_objects(param->client);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ua_ioctl(void *dev, int cmd, void *arg)
|
||||||
|
{
|
||||||
|
return EOK;
|
||||||
|
}
|
||||||
|
|
|
@ -9,23 +9,64 @@
|
||||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||||
* See the Mulan PSL v2 for more details.
|
* See the Mulan PSL v2 for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file ua_api.h
|
||||||
|
* @brief API for OpcUa function
|
||||||
|
* @version 1.0
|
||||||
|
* @author AIIT XUOS Lab
|
||||||
|
* @date 2021.11.11
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef __UA_API_H__
|
#ifndef __UA_API_H__
|
||||||
#define __UA_API_H__
|
#define __UA_API_H__
|
||||||
|
|
||||||
#include "open62541.h"
|
#include "open62541.h"
|
||||||
|
|
||||||
#define OPC_SERVER "opc.tcp://192.168.250.5:4840"
|
#define UA_DEV_IP_LEN 48
|
||||||
|
#define UA_NODE_LEN 32
|
||||||
|
|
||||||
#define ua_print //printf
|
enum UaAction_e
|
||||||
#define ua_trace() //printf("ua: [%s] line %d checked!\n", __func__, __LINE__)
|
{
|
||||||
|
UA_ACT_ATTR,
|
||||||
|
UA_ACT_OBJ,
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct UaParam
|
||||||
|
{
|
||||||
|
enum UaAction_e act;
|
||||||
|
UA_NodeId ua_id;
|
||||||
|
char ua_remote_ip[UA_DEV_IP_LEN];
|
||||||
|
char ua_node[UA_NODE_LEN];
|
||||||
|
UA_Client *client;
|
||||||
|
}UaParamType;
|
||||||
|
|
||||||
|
#define ua_print //KPrintf
|
||||||
|
#define ua_trace() //KPrintf("ua: [%s] line %d checked!\n", __func__, __LINE__)
|
||||||
#define ua_pr_info KPrintf
|
#define ua_pr_info KPrintf
|
||||||
#define ua_debug
|
#define ua_debug //KPrintf
|
||||||
|
|
||||||
|
extern const char *opc_server_url;
|
||||||
|
extern char test_ua_ip[];
|
||||||
|
|
||||||
int ua_server_connect(void);
|
int ua_server_connect(void);
|
||||||
int ua_get_server_info(UA_Client *client);
|
|
||||||
void ua_browser_objects(UA_Client *client);
|
|
||||||
void ua_browser_nodes(UA_Client *client);
|
void ua_browser_nodes(UA_Client *client);
|
||||||
|
void ua_browser_id(UA_Client *client, UA_NodeId id);
|
||||||
void ua_read_time(UA_Client *client);
|
void ua_read_time(UA_Client *client);
|
||||||
int16 ua_test(void);
|
void ua_add_nodes(UA_Client *client);
|
||||||
|
|
||||||
|
int ua_open(void *dev); // open and connect PLC device
|
||||||
|
void ua_close(void* dev); // close and disconnect PLC device
|
||||||
|
int ua_read(void* dev, void *buf, size_t len); // read data from PLC
|
||||||
|
int ua_write(void* dev, const void *buf, size_t len); // write data from PLC
|
||||||
|
int ua_ioctl(void* dev, int cmd, void *arg); // send control command to PLC
|
||||||
|
|
||||||
|
char *ua_get_nodeid_str(UA_NodeId *node_id);
|
||||||
|
void ua_read_nodeid_value(UA_Client *client, UA_NodeId id, UA_Int32 *value);
|
||||||
|
void ua_write_nodeid_value(UA_Client *client, UA_NodeId id, char* value);
|
||||||
|
void ua_test_attr(UA_Client *client);
|
||||||
|
UA_StatusCode ua_read_array_value(UA_Client *client, int array_size, UA_ReadValueId *array);
|
||||||
|
void ua_test_browser_objects(UA_Client *client);
|
||||||
|
int ua_test_interact_server(UA_Client *client);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -10,81 +10,164 @@
|
||||||
* See the Mulan PSL v2 for more details.
|
* See the Mulan PSL v2 for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "open62541.h"
|
/**
|
||||||
|
* @file ua_client.c
|
||||||
|
* @brief Client for OpcUa function
|
||||||
|
* @version 1.0
|
||||||
|
* @author AIIT XUOS Lab
|
||||||
|
* @date 2021.11.11
|
||||||
|
*/
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include "open62541.h"
|
||||||
#include "ua_api.h"
|
#include "ua_api.h"
|
||||||
|
|
||||||
|
#define UA_RESPONSE_TIMEOUT 10000
|
||||||
|
|
||||||
|
const char *opc_server_url = {"opc.tcp://192.168.250.2:4840"};
|
||||||
|
|
||||||
#ifdef UA_ENABLE_SUBSCRIPTIONS
|
#ifdef UA_ENABLE_SUBSCRIPTIONS
|
||||||
static void handler_TheAnswerChanged(UA_Client *client, UA_UInt32 subId, void *subContext,
|
static void handler_TheAnswerChanged(UA_Client* client, UA_UInt32 subId, void* subContext,
|
||||||
UA_UInt32 monId, void *monContext, UA_DataValue *value)
|
UA_UInt32 monId, void* monContext, UA_DataValue* value)
|
||||||
{
|
{
|
||||||
ua_print("The Answer has changed!\n");
|
ua_print("The Answer has changed!\n");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static UA_StatusCode nodeIter(UA_NodeId childId, UA_Boolean isInverse, UA_NodeId referenceTypeId, void *handle)
|
static UA_StatusCode nodeIter(UA_NodeId childId, UA_Boolean isInverse, UA_NodeId referenceTypeId, void* handle)
|
||||||
{
|
{
|
||||||
if(isInverse)
|
if(isInverse)
|
||||||
{
|
{
|
||||||
return UA_STATUSCODE_GOOD;
|
return UA_STATUSCODE_GOOD;
|
||||||
}
|
}
|
||||||
|
|
||||||
UA_NodeId *parent = (UA_NodeId *)handle;
|
UA_NodeId* parent = (UA_NodeId*)handle;
|
||||||
ua_pr_info("%d, %d --- %d ---> NodeId %d, %d\n",
|
ua_pr_info("%d, %d --- %d ---> NodeId %d, %d\n",
|
||||||
parent->namespaceIndex, parent->identifier.numeric,
|
parent->namespaceIndex, parent->identifier.numeric,
|
||||||
referenceTypeId.identifier.numeric, childId.namespaceIndex,
|
referenceTypeId.identifier.numeric, childId.namespaceIndex,
|
||||||
childId.identifier.numeric);
|
childId.identifier.numeric);
|
||||||
|
|
||||||
return UA_STATUSCODE_GOOD;
|
return UA_STATUSCODE_GOOD;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ua_get_points(UA_Client *client)
|
int ua_get_points(UA_Client* client)
|
||||||
{
|
{
|
||||||
/* Listing endpoints */
|
/* Listing endpoints */
|
||||||
UA_EndpointDescription* endpointArray = NULL;
|
UA_EndpointDescription* endpointArray = NULL;
|
||||||
size_t endpointArraySize = 0;
|
size_t endpointArraySize = 0;
|
||||||
UA_StatusCode retval = UA_Client_getEndpoints(client, OPC_SERVER,
|
UA_StatusCode ret = UA_Client_getEndpoints(client, opc_server_url,
|
||||||
&endpointArraySize, &endpointArray);
|
&endpointArraySize, &endpointArray);
|
||||||
if(retval != UA_STATUSCODE_GOOD)
|
|
||||||
|
if(ret != UA_STATUSCODE_GOOD)
|
||||||
{
|
{
|
||||||
UA_Array_delete(endpointArray, endpointArraySize, &UA_TYPES[UA_TYPES_ENDPOINTDESCRIPTION]);
|
UA_Array_delete(endpointArray, endpointArraySize, &UA_TYPES[UA_TYPES_ENDPOINTDESCRIPTION]);
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
ua_print("%i endpoints found\n", (int)endpointArraySize);
|
ua_print("%i endpoints found\n", (int)endpointArraySize);
|
||||||
for(size_t i=0;i<endpointArraySize;i++)
|
|
||||||
|
for(size_t i=0; i<endpointArraySize; i++)
|
||||||
{
|
{
|
||||||
ua_print("URL of endpoint %i is %.*s\n", (int)i,
|
ua_print("URL of endpoint %i is %.*s\n", (int)i,
|
||||||
(int)endpointArray[i].endpointUrl.length,
|
(int)endpointArray[i].endpointUrl.length,
|
||||||
endpointArray[i].endpointUrl.data);
|
endpointArray[i].endpointUrl.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
UA_Array_delete(endpointArray,endpointArraySize, &UA_TYPES[UA_TYPES_ENDPOINTDESCRIPTION]);
|
UA_Array_delete(endpointArray,endpointArraySize, &UA_TYPES[UA_TYPES_ENDPOINTDESCRIPTION]);
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ua_browser_objects(UA_Client *client)
|
void ua_print_value(UA_Variant* val)
|
||||||
{
|
{
|
||||||
/* Browse some objects */
|
if(val->type == &UA_TYPES[UA_TYPES_LOCALIZEDTEXT])
|
||||||
ua_pr_info("Browsing nodes in objects folder:\n");
|
{
|
||||||
|
UA_LocalizedText* ptr = (UA_LocalizedText*)val->data;
|
||||||
|
ua_pr_info("%.*s (Text)\n", ptr->text.length, ptr->text.data);
|
||||||
|
}
|
||||||
|
else if(val->type == &UA_TYPES[UA_TYPES_UINT32])
|
||||||
|
{
|
||||||
|
UA_UInt32* ptr = (UA_UInt32*)val->data;
|
||||||
|
ua_pr_info("%d (UInt32)\n", *ptr);
|
||||||
|
}
|
||||||
|
else if(val->type == &UA_TYPES[UA_TYPES_BOOLEAN])
|
||||||
|
{
|
||||||
|
UA_Boolean* ptr = (UA_Boolean*)val->data;
|
||||||
|
ua_pr_info("%i (BOOL)\n", *ptr);
|
||||||
|
}
|
||||||
|
else if(val->type == &UA_TYPES[UA_TYPES_INT32])
|
||||||
|
{
|
||||||
|
UA_Int32* ptr = (UA_Int32*)val->data;
|
||||||
|
ua_pr_info("%d (Int32)\n", *ptr);
|
||||||
|
}
|
||||||
|
else if(val->type == &UA_TYPES[UA_TYPES_INT16])
|
||||||
|
{
|
||||||
|
UA_Int16* ptr = (UA_Int16*)val->data;
|
||||||
|
ua_pr_info("%d (Int16)\n", *ptr);
|
||||||
|
}
|
||||||
|
else if(val->type == &UA_TYPES[UA_TYPES_STRING])
|
||||||
|
{
|
||||||
|
UA_String* ptr = (UA_String*)val->data;
|
||||||
|
ua_pr_info("%*.s (String)\n", ptr->length, ptr->data);
|
||||||
|
}
|
||||||
|
else if(val->type == &UA_TYPES[UA_TYPES_DATETIME])
|
||||||
|
{
|
||||||
|
UA_DateTime* ptr = (UA_DateTime*)val->data;
|
||||||
|
UA_DateTimeStruct dts = UA_DateTime_toStruct(*ptr);
|
||||||
|
ua_pr_info("%d-%d-%d %d:%d:%d.%03d (Time)\n",
|
||||||
|
dts.day, dts.month, dts.year, dts.hour, dts.min, dts.sec, dts.milliSec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
UA_BrowseRequest bReq;
|
char *ua_get_nodeid_str(UA_NodeId *node_id)
|
||||||
UA_BrowseRequest_init(&bReq);
|
{
|
||||||
|
static char nodeid_str[UA_NODE_LEN] = {0};
|
||||||
|
|
||||||
bReq.requestedMaxReferencesPerNode = 0;
|
switch(node_id->identifierType)
|
||||||
bReq.nodesToBrowse = UA_BrowseDescription_new();
|
{
|
||||||
bReq.nodesToBrowseSize = 1;
|
case UA_NODEIDTYPE_NUMERIC:
|
||||||
bReq.nodesToBrowse[0].nodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER); /* browse objects folder */
|
snprintf(nodeid_str, UA_NODE_LEN, "n%d,%d", node_id->namespaceIndex, node_id->identifier.numeric);
|
||||||
bReq.nodesToBrowse[0].resultMask = UA_BROWSERESULTMASK_ALL; /* return everything */
|
break;
|
||||||
|
case UA_NODEIDTYPE_STRING:
|
||||||
|
snprintf(nodeid_str, UA_NODE_LEN, "n%d,%.*s", node_id->namespaceIndex, node_id->identifier.string.length,
|
||||||
|
node_id->identifier.string.data);
|
||||||
|
break;
|
||||||
|
case UA_NODEIDTYPE_BYTESTRING:
|
||||||
|
snprintf(nodeid_str, UA_NODE_LEN, "n%d,%s", node_id->namespaceIndex, node_id->identifier.byteString.data);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return nodeid_str;
|
||||||
|
}
|
||||||
|
|
||||||
UA_BrowseResponse bResp = UA_Client_Service_browse(client, bReq);
|
void ua_print_nodeid(UA_NodeId *node_id)
|
||||||
|
{
|
||||||
|
switch(node_id->identifierType)
|
||||||
|
{
|
||||||
|
case UA_NODEIDTYPE_NUMERIC:
|
||||||
|
ua_pr_info(" NodeID n%d,%d ", node_id->namespaceIndex, node_id->identifier.numeric);
|
||||||
|
break;
|
||||||
|
case UA_NODEIDTYPE_STRING:
|
||||||
|
ua_pr_info(" NodeID n%d,%.*s ", node_id->namespaceIndex, node_id->identifier.string.length,
|
||||||
|
node_id->identifier.string.data);
|
||||||
|
break;
|
||||||
|
case UA_NODEIDTYPE_BYTESTRING:
|
||||||
|
ua_pr_info(" NodeID n%d,%s ", node_id->namespaceIndex, node_id->identifier.byteString.data);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ua_print_object(UA_BrowseResponse* res)
|
||||||
|
{
|
||||||
ua_pr_info("%-9s %-16s %-16s %-16s\n", "NAMESPACE", "NODEID", "BROWSE NAME", "DISPLAY NAME");
|
ua_pr_info("%-9s %-16s %-16s %-16s\n", "NAMESPACE", "NODEID", "BROWSE NAME", "DISPLAY NAME");
|
||||||
|
|
||||||
for(size_t i = 0; i < bResp.resultsSize; ++i)
|
for(size_t i = 0; i < res->resultsSize; ++i)
|
||||||
{
|
{
|
||||||
for(size_t j = 0; j < bResp.results[i].referencesSize; ++j)
|
for(size_t j = 0; j < res->results[i].referencesSize; ++j)
|
||||||
{
|
{
|
||||||
UA_ReferenceDescription *ref = &(bResp.results[i].references[j]);
|
UA_ReferenceDescription* ref = &(res->results[i].references[j]);
|
||||||
|
|
||||||
if(ref->nodeId.nodeId.identifierType == UA_NODEIDTYPE_NUMERIC)
|
if(ref->nodeId.nodeId.identifierType == UA_NODEIDTYPE_NUMERIC)
|
||||||
{
|
{
|
||||||
ua_pr_info("%-9d %-16d %-16.*s %-16.*s\n", ref->nodeId.nodeId.namespaceIndex,
|
ua_pr_info("%-9d %-16d %-16.*s %-16.*s\n", ref->nodeId.nodeId.namespaceIndex,
|
||||||
|
@ -100,95 +183,194 @@ void ua_browser_objects(UA_Client *client)
|
||||||
(int)ref->browseName.name.length, ref->browseName.name.data,
|
(int)ref->browseName.name.length, ref->browseName.name.data,
|
||||||
(int)ref->displayName.text.length, ref->displayName.text.data);
|
(int)ref->displayName.text.length, ref->displayName.text.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: distinguish further types */
|
/* TODO: distinguish further types */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ua_pr_info("\n");
|
ua_pr_info("\n");
|
||||||
UA_BrowseRequest_clear(&bReq);
|
|
||||||
UA_BrowseResponse_clear(&bResp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ua_browser_nodes(UA_Client *client)
|
UA_StatusCode ua_read_array_value(UA_Client* client, int array_size, UA_ReadValueId* array)
|
||||||
{
|
{
|
||||||
/* Same thing, this time using the node iterator... */
|
UA_ReadRequest request;
|
||||||
UA_NodeId *parent = UA_NodeId_new();
|
UA_ReadRequest_init(&request);
|
||||||
|
request.nodesToRead = array;
|
||||||
|
request.nodesToReadSize = array_size;
|
||||||
|
UA_ReadResponse response = UA_Client_Service_read(client, request);
|
||||||
|
|
||||||
|
if((response.responseHeader.serviceResult != UA_STATUSCODE_GOOD)
|
||||||
|
|| (response.resultsSize != array_size))
|
||||||
|
{
|
||||||
|
UA_ReadResponse_clear(&response);
|
||||||
|
ua_pr_info("ua: [%s] read failed 0x%x\n", __func__,
|
||||||
|
response.responseHeader.serviceResult);
|
||||||
|
return UA_STATUSCODE_BADUNEXPECTEDERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
UA_StatusCode* arr_ret = malloc(array_size * sizeof(UA_StatusCode));
|
||||||
|
|
||||||
|
for(int i = 0; i < array_size; ++i)
|
||||||
|
{
|
||||||
|
if((response.results[i].status == UA_STATUSCODE_GOOD)
|
||||||
|
&& (response.results[i].hasValue))
|
||||||
|
{
|
||||||
|
ua_pr_info("node %s: ", ua_get_nodeid_str(&array[i].nodeId));
|
||||||
|
ua_print_value(&response.results[i].value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ua_pr_info("\n");
|
||||||
|
|
||||||
|
free(arr_ret);
|
||||||
|
UA_ReadResponse_clear(&response);
|
||||||
|
return UA_STATUSCODE_GOOD;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ua_browser_id(UA_Client* client, UA_NodeId id)
|
||||||
|
{
|
||||||
|
/* Browse some objects */
|
||||||
|
ua_pr_info("Browsing nodes in objects folder:\n");
|
||||||
|
UA_BrowseRequest bReq;
|
||||||
|
UA_BrowseRequest_init(&bReq);
|
||||||
|
bReq.requestedMaxReferencesPerNode = 0;
|
||||||
|
bReq.nodesToBrowse = UA_BrowseDescription_new();
|
||||||
|
bReq.nodesToBrowseSize = 1;
|
||||||
|
bReq.nodesToBrowse[0].nodeId = id; /* browse objects folder */
|
||||||
|
bReq.nodesToBrowse[0].resultMask = UA_BROWSERESULTMASK_ALL; /* return everything */
|
||||||
|
UA_BrowseResponse res = UA_Client_Service_browse(client, bReq);
|
||||||
|
ua_print_object(&res);
|
||||||
|
UA_BrowseResponse_clear(&res);
|
||||||
|
// UA_BrowseRequest_clear(&bReq);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ua_browser_nodes(UA_Client* client)
|
||||||
|
{
|
||||||
|
UA_NodeId* parent = UA_NodeId_new();
|
||||||
*parent = UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER);
|
*parent = UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER);
|
||||||
UA_Client_forEachChildNodeCall(client, UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER),
|
UA_Client_forEachChildNodeCall(client, UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER), nodeIter, (void*) parent);
|
||||||
nodeIter, (void *) parent);
|
|
||||||
UA_NodeId_delete(parent);
|
UA_NodeId_delete(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
UA_UInt32 ua_start_sub(UA_Client *client)
|
UA_UInt32 ua_start_sub(UA_Client* client, UA_NodeId node_id)
|
||||||
{
|
{
|
||||||
/* Create a subscription */
|
/* Create a subscription */
|
||||||
UA_CreateSubscriptionRequest request = UA_CreateSubscriptionRequest_default();
|
UA_CreateSubscriptionRequest request = UA_CreateSubscriptionRequest_default();
|
||||||
UA_CreateSubscriptionResponse response = UA_Client_Subscriptions_create(client, request,
|
UA_CreateSubscriptionResponse response = UA_Client_Subscriptions_create(client, request,
|
||||||
NULL, NULL, NULL);
|
NULL, NULL, NULL);
|
||||||
|
|
||||||
UA_UInt32 subId = response.subscriptionId;
|
UA_UInt32 subId = response.subscriptionId;
|
||||||
|
|
||||||
if(response.responseHeader.serviceResult == UA_STATUSCODE_GOOD)
|
if(response.responseHeader.serviceResult == UA_STATUSCODE_GOOD)
|
||||||
|
{
|
||||||
ua_print("Create subscription succeeded, id %u\n", subId);
|
ua_print("Create subscription succeeded, id %u\n", subId);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ua_print("Create subscription failed, id %u\n", response.responseHeader.serviceResult);
|
||||||
|
return response.responseHeader.serviceResult;
|
||||||
|
}
|
||||||
|
|
||||||
UA_MonitoredItemCreateRequest monRequest =
|
UA_MonitoredItemCreateRequest monRequest =
|
||||||
UA_MonitoredItemCreateRequest_default(UA_NODEID_STRING(1, "the.answer"));
|
UA_MonitoredItemCreateRequest_default(node_id);
|
||||||
|
|
||||||
UA_MonitoredItemCreateResult monResponse =
|
UA_MonitoredItemCreateResult monResponse =
|
||||||
UA_Client_MonitoredItems_createDataChange(client, response.subscriptionId,
|
UA_Client_MonitoredItems_createDataChange(client, response.subscriptionId,
|
||||||
UA_TIMESTAMPSTORETURN_BOTH,
|
UA_TIMESTAMPSTORETURN_BOTH,
|
||||||
monRequest, NULL, handler_TheAnswerChanged, NULL);
|
monRequest, NULL, handler_TheAnswerChanged, NULL);
|
||||||
if(monResponse.statusCode == UA_STATUSCODE_GOOD)
|
|
||||||
ua_print("Monitoring 'the.answer', id %u\n", monResponse.monitoredItemId);
|
|
||||||
|
|
||||||
|
if(monResponse.statusCode == UA_STATUSCODE_GOOD)
|
||||||
|
{
|
||||||
|
ua_print("Monitoring 'the.answer', id %u\n", monResponse.monitoredItemId);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ua_print("%s return 0x%x\n", __func__, monResponse.statusCode);
|
||||||
|
}
|
||||||
|
|
||||||
/* The first publish request should return the initial value of the variable */
|
/* The first publish request should return the initial value of the variable */
|
||||||
UA_Client_run_iterate(client, 1000);
|
UA_Client_run_iterate(client, UA_RESPONSE_TIMEOUT);
|
||||||
return subId;
|
return subId;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ua_read_attr(UA_Client *client)
|
void ua_write_nodeid_value(UA_Client* client, UA_NodeId id, char* value)
|
||||||
{
|
{
|
||||||
/* Read attribute */
|
UA_Boolean bool_val;
|
||||||
UA_Int32 value = 0;
|
uint32_t integer_val;
|
||||||
ua_print("\nReading the value of node (1, \"the.answer\"):\n");
|
|
||||||
UA_Variant *val = UA_Variant_new();
|
|
||||||
UA_StatusCode retval = UA_Client_readValueAttribute(client, UA_NODEID_STRING(1, "the.answer"), val);
|
|
||||||
if(retval == UA_STATUSCODE_GOOD && UA_Variant_isScalar(val) &&
|
|
||||||
val->type == &UA_TYPES[UA_TYPES_INT32]) {
|
|
||||||
value = *(UA_Int32*)val->data;
|
|
||||||
ua_print("the value is: %i\n", value);
|
|
||||||
}
|
|
||||||
UA_Variant_delete(val);
|
|
||||||
|
|
||||||
/* Write node attribute */
|
|
||||||
value++;
|
|
||||||
ua_print("\nWriting a value of node (1, \"the.answer\"):\n");
|
|
||||||
UA_WriteRequest wReq;
|
UA_WriteRequest wReq;
|
||||||
UA_WriteRequest_init(&wReq);
|
UA_WriteRequest_init(&wReq);
|
||||||
|
|
||||||
wReq.nodesToWrite = UA_WriteValue_new();
|
wReq.nodesToWrite = UA_WriteValue_new();
|
||||||
wReq.nodesToWriteSize = 1;
|
wReq.nodesToWriteSize = 1;
|
||||||
wReq.nodesToWrite[0].nodeId = UA_NODEID_STRING_ALLOC(1, "the.answer");
|
|
||||||
|
if(strncmp(value, "1b", 2) == 0)
|
||||||
|
{
|
||||||
|
wReq.nodesToWrite[0].value.value.type = &UA_TYPES[UA_TYPES_BOOLEAN];
|
||||||
|
bool_val = 1;
|
||||||
|
wReq.nodesToWrite[0].value.value.data = &bool_val;
|
||||||
|
}
|
||||||
|
else if(strncmp(value, "0b", 2) == 0)
|
||||||
|
{
|
||||||
|
wReq.nodesToWrite[0].value.value.type = &UA_TYPES[UA_TYPES_BOOLEAN];
|
||||||
|
bool_val = 0;
|
||||||
|
wReq.nodesToWrite[0].value.value.data = &bool_val;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wReq.nodesToWrite[0].value.value.type = &UA_TYPES[UA_TYPES_INT16];
|
||||||
|
sscanf(value, "%d", &integer_val);
|
||||||
|
wReq.nodesToWrite[0].value.value.data = &integer_val;
|
||||||
|
}
|
||||||
|
|
||||||
|
wReq.nodesToWrite[0].nodeId = id;
|
||||||
wReq.nodesToWrite[0].attributeId = UA_ATTRIBUTEID_VALUE;
|
wReq.nodesToWrite[0].attributeId = UA_ATTRIBUTEID_VALUE;
|
||||||
wReq.nodesToWrite[0].value.hasValue = true;
|
wReq.nodesToWrite[0].value.hasValue = true;
|
||||||
wReq.nodesToWrite[0].value.value.type = &UA_TYPES[UA_TYPES_INT32];
|
|
||||||
wReq.nodesToWrite[0].value.value.storageType = UA_VARIANT_DATA_NODELETE; /* do not free the integer on deletion */
|
wReq.nodesToWrite[0].value.value.storageType = UA_VARIANT_DATA_NODELETE; /* do not free the integer on deletion */
|
||||||
wReq.nodesToWrite[0].value.value.data = &value;
|
|
||||||
UA_WriteResponse wResp = UA_Client_Service_write(client, wReq);
|
UA_WriteResponse wResp = UA_Client_Service_write(client, wReq);
|
||||||
|
|
||||||
if(wResp.responseHeader.serviceResult == UA_STATUSCODE_GOOD)
|
if(wResp.responseHeader.serviceResult == UA_STATUSCODE_GOOD)
|
||||||
ua_print("the new value is: %i\n", value);
|
{
|
||||||
|
ua_pr_info("write new value is: %s\n", value);
|
||||||
|
}
|
||||||
|
|
||||||
UA_WriteRequest_clear(&wReq);
|
UA_WriteRequest_clear(&wReq);
|
||||||
UA_WriteResponse_clear(&wResp);
|
UA_WriteResponse_clear(&wResp);
|
||||||
|
|
||||||
/* Write node attribute (using the highlevel API) */
|
// /* Write node attribute (using the highlevel API) */
|
||||||
value++;
|
// value++;
|
||||||
UA_Variant *myVariant = UA_Variant_new();
|
// UA_Variant *myVariant = UA_Variant_new();
|
||||||
UA_Variant_setScalarCopy(myVariant, &value, &UA_TYPES[UA_TYPES_INT32]);
|
// UA_Variant_setScalarCopy(myVariant, &value, &UA_TYPES[UA_TYPES_INT32]);
|
||||||
UA_Client_writeValueAttribute(client, UA_NODEID_STRING(1, "the.answer"), myVariant);
|
// UA_Client_writeValueAttribute(client, UA_NODEID_STRING(1, UA_NODE_STR), myVariant);
|
||||||
UA_Variant_delete(myVariant);
|
// UA_Variant_delete(myVariant);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ua_call_remote(UA_Client *client)
|
/* Read attribute */
|
||||||
|
void ua_read_nodeid_value(UA_Client* client, UA_NodeId id, UA_Int32 *value)
|
||||||
|
{
|
||||||
|
UA_Variant* val = UA_Variant_new();
|
||||||
|
UA_StatusCode ret = UA_Client_readValueAttribute(client, id, val);
|
||||||
|
|
||||||
|
if(ret == UA_STATUSCODE_GOOD)
|
||||||
|
{
|
||||||
|
ua_print_value(val);
|
||||||
|
if(UA_Variant_isScalar(val))
|
||||||
|
{
|
||||||
|
if(val->type == &UA_TYPES[UA_TYPES_BOOLEAN])
|
||||||
|
{
|
||||||
|
*value = *(UA_Boolean *)val->data;
|
||||||
|
}
|
||||||
|
else if(val->type == &UA_TYPES[UA_TYPES_INT32])
|
||||||
|
{
|
||||||
|
*value = *(UA_Int32 *)val->data;
|
||||||
|
}
|
||||||
|
else if(val->type == &UA_TYPES[UA_TYPES_INT16])
|
||||||
|
{
|
||||||
|
*value = *(UA_Int16 *)val->data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UA_Variant_delete(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ua_call_remote(UA_Client* client)
|
||||||
{
|
{
|
||||||
/* Call a remote method */
|
/* Call a remote method */
|
||||||
UA_Variant input;
|
UA_Variant input;
|
||||||
|
@ -196,10 +378,11 @@ void ua_call_remote(UA_Client *client)
|
||||||
UA_Variant_init(&input);
|
UA_Variant_init(&input);
|
||||||
UA_Variant_setScalarCopy(&input, &argString, &UA_TYPES[UA_TYPES_STRING]);
|
UA_Variant_setScalarCopy(&input, &argString, &UA_TYPES[UA_TYPES_STRING]);
|
||||||
size_t outputSize;
|
size_t outputSize;
|
||||||
UA_Variant *output;
|
UA_Variant* output;
|
||||||
UA_StatusCode retval = UA_Client_call(client, UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER),
|
UA_StatusCode ret = UA_Client_call(client, UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER),
|
||||||
UA_NODEID_NUMERIC(1, 62541), 1, &input, &outputSize, &output);
|
UA_NODEID_NUMERIC(1, 62541), 1, &input, &outputSize, &output);
|
||||||
if(retval == UA_STATUSCODE_GOOD)
|
|
||||||
|
if(ret == UA_STATUSCODE_GOOD)
|
||||||
{
|
{
|
||||||
ua_print("Method call was successful, and %lu returned values available.\n",
|
ua_print("Method call was successful, and %lu returned values available.\n",
|
||||||
(unsigned long)outputSize);
|
(unsigned long)outputSize);
|
||||||
|
@ -207,13 +390,14 @@ void ua_call_remote(UA_Client *client)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ua_print("Method call was unsuccessful, and %x returned values available.\n", retval);
|
ua_print("Method call was unsuccessful, and %x returned values available.\n", ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
UA_Variant_clear(&input);
|
UA_Variant_clear(&input);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ua_add_nodes(UA_Client *client)
|
void ua_add_nodes(UA_Client* client)
|
||||||
{
|
{
|
||||||
/* Add new nodes*/
|
/* Add new nodes*/
|
||||||
/* New ReferenceType */
|
/* New ReferenceType */
|
||||||
|
@ -222,43 +406,52 @@ void ua_add_nodes(UA_Client *client)
|
||||||
ref_attr.displayName = UA_LOCALIZEDTEXT("en-US", "NewReference");
|
ref_attr.displayName = UA_LOCALIZEDTEXT("en-US", "NewReference");
|
||||||
ref_attr.description = UA_LOCALIZEDTEXT("en-US", "References something that might or might not exist");
|
ref_attr.description = UA_LOCALIZEDTEXT("en-US", "References something that might or might not exist");
|
||||||
ref_attr.inverseName = UA_LOCALIZEDTEXT("en-US", "IsNewlyReferencedBy");
|
ref_attr.inverseName = UA_LOCALIZEDTEXT("en-US", "IsNewlyReferencedBy");
|
||||||
UA_StatusCode retval = UA_Client_addReferenceTypeNode(client,
|
UA_StatusCode ret = UA_Client_addReferenceTypeNode(client,
|
||||||
UA_NODEID_NUMERIC(1, 12133),
|
UA_NODEID_NUMERIC(1, 12133),
|
||||||
UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES),
|
UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES),
|
||||||
UA_NODEID_NUMERIC(0, UA_NS0ID_HASSUBTYPE),
|
UA_NODEID_NUMERIC(0, UA_NS0ID_HASSUBTYPE),
|
||||||
UA_QUALIFIEDNAME(1, "NewReference"),
|
UA_QUALIFIEDNAME(1, "NewReference"),
|
||||||
ref_attr, &ref_id);
|
ref_attr, &ref_id);
|
||||||
if(retval == UA_STATUSCODE_GOOD )
|
|
||||||
|
if(ret == UA_STATUSCODE_GOOD)
|
||||||
|
{
|
||||||
ua_print("Created 'NewReference' with numeric NodeID %u\n", ref_id.identifier.numeric);
|
ua_print("Created 'NewReference' with numeric NodeID %u\n", ref_id.identifier.numeric);
|
||||||
|
}
|
||||||
|
|
||||||
/* New ObjectType */
|
/* New ObjectType */
|
||||||
UA_NodeId objt_id;
|
UA_NodeId objt_id;
|
||||||
UA_ObjectTypeAttributes objt_attr = UA_ObjectTypeAttributes_default;
|
UA_ObjectTypeAttributes objt_attr = UA_ObjectTypeAttributes_default;
|
||||||
objt_attr.displayName = UA_LOCALIZEDTEXT("en-US", "TheNewObjectType");
|
objt_attr.displayName = UA_LOCALIZEDTEXT("en-US", "TheNewObjectType");
|
||||||
objt_attr.description = UA_LOCALIZEDTEXT("en-US", "Put innovative description here");
|
objt_attr.description = UA_LOCALIZEDTEXT("en-US", "Put innovative description here");
|
||||||
retval = UA_Client_addObjectTypeNode(client,
|
ret = UA_Client_addObjectTypeNode(client,
|
||||||
UA_NODEID_NUMERIC(1, 12134),
|
UA_NODEID_NUMERIC(1, 12134),
|
||||||
UA_NODEID_NUMERIC(0, UA_NS0ID_BASEOBJECTTYPE),
|
UA_NODEID_NUMERIC(0, UA_NS0ID_BASEOBJECTTYPE),
|
||||||
UA_NODEID_NUMERIC(0, UA_NS0ID_HASSUBTYPE),
|
UA_NODEID_NUMERIC(0, UA_NS0ID_HASSUBTYPE),
|
||||||
UA_QUALIFIEDNAME(1, "NewObjectType"),
|
UA_QUALIFIEDNAME(1, "NewObjectType"),
|
||||||
objt_attr, &objt_id);
|
objt_attr, &objt_id);
|
||||||
if(retval == UA_STATUSCODE_GOOD)
|
|
||||||
|
if(ret == UA_STATUSCODE_GOOD)
|
||||||
|
{
|
||||||
ua_print("Created 'NewObjectType' with numeric NodeID %u\n", objt_id.identifier.numeric);
|
ua_print("Created 'NewObjectType' with numeric NodeID %u\n", objt_id.identifier.numeric);
|
||||||
|
}
|
||||||
|
|
||||||
/* New Object */
|
/* New Object */
|
||||||
UA_NodeId obj_id;
|
UA_NodeId obj_id;
|
||||||
UA_ObjectAttributes obj_attr = UA_ObjectAttributes_default;
|
UA_ObjectAttributes obj_attr = UA_ObjectAttributes_default;
|
||||||
obj_attr.displayName = UA_LOCALIZEDTEXT("en-US", "TheNewGreatNode");
|
obj_attr.displayName = UA_LOCALIZEDTEXT("en-US", "TheNewGreatNode");
|
||||||
obj_attr.description = UA_LOCALIZEDTEXT("de-DE", "Hier koennte Ihre Webung stehen!");
|
obj_attr.description = UA_LOCALIZEDTEXT("de-DE", "Hier koennte Ihre Webung stehen!");
|
||||||
retval = UA_Client_addObjectNode(client,
|
ret = UA_Client_addObjectNode(client,
|
||||||
UA_NODEID_NUMERIC(1, 0),
|
UA_NODEID_NUMERIC(1, 0),
|
||||||
UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER),
|
UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER),
|
||||||
UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES),
|
UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES),
|
||||||
UA_QUALIFIEDNAME(1, "TheGreatNode"),
|
UA_QUALIFIEDNAME(1, "TheGreatNode"),
|
||||||
UA_NODEID_NUMERIC(1, 12134),
|
UA_NODEID_NUMERIC(1, 12134),
|
||||||
obj_attr, &obj_id);
|
obj_attr, &obj_id);
|
||||||
if(retval == UA_STATUSCODE_GOOD )
|
|
||||||
|
if(ret == UA_STATUSCODE_GOOD)
|
||||||
|
{
|
||||||
ua_print("Created 'NewObject' with numeric NodeID %u\n", obj_id.identifier.numeric);
|
ua_print("Created 'NewObject' with numeric NodeID %u\n", obj_id.identifier.numeric);
|
||||||
|
}
|
||||||
|
|
||||||
/* New Integer Variable */
|
/* New Integer Variable */
|
||||||
UA_NodeId var_id;
|
UA_NodeId var_id;
|
||||||
|
@ -270,68 +463,36 @@ void ua_add_nodes(UA_Client *client)
|
||||||
/* This does not copy the value */
|
/* This does not copy the value */
|
||||||
UA_Variant_setScalar(&var_attr.value, &int_value, &UA_TYPES[UA_TYPES_INT32]);
|
UA_Variant_setScalar(&var_attr.value, &int_value, &UA_TYPES[UA_TYPES_INT32]);
|
||||||
var_attr.dataType = UA_TYPES[UA_TYPES_INT32].typeId;
|
var_attr.dataType = UA_TYPES[UA_TYPES_INT32].typeId;
|
||||||
retval = UA_Client_addVariableNode(client,
|
ret = UA_Client_addVariableNode(client,
|
||||||
UA_NODEID_NUMERIC(1, 0), // Assign new/random NodeID
|
UA_NODEID_NUMERIC(1, 0), // Assign new/random NodeID
|
||||||
UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER),
|
UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER),
|
||||||
UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES),
|
UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES),
|
||||||
UA_QUALIFIEDNAME(0, "VariableNode"),
|
UA_QUALIFIEDNAME(0, "VariableNode"),
|
||||||
UA_NODEID_NULL, // no variable type
|
UA_NODEID_NULL, // no variable type
|
||||||
var_attr, &var_id);
|
var_attr, &var_id);
|
||||||
if(retval == UA_STATUSCODE_GOOD )
|
|
||||||
|
if(ret == UA_STATUSCODE_GOOD)
|
||||||
|
{
|
||||||
ua_print("Created 'NewVariable' with numeric NodeID %u\n", var_id.identifier.numeric);
|
ua_print("Created 'NewVariable' with numeric NodeID %u\n", var_id.identifier.numeric);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int ua_get_server_info(UA_Client *client)
|
void ua_read_time(UA_Client* client)
|
||||||
{
|
{
|
||||||
ua_browser_objects(client);
|
UA_Variant value;
|
||||||
|
|
||||||
/* Same thing, this time using the node iterator... */
|
|
||||||
ua_browser_nodes(client);
|
|
||||||
|
|
||||||
#ifdef UA_ENABLE_SUBSCRIPTIONS
|
|
||||||
UA_Int32 subId = ua_start_sub(client);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ua_read_attr(client);
|
|
||||||
|
|
||||||
#ifdef UA_ENABLE_SUBSCRIPTIONS
|
|
||||||
/* Take another look at the.answer */
|
|
||||||
UA_Client_run_iterate(client, 100);
|
|
||||||
/* Delete the subscription */
|
|
||||||
if(UA_Client_Subscriptions_deleteSingle(client, subId) == UA_STATUSCODE_GOOD)
|
|
||||||
ua_print("Subscription removed\n");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef UA_ENABLE_METHODCALLS
|
|
||||||
ua_call_remote(client);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef UA_ENABLE_NODEMANAGEMENT
|
|
||||||
ua_add_nodes(client);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ua_read_time(UA_Client *client)
|
|
||||||
{
|
|
||||||
/* Read the value attribute of the node. UA_Client_readValueAttribute is a
|
|
||||||
* wrapper for the raw read service available as UA_Client_Service_read. */
|
|
||||||
UA_Variant value; /* Variants can hold scalar values and arrays of any type */
|
|
||||||
UA_Variant_init(&value);
|
UA_Variant_init(&value);
|
||||||
|
|
||||||
/* NodeId of the variable holding the current time */
|
|
||||||
const UA_NodeId nodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERSTATUS_CURRENTTIME);
|
const UA_NodeId nodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERSTATUS_CURRENTTIME);
|
||||||
UA_StatusCode retval = UA_Client_readValueAttribute(client, nodeId, &value);
|
UA_StatusCode ret = UA_Client_readValueAttribute(client, nodeId, &value);
|
||||||
|
|
||||||
if(retval == UA_STATUSCODE_GOOD && UA_Variant_hasScalarType(&value, &UA_TYPES[UA_TYPES_DATETIME]))
|
if(ret == UA_STATUSCODE_GOOD && UA_Variant_hasScalarType(&value, &UA_TYPES[UA_TYPES_DATETIME]))
|
||||||
{
|
{
|
||||||
UA_DateTime raw_date = *(UA_DateTime *) value.data;
|
UA_DateTime raw_date = *(UA_DateTime*) value.data;
|
||||||
UA_DateTimeStruct dts = UA_DateTime_toStruct(raw_date);
|
UA_DateTimeStruct dts = UA_DateTime_toStruct(raw_date);
|
||||||
UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "date is: %u-%u-%u %u:%u:%u.%03u\n",
|
ua_pr_info("date is: %d-%d-%d %d:%d:%d.%03d\n",
|
||||||
dts.day, dts.month, dts.year, dts.hour, dts.min, dts.sec, dts.milliSec);
|
dts.day, dts.month, dts.year, dts.hour, dts.min, dts.sec, dts.milliSec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clean up */
|
/* Clean up */
|
||||||
UA_Variant_clear(&value);
|
UA_Variant_clear(&value);
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,17 +10,85 @@
|
||||||
* See the Mulan PSL v2 for more details.
|
* See the Mulan PSL v2 for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file ua_test.c
|
||||||
|
* @brief Test for OpcUa function
|
||||||
|
* @version 1.0
|
||||||
|
* @author AIIT XUOS Lab
|
||||||
|
* @date 2021.11.11
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "open62541.h"
|
||||||
|
#include "ua_api.h"
|
||||||
|
|
||||||
|
//for target NODEID
|
||||||
|
#define UA_TEST_BROWSER_NODEID UA_NODEID_STRING(3, "ServerInterfaces")
|
||||||
|
#define UA_TEST_BROWSER_NODEID1 UA_NODEID_NUMERIC(4, 1)
|
||||||
|
#define UA_TEST_WRITE_NODEID UA_NODEID_NUMERIC(4, 5)
|
||||||
|
|
||||||
|
|
||||||
|
static UA_StatusCode ua_test_read_array(UA_Client *client)
|
||||||
|
{
|
||||||
|
const int item_size = 4;
|
||||||
|
UA_ReadValueId test_item[item_size];
|
||||||
|
|
||||||
|
for (int i = 0; i < item_size; i++)
|
||||||
|
{
|
||||||
|
UA_ReadValueId_init(&test_item[i]);
|
||||||
|
test_item[i].attributeId = UA_ATTRIBUTEID_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
test_item[0].nodeId = UA_NODEID_NUMERIC(4, 2);
|
||||||
|
test_item[1].nodeId = UA_NODEID_NUMERIC(4, 3);
|
||||||
|
test_item[2].nodeId = UA_NODEID_NUMERIC(4, 4);
|
||||||
|
test_item[3].nodeId = UA_NODEID_NUMERIC(4, 5);
|
||||||
|
|
||||||
|
return ua_read_array_value(client, item_size, test_item);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ua_test_browser_objects(UA_Client *client)
|
||||||
|
{
|
||||||
|
UA_NodeId test_id;
|
||||||
|
ua_browser_id(client, UA_TEST_BROWSER_NODEID);
|
||||||
|
ua_browser_id(client, UA_TEST_BROWSER_NODEID1);
|
||||||
|
test_id = UA_TEST_BROWSER_NODEID1;
|
||||||
|
ua_pr_info("Show values in %s:\n", ua_get_nodeid_str(&test_id));
|
||||||
|
ua_test_read_array(client);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ua_test_write_attr(UA_Client *client)
|
||||||
|
{
|
||||||
|
UA_Int32 value;
|
||||||
|
char val_str[UA_NODE_LEN];
|
||||||
|
UA_NodeId id = UA_TEST_WRITE_NODEID;
|
||||||
|
|
||||||
|
ua_pr_info("--- Test write %s ---\n", ua_get_nodeid_str(&id));
|
||||||
|
ua_read_nodeid_value(client, id, &value);
|
||||||
|
ua_write_nodeid_value(client, id, itoa(value + 1, val_str, 10));
|
||||||
|
ua_read_nodeid_value(client, id, &value);
|
||||||
|
ua_pr_info("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
int ua_test_interact_server(UA_Client *client)
|
||||||
|
{
|
||||||
|
ua_read_time(client);
|
||||||
|
ua_test_browser_objects(client);
|
||||||
|
ua_test_write_attr(client);
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
int16 ua_test(void)
|
int16 ua_test(void)
|
||||||
{
|
{
|
||||||
UA_Client *client = UA_Client_new();
|
UA_Client *client = UA_Client_new();
|
||||||
UA_StatusCode retval = UA_Client_connect(client, OPC_SERVER);
|
UA_StatusCode retval = UA_Client_connect(client, opc_server_url);
|
||||||
if(retval != UA_STATUSCODE_GOOD) {
|
if(retval != UA_STATUSCODE_GOOD) {
|
||||||
UA_Client_delete(client);
|
UA_Client_delete(client);
|
||||||
return (int)retval;
|
return (int)retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
ua_read_time(client);
|
ua_read_time(client);
|
||||||
ua_run_test(client);
|
|
||||||
|
|
||||||
/* Clean up */
|
/* Clean up */
|
||||||
UA_Client_disconnect(client);
|
UA_Client_disconnect(client);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
SRC_FILES := plc.c
|
SRC_FILES := plc_device.c plc_channel.c plc_driver.c
|
||||||
|
|
||||||
include $(KERNEL_ROOT)/compiler.mk
|
include $(KERNEL_ROOT)/compiler.mk
|
||||||
|
|
||||||
|
|
|
@ -1,58 +0,0 @@
|
||||||
/*
|
|
||||||
* 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 plc.c
|
|
||||||
* @brief plc relative activities
|
|
||||||
* @version 1.0
|
|
||||||
* @author AIIT XUOS Lab
|
|
||||||
* @date 2021.12.15
|
|
||||||
*/
|
|
||||||
#ifdef USING_CONTROL_PLC_OPCUA
|
|
||||||
#include "../interoperability/opcua/open62541.h"
|
|
||||||
#endif
|
|
||||||
#include "plc.h"
|
|
||||||
|
|
||||||
|
|
||||||
struct PlcDevice plc_device;
|
|
||||||
|
|
||||||
// open and connect PLC device
|
|
||||||
void plc_open(struct PlcDevice *pdev)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// close and disconnect PLC device
|
|
||||||
void plc_close(struct PlcDevice *pdev)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// read data from PLC
|
|
||||||
void plc_read(struct PlcDevice *pdev, void *buf, size_t len)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// write data from PLC
|
|
||||||
void plc_write(struct PlcDevice *pdev, const void *buf, size_t len)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// send control command to PLC
|
|
||||||
void plc_ioctl(struct PlcDevice *pdev, int cmd, void *arg)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void plc_init(struct PlcDevice *plc_dev)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,538 @@
|
||||||
|
/*
|
||||||
|
* 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 plc_ch.c
|
||||||
|
* @brief Support channel driver framework provide ch API version 1.0
|
||||||
|
* @author AIIT XUOS Lab
|
||||||
|
* @date 2021-04-24
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "string.h"
|
||||||
|
#include "plc_channel.h"
|
||||||
|
#include "plc_device.h"
|
||||||
|
#include "transform.h"
|
||||||
|
|
||||||
|
DoublelistType ch_linklist;
|
||||||
|
|
||||||
|
/*Create the ch linklist*/
|
||||||
|
static void ChannelLinkInit(struct Channel *ch)
|
||||||
|
{
|
||||||
|
static uint8 ch_link_flag = RET_FALSE;
|
||||||
|
|
||||||
|
if(!ch_link_flag) {
|
||||||
|
AppInitDoubleList(&ch_linklist);
|
||||||
|
ch_link_flag = RET_TRUE;
|
||||||
|
ch->ch_link_flag = RET_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Create the driver of the ch linklist*/
|
||||||
|
if(!ch->ch_drvlink_flag) {
|
||||||
|
AppInitDoubleList(&ch->ch_drvlink);
|
||||||
|
ch->ch_drvlink_flag = RET_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Create the hardware device of the ch linklist*/
|
||||||
|
if(!ch->ch_devlink_flag) {
|
||||||
|
AppInitDoubleList(&ch->ch_devlink);
|
||||||
|
ch->ch_devlink_flag = RET_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ChannelMatchDrvDev(struct ChDrv *driver, struct ChDev *device)
|
||||||
|
{
|
||||||
|
CHECK_CH_PARAM(driver);
|
||||||
|
CHECK_CH_PARAM(device);
|
||||||
|
|
||||||
|
if(!strncmp(driver->owner_ch->ch_name, device->owner_ch->ch_name, NAME_NUM_MAX)) {
|
||||||
|
KPrintf("ChannelMatchDrvDev match successfully, ch name %s\n", driver->owner_ch->ch_name);
|
||||||
|
|
||||||
|
driver->private_data = device->private_data;//driver get the device param
|
||||||
|
device->owner_ch->owner_driver = driver;
|
||||||
|
driver->owner_ch->owner_haldev = device;
|
||||||
|
|
||||||
|
return EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: support to obtain ch for a certain dev if necessary, then configure and init its drv
|
||||||
|
* @param ch - ch pointer
|
||||||
|
* @param dev - dev pointer
|
||||||
|
* @param drv_name - drv name
|
||||||
|
* @param config - ChConfigInfo pointer
|
||||||
|
* @return successful:EOK,failed:ERROR
|
||||||
|
*/
|
||||||
|
int DeviceObtainChannel(struct Channel *ch, struct ChDev *dev, const char *drv_name, struct ChConfigInfo *cfg)
|
||||||
|
{
|
||||||
|
CHECK_CH_PARAM(ch);
|
||||||
|
CHECK_CH_PARAM(dev);
|
||||||
|
|
||||||
|
int32 ret = EOK;
|
||||||
|
|
||||||
|
ret = PrivMutexObtain(&ch->ch_lock);
|
||||||
|
if(EOK != ret) {
|
||||||
|
KPrintf("DevObtainChannel ch_lock error %d!\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ch->owner_haldev != dev) {
|
||||||
|
struct ChDrv *drv = ChannelFindDriver(ch, drv_name);
|
||||||
|
|
||||||
|
cfg->configure_cmd = OPE_CFG;
|
||||||
|
drv->configure(drv, cfg);
|
||||||
|
|
||||||
|
cfg->configure_cmd = OPE_INT;
|
||||||
|
drv->configure(drv, cfg);
|
||||||
|
|
||||||
|
ch->owner_haldev = dev;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: support to register ch pointer with linklist
|
||||||
|
* @param ch - ch pointer
|
||||||
|
* @return successful:EOK,failed:NONE
|
||||||
|
*/
|
||||||
|
int ChannelRegister(struct Channel *ch)
|
||||||
|
{
|
||||||
|
int ret = EOK;
|
||||||
|
CHECK_CH_PARAM(ch);
|
||||||
|
|
||||||
|
ch->match = ChannelMatchDrvDev;
|
||||||
|
|
||||||
|
ChannelLinkInit(ch);
|
||||||
|
|
||||||
|
PrivMutexCreate(&ch->ch_lock, NULL);
|
||||||
|
|
||||||
|
AppDoubleListInsertNodeAfter(&ch_linklist, &(ch->ch_link));
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: support to release ch pointer in linklist
|
||||||
|
* @param ch - ch pointer
|
||||||
|
* @return successful:EOK,failed:NONE
|
||||||
|
*/
|
||||||
|
int ChannelRelease(struct Channel *ch)
|
||||||
|
{
|
||||||
|
CHECK_CH_PARAM(ch);
|
||||||
|
|
||||||
|
PrivMutexAbandon(&ch->ch_lock);
|
||||||
|
|
||||||
|
ch->ch_cnt = 0;
|
||||||
|
ch->driver_cnt = 0;
|
||||||
|
ch->haldev_cnt = 0;
|
||||||
|
|
||||||
|
ch->ch_link_flag = RET_FALSE;
|
||||||
|
ch->ch_drvlink_flag = RET_FALSE;
|
||||||
|
ch->ch_devlink_flag = RET_FALSE;
|
||||||
|
|
||||||
|
return EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: support to unregister ch pointer and delete its linklist node
|
||||||
|
* @param ch - ch pointer
|
||||||
|
* @return successful:EOK,failed:NONE
|
||||||
|
*/
|
||||||
|
int ChannelUnregister(struct Channel *ch)
|
||||||
|
{
|
||||||
|
CHECK_CH_PARAM(ch);
|
||||||
|
|
||||||
|
ch->ch_cnt--;
|
||||||
|
|
||||||
|
AppDoubleListRmNode(&(ch->ch_link));
|
||||||
|
|
||||||
|
return EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: support to register driver pointer to ch pointer
|
||||||
|
* @param ch - ch pointer
|
||||||
|
* @param driver - driver pointer
|
||||||
|
* @return successful:EOK,failed:NONE
|
||||||
|
*/
|
||||||
|
int DriverRegisterToChannel(struct Channel *ch, struct ChDrv *driver)
|
||||||
|
{
|
||||||
|
CHECK_CH_PARAM(ch);
|
||||||
|
CHECK_CH_PARAM(driver);
|
||||||
|
|
||||||
|
driver->owner_ch = ch;
|
||||||
|
ch->driver_cnt++;
|
||||||
|
|
||||||
|
AppDoubleListInsertNodeAfter(&ch->ch_drvlink, &(driver->driver_link));
|
||||||
|
|
||||||
|
return EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: support to register dev pointer to ch pointer
|
||||||
|
* @param ch - ch pointer
|
||||||
|
* @param device - device pointer
|
||||||
|
* @return successful:EOK,failed:NONE
|
||||||
|
*/
|
||||||
|
int DeviceRegisterToChannel(struct Channel *ch, struct ChDev *device)
|
||||||
|
{
|
||||||
|
CHECK_CH_PARAM(ch);
|
||||||
|
CHECK_CH_PARAM(device);
|
||||||
|
|
||||||
|
device->owner_ch = ch;
|
||||||
|
ch->haldev_cnt++;
|
||||||
|
|
||||||
|
AppDoubleListInsertNodeAfter(&ch->ch_devlink, &(device->dev_link));
|
||||||
|
|
||||||
|
return EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: support to delete driver pointer from ch pointer
|
||||||
|
* @param ch - ch pointer
|
||||||
|
* @param driver - driver pointer
|
||||||
|
* @return successful:EOK,failed:NONE
|
||||||
|
*/
|
||||||
|
int DriverDeleteFromChannel(struct Channel *ch, struct ChDrv *driver)
|
||||||
|
{
|
||||||
|
CHECK_CH_PARAM(ch);
|
||||||
|
CHECK_CH_PARAM(driver);
|
||||||
|
|
||||||
|
ch->driver_cnt--;
|
||||||
|
|
||||||
|
AppDoubleListRmNode(&(driver->driver_link));
|
||||||
|
|
||||||
|
free(driver);
|
||||||
|
|
||||||
|
return EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: support to delete dev pointer from ch pointer
|
||||||
|
* @param ch - ch pointer
|
||||||
|
* @param device - device pointer
|
||||||
|
* @return successful:EOK,failed:NONE
|
||||||
|
*/
|
||||||
|
int DeviceDeleteFromChannel(struct Channel *ch, struct ChDev *device)
|
||||||
|
{
|
||||||
|
CHECK_CH_PARAM(ch);
|
||||||
|
CHECK_CH_PARAM(device);
|
||||||
|
|
||||||
|
ch->haldev_cnt--;
|
||||||
|
|
||||||
|
AppDoubleListRmNode(&(device->dev_link));
|
||||||
|
|
||||||
|
free(device);
|
||||||
|
|
||||||
|
return EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: support to find ch pointer by ch name
|
||||||
|
* @param ch_name - ch name
|
||||||
|
* @return successful:ch pointer,failed:NONE
|
||||||
|
*/
|
||||||
|
ChannelType ChannelFind(const char *ch_name)
|
||||||
|
{
|
||||||
|
struct Channel *ch = NONE;
|
||||||
|
|
||||||
|
DoublelistType *node = NONE;
|
||||||
|
DoublelistType *head = &ch_linklist;
|
||||||
|
|
||||||
|
for (node = head->node_next; node != head; node = node->node_next)
|
||||||
|
{
|
||||||
|
ch = DOUBLE_LIST_ENTRY(node, struct Channel, ch_link);
|
||||||
|
if(!strcmp(ch->ch_name, ch_name)) {
|
||||||
|
return ch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
KPrintf("ChannelFind cannot find the %s ch.return NULL\n", ch_name);
|
||||||
|
return NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: support to find driver pointer of certain ch by driver name
|
||||||
|
* @param ch - ch pointer
|
||||||
|
* @param driver_name - driver name
|
||||||
|
* @return successful:EOK,failed:NONE
|
||||||
|
*/
|
||||||
|
ChDrvType ChannelFindDriver(struct Channel *ch, const char *driver_name)
|
||||||
|
{
|
||||||
|
CHECK_CH_PARAM(ch);
|
||||||
|
struct ChDrv *driver = NONE;
|
||||||
|
|
||||||
|
DoublelistType *node = NONE;
|
||||||
|
DoublelistType *head = &ch->ch_drvlink;
|
||||||
|
|
||||||
|
for (node = head->node_next; node != head; node = node->node_next)
|
||||||
|
{
|
||||||
|
driver = DOUBLE_LIST_ENTRY(node, struct ChDrv, driver_link);
|
||||||
|
if(!strcmp(driver->drv_name, driver_name)) {
|
||||||
|
return driver;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
KPrintf("ChannelFindDriver cannot find the %s driver.return NULL\n", driver_name);
|
||||||
|
return NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: support to find device pointer of certain ch by device name
|
||||||
|
* @param ch - ch pointer
|
||||||
|
* @param device_name - device name
|
||||||
|
* @return successful:EOK,failed:NONE
|
||||||
|
*/
|
||||||
|
ChDevType ChannelFindDevice(struct Channel *ch, const char *device_name)
|
||||||
|
{
|
||||||
|
CHECK_CH_PARAM(ch);
|
||||||
|
struct ChDev *device = NONE;
|
||||||
|
|
||||||
|
DoublelistType *node = NONE;
|
||||||
|
DoublelistType *head = &ch->ch_devlink;
|
||||||
|
|
||||||
|
for (node = head->node_next; node != head; node = node->node_next)
|
||||||
|
{
|
||||||
|
device = DOUBLE_LIST_ENTRY(node, struct ChDev, dev_link);
|
||||||
|
|
||||||
|
if(!strcmp(device->dev_name, device_name)) {
|
||||||
|
return device;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
KPrintf("ChannelFindDevice cannot find the %s device.return NULL\n", device_name);
|
||||||
|
return NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: support to set dev receive function callback
|
||||||
|
* @param dev - dev pointer
|
||||||
|
* @param dev_recv_callback - callback function
|
||||||
|
* @return successful:EOK,failed:ERROR
|
||||||
|
*/
|
||||||
|
uint32 ChannelDevRecvCallback(struct ChDev *dev, int (*dev_recv_callback) (void *dev, x_size_t length))
|
||||||
|
{
|
||||||
|
CHECK_CH_PARAM(dev );
|
||||||
|
|
||||||
|
dev->dev_recv_callback = dev_recv_callback;
|
||||||
|
|
||||||
|
return EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: support to open dev
|
||||||
|
* @param dev - dev pointer
|
||||||
|
* @return successful:EOK,failed:ERROR
|
||||||
|
*/
|
||||||
|
uint32 ChannelDevOpen(struct ChDev *dev)
|
||||||
|
{
|
||||||
|
CHECK_CH_PARAM(dev);
|
||||||
|
|
||||||
|
int ret = EOK;
|
||||||
|
|
||||||
|
if (dev->dev_done->open) {
|
||||||
|
ret = dev->dev_done->open(dev);
|
||||||
|
if(ret) {
|
||||||
|
KPrintf("ChannelDevOpen error ret %u\n", ret);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: support to close dev
|
||||||
|
* @param dev - dev pointer
|
||||||
|
* @return successful:EOK,failed:ERROR
|
||||||
|
*/
|
||||||
|
uint32 ChannelDevClose(struct ChDev *dev)
|
||||||
|
{
|
||||||
|
CHECK_CH_PARAM(dev);
|
||||||
|
|
||||||
|
int ret = EOK;
|
||||||
|
|
||||||
|
if (dev->dev_done->close) {
|
||||||
|
ret = dev->dev_done->close(dev);
|
||||||
|
if(ret) {
|
||||||
|
KPrintf("ChannelDevClose error ret %u\n", ret);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: support to write data to dev
|
||||||
|
* @param dev - dev pointer
|
||||||
|
* @param write_param - ChWriteParam
|
||||||
|
* @return successful:EOK,failed:NONE
|
||||||
|
*/
|
||||||
|
uint32 ChannelDevWriteData(struct ChDev *dev, struct ChWriteParam *write_param)
|
||||||
|
{
|
||||||
|
CHECK_CH_PARAM(dev);
|
||||||
|
|
||||||
|
if (dev->dev_done->write) {
|
||||||
|
return dev->dev_done->write(dev, write_param);
|
||||||
|
}
|
||||||
|
|
||||||
|
return EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: support to read data from dev
|
||||||
|
* @param dev - dev pointer
|
||||||
|
* @param read_param - ChReadParam
|
||||||
|
* @return successful:EOK,failed:NONE
|
||||||
|
*/
|
||||||
|
uint32 ChannelDevReadData(struct ChDev *dev, struct ChReadParam *read_param)
|
||||||
|
{
|
||||||
|
CHECK_CH_PARAM(dev);
|
||||||
|
|
||||||
|
if (dev->dev_done->read) {
|
||||||
|
return dev->dev_done->read(dev, read_param);
|
||||||
|
}
|
||||||
|
|
||||||
|
return EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: support to configure drv, include OPE_CFG and OPE_INT
|
||||||
|
* @param drv - drv pointer
|
||||||
|
* @param config - ChConfigInfo
|
||||||
|
* @return successful:EOK,failed:NONE
|
||||||
|
*/
|
||||||
|
uint32 ChannelDrvConfigure(struct ChDrv *drv, struct ChConfigInfo *config)
|
||||||
|
{
|
||||||
|
CHECK_CH_PARAM(drv);
|
||||||
|
CHECK_CH_PARAM(config);
|
||||||
|
|
||||||
|
int ret = EOK;
|
||||||
|
|
||||||
|
if (drv->configure) {
|
||||||
|
ret = drv->configure(drv, config);
|
||||||
|
if(ret) {
|
||||||
|
KPrintf("ChannelDrvCfg error, ret %u\n", ret);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PlcChannelInit(struct PlcChannel* plc_ch, const char* ch_name)
|
||||||
|
{
|
||||||
|
CHECK_CH_PARAM(plc_ch);
|
||||||
|
CHECK_CH_PARAM(ch_name);
|
||||||
|
int ret = EOK;
|
||||||
|
|
||||||
|
if(CHANNEL_INSTALL != plc_ch->ch.ch_state)
|
||||||
|
{
|
||||||
|
strncpy(plc_ch->ch.ch_name, ch_name, NAME_NUM_MAX);
|
||||||
|
plc_ch->ch.ch_type = CH_PLC_TYPE;
|
||||||
|
plc_ch->ch.ch_state = CHANNEL_INSTALL;
|
||||||
|
plc_ch->ch.private_data = plc_ch->private_data;
|
||||||
|
ret = ChannelRegister(&plc_ch->ch);
|
||||||
|
|
||||||
|
if(EOK != ret)
|
||||||
|
{
|
||||||
|
KPrintf("PlcChannelInit ChannelRegister error %u\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
KPrintf("PlcChannelInit ChannelRegister channel has been register state %u\n",
|
||||||
|
plc_ch->ch.ch_state);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PlcDriverInit(struct PlcDriver* plc_driver, const char* driver_name)
|
||||||
|
{
|
||||||
|
CHECK_CH_PARAM(plc_driver);
|
||||||
|
CHECK_CH_PARAM(driver_name);
|
||||||
|
int ret = EOK;
|
||||||
|
|
||||||
|
if(CHDRV_INSTALL != plc_driver->driver.driver_state)
|
||||||
|
{
|
||||||
|
plc_driver->driver.driver_type = CHDRV_PLC_TYPE;
|
||||||
|
plc_driver->driver.driver_state = CHDRV_INSTALL;
|
||||||
|
strncpy(plc_driver->driver.drv_name, driver_name, NAME_NUM_MAX);
|
||||||
|
plc_driver->driver.configure = plc_driver->configure;
|
||||||
|
ret = PlcDriverRegister(&plc_driver->driver);
|
||||||
|
|
||||||
|
if(EOK != ret)
|
||||||
|
{
|
||||||
|
KPrintf("PlcDriverInit DriverRegister error %u\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
KPrintf("PlcDriverInit Driver %s has been register state %u\n",
|
||||||
|
driver_name, plc_driver->driver.driver_state);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PlcReleaseChannel(struct PlcChannel* plc_ch)
|
||||||
|
{
|
||||||
|
CHECK_CH_PARAM(plc_ch);
|
||||||
|
return ChannelRelease(&plc_ch->ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
int PlcDriverAttachToChannel(const char* drv_name, const char* ch_name)
|
||||||
|
{
|
||||||
|
CHECK_CH_PARAM(drv_name);
|
||||||
|
CHECK_CH_PARAM(ch_name);
|
||||||
|
int ret = EOK;
|
||||||
|
struct Channel* ch;
|
||||||
|
struct ChDrv* driver;
|
||||||
|
ch = ChannelFind(ch_name);
|
||||||
|
|
||||||
|
if(NONE == ch)
|
||||||
|
{
|
||||||
|
KPrintf("PlcDriverAttachToChannel find plc channel error!name %s\n", ch_name);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(CH_PLC_TYPE == ch->ch_type)
|
||||||
|
{
|
||||||
|
driver = PlcDriverFind(drv_name, CHDRV_PLC_TYPE);
|
||||||
|
|
||||||
|
if(NONE == driver)
|
||||||
|
{
|
||||||
|
KPrintf("PlcDriverAttachToChannel find plc driver error!name %s\n", drv_name);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(CHDRV_PLC_TYPE == driver->driver_type)
|
||||||
|
{
|
||||||
|
ret = DriverRegisterToChannel(ch, driver);
|
||||||
|
|
||||||
|
if(EOK != ret)
|
||||||
|
{
|
||||||
|
KPrintf("PlcDriverAttachToChannel DriverRegisterToBus error %u\n", ret);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
|
@ -0,0 +1,278 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 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 plc_channel.h
|
||||||
|
* @brief define ch driver framework function and common API
|
||||||
|
* @version 1.0
|
||||||
|
* @author AIIT XUOS Lab
|
||||||
|
* @date 2022-03-01
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __PLC_CHANNEL_H_
|
||||||
|
#define __PLC_CHANNEL_H_
|
||||||
|
|
||||||
|
#include "list.h"
|
||||||
|
|
||||||
|
#define x_OffPos uint32
|
||||||
|
#define x_size_t size_t
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define OPE_INT 0x0000
|
||||||
|
#define OPE_CFG 0x0001
|
||||||
|
|
||||||
|
#define OPER_WDT_SET_TIMEOUT 0x0002
|
||||||
|
#define OPER_WDT_KEEPALIVE 0x0003
|
||||||
|
|
||||||
|
#define CHECK_CH_PARAM(param) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
if(param == NONE) { \
|
||||||
|
KPrintf("PARAM CHECK FAILED ...%s %d %s is NULL.\n",__FUNCTION__,__LINE__,#param); \
|
||||||
|
while(RET_TRUE); \
|
||||||
|
} \
|
||||||
|
}while (0)
|
||||||
|
|
||||||
|
typedef struct Channel *ChannelType;
|
||||||
|
typedef struct ChDev *ChDevType;
|
||||||
|
typedef struct ChDrv *ChDrvType;
|
||||||
|
|
||||||
|
/* need to add new ch type in ../tool/shell/letter-shell/cmd.c, ensure ShowBus cmd supported*/
|
||||||
|
enum ChType_e
|
||||||
|
{
|
||||||
|
CH_PLC_TYPE,
|
||||||
|
CH_END_TYPE,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ChState_e
|
||||||
|
{
|
||||||
|
CHANNEL_INIT = 0,
|
||||||
|
CHANNEL_INSTALL,
|
||||||
|
CHANNEL_UNINSTALL,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ChDevType_e
|
||||||
|
{
|
||||||
|
CHDEV_PLC_TYPE,
|
||||||
|
CHDEV_END_TYPE,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ChDevState_e
|
||||||
|
{
|
||||||
|
CHDEV_INIT = 0,
|
||||||
|
CHDEV_INSTALL,
|
||||||
|
CHDEV_UNINSTALL,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ChDrvType_e
|
||||||
|
{
|
||||||
|
CHDRV_PLC_TYPE,
|
||||||
|
CHDRV_END_TYPE,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ChDrvState_e
|
||||||
|
{
|
||||||
|
CHDRV_INIT = 0,
|
||||||
|
CHDRV_INSTALL,
|
||||||
|
CHDRV_UNINSTALL,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ChConfigInfo
|
||||||
|
{
|
||||||
|
int configure_cmd;
|
||||||
|
void *private_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ChReadParam
|
||||||
|
{
|
||||||
|
x_OffPos pos;
|
||||||
|
void* buffer;
|
||||||
|
x_size_t size;
|
||||||
|
x_size_t read_length;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ChWriteParam
|
||||||
|
{
|
||||||
|
x_OffPos pos;
|
||||||
|
const void* buffer;
|
||||||
|
x_size_t size;
|
||||||
|
};
|
||||||
|
|
||||||
|
//struct ChHalDevBlockParam
|
||||||
|
//{
|
||||||
|
// uint32 cmd;
|
||||||
|
////tst by wly
|
||||||
|
//// struct DeviceBlockArrange dev_block;
|
||||||
|
//// struct DeviceBlockAddr *dev_addr;
|
||||||
|
//};
|
||||||
|
|
||||||
|
struct ChHalDevDone
|
||||||
|
{
|
||||||
|
uint32 (*open) (void *dev);
|
||||||
|
uint32 (*close) (void *dev);
|
||||||
|
uint32 (*write) (void *dev, struct ChWriteParam *write_param);
|
||||||
|
uint32 (*read) (void *dev, struct ChReadParam *read_param);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ChDev
|
||||||
|
{
|
||||||
|
int8 dev_name[NAME_NUM_MAX];
|
||||||
|
enum ChDevType_e dev_type;
|
||||||
|
enum ChDevState_e dev_state;
|
||||||
|
|
||||||
|
const struct ChHalDevDone *dev_done;
|
||||||
|
|
||||||
|
int (*dev_recv_callback) (void *dev, x_size_t length);
|
||||||
|
// int (*dev_block_control) (struct ChDev *dev, struct ChHalDevBlockParam *block_param);
|
||||||
|
|
||||||
|
struct Channel *owner_ch;
|
||||||
|
void *private_data;
|
||||||
|
|
||||||
|
int32 dev_sem;
|
||||||
|
|
||||||
|
DoublelistType dev_link;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ChDrv
|
||||||
|
{
|
||||||
|
int8 drv_name[NAME_NUM_MAX];
|
||||||
|
enum ChDrvType_e driver_type;
|
||||||
|
enum ChDrvState_e driver_state;
|
||||||
|
|
||||||
|
uint32 (*configure)(void *drv, struct ChConfigInfo *config);
|
||||||
|
|
||||||
|
struct Channel *owner_ch;
|
||||||
|
void *private_data;
|
||||||
|
|
||||||
|
DoublelistType driver_link;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Channel
|
||||||
|
{
|
||||||
|
int8 ch_name[NAME_NUM_MAX];
|
||||||
|
enum ChType_e ch_type;
|
||||||
|
enum ChState_e ch_state;
|
||||||
|
|
||||||
|
int32 (*match)(struct ChDrv *driver, struct ChDev *device);
|
||||||
|
|
||||||
|
int ch_lock;
|
||||||
|
|
||||||
|
struct ChDev *owner_haldev;
|
||||||
|
struct ChDrv *owner_driver;
|
||||||
|
|
||||||
|
void *private_data;
|
||||||
|
|
||||||
|
/*manage the drv of the channel*/
|
||||||
|
uint8 driver_cnt;
|
||||||
|
uint8 ch_drvlink_flag;
|
||||||
|
DoublelistType ch_drvlink;
|
||||||
|
|
||||||
|
/*manage the dev of the channel*/
|
||||||
|
uint8 haldev_cnt;
|
||||||
|
uint8 ch_devlink_flag;
|
||||||
|
DoublelistType ch_devlink;
|
||||||
|
|
||||||
|
uint8 ch_cnt;
|
||||||
|
uint8 ch_link_flag;
|
||||||
|
DoublelistType ch_link;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*Register the BUS,manage with the double linklist*/
|
||||||
|
int ChannelRegister(struct Channel *ch);
|
||||||
|
|
||||||
|
/*Release the BUS framework*/
|
||||||
|
int ChannelRelease(struct Channel *ch);
|
||||||
|
|
||||||
|
/*Unregister a certain kind of BUS*/
|
||||||
|
int ChannelUnregister(struct Channel *ch);
|
||||||
|
|
||||||
|
/*Register the driver to the channel*/
|
||||||
|
int DriverRegisterToChannel(struct Channel *ch, struct ChDrv *driver);
|
||||||
|
|
||||||
|
/*Register the device to the channel*/
|
||||||
|
int DeviceRegisterToChannel(struct Channel *ch, struct ChDev *device);
|
||||||
|
|
||||||
|
/*Delete the driver from the channel*/
|
||||||
|
int DriverDeleteFromChannel(struct Channel *ch, struct ChDrv *driver);
|
||||||
|
|
||||||
|
/*Delete the device from the channel*/
|
||||||
|
int DeviceDeleteFromChannel(struct Channel *ch, struct ChDev *device);
|
||||||
|
|
||||||
|
/*Find the ch with ch name*/
|
||||||
|
ChannelType ChannelFind(const char *ch_name);
|
||||||
|
|
||||||
|
/*Find the driver of cetain channel*/
|
||||||
|
ChDrvType ChannelFindDriver(struct Channel *ch, const char *driver_name);
|
||||||
|
|
||||||
|
/*Find the device of certain channel*/
|
||||||
|
ChDevType ChannelFindDevice(struct Channel *ch, const char *device_name);
|
||||||
|
|
||||||
|
/*Dev receive data callback function*/
|
||||||
|
uint32 ChannelDevRecvCallback(struct ChDev *dev, int (*dev_recv_callback) (void *dev, x_size_t length));
|
||||||
|
|
||||||
|
/*Open the device of the channel*/
|
||||||
|
uint32 ChannelDevOpen(struct ChDev *dev);
|
||||||
|
|
||||||
|
/*Close the device of the channel*/
|
||||||
|
uint32 ChannelDevClose(struct ChDev *dev);
|
||||||
|
|
||||||
|
/*Write data to the device*/
|
||||||
|
uint32 ChannelDevWriteData(struct ChDev *dev, struct ChWriteParam *write_param);
|
||||||
|
|
||||||
|
/*Read data from the device*/
|
||||||
|
uint32 ChannelDevReadData(struct ChDev *dev, struct ChReadParam *read_param);
|
||||||
|
|
||||||
|
/*Configure the driver of the channel*/
|
||||||
|
uint32 ChannelDrvConfigure(struct ChDrv *drv, struct ChConfigInfo *config);
|
||||||
|
|
||||||
|
/*Obtain the ch using a certain dev*/
|
||||||
|
int DeviceObtainChannel(struct Channel *ch, struct ChDev *dev, const char *drv_name, struct ChConfigInfo *config);
|
||||||
|
|
||||||
|
|
||||||
|
struct PlcDriver
|
||||||
|
{
|
||||||
|
struct ChDrv driver;
|
||||||
|
uint32 (*configure) (void *drv, struct ChConfigInfo *cfg);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PlcChannel
|
||||||
|
{
|
||||||
|
struct Channel ch;
|
||||||
|
void *private_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*Register the plc bus*/
|
||||||
|
int PlcChannelInit(struct PlcChannel *plc_ch, const char *ch_name);
|
||||||
|
|
||||||
|
/*Register the plc driver*/
|
||||||
|
int PlcDriverInit(struct PlcDriver *plc_driver, const char *driver_name);
|
||||||
|
|
||||||
|
/*Release the plc device*/
|
||||||
|
int PlcReleaseChannel(struct PlcChannel *plc_ch);
|
||||||
|
|
||||||
|
/*Register the plc driver to the plc bus*/
|
||||||
|
int PlcDriverAttachToChannel(const char *drv_name, const char *ch_name);
|
||||||
|
|
||||||
|
/*Register the driver, manage with the double linklist*/
|
||||||
|
int PlcDriverRegister(struct ChDrv *driver);
|
||||||
|
|
||||||
|
/*Find the register driver*/
|
||||||
|
ChDrvType PlcDriverFind(const char *drv_name, enum ChDrvType_e drv_type);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,189 @@
|
||||||
|
/*
|
||||||
|
* 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 plc.c
|
||||||
|
* @brief plc relative activities
|
||||||
|
* @version 1.0
|
||||||
|
* @author AIIT XUOS Lab
|
||||||
|
* @date 2021.12.15
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ua_api.h"
|
||||||
|
#include "plc_channel.h"
|
||||||
|
#include "plc_device.h"
|
||||||
|
|
||||||
|
DoublelistType plcdev_list;
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
/*Create the plc device linklist*/
|
||||||
|
static void PlcDeviceLinkInit()
|
||||||
|
{
|
||||||
|
AppInitDoubleList(&plcdev_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int PlcDeviceOpen(void *dev)
|
||||||
|
{
|
||||||
|
CHECK_CH_PARAM(dev);
|
||||||
|
|
||||||
|
struct PlcDevice *plc_dev = (struct PlcDevice *)dev;
|
||||||
|
|
||||||
|
if(plc_dev->net == PLC_IND_ENET_OPCUA)
|
||||||
|
{
|
||||||
|
return ua_open(plc_dev->priv_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
return EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void PlcDeviceClose(void *dev)
|
||||||
|
{
|
||||||
|
CHECK_CH_PARAM(dev);
|
||||||
|
|
||||||
|
struct PlcDevice *plc_dev = (struct PlcDevice *)dev;
|
||||||
|
|
||||||
|
if(plc_dev->net == PLC_IND_ENET_OPCUA)
|
||||||
|
{
|
||||||
|
ua_close(plc_dev->priv_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int PlcDeviceWrite(void *dev, const void *buf, size_t len)
|
||||||
|
{
|
||||||
|
CHECK_CH_PARAM(dev);
|
||||||
|
|
||||||
|
int ret;
|
||||||
|
struct PlcDevice *plc_dev = (struct PlcDevice *)dev;
|
||||||
|
|
||||||
|
if(plc_dev->net == PLC_IND_ENET_OPCUA)
|
||||||
|
{
|
||||||
|
ret = ua_write(plc_dev->priv_data, buf, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int PlcDeviceRead(void *dev, void *buf, size_t len)
|
||||||
|
{
|
||||||
|
CHECK_CH_PARAM(dev);
|
||||||
|
CHECK_CH_PARAM(buf);
|
||||||
|
|
||||||
|
int ret;
|
||||||
|
struct PlcDevice *plc_dev = (struct PlcDevice *)dev;
|
||||||
|
|
||||||
|
if(plc_dev->net == PLC_IND_ENET_OPCUA)
|
||||||
|
{
|
||||||
|
ret = ua_read(plc_dev->priv_data, buf, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct PlcOps plc_done =
|
||||||
|
{
|
||||||
|
.open = PlcDeviceOpen,
|
||||||
|
.close = PlcDeviceClose,
|
||||||
|
.write = PlcDeviceWrite,
|
||||||
|
.read = PlcDeviceRead,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* find PLC device with device name */
|
||||||
|
struct ChDev *PlcDevFind(const char *dev_name)
|
||||||
|
{
|
||||||
|
CHECK_CH_PARAM(dev_name);
|
||||||
|
|
||||||
|
struct PlcDevice *device = NONE;
|
||||||
|
struct ChDev *haldev = NONE;
|
||||||
|
|
||||||
|
DoublelistType *node = NONE;
|
||||||
|
DoublelistType *head = &plcdev_list;
|
||||||
|
|
||||||
|
for (node = head->node_next; node != head; node = node->node_next) {
|
||||||
|
device = DOUBLE_LIST_ENTRY(node, struct PlcDevice, link);
|
||||||
|
if (!strcmp(device->name, dev_name)) {
|
||||||
|
haldev = &device->haldev;
|
||||||
|
return haldev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
plc_print("plc: [%s] cannot find the %s device\n", __func__, dev_name);
|
||||||
|
return NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PlcDevRegister(struct PlcDevice *plc_device, void *plc_param, const char *device_name)
|
||||||
|
{
|
||||||
|
CHECK_CH_PARAM(plc_device);
|
||||||
|
CHECK_CH_PARAM(device_name);
|
||||||
|
|
||||||
|
int ret = EOK;
|
||||||
|
static uint8_t dev_link_flag = 0;
|
||||||
|
|
||||||
|
if (!dev_link_flag) {
|
||||||
|
PlcDeviceLinkInit();
|
||||||
|
dev_link_flag = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CHDEV_INSTALL != plc_device->state) {
|
||||||
|
strncpy(plc_device->haldev.dev_name, device_name, NAME_NUM_MAX);
|
||||||
|
plc_device->haldev.dev_type = CHDEV_PLC_TYPE;
|
||||||
|
plc_device->haldev.dev_state = CHDEV_INSTALL;
|
||||||
|
|
||||||
|
strncpy(plc_device->name, device_name, strlen(device_name));
|
||||||
|
plc_device->ops = &plc_done;
|
||||||
|
|
||||||
|
AppDoubleListInsertNodeAfter(&plcdev_list, &(plc_device->link));
|
||||||
|
plc_device->state = CHDEV_INSTALL;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
KPrintf("PlcDevRegister device %s has been register state%u\n", device_name, plc_device->state);
|
||||||
|
ret = ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PlcDeviceAttachToChannel(const char *dev_name, const char *ch_name)
|
||||||
|
{
|
||||||
|
CHECK_CH_PARAM(dev_name);
|
||||||
|
CHECK_CH_PARAM(ch_name);
|
||||||
|
|
||||||
|
int ret = EOK;
|
||||||
|
|
||||||
|
struct Channel *ch;
|
||||||
|
struct ChDev *device;
|
||||||
|
|
||||||
|
ch = ChannelFind(ch_name);
|
||||||
|
if (NONE == ch) {
|
||||||
|
KPrintf("PlcDeviceAttachToChannel find plc ch error!name %s\n", ch_name);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CH_PLC_TYPE == ch->ch_type) {
|
||||||
|
device = PlcDevFind(dev_name);
|
||||||
|
if (NONE == device) {
|
||||||
|
KPrintf("PlcDeviceAttachToChannel find plc device %s error!\n", dev_name);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CHDEV_PLC_TYPE == device->dev_type) {
|
||||||
|
ret = DeviceRegisterToChannel(ch, device);
|
||||||
|
if (EOK != ret) {
|
||||||
|
KPrintf("PlcDeviceAttachToChannel DeviceRegisterToChannel error %u\n", ret);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return EOK;
|
||||||
|
}
|
||||||
|
|
|
@ -11,28 +11,38 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file plc.h
|
* @file plc_dev.h
|
||||||
* @brief plc relative definition and structure
|
* @brief plc relative definition and structure
|
||||||
* @version 1.0
|
* @version 1.0
|
||||||
* @author AIIT XUOS Lab
|
* @author AIIT XUOS Lab
|
||||||
* @date 2021.12.15
|
* @date 2022-01-24
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "xs_klist.h"
|
#ifndef __PLC_DEV_H_
|
||||||
|
#define __PLC_DEV_H_
|
||||||
|
|
||||||
|
#include "list.h"
|
||||||
|
#include "plc_channel.h"
|
||||||
|
|
||||||
|
#undef open
|
||||||
|
#undef close
|
||||||
|
#undef read
|
||||||
|
#undef write
|
||||||
|
|
||||||
#define IP_ADDR_SIZE 32
|
#define IP_ADDR_SIZE 32
|
||||||
#define PLC_NAME_SIZE 32
|
#define PLC_NAME_SIZE 32
|
||||||
|
|
||||||
// PLC device information
|
// PLC device information
|
||||||
struct PlcInfo {
|
typedef struct PlcInfo {
|
||||||
uint32_t ability; // PLC ability
|
uint32_t ability; // PLC ability
|
||||||
uint32_t id; // PLC Device ID
|
uint32_t id; // PLC Device ID
|
||||||
uint32_t soft_version; // software version
|
uint32_t soft_version; // software version
|
||||||
uint32_t hard_version; // hardware version
|
uint32_t hard_version; // hardware version
|
||||||
uint32_t date; // manufact date
|
uint32_t date; // manufact date
|
||||||
const char *vendor; // vendor
|
const char *vendor; // vendor
|
||||||
const char *model; // product model
|
const char *model; // model
|
||||||
};
|
const char *product; // product
|
||||||
|
}PlcInfoType;
|
||||||
|
|
||||||
enum PlcSerialType {
|
enum PlcSerialType {
|
||||||
PLC_SERIAL_232,
|
PLC_SERIAL_232,
|
||||||
|
@ -55,13 +65,13 @@ union PlcCfg {
|
||||||
struct PlcDevice;
|
struct PlcDevice;
|
||||||
|
|
||||||
// operation API
|
// operation API
|
||||||
struct PlcOps {
|
typedef struct PlcOps {
|
||||||
int (*open)(struct PlcDevice *pdev); // open and connect PLC device
|
int (*open)(void *dev); // open and connect PLC device
|
||||||
void (*close)(struct PlcDevice*pdev); // close and disconnect PLC device
|
void (*close)(void* dev); // close and disconnect PLC device
|
||||||
int (*read)(struct PlcDevice* pdev, void *buf, size_t len); // read data from PLC
|
int (*read)(void* dev, void *buf, size_t len); // read data from PLC
|
||||||
int (*write)(struct PlcDevice* pdev, const void *buf, size_t len); // write data from PLC
|
int (*write)(void* dev, const void *buf, size_t len); // write data from PLC
|
||||||
int (*ioctl)(struct PlcDevice* pdev, int cmd, void *arg); // send control command to PLC
|
int (*ioctl)(void* dev, int cmd, void *arg); // send control command to PLC
|
||||||
};
|
}PlcOpsType;
|
||||||
|
|
||||||
enum PlcCtlType {
|
enum PlcCtlType {
|
||||||
PLC_CTRL_TYPE_HSC,
|
PLC_CTRL_TYPE_HSC,
|
||||||
|
@ -69,15 +79,13 @@ enum PlcCtlType {
|
||||||
PLC_CTRL_TYPE_PHASING
|
PLC_CTRL_TYPE_PHASING
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#define PLC_ABILITY_HSC ((uint32_t)(1 << PLC_CTRL_TYPE_HSC))
|
#define PLC_ABILITY_HSC ((uint32_t)(1 << PLC_CTRL_TYPE_HSC))
|
||||||
#define PLC_ABILITY_PID ((uint32_t)(1 << PLC_CTRL_TYPE_PID))
|
#define PLC_ABILITY_PID ((uint32_t)(1 << PLC_CTRL_TYPE_PID))
|
||||||
#define PLC_ABILITY_PHASING ((uint32_t)(1 << PLC_CTRL_TYPE_PHASING))
|
#define PLC_ABILITY_PHASING ((uint32_t)(1 << PLC_CTRL_TYPE_PHASING))
|
||||||
|
|
||||||
|
|
||||||
enum PlcIndHybridNet
|
enum PlcIndHybridNet
|
||||||
{
|
{
|
||||||
//PLC Field Bus
|
// PLC Field Bus
|
||||||
PLC_IND_FIELD_MODBUS_485,
|
PLC_IND_FIELD_MODBUS_485,
|
||||||
PLC_IND_FIELD_PROFIBUS,
|
PLC_IND_FIELD_PROFIBUS,
|
||||||
PLC_IND_FIELD_CANOPEN,
|
PLC_IND_FIELD_CANOPEN,
|
||||||
|
@ -91,7 +99,7 @@ enum PlcIndHybridNet
|
||||||
PLC_IND_ENET_SERCOS,
|
PLC_IND_ENET_SERCOS,
|
||||||
PLC_IND_ENET_OPCUA,
|
PLC_IND_ENET_OPCUA,
|
||||||
|
|
||||||
//PLC wireless net
|
// PLC wireless net
|
||||||
PLC_IND_WIRELESS
|
PLC_IND_WIRELESS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -103,22 +111,43 @@ enum PlcTransType
|
||||||
};
|
};
|
||||||
|
|
||||||
//communication interface
|
//communication interface
|
||||||
struct PlcInterface
|
typedef struct PlcInterface
|
||||||
{
|
{
|
||||||
enum PlcIndHybridNet net;
|
|
||||||
enum PlcTransType trans;
|
|
||||||
char ip_addr[IP_ADDR_SIZE];
|
char ip_addr[IP_ADDR_SIZE];
|
||||||
char attrib;
|
char attrib;
|
||||||
};
|
}PlcInterfaceType;
|
||||||
|
|
||||||
// identify PLC device
|
// identify PLC device
|
||||||
struct PlcDevice {
|
typedef struct PlcDevice {
|
||||||
const char name[PLC_NAME_SIZE]; /* name of the device */
|
struct ChDev haldev; /* hardware device driver for channel */
|
||||||
|
enum ChDevState_e state;
|
||||||
|
|
||||||
|
char name[PLC_NAME_SIZE]; /* name of the device */
|
||||||
enum PlcCtlType type; /* PLC Control Type */
|
enum PlcCtlType type; /* PLC Control Type */
|
||||||
|
enum PlcIndHybridNet net;
|
||||||
|
enum PlcTransType trans;
|
||||||
|
|
||||||
struct PlcInfo info;/* Plc info, such as vendor name and model name */
|
struct PlcInfo info;/* Plc info, such as vendor name and model name */
|
||||||
union PlcCfg cfg;
|
union PlcCfg cfg;
|
||||||
struct PlcOps ops; /* filesystem-like APIs for data transferring */
|
struct PlcOps *ops; /* filesystem-like APIs for data transferring */
|
||||||
struct PlcInterface interface; /* protocols used for transferring data from program to plc */
|
struct PlcInterface interface; /* protocols used for transferring data from program to plc */
|
||||||
DoubleLinklistType link;/* link list node */
|
|
||||||
};
|
|
||||||
|
|
||||||
|
void *priv_data; /* private data for different PLC*/
|
||||||
|
DoublelistType link;/* link list node */
|
||||||
|
}PlcDeviceType;
|
||||||
|
|
||||||
|
typedef struct PlcCtrlParam {
|
||||||
|
void *node_id; // for node ID
|
||||||
|
int value;
|
||||||
|
}PlcCtrlParamType;
|
||||||
|
|
||||||
|
#define plc_print KPrintf
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
int PlcDevRegister(struct PlcDevice *plc_device, void *plc_param, const char *device_name);
|
||||||
|
int PlcDeviceAttachToChannel(const char *dev_name, const char *ch_name);
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,71 @@
|
||||||
|
/*
|
||||||
|
* 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 drv_plc.c
|
||||||
|
* @brief register plc drv function using bus driver framework
|
||||||
|
* @version 1.0
|
||||||
|
* @author AIIT XUOS Lab
|
||||||
|
* @date 2022-01-24
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "transform.h"
|
||||||
|
#include "plc_channel.h"
|
||||||
|
#include "plc_device.h"
|
||||||
|
|
||||||
|
static DoublelistType plcdrv_linklist;
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
/*Create the driver linklist*/
|
||||||
|
static void PlcDrvLinkInit()
|
||||||
|
{
|
||||||
|
AppInitDoubleList(&plcdrv_linklist);
|
||||||
|
}
|
||||||
|
|
||||||
|
ChDrvType PlcDriverFind(const char *drv_name, enum ChDrvType_e drv_type)
|
||||||
|
{
|
||||||
|
CHECK_CH_PARAM(drv_name);
|
||||||
|
|
||||||
|
struct ChDrv *driver = NONE;
|
||||||
|
|
||||||
|
DoublelistType *node = NONE;
|
||||||
|
DoublelistType *head = &plcdrv_linklist;
|
||||||
|
|
||||||
|
for (node = head->node_next; node != head; node = node->node_next) {
|
||||||
|
driver = DOUBLE_LIST_ENTRY(node, struct ChDrv, driver_link);
|
||||||
|
if ((!strcmp(driver->drv_name, drv_name)) && (drv_type == driver->driver_type)) {
|
||||||
|
return driver;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
KPrintf("PlcDriverFind cannot find the %s driver.return NULL\n", drv_name);
|
||||||
|
return NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PlcDriverRegister(struct ChDrv *driver)
|
||||||
|
{
|
||||||
|
CHECK_CH_PARAM(driver);
|
||||||
|
|
||||||
|
int ret = EOK;
|
||||||
|
static uint8_t driver_link_flag = 0;
|
||||||
|
|
||||||
|
if (!driver_link_flag) {
|
||||||
|
PlcDrvLinkInit();
|
||||||
|
driver_link_flag = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
AppDoubleListInsertNodeAfter(&plcdrv_linklist, &(driver->driver_link));
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
SRC_DIR :=
|
SRC_FILES := control.c
|
||||||
|
|
||||||
include $(KERNEL_ROOT)/compiler.mk
|
include $(KERNEL_ROOT)/compiler.mk
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
{
|
||||||
|
"siemens plc":
|
||||||
|
{
|
||||||
|
"device type": "PLC",
|
||||||
|
"control type": "HSC",
|
||||||
|
"info":
|
||||||
|
{
|
||||||
|
"plc ability" : 1,
|
||||||
|
"plc device id": 1,
|
||||||
|
"soft version" : 1,
|
||||||
|
"hardware version": 1,
|
||||||
|
"date": "2022-1-28",
|
||||||
|
"vendor": "siemens",
|
||||||
|
"model":"S300"
|
||||||
|
},
|
||||||
|
|
||||||
|
"serial config":
|
||||||
|
{
|
||||||
|
"serial type":"485",
|
||||||
|
"station id" : "station1",
|
||||||
|
"serial port" : 1
|
||||||
|
},
|
||||||
|
|
||||||
|
"network config":
|
||||||
|
{
|
||||||
|
"ip addr" : "192.168.250.5",
|
||||||
|
"ip port" : 4840
|
||||||
|
},
|
||||||
|
|
||||||
|
"interface":
|
||||||
|
{
|
||||||
|
"inhybridnet":"OPCUA",
|
||||||
|
"transport":"TCP",
|
||||||
|
"ip address": "192.168.250.5",
|
||||||
|
"attribute" : "1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,8 @@
|
||||||
|
|
||||||
|
#include "cJSON.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void control_init(void)
|
void control_init(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -6,6 +10,12 @@ void control_init(void)
|
||||||
|
|
||||||
void control_read_file()
|
void control_read_file()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -171,9 +171,6 @@ int PrivMutexDelete(pthread_mutex_t *p_mutex);
|
||||||
int PrivMutexObtain(pthread_mutex_t *p_mutex);
|
int PrivMutexObtain(pthread_mutex_t *p_mutex);
|
||||||
int PrivMutexAbandon(pthread_mutex_t *p_mutex);
|
int PrivMutexAbandon(pthread_mutex_t *p_mutex);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*********************semaphore**********************/
|
/*********************semaphore**********************/
|
||||||
|
|
||||||
int PrivSemaphoreCreate(sem_t *sem, int pshared, unsigned int value);
|
int PrivSemaphoreCreate(sem_t *sem, int pshared, unsigned int value);
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
Subproject commit 562239ecb2d84dd9de2dd206da41df19602e20cb
|
|
|
@ -1 +0,0 @@
|
||||||
Subproject commit 3fede42098e5883f336d846ac30edfe749899494
|
|
|
@ -23,6 +23,7 @@ Author: AIIT XUOS Lab
|
||||||
Modification:
|
Modification:
|
||||||
1. support imxrt1052-board MPU、clock、memory init
|
1. support imxrt1052-board MPU、clock、memory init
|
||||||
2. support imxrt1052-board uart、semc、sdio driver init
|
2. support imxrt1052-board uart、semc、sdio driver init
|
||||||
|
3. support imxrt1052-board I2C, SPI, ADC, RTC driver init
|
||||||
*************************************************/
|
*************************************************/
|
||||||
|
|
||||||
#include "fsl_common.h"
|
#include "fsl_common.h"
|
||||||
|
@ -67,6 +68,9 @@ int MountSDCard(void)
|
||||||
|
|
||||||
#include <connect_ethernet.h>
|
#include <connect_ethernet.h>
|
||||||
#include <connect_uart.h>
|
#include <connect_uart.h>
|
||||||
|
#include <connect_adc.h>
|
||||||
|
#include <connect_spi.h>
|
||||||
|
#include <connect_rtc.h>
|
||||||
|
|
||||||
#define NVIC_PRIORITYGROUP_0 0x00000007U /*!< 0 bits for pre-emption priority
|
#define NVIC_PRIORITYGROUP_0 0x00000007U /*!< 0 bits for pre-emption priority
|
||||||
4 bits for subpriority */
|
4 bits for subpriority */
|
||||||
|
@ -660,6 +664,18 @@ void InitBoardHardware()
|
||||||
Imrt1052HwUartInit();
|
Imrt1052HwUartInit();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef BSP_USING_ADC
|
||||||
|
Imrt1052HwAdcInit();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef BSP_USING_SPI
|
||||||
|
Imrt1052HwSpiInit();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef BSP_USING_RTC
|
||||||
|
Imrt1052HwRtcInit();
|
||||||
|
#endif
|
||||||
|
|
||||||
InstallConsole(KERNEL_CONSOLE_BUS_NAME, KERNEL_CONSOLE_DRV_NAME, KERNEL_CONSOLE_DEVICE_NAME);
|
InstallConsole(KERNEL_CONSOLE_BUS_NAME, KERNEL_CONSOLE_DRV_NAME, KERNEL_CONSOLE_DEVICE_NAME);
|
||||||
|
|
||||||
#ifdef BSP_USING_SDIO
|
#ifdef BSP_USING_SDIO
|
||||||
|
|
|
@ -2,7 +2,15 @@ export CROSS_COMPILE ?=/usr/bin/arm-none-eabi-
|
||||||
|
|
||||||
export CFLAGS := -mcpu=cortex-m7 -mthumb -ffunction-sections -fdata-sections -Dgcc -O0 -gdwarf-2 -g -fgnu89-inline -Wa,-mimplicit-it=thumb
|
export CFLAGS := -mcpu=cortex-m7 -mthumb -ffunction-sections -fdata-sections -Dgcc -O0 -gdwarf-2 -g -fgnu89-inline -Wa,-mimplicit-it=thumb
|
||||||
export AFLAGS := -c -mcpu=cortex-m7 -mthumb -ffunction-sections -fdata-sections -x assembler-with-cpp -Wa,-mimplicit-it=thumb -gdwarf-2
|
export AFLAGS := -c -mcpu=cortex-m7 -mthumb -ffunction-sections -fdata-sections -x assembler-with-cpp -Wa,-mimplicit-it=thumb -gdwarf-2
|
||||||
|
|
||||||
|
### if use USB function, use special lds file because USB uses ITCM
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_BSP_USING_USB),y)
|
||||||
|
export LFLAGS := -mcpu=cortex-m7 -mthumb -ffunction-sections -fdata-sections -Wl,--gc-sections,-Map=XiZi_ok1052-c.map,-cref,-u,Reset_Handler -T $(BSP_ROOT)/link-usb.lds
|
||||||
|
else
|
||||||
export LFLAGS := -mcpu=cortex-m7 -mthumb -ffunction-sections -fdata-sections -Wl,--gc-sections,-Map=XiZi_ok1052-c.map,-cref,-u,Reset_Handler -T $(BSP_ROOT)/link.lds
|
export LFLAGS := -mcpu=cortex-m7 -mthumb -ffunction-sections -fdata-sections -Wl,--gc-sections,-Map=XiZi_ok1052-c.map,-cref,-u,Reset_Handler -T $(BSP_ROOT)/link.lds
|
||||||
|
endif
|
||||||
|
|
||||||
export CXXFLAGS := -mcpu=cortex-m7 -mthumb -ffunction-sections -fdata-sections -Dgcc -O0 -gdwarf-2 -g
|
export CXXFLAGS := -mcpu=cortex-m7 -mthumb -ffunction-sections -fdata-sections -Dgcc -O0 -gdwarf-2 -g
|
||||||
|
|
||||||
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 APPLFLAGS := -mcpu=cortex-m7 -mthumb -ffunction-sections -fdata-sections -Wl,--gc-sections,-Map=XiZi_app.map,-cref,-u, -T $(BSP_ROOT)/link_userspace.lds
|
||||||
|
|
|
@ -5,19 +5,6 @@
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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 board.h
|
* @file board.h
|
||||||
* @brief define imxrt1052-board init configure and start-up function
|
* @brief define imxrt1052-board init configure and start-up function
|
||||||
|
|
|
@ -71,6 +71,8 @@ void BOARD_InitBootPins(void);
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void BOARD_InitPins(void);
|
void BOARD_InitPins(void);
|
||||||
|
void BOARD_InitI2C1Pins(void);
|
||||||
|
void BOARD_InitSPIPins(void);
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,250 @@
|
||||||
|
/*
|
||||||
|
** ###################################################################
|
||||||
|
** Processors: MIMXRT1052CVJ5B
|
||||||
|
** MIMXRT1052CVL5B
|
||||||
|
** MIMXRT1052DVJ6B
|
||||||
|
** MIMXRT1052DVL6B
|
||||||
|
**
|
||||||
|
** Compiler: GNU C Compiler
|
||||||
|
** Reference manual: IMXRT1050RM Rev.1, 03/2018
|
||||||
|
** Version: rev. 1.0, 2018-09-21
|
||||||
|
** Build: b180921
|
||||||
|
**
|
||||||
|
** Abstract:
|
||||||
|
** Linker file for the GNU C Compiler
|
||||||
|
**
|
||||||
|
** Copyright 2016 Freescale Semiconductor, Inc.
|
||||||
|
** Copyright 2016-2018 NXP
|
||||||
|
** All rights reserved.
|
||||||
|
**
|
||||||
|
** SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
**
|
||||||
|
** http: www.nxp.com
|
||||||
|
** mail: support@nxp.com
|
||||||
|
**
|
||||||
|
** ###################################################################
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file link.lds
|
||||||
|
* @brief ok1052-c Linker script
|
||||||
|
* @version 1.0
|
||||||
|
* @author AIIT XUOS Lab
|
||||||
|
* @date 2021-05-28
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
File name: link.lds
|
||||||
|
Description: ok1052-c Linker script
|
||||||
|
Others: take MIMXRT1052xxxxx_flexspi_nor.ld for references
|
||||||
|
History:
|
||||||
|
1. Date: 2021-05-28
|
||||||
|
Author: AIIT XUOS Lab
|
||||||
|
Modification:
|
||||||
|
1. add shell cmd table and g_service_table
|
||||||
|
*************************************************/
|
||||||
|
|
||||||
|
/* Entry Point */
|
||||||
|
ENTRY(Reset_Handler)
|
||||||
|
|
||||||
|
HEAP_SIZE = DEFINED(__heap_size__) ? __heap_size__ : 0x0400;
|
||||||
|
STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x1000;
|
||||||
|
|
||||||
|
/* Specify the memory areas */
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
m_interrupts (RX) : ORIGIN = 0x60002000, LENGTH = 0x00000400
|
||||||
|
m_text (RX) : ORIGIN = 0x60002400, LENGTH = 0x03FFDC00
|
||||||
|
m_data (RW) : ORIGIN = 0x20000000, LENGTH = 0x00020000
|
||||||
|
m_data2 (RW) : ORIGIN = 0x20200000, LENGTH = 0x00060000
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Define output sections */
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
|
||||||
|
/* The startup code goes first into internal RAM */
|
||||||
|
.interrupts :
|
||||||
|
{
|
||||||
|
__VECTOR_TABLE = .;
|
||||||
|
. = ALIGN(4);
|
||||||
|
KEEP(*(.isr_vector)) /* Startup code */
|
||||||
|
. = ALIGN(4);
|
||||||
|
} > m_interrupts
|
||||||
|
|
||||||
|
__VECTOR_RAM = __VECTOR_TABLE;
|
||||||
|
__RAM_VECTOR_TABLE_SIZE_BYTES = 0x0;
|
||||||
|
|
||||||
|
/* The program code and other data goes into internal RAM */
|
||||||
|
.text :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
*(.text) /* .text sections (code) */
|
||||||
|
*(.text*) /* .text* sections (code) */
|
||||||
|
*(.rodata) /* .rodata sections (constants, strings, etc.) */
|
||||||
|
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
|
||||||
|
*(.glue_7) /* glue arm to thumb code */
|
||||||
|
*(.glue_7t) /* glue thumb to arm code */
|
||||||
|
*(.eh_frame)
|
||||||
|
KEEP (*(.init))
|
||||||
|
KEEP (*(.fini))
|
||||||
|
. = ALIGN(4);
|
||||||
|
|
||||||
|
|
||||||
|
/* section information for shell */
|
||||||
|
. = ALIGN(4);
|
||||||
|
_shell_command_start = .;
|
||||||
|
KEEP (*(shellCommand))
|
||||||
|
_shell_command_end = .;
|
||||||
|
. = ALIGN(4);
|
||||||
|
|
||||||
|
__isrtbl_idx_start = .;
|
||||||
|
KEEP(*(.isrtbl.idx))
|
||||||
|
__isrtbl_start = .;
|
||||||
|
KEEP(*(.isrtbl))
|
||||||
|
__isrtbl_end = .;
|
||||||
|
. = ALIGN(4);
|
||||||
|
|
||||||
|
PROVIDE(g_service_table_start = ABSOLUTE(.));
|
||||||
|
KEEP(*(.g_service_table))
|
||||||
|
PROVIDE(g_service_table_end = ABSOLUTE(.));
|
||||||
|
} > m_text
|
||||||
|
|
||||||
|
.ARM.extab :
|
||||||
|
{
|
||||||
|
*(.ARM.extab* .gnu.linkonce.armextab.*)
|
||||||
|
} > m_text
|
||||||
|
|
||||||
|
.ARM :
|
||||||
|
{
|
||||||
|
__exidx_start = .;
|
||||||
|
*(.ARM.exidx*)
|
||||||
|
__exidx_end = .;
|
||||||
|
} > m_text
|
||||||
|
|
||||||
|
.ctors :
|
||||||
|
{
|
||||||
|
__CTOR_LIST__ = .;
|
||||||
|
/* gcc uses crtbegin.o to find the start of
|
||||||
|
the constructors, so we make sure it is
|
||||||
|
first. Because this is a wildcard, it
|
||||||
|
doesn't matter if the user does not
|
||||||
|
actually link against crtbegin.o; the
|
||||||
|
linker won't look for a file to match a
|
||||||
|
wildcard. The wildcard also means that it
|
||||||
|
doesn't matter which directory crtbegin.o
|
||||||
|
is in. */
|
||||||
|
KEEP (*crtbegin.o(.ctors))
|
||||||
|
KEEP (*crtbegin?.o(.ctors))
|
||||||
|
/* We don't want to include the .ctor section from
|
||||||
|
from the crtend.o file until after the sorted ctors.
|
||||||
|
The .ctor section from the crtend file contains the
|
||||||
|
end of ctors marker and it must be last */
|
||||||
|
KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors))
|
||||||
|
KEEP (*(SORT(.ctors.*)))
|
||||||
|
KEEP (*(.ctors))
|
||||||
|
__CTOR_END__ = .;
|
||||||
|
} > m_text
|
||||||
|
|
||||||
|
.dtors :
|
||||||
|
{
|
||||||
|
__DTOR_LIST__ = .;
|
||||||
|
KEEP (*crtbegin.o(.dtors))
|
||||||
|
KEEP (*crtbegin?.o(.dtors))
|
||||||
|
KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors))
|
||||||
|
KEEP (*(SORT(.dtors.*)))
|
||||||
|
KEEP (*(.dtors))
|
||||||
|
__DTOR_END__ = .;
|
||||||
|
} > m_text
|
||||||
|
|
||||||
|
.preinit_array :
|
||||||
|
{
|
||||||
|
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||||
|
KEEP (*(.preinit_array*))
|
||||||
|
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||||
|
} > m_text
|
||||||
|
|
||||||
|
.init_array :
|
||||||
|
{
|
||||||
|
PROVIDE_HIDDEN (__init_array_start = .);
|
||||||
|
KEEP (*(SORT(.init_array.*)))
|
||||||
|
KEEP (*(.init_array*))
|
||||||
|
PROVIDE_HIDDEN (__init_array_end = .);
|
||||||
|
} > m_text
|
||||||
|
|
||||||
|
.fini_array :
|
||||||
|
{
|
||||||
|
PROVIDE_HIDDEN (__fini_array_start = .);
|
||||||
|
KEEP (*(SORT(.fini_array.*)))
|
||||||
|
KEEP (*(.fini_array*))
|
||||||
|
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||||
|
} > m_text
|
||||||
|
|
||||||
|
__etext = .; /* define a global symbol at end of code */
|
||||||
|
__DATA_ROM = .; /* Symbol is used by startup for data initialization */
|
||||||
|
|
||||||
|
.data : AT(__DATA_ROM)
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
__DATA_RAM = .;
|
||||||
|
__data_start__ = .; /* create a global symbol at data start */
|
||||||
|
*(m_usb_dma_init_data)
|
||||||
|
*(.data) /* .data sections */
|
||||||
|
*(.data*) /* .data* sections */
|
||||||
|
KEEP(*(.jcr*))
|
||||||
|
. = ALIGN(4);
|
||||||
|
__data_end__ = .; /* define a global symbol at data end */
|
||||||
|
} > m_data
|
||||||
|
|
||||||
|
__NDATA_ROM = __DATA_ROM + (__data_end__ - __data_start__);
|
||||||
|
.ncache.init : AT(__NDATA_ROM)
|
||||||
|
{
|
||||||
|
__noncachedata_start__ = .; /* create a global symbol at ncache data start */
|
||||||
|
*(NonCacheable.init)
|
||||||
|
. = ALIGN(4);
|
||||||
|
__noncachedata_init_end__ = .; /* create a global symbol at initialized ncache data end */
|
||||||
|
} > m_data
|
||||||
|
. = __noncachedata_init_end__;
|
||||||
|
.ncache :
|
||||||
|
{
|
||||||
|
*(NonCacheable)
|
||||||
|
. = ALIGN(4);
|
||||||
|
__noncachedata_end__ = .; /* define a global symbol at ncache data end */
|
||||||
|
} > m_data
|
||||||
|
|
||||||
|
__DATA_END = __NDATA_ROM + (__noncachedata_init_end__ - __noncachedata_start__);
|
||||||
|
text_end = ORIGIN(m_text) + LENGTH(m_text);
|
||||||
|
ASSERT(__DATA_END <= text_end, "region m_text overflowed with text and data")
|
||||||
|
|
||||||
|
/* Uninitialized data section */
|
||||||
|
.bss :
|
||||||
|
{
|
||||||
|
/* This is used by the startup in order to initialize the .bss section */
|
||||||
|
. = ALIGN(4);
|
||||||
|
__START_BSS = .;
|
||||||
|
__bss_start__ = .;
|
||||||
|
*(m_usb_dma_noninit_data)
|
||||||
|
*(.bss)
|
||||||
|
*(.bss*)
|
||||||
|
*(COMMON)
|
||||||
|
. = ALIGN(4);
|
||||||
|
__bss_end__ = .;
|
||||||
|
__END_BSS = .;
|
||||||
|
} > m_data
|
||||||
|
|
||||||
|
.stack :
|
||||||
|
{
|
||||||
|
. = ALIGN(8);
|
||||||
|
stack_start = .;
|
||||||
|
. += STACK_SIZE;
|
||||||
|
stack_end = .;
|
||||||
|
__StackTop = .;
|
||||||
|
heap_start = .;
|
||||||
|
} > m_data
|
||||||
|
|
||||||
|
PROVIDE(heap_end = ORIGIN(m_data) + LENGTH(m_data));
|
||||||
|
|
||||||
|
.ARM.attributes 0 : { *(.ARM.attributes) }
|
||||||
|
}
|
||||||
|
|
|
@ -241,9 +241,9 @@ SECTIONS
|
||||||
stack_end = .;
|
stack_end = .;
|
||||||
__StackTop = .;
|
__StackTop = .;
|
||||||
heap_start = .;
|
heap_start = .;
|
||||||
} > m_data
|
} > m_data2
|
||||||
|
|
||||||
PROVIDE(heap_end = ORIGIN(m_data) + LENGTH(m_data));
|
PROVIDE(heap_end = ORIGIN(m_data2) + LENGTH(m_data2));
|
||||||
|
|
||||||
.ARM.attributes 0 : { *(.ARM.attributes) }
|
.ARM.attributes 0 : { *(.ARM.attributes) }
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,50 @@ menuconfig BSP_USING_LWIP
|
||||||
default n
|
default n
|
||||||
select RESOURCES_LWIP
|
select RESOURCES_LWIP
|
||||||
|
|
||||||
|
menuconfig BSP_USING_GPIO
|
||||||
|
bool "Using GPIO device "
|
||||||
|
default y
|
||||||
|
select RESOURCES_PIN
|
||||||
|
|
||||||
|
if BSP_USING_GPIO
|
||||||
|
source "$BSP_DIR/third_party_driver/gpio/Kconfig"
|
||||||
|
endif
|
||||||
|
|
||||||
|
menuconfig BSP_USING_I2C
|
||||||
|
bool "Using I2C device"
|
||||||
|
default y
|
||||||
|
select RESOURCES_I2C
|
||||||
|
|
||||||
|
if BSP_USING_I2C
|
||||||
|
source "$BSP_DIR/third_party_driver/i2c/Kconfig"
|
||||||
|
endif
|
||||||
|
|
||||||
|
menuconfig BSP_USING_ADC
|
||||||
|
bool "Using ADC device"
|
||||||
|
default y
|
||||||
|
select RESOURCES_ADC
|
||||||
|
|
||||||
|
if BSP_USING_ADC
|
||||||
|
source "$BSP_DIR/third_party_driver/adc/Kconfig"
|
||||||
|
endif
|
||||||
|
|
||||||
|
menuconfig BSP_USING_SPI
|
||||||
|
bool "Using SPI device"
|
||||||
|
default y
|
||||||
|
select RESOURCES_SPI
|
||||||
|
|
||||||
|
if BSP_USING_SPI
|
||||||
|
source "$BSP_DIR/third_party_driver/spi/Kconfig"
|
||||||
|
endif
|
||||||
|
|
||||||
|
menuconfig BSP_USING_RTC
|
||||||
|
bool "Using RTC device"
|
||||||
|
default n
|
||||||
|
select RESOURCES_RTC
|
||||||
|
if BSP_USING_RTC
|
||||||
|
source "$BSP_DIR/third_party_driver/rtc/Kconfig"
|
||||||
|
endif
|
||||||
|
|
||||||
menuconfig BSP_USING_SEMC
|
menuconfig BSP_USING_SEMC
|
||||||
bool "Using SEMC device"
|
bool "Using SEMC device"
|
||||||
default n
|
default n
|
||||||
|
|
|
@ -8,10 +8,27 @@ ifeq ($(CONFIG_BSP_USING_LWIP),y)
|
||||||
SRC_DIR += ethernet
|
SRC_DIR += ethernet
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_BSP_USING_I2C),y)
|
||||||
|
SRC_DIR += i2c
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_BSP_USING_ADC),y)
|
||||||
|
SRC_DIR += adc
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_BSP_USING_SPI),y)
|
||||||
|
SRC_DIR += spi
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq ($(CONFIG_BSP_USING_SEMC),y)
|
ifeq ($(CONFIG_BSP_USING_SEMC),y)
|
||||||
SRC_DIR += semc
|
SRC_DIR += semc
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_BSP_USING_RTC),y)
|
||||||
|
SRC_DIR += rtc
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
ifeq ($(CONFIG_BSP_USING_SDIO),y)
|
ifeq ($(CONFIG_BSP_USING_SDIO),y)
|
||||||
SRC_DIR += sdio
|
SRC_DIR += sdio
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
config BSP_USING_ADC1
|
||||||
|
bool "Enable ADC1"
|
||||||
|
default y
|
||||||
|
if BSP_USING_ADC1
|
||||||
|
config ADC_BUS_NAME_1
|
||||||
|
string "adc bus 1 name"
|
||||||
|
default "adc1"
|
||||||
|
config ADC_DRV_NAME_1
|
||||||
|
string "adc bus 1 driver name"
|
||||||
|
default "adc1_drv"
|
||||||
|
config ADC_1_DEVICE_NAME_0
|
||||||
|
string "adc bus 1 device name"
|
||||||
|
default "adc1_dev"
|
||||||
|
endif
|
||||||
|
|
||||||
|
config BSP_USING_ADC2
|
||||||
|
bool "Enable ADC2"
|
||||||
|
default y
|
||||||
|
if BSP_USING_ADC2
|
||||||
|
config ADC_BUS_NAME_2
|
||||||
|
string "adc bus 2 name"
|
||||||
|
default "adc2"
|
||||||
|
config ADC_DRV_NAME_2
|
||||||
|
string "adc bus 2 driver name"
|
||||||
|
default "adc2_drv"
|
||||||
|
config ADC_2_DEVICE_NAME_0
|
||||||
|
string "adc bus 2 device name"
|
||||||
|
default "adc2_dev"
|
||||||
|
endif
|
|
@ -0,0 +1,3 @@
|
||||||
|
SRC_FILES := fsl_adc.c connect_adc.c
|
||||||
|
|
||||||
|
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -0,0 +1,295 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 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 Demo for ADC function
|
||||||
|
* @version 1.0
|
||||||
|
* @author AIIT XUOS Lab
|
||||||
|
* @date 2022.1.18
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "board.h"
|
||||||
|
#include "fsl_adc.h"
|
||||||
|
#include "fsl_common.h"
|
||||||
|
#include "dev_adc.h"
|
||||||
|
#include "bus_adc.h"
|
||||||
|
#include "connect_adc.h"
|
||||||
|
|
||||||
|
#define ADC1_BASE_ADDR ADC1
|
||||||
|
#define ADC1_IRQ ADC1_IRQn
|
||||||
|
#define ADC1_USER_CHANNEL 3U
|
||||||
|
#define ADC1_CHANNEL_GROUP 0U
|
||||||
|
|
||||||
|
#define ADC2_BASE_ADDR ADC2
|
||||||
|
#define ADC2_IRQ ADC2_IRQn
|
||||||
|
#define ADC2_USER_CHANNEL 4U
|
||||||
|
#define ADC2_CHANNEL_GROUP 0U
|
||||||
|
|
||||||
|
#define adc_print KPrintf
|
||||||
|
|
||||||
|
volatile bool adc1_flag;
|
||||||
|
volatile uint32_t adc1_val;
|
||||||
|
volatile uint32_t adc1_irq_cnt;
|
||||||
|
volatile bool adc2_flag;
|
||||||
|
volatile uint32_t adc2_val;
|
||||||
|
volatile uint32_t adc2_irq_cnt;
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Code
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
void ADC1_IRQHandler(int vector, void *param)
|
||||||
|
{
|
||||||
|
adc1_flag = true;
|
||||||
|
/* Read conversion result to clear the conversion completed flag. */
|
||||||
|
adc1_val = ADC_GetChannelConversionValue(ADC1_BASE_ADDR, ADC1_CHANNEL_GROUP);
|
||||||
|
adc1_irq_cnt++;
|
||||||
|
/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
|
||||||
|
exception return operation might vector to incorrect interrupt */
|
||||||
|
#if defined __CORTEX_M && (__CORTEX_M == 4U)
|
||||||
|
__DSB();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
DECLARE_HW_IRQ(ADC1_IRQn, ADC1_IRQHandler, NONE);
|
||||||
|
|
||||||
|
void ADC2_IRQHandler(int vector, void *param)
|
||||||
|
{
|
||||||
|
adc2_flag = true;
|
||||||
|
/* Read conversion result to clear the conversion completed flag. */
|
||||||
|
adc2_val = ADC_GetChannelConversionValue(ADC2_BASE_ADDR, ADC2_CHANNEL_GROUP);
|
||||||
|
adc2_irq_cnt++;
|
||||||
|
/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
|
||||||
|
exception return operation might vector to incorrect interrupt */
|
||||||
|
#if defined __CORTEX_M && (__CORTEX_M == 4U)
|
||||||
|
__DSB();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
DECLARE_HW_IRQ(ADC2_IRQn, ADC2_IRQHandler, NONE);
|
||||||
|
|
||||||
|
uint32 Imrt1052AdcOpen(void *dev)
|
||||||
|
{
|
||||||
|
struct AdcHardwareDevice *adc_dev = (struct AdcHardwareDevice *)dev;
|
||||||
|
adc_config_t adc_cfg;
|
||||||
|
|
||||||
|
#ifdef BSP_USING_ADC1
|
||||||
|
if (0 == strncmp(adc_dev->haldev.dev_name, ADC_1_DEVICE_NAME_0, NAME_NUM_MAX)) {
|
||||||
|
EnableIRQ(ADC1_IRQn);
|
||||||
|
ADC_GetDefaultConfig(&adc_cfg);
|
||||||
|
ADC_Init(ADC1, &adc_cfg);
|
||||||
|
#if !(defined(FSL_FEATURE_ADC_SUPPORT_HARDWARE_TRIGGER_REMOVE) && FSL_FEATURE_ADC_SUPPORT_HARDWARE_TRIGGER_REMOVE)
|
||||||
|
ADC_EnableHardwareTrigger(ADC1, false);
|
||||||
|
#endif
|
||||||
|
/* Do auto hardware calibration. */
|
||||||
|
if (kStatus_Success == ADC_DoAutoCalibration(ADC1))
|
||||||
|
{
|
||||||
|
adc_print("ADC_DoAntoCalibration() Done.\r\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
adc_print("ADC_DoAutoCalibration() Failed.\r\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef BSP_USING_ADC2
|
||||||
|
if (0 == strncmp(adc_dev->haldev.dev_name, ADC_2_DEVICE_NAME_0, NAME_NUM_MAX)) {
|
||||||
|
EnableIRQ(ADC2_IRQn);
|
||||||
|
ADC_GetDefaultConfig(&adc_cfg);
|
||||||
|
ADC_Init(ADC2, &adc_cfg);
|
||||||
|
#if !(defined(FSL_FEATURE_ADC_SUPPORT_HARDWARE_TRIGGER_REMOVE) && FSL_FEATURE_ADC_SUPPORT_HARDWARE_TRIGGER_REMOVE)
|
||||||
|
ADC_EnableHardwareTrigger(ADC2, false);
|
||||||
|
#endif
|
||||||
|
/* Do auto hardware calibration. */
|
||||||
|
if (kStatus_Success == ADC_DoAutoCalibration(ADC2))
|
||||||
|
{
|
||||||
|
adc_print("ADC_DoAntoCalibration() Done.\r\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
adc_print("ADC_DoAutoCalibration() Failed.\r\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 Imrt1052AdcClose(void *dev)
|
||||||
|
{
|
||||||
|
return EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 Imrt1052AdcRead(void *dev, struct BusBlockReadParam *read_param)
|
||||||
|
{
|
||||||
|
struct AdcHardwareDevice *adc_dev = (struct AdcHardwareDevice *)dev;
|
||||||
|
adc_channel_config_t ch_cfg;
|
||||||
|
|
||||||
|
#ifdef BSP_USING_ADC1
|
||||||
|
if (0 == strncmp(adc_dev->haldev.dev_name, ADC_1_DEVICE_NAME_0, NAME_NUM_MAX)) {
|
||||||
|
/* Configure the user channel and interrupt. */
|
||||||
|
ch_cfg.channelNumber = ADC1_USER_CHANNEL;
|
||||||
|
ch_cfg.enableInterruptOnConversionCompleted = true;
|
||||||
|
adc1_irq_cnt = 0U; /* Clear the interrupt counter. */
|
||||||
|
adc1_flag = false;
|
||||||
|
ADC_SetChannelConfig(ADC1, ADC1_CHANNEL_GROUP, &ch_cfg);
|
||||||
|
while (adc1_flag == false);
|
||||||
|
|
||||||
|
adc_print("ADC Value: %d\r\n", adc1_val);
|
||||||
|
adc_print("ADC Interrupt Counter: %d\r\n", adc1_irq_cnt);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef BSP_USING_ADC2
|
||||||
|
if (0 == strncmp(adc_dev->haldev.dev_name, ADC_2_DEVICE_NAME_0, NAME_NUM_MAX)) {
|
||||||
|
/* Configure the user channel and interrupt. */
|
||||||
|
ch_cfg.channelNumber = ADC2_USER_CHANNEL;
|
||||||
|
ch_cfg.enableInterruptOnConversionCompleted = true;
|
||||||
|
adc2_irq_cnt = 0U; /* Clear the interrupt counter. */
|
||||||
|
adc2_flag = false;
|
||||||
|
ADC_SetChannelConfig(ADC2, ADC2_CHANNEL_GROUP, &ch_cfg);
|
||||||
|
while (adc2_flag == false);
|
||||||
|
|
||||||
|
adc_print("ADC Value: %d\r\n", adc2_val);
|
||||||
|
adc_print("ADC Interrupt Counter: %d\r\n", adc2_irq_cnt);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return adc1_val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32 Imrt1052AdcDrvConfigure(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 Imrt1052HwAdc *adc_cfg = (struct Imrt1052HwAdc *)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 > 18) {
|
||||||
|
KPrintf("Imrt1052AdcDrvConfigure set adc channel(0-18) %u error!", adc_cfg->adc_channel);
|
||||||
|
adc_cfg->adc_channel = 0;
|
||||||
|
ret = ERROR;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct AdcDevDone dev_done =
|
||||||
|
{
|
||||||
|
Imrt1052AdcOpen,
|
||||||
|
Imrt1052AdcClose,
|
||||||
|
NONE,
|
||||||
|
Imrt1052AdcRead,
|
||||||
|
};
|
||||||
|
|
||||||
|
int Imrt1052HwAdcInit(void)
|
||||||
|
{
|
||||||
|
x_err_t ret = EOK;
|
||||||
|
|
||||||
|
#ifdef BSP_USING_ADC1
|
||||||
|
static struct AdcBus adc1_bus;
|
||||||
|
static struct AdcDriver adc1_drv;
|
||||||
|
static struct AdcHardwareDevice adc1_dev;
|
||||||
|
static struct Imrt1052HwAdc adc1_cfg;
|
||||||
|
|
||||||
|
adc1_drv.configure = Imrt1052AdcDrvConfigure;
|
||||||
|
|
||||||
|
ret = AdcBusInit(&adc1_bus, ADC_BUS_NAME_1);
|
||||||
|
if (ret != EOK) {
|
||||||
|
KPrintf("ADC1 bus init error %d\n", ret);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = AdcDriverInit(&adc1_drv, ADC_DRV_NAME_1);
|
||||||
|
if (ret != EOK) {
|
||||||
|
KPrintf("ADC1 driver init error %d\n", ret);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
ret = AdcDriverAttachToBus(ADC_DRV_NAME_1, ADC_BUS_NAME_1);
|
||||||
|
if (ret != EOK) {
|
||||||
|
KPrintf("ADC1 driver attach error %d\n", ret);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
adc1_dev.adc_dev_done = &dev_done;
|
||||||
|
|
||||||
|
ret = AdcDeviceRegister(&adc1_dev, (void *)&adc1_cfg, ADC_1_DEVICE_NAME_0);
|
||||||
|
if (ret != EOK) {
|
||||||
|
KPrintf("ADC1 device register error %d\n", ret);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = AdcDeviceAttachToBus(ADC_1_DEVICE_NAME_0, ADC_BUS_NAME_1);
|
||||||
|
if (ret != EOK) {
|
||||||
|
KPrintf("ADC1 device register error %d\n", ret);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef BSP_USING_ADC2
|
||||||
|
static struct AdcBus adc2_bus;
|
||||||
|
static struct AdcDriver adc2_drv;
|
||||||
|
static struct AdcHardwareDevice adc2_dev;
|
||||||
|
static struct Imrt1052HwAdc adc2_cfg;
|
||||||
|
|
||||||
|
adc2_drv.configure = Imrt1052AdcDrvConfigure;
|
||||||
|
|
||||||
|
ret = AdcBusInit(&adc2_bus, ADC_BUS_NAME_2);
|
||||||
|
if (ret != EOK) {
|
||||||
|
KPrintf("ADC2 bus init error %d\n", ret);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = AdcDriverInit(&adc2_drv, ADC_DRV_NAME_2);
|
||||||
|
if (ret != EOK) {
|
||||||
|
KPrintf("ADC2 driver init error %d\n", ret);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
ret = AdcDriverAttachToBus(ADC_DRV_NAME_2, ADC_BUS_NAME_2);
|
||||||
|
if (ret != EOK) {
|
||||||
|
KPrintf("ADC2 driver attach error %d\n", ret);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
adc2_dev.adc_dev_done = &dev_done;
|
||||||
|
|
||||||
|
ret = AdcDeviceRegister(&adc2_dev, (void *)&adc2_cfg, ADC_2_DEVICE_NAME_0);
|
||||||
|
if (ret != EOK) {
|
||||||
|
KPrintf("ADC2 device register error %d\n", ret);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = AdcDeviceAttachToBus(ADC_2_DEVICE_NAME_0, ADC_BUS_NAME_2);
|
||||||
|
if (ret != EOK) {
|
||||||
|
KPrintf("ADC2 device register error %d\n", ret);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,394 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016, Freescale Semiconductor, Inc.
|
||||||
|
* Copyright 2016-2017 NXP
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "fsl_adc.h"
|
||||||
|
|
||||||
|
/* Component ID definition, used by tools. */
|
||||||
|
#ifndef FSL_COMPONENT_ID
|
||||||
|
#define FSL_COMPONENT_ID "platform.drivers.adc_12b1msps_sar"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Prototypes
|
||||||
|
******************************************************************************/
|
||||||
|
/*!
|
||||||
|
* @brief Get instance number for ADC module.
|
||||||
|
*
|
||||||
|
* @param base ADC peripheral base address
|
||||||
|
*/
|
||||||
|
static uint32_t ADC_GetInstance(ADC_Type *base);
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Variables
|
||||||
|
******************************************************************************/
|
||||||
|
/*! @brief Pointers to ADC bases for each instance. */
|
||||||
|
static ADC_Type *const s_adcBases[] = ADC_BASE_PTRS;
|
||||||
|
|
||||||
|
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
|
||||||
|
/*! @brief Pointers to ADC clocks for each instance. */
|
||||||
|
static const clock_ip_name_t s_adcClocks[] = ADC_CLOCKS;
|
||||||
|
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Code
|
||||||
|
******************************************************************************/
|
||||||
|
static uint32_t ADC_GetInstance(ADC_Type *base)
|
||||||
|
{
|
||||||
|
uint32_t instance;
|
||||||
|
|
||||||
|
/* Find the instance index from base address mappings. */
|
||||||
|
for (instance = 0; instance < ARRAY_SIZE(s_adcBases); instance++)
|
||||||
|
{
|
||||||
|
if (s_adcBases[instance] == base)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(instance < ARRAY_SIZE(s_adcBases));
|
||||||
|
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* brief Initialize the ADC module.
|
||||||
|
*
|
||||||
|
* param base ADC peripheral base address.
|
||||||
|
* param config Pointer to "adc_config_t" structure.
|
||||||
|
*/
|
||||||
|
void ADC_Init(ADC_Type *base, const adc_config_t *config)
|
||||||
|
{
|
||||||
|
assert(NULL != config);
|
||||||
|
|
||||||
|
uint32_t tmp32;
|
||||||
|
|
||||||
|
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
|
||||||
|
/* Enable the clock. */
|
||||||
|
CLOCK_EnableClock(s_adcClocks[ADC_GetInstance(base)]);
|
||||||
|
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
|
||||||
|
/* ADCx_CFG */
|
||||||
|
tmp32 = base->CFG & (ADC_CFG_AVGS_MASK | ADC_CFG_ADTRG_MASK); /* Reserve AVGS and ADTRG bits. */
|
||||||
|
tmp32 |= ADC_CFG_REFSEL(config->referenceVoltageSource) | ADC_CFG_ADSTS(config->samplePeriodMode) |
|
||||||
|
ADC_CFG_ADICLK(config->clockSource) | ADC_CFG_ADIV(config->clockDriver) | ADC_CFG_MODE(config->resolution);
|
||||||
|
if (config->enableOverWrite)
|
||||||
|
{
|
||||||
|
tmp32 |= ADC_CFG_OVWREN_MASK;
|
||||||
|
}
|
||||||
|
if (config->enableLongSample)
|
||||||
|
{
|
||||||
|
tmp32 |= ADC_CFG_ADLSMP_MASK;
|
||||||
|
}
|
||||||
|
if (config->enableLowPower)
|
||||||
|
{
|
||||||
|
tmp32 |= ADC_CFG_ADLPC_MASK;
|
||||||
|
}
|
||||||
|
if (config->enableHighSpeed)
|
||||||
|
{
|
||||||
|
tmp32 |= ADC_CFG_ADHSC_MASK;
|
||||||
|
}
|
||||||
|
base->CFG = tmp32;
|
||||||
|
|
||||||
|
/* ADCx_GC */
|
||||||
|
tmp32 = base->GC & ~(ADC_GC_ADCO_MASK | ADC_GC_ADACKEN_MASK);
|
||||||
|
if (config->enableContinuousConversion)
|
||||||
|
{
|
||||||
|
tmp32 |= ADC_GC_ADCO_MASK;
|
||||||
|
}
|
||||||
|
if (config->enableAsynchronousClockOutput)
|
||||||
|
{
|
||||||
|
tmp32 |= ADC_GC_ADACKEN_MASK;
|
||||||
|
}
|
||||||
|
base->GC = tmp32;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* brief De-initializes the ADC module.
|
||||||
|
*
|
||||||
|
* param base ADC peripheral base address.
|
||||||
|
*/
|
||||||
|
void ADC_Deinit(ADC_Type *base)
|
||||||
|
{
|
||||||
|
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
|
||||||
|
/* Disable the clock. */
|
||||||
|
CLOCK_DisableClock(s_adcClocks[ADC_GetInstance(base)]);
|
||||||
|
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* brief Gets an available pre-defined settings for the converter's configuration.
|
||||||
|
*
|
||||||
|
* This function initializes the converter configuration structure with available settings. The default values are:
|
||||||
|
* code
|
||||||
|
* config->enableAsynchronousClockOutput = true;
|
||||||
|
* config->enableOverWrite = false;
|
||||||
|
* config->enableContinuousConversion = false;
|
||||||
|
* config->enableHighSpeed = false;
|
||||||
|
* config->enableLowPower = false;
|
||||||
|
* config->enableLongSample = false;
|
||||||
|
* config->referenceVoltageSource = kADC_ReferenceVoltageSourceAlt0;
|
||||||
|
* config->samplePeriodMode = kADC_SamplePeriod2or12Clocks;
|
||||||
|
* config->clockSource = kADC_ClockSourceAD;
|
||||||
|
* config->clockDriver = kADC_ClockDriver1;
|
||||||
|
* config->resolution = kADC_Resolution12Bit;
|
||||||
|
* endcode
|
||||||
|
* param base ADC peripheral base address.
|
||||||
|
* param config Pointer to the configuration structure.
|
||||||
|
*/
|
||||||
|
void ADC_GetDefaultConfig(adc_config_t *config)
|
||||||
|
{
|
||||||
|
assert(NULL != config);
|
||||||
|
|
||||||
|
/* Initializes the configure structure to zero. */
|
||||||
|
memset(config, 0, sizeof(*config));
|
||||||
|
|
||||||
|
config->enableAsynchronousClockOutput = true;
|
||||||
|
config->enableOverWrite = false;
|
||||||
|
config->enableContinuousConversion = false;
|
||||||
|
config->enableHighSpeed = false;
|
||||||
|
config->enableLowPower = false;
|
||||||
|
config->enableLongSample = false;
|
||||||
|
config->referenceVoltageSource = kADC_ReferenceVoltageSourceAlt0;
|
||||||
|
config->samplePeriodMode = kADC_SamplePeriod2or12Clocks;
|
||||||
|
config->clockSource = kADC_ClockSourceAD;
|
||||||
|
config->clockDriver = kADC_ClockDriver1;
|
||||||
|
config->resolution = kADC_Resolution12Bit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* brief Configures the conversion channel.
|
||||||
|
*
|
||||||
|
* This operation triggers the conversion when in software trigger mode. When in hardware trigger mode, this API
|
||||||
|
* configures the channel while the external trigger source helps to trigger the conversion.
|
||||||
|
*
|
||||||
|
* Note that the "Channel Group" has a detailed description.
|
||||||
|
* To allow sequential conversions of the ADC to be triggered by internal peripherals, the ADC has more than one
|
||||||
|
* group of status and control registers, one for each conversion. The channel group parameter indicates which group of
|
||||||
|
* registers are used, for example channel group 0 is for Group A registers and channel group 1 is for Group B
|
||||||
|
* registers. The
|
||||||
|
* channel groups are used in a "ping-pong" approach to control the ADC operation. At any point, only one of
|
||||||
|
* the channel groups is actively controlling ADC conversions. The channel group 0 is used for both software and
|
||||||
|
* hardware
|
||||||
|
* trigger modes. Channel groups 1 and greater indicate potentially multiple channel group registers for
|
||||||
|
* use only in hardware trigger mode. See the chip configuration information in the appropriate MCU reference manual
|
||||||
|
* about the
|
||||||
|
* number of SC1n registers (channel groups) specific to this device. None of the channel groups 1 or greater are used
|
||||||
|
* for software trigger operation. Therefore, writing to these channel groups does not initiate a new conversion.
|
||||||
|
* Updating the channel group 0 while a different channel group is actively controlling a conversion is allowed and
|
||||||
|
* vice versa. Writing any of the channel group registers while that specific channel group is actively controlling a
|
||||||
|
* conversion aborts the current conversion.
|
||||||
|
*
|
||||||
|
* param base ADC peripheral base address.
|
||||||
|
* param channelGroup Channel group index.
|
||||||
|
* param config Pointer to the "adc_channel_config_t" structure for the conversion channel.
|
||||||
|
*/
|
||||||
|
void ADC_SetChannelConfig(ADC_Type *base, uint32_t channelGroup, const adc_channel_config_t *config)
|
||||||
|
{
|
||||||
|
assert(NULL != config);
|
||||||
|
assert(channelGroup < FSL_FEATURE_ADC_CONVERSION_CONTROL_COUNT);
|
||||||
|
|
||||||
|
uint32_t tmp32;
|
||||||
|
|
||||||
|
tmp32 = ADC_HC_ADCH(config->channelNumber);
|
||||||
|
if (config->enableInterruptOnConversionCompleted)
|
||||||
|
{
|
||||||
|
tmp32 |= ADC_HC_AIEN_MASK;
|
||||||
|
}
|
||||||
|
base->HC[channelGroup] = tmp32;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*To complete calibration, the user must follow the below procedure:
|
||||||
|
* 1. Configure ADC_CFG with actual operating values for maximum accuracy.
|
||||||
|
* 2. Configure the ADC_GC values along with CAL bit.
|
||||||
|
* 3. Check the status of CALF bit in ADC_GS and the CAL bit in ADC_GC.
|
||||||
|
* 4. When CAL bit becomes '0' then check the CALF status and COCO[0] bit status.
|
||||||
|
*/
|
||||||
|
/*!
|
||||||
|
* brief Automates the hardware calibration.
|
||||||
|
*
|
||||||
|
* This auto calibration helps to adjust the plus/minus side gain automatically.
|
||||||
|
* Execute the calibration before using the converter. Note that the software trigger should be used
|
||||||
|
* during calibration.
|
||||||
|
*
|
||||||
|
* param base ADC peripheral base address.
|
||||||
|
*
|
||||||
|
* return Execution status.
|
||||||
|
* retval kStatus_Success Calibration is done successfully.
|
||||||
|
* retval kStatus_Fail Calibration has failed.
|
||||||
|
*/
|
||||||
|
status_t ADC_DoAutoCalibration(ADC_Type *base)
|
||||||
|
{
|
||||||
|
status_t status = kStatus_Success;
|
||||||
|
#if !(defined(FSL_FEATURE_ADC_SUPPORT_HARDWARE_TRIGGER_REMOVE) && FSL_FEATURE_ADC_SUPPORT_HARDWARE_TRIGGER_REMOVE)
|
||||||
|
bool bHWTrigger = false;
|
||||||
|
|
||||||
|
/* The calibration would be failed when in hardwar mode.
|
||||||
|
* Remember the hardware trigger state here and restore it later if the hardware trigger is enabled.*/
|
||||||
|
if (0U != (ADC_CFG_ADTRG_MASK & base->CFG))
|
||||||
|
{
|
||||||
|
bHWTrigger = true;
|
||||||
|
ADC_EnableHardwareTrigger(base, false);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Clear the CALF and launch the calibration. */
|
||||||
|
base->GS = ADC_GS_CALF_MASK; /* Clear the CALF. */
|
||||||
|
base->GC |= ADC_GC_CAL_MASK; /* Launch the calibration. */
|
||||||
|
|
||||||
|
/* Check the status of CALF bit in ADC_GS and the CAL bit in ADC_GC. */
|
||||||
|
while (0U != (base->GC & ADC_GC_CAL_MASK))
|
||||||
|
{
|
||||||
|
/* Check the CALF when the calibration is active. */
|
||||||
|
if (0U != (ADC_GetStatusFlags(base) & kADC_CalibrationFailedFlag))
|
||||||
|
{
|
||||||
|
status = kStatus_Fail;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* When CAL bit becomes '0' then check the CALF status and COCO[0] bit status. */
|
||||||
|
if (0U == ADC_GetChannelStatusFlags(base, 0U)) /* Check the COCO[0] bit status. */
|
||||||
|
{
|
||||||
|
status = kStatus_Fail;
|
||||||
|
}
|
||||||
|
if (0U != (ADC_GetStatusFlags(base) & kADC_CalibrationFailedFlag)) /* Check the CALF status. */
|
||||||
|
{
|
||||||
|
status = kStatus_Fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clear conversion done flag. */
|
||||||
|
ADC_GetChannelConversionValue(base, 0U);
|
||||||
|
|
||||||
|
#if !(defined(FSL_FEATURE_ADC_SUPPORT_HARDWARE_TRIGGER_REMOVE) && FSL_FEATURE_ADC_SUPPORT_HARDWARE_TRIGGER_REMOVE)
|
||||||
|
/* Restore original trigger mode. */
|
||||||
|
if (true == bHWTrigger)
|
||||||
|
{
|
||||||
|
ADC_EnableHardwareTrigger(base, true);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* brief Set user defined offset.
|
||||||
|
*
|
||||||
|
* param base ADC peripheral base address.
|
||||||
|
* param config Pointer to "adc_offest_config_t" structure.
|
||||||
|
*/
|
||||||
|
void ADC_SetOffsetConfig(ADC_Type *base, const adc_offest_config_t *config)
|
||||||
|
{
|
||||||
|
assert(NULL != config);
|
||||||
|
|
||||||
|
uint32_t tmp32;
|
||||||
|
|
||||||
|
tmp32 = ADC_OFS_OFS(config->offsetValue);
|
||||||
|
if (config->enableSigned)
|
||||||
|
{
|
||||||
|
tmp32 |= ADC_OFS_SIGN_MASK;
|
||||||
|
}
|
||||||
|
base->OFS = tmp32;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* brief Configures the hardware compare mode.
|
||||||
|
*
|
||||||
|
* The hardware compare mode provides a way to process the conversion result automatically by using hardware. Only the
|
||||||
|
* result
|
||||||
|
* in the compare range is available. To compare the range, see "adc_hardware_compare_mode_t" or the appopriate
|
||||||
|
* reference
|
||||||
|
* manual for more information.
|
||||||
|
*
|
||||||
|
* param base ADC peripheral base address.
|
||||||
|
* param Pointer to "adc_hardware_compare_config_t" structure.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void ADC_SetHardwareCompareConfig(ADC_Type *base, const adc_hardware_compare_config_t *config)
|
||||||
|
{
|
||||||
|
uint32_t tmp32;
|
||||||
|
|
||||||
|
tmp32 = base->GC & ~(ADC_GC_ACFE_MASK | ADC_GC_ACFGT_MASK | ADC_GC_ACREN_MASK);
|
||||||
|
if (NULL == config) /* Pass "NULL" to disable the feature. */
|
||||||
|
{
|
||||||
|
base->GC = tmp32;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* Enable the feature. */
|
||||||
|
tmp32 |= ADC_GC_ACFE_MASK;
|
||||||
|
|
||||||
|
/* Select the hardware compare working mode. */
|
||||||
|
switch (config->hardwareCompareMode)
|
||||||
|
{
|
||||||
|
case kADC_HardwareCompareMode0:
|
||||||
|
break;
|
||||||
|
case kADC_HardwareCompareMode1:
|
||||||
|
tmp32 |= ADC_GC_ACFGT_MASK;
|
||||||
|
break;
|
||||||
|
case kADC_HardwareCompareMode2:
|
||||||
|
tmp32 |= ADC_GC_ACREN_MASK;
|
||||||
|
break;
|
||||||
|
case kADC_HardwareCompareMode3:
|
||||||
|
tmp32 |= ADC_GC_ACFGT_MASK | ADC_GC_ACREN_MASK;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
base->GC = tmp32;
|
||||||
|
|
||||||
|
/* Load the compare values. */
|
||||||
|
tmp32 = ADC_CV_CV1(config->value1) | ADC_CV_CV2(config->value2);
|
||||||
|
base->CV = tmp32;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* brief Configures the hardware average mode.
|
||||||
|
*
|
||||||
|
* The hardware average mode provides a way to process the conversion result automatically by using hardware. The
|
||||||
|
* multiple
|
||||||
|
* conversion results are accumulated and averaged internally making them easier to read.
|
||||||
|
*
|
||||||
|
* param base ADC peripheral base address.
|
||||||
|
* param mode Setting the hardware average mode. See "adc_hardware_average_mode_t".
|
||||||
|
*/
|
||||||
|
void ADC_SetHardwareAverageConfig(ADC_Type *base, adc_hardware_average_mode_t mode)
|
||||||
|
{
|
||||||
|
uint32_t tmp32;
|
||||||
|
|
||||||
|
if (mode == kADC_HardwareAverageDiasable)
|
||||||
|
{
|
||||||
|
base->GC &= ~ADC_GC_AVGE_MASK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tmp32 = base->CFG & ~ADC_CFG_AVGS_MASK;
|
||||||
|
tmp32 |= ADC_CFG_AVGS(mode);
|
||||||
|
base->CFG = tmp32;
|
||||||
|
base->GC |= ADC_GC_AVGE_MASK; /* Enable the hardware compare. */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* brief Clears the converter's status falgs.
|
||||||
|
*
|
||||||
|
* param base ADC peripheral base address.
|
||||||
|
* param mask Mask value for the cleared flags. See "adc_status_flags_t".
|
||||||
|
*/
|
||||||
|
void ADC_ClearStatusFlags(ADC_Type *base, uint32_t mask)
|
||||||
|
{
|
||||||
|
uint32_t tmp32 = 0;
|
||||||
|
|
||||||
|
if (0U != (mask & kADC_CalibrationFailedFlag))
|
||||||
|
{
|
||||||
|
tmp32 |= ADC_GS_CALF_MASK;
|
||||||
|
}
|
||||||
|
if (0U != (mask & kADC_ConversionActiveFlag))
|
||||||
|
{
|
||||||
|
tmp32 |= ADC_GS_ADACT_MASK;
|
||||||
|
}
|
||||||
|
base->GS = tmp32;
|
||||||
|
}
|
|
@ -0,0 +1,420 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016, Freescale Semiconductor, Inc.
|
||||||
|
* Copyright 2016-2017 NXP
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _FSL_ADC_H_
|
||||||
|
#define _FSL_ADC_H_
|
||||||
|
|
||||||
|
#include "fsl_common.h"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @addtogroup adc_12b1msps_sar
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Definitions
|
||||||
|
******************************************************************************/
|
||||||
|
/*! @brief ADC driver version */
|
||||||
|
#define FSL_ADC_DRIVER_VERSION (MAKE_VERSION(2, 0, 2)) /*!< Version 2.0.2. */
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Converter's status flags.
|
||||||
|
*/
|
||||||
|
typedef enum _adc_status_flags
|
||||||
|
{
|
||||||
|
kADC_ConversionActiveFlag = ADC_GS_ADACT_MASK, /*!< Conversion is active,not support w1c. */
|
||||||
|
kADC_CalibrationFailedFlag = ADC_GS_CALF_MASK, /*!< Calibration is failed,support w1c. */
|
||||||
|
kADC_AsynchronousWakeupInterruptFlag =
|
||||||
|
ADC_GS_AWKST_MASK, /*!< Asynchronous wakeup interrupt occurred, support w1c. */
|
||||||
|
} adc_status_flags_t;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Reference voltage source.
|
||||||
|
*/
|
||||||
|
typedef enum _adc_reference_voltage_source
|
||||||
|
{
|
||||||
|
kADC_ReferenceVoltageSourceAlt0 = 0U, /*!< For external pins pair of VrefH and VrefL. */
|
||||||
|
} adc_reference_voltage_source_t;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Sample time duration.
|
||||||
|
*/
|
||||||
|
typedef enum _adc_sample_period_mode
|
||||||
|
{
|
||||||
|
/* This group of enumeration is for internal use which is related to register setting. */
|
||||||
|
kADC_SamplePeriod2or12Clocks = 0U, /*!< Long sample 12 clocks or short sample 2 clocks. */
|
||||||
|
kADC_SamplePeriod4or16Clocks = 1U, /*!< Long sample 16 clocks or short sample 4 clocks. */
|
||||||
|
kADC_SamplePeriod6or20Clocks = 2U, /*!< Long sample 20 clocks or short sample 6 clocks. */
|
||||||
|
kADC_SamplePeriod8or24Clocks = 3U, /*!< Long sample 24 clocks or short sample 8 clocks. */
|
||||||
|
/* This group of enumeration is for a public user. */
|
||||||
|
/* For long sample mode. */
|
||||||
|
kADC_SamplePeriodLong12Clcoks = kADC_SamplePeriod2or12Clocks, /*!< Long sample 12 clocks. */
|
||||||
|
kADC_SamplePeriodLong16Clcoks = kADC_SamplePeriod4or16Clocks, /*!< Long sample 16 clocks. */
|
||||||
|
kADC_SamplePeriodLong20Clcoks = kADC_SamplePeriod6or20Clocks, /*!< Long sample 20 clocks. */
|
||||||
|
kADC_SamplePeriodLong24Clcoks = kADC_SamplePeriod8or24Clocks, /*!< Long sample 24 clocks. */
|
||||||
|
/* For short sample mode. */
|
||||||
|
kADC_SamplePeriodShort2Clocks = kADC_SamplePeriod2or12Clocks, /*!< Short sample 2 clocks. */
|
||||||
|
kADC_SamplePeriodShort4Clocks = kADC_SamplePeriod4or16Clocks, /*!< Short sample 4 clocks. */
|
||||||
|
kADC_SamplePeriodShort6Clocks = kADC_SamplePeriod6or20Clocks, /*!< Short sample 6 clocks. */
|
||||||
|
kADC_SamplePeriodShort8Clocks = kADC_SamplePeriod8or24Clocks, /*!< Short sample 8 clocks. */
|
||||||
|
} adc_sample_period_mode_t;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Clock source.
|
||||||
|
*/
|
||||||
|
typedef enum _adc_clock_source
|
||||||
|
{
|
||||||
|
kADC_ClockSourceIPG = 0U, /*!< Select IPG clock to generate ADCK. */
|
||||||
|
kADC_ClockSourceIPGDiv2 = 1U, /*!< Select IPG clock divided by 2 to generate ADCK. */
|
||||||
|
#if !(defined(FSL_FEATURE_ADC_SUPPORT_ALTCLK_REMOVE) && FSL_FEATURE_ADC_SUPPORT_ALTCLK_REMOVE)
|
||||||
|
kADC_ClockSourceALT = 2U, /*!< Select alternate clock to generate ADCK. */
|
||||||
|
#endif
|
||||||
|
kADC_ClockSourceAD = 3U, /*!< Select Asynchronous clock to generate ADCK. */
|
||||||
|
} adc_clock_source_t;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Clock divider for the converter.
|
||||||
|
*/
|
||||||
|
typedef enum _adc_clock_drvier
|
||||||
|
{
|
||||||
|
kADC_ClockDriver1 = 0U, /*!< For divider 1 from the input clock to the module. */
|
||||||
|
kADC_ClockDriver2 = 1U, /*!< For divider 2 from the input clock to the module. */
|
||||||
|
kADC_ClockDriver4 = 2U, /*!< For divider 4 from the input clock to the module. */
|
||||||
|
kADC_ClockDriver8 = 3U, /*!< For divider 8 from the input clock to the module. */
|
||||||
|
} adc_clock_driver_t;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Converter's resolution.
|
||||||
|
*/
|
||||||
|
typedef enum _adc_resolution
|
||||||
|
{
|
||||||
|
kADC_Resolution8Bit = 0U, /*!< Single End 8-bit resolution. */
|
||||||
|
kADC_Resolution10Bit = 1U, /*!< Single End 10-bit resolution. */
|
||||||
|
kADC_Resolution12Bit = 2U, /*!< Single End 12-bit resolution. */
|
||||||
|
} adc_resolution_t;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Converter hardware compare mode.
|
||||||
|
*/
|
||||||
|
typedef enum _adc_hardware_compare_mode
|
||||||
|
{
|
||||||
|
kADC_HardwareCompareMode0 = 0U, /*!< Compare true if the result is less than the value1. */
|
||||||
|
kADC_HardwareCompareMode1 = 1U, /*!< Compare true if the result is greater than or equal to value1. */
|
||||||
|
kADC_HardwareCompareMode2 = 2U, /*!< Value1 <= Value2, compare true if the result is less than value1 Or
|
||||||
|
the result is Greater than value2.
|
||||||
|
Value1 > Value2, compare true if the result is less than value1 And the
|
||||||
|
result is greater than value2*/
|
||||||
|
kADC_HardwareCompareMode3 = 3U, /*!< Value1 <= Value2, compare true if the result is greater than or equal
|
||||||
|
to value1 And the result is less than or equal to value2.
|
||||||
|
Value1 > Value2, compare true if the result is greater than or equal to
|
||||||
|
value1 Or the result is less than or equal to value2. */
|
||||||
|
} adc_hardware_compare_mode_t;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Converter hardware average mode.
|
||||||
|
*/
|
||||||
|
typedef enum _adc_hardware_average_mode
|
||||||
|
{
|
||||||
|
kADC_HardwareAverageCount4 = 0U, /*!< For hardware average with 4 samples. */
|
||||||
|
kADC_HardwareAverageCount8 = 1U, /*!< For hardware average with 8 samples. */
|
||||||
|
kADC_HardwareAverageCount16 = 2U, /*!< For hardware average with 16 samples. */
|
||||||
|
kADC_HardwareAverageCount32 = 3U, /*!< For hardware average with 32 samples. */
|
||||||
|
kADC_HardwareAverageDiasable = 4U, /*!< Disable the hardware average function. */
|
||||||
|
} adc_hardware_average_mode_t;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Converter configuration.
|
||||||
|
*/
|
||||||
|
typedef struct _adc_config
|
||||||
|
{
|
||||||
|
bool enableOverWrite; /*!< Enable the overwriting. */
|
||||||
|
bool enableContinuousConversion; /*!< Enable the continuous conversion mode. */
|
||||||
|
bool enableHighSpeed; /*!< Enable the high-speed mode. */
|
||||||
|
bool enableLowPower; /*!< Enable the low power mode. */
|
||||||
|
bool enableLongSample; /*!< Enable the long sample mode. */
|
||||||
|
bool enableAsynchronousClockOutput; /*!< Enable the asynchronous clock output. */
|
||||||
|
adc_reference_voltage_source_t referenceVoltageSource; /*!< Select the reference voltage source. */
|
||||||
|
adc_sample_period_mode_t samplePeriodMode; /*!< Select the sample period in long sample mode or short mode. */
|
||||||
|
adc_clock_source_t clockSource; /*!< Select the input clock source to generate the internal clock ADCK. */
|
||||||
|
adc_clock_driver_t clockDriver; /*!< Select the divide ratio used by the ADC to generate the internal clock ADCK. */
|
||||||
|
adc_resolution_t resolution; /*!< Select the ADC resolution mode. */
|
||||||
|
} adc_config_t;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Converter Offset configuration.
|
||||||
|
*/
|
||||||
|
typedef struct _adc_offest_config
|
||||||
|
{
|
||||||
|
bool enableSigned; /*!< if false,The offset value is added with the raw result.
|
||||||
|
if true,The offset value is subtracted from the raw converted value. */
|
||||||
|
uint32_t offsetValue; /*!< User configurable offset value(0-4095). */
|
||||||
|
} adc_offest_config_t;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief ADC hardware compare configuration.
|
||||||
|
*
|
||||||
|
* In kADC_HardwareCompareMode0, compare true if the result is less than the value1.
|
||||||
|
* In kADC_HardwareCompareMode1, compare true if the result is greater than or equal to value1.
|
||||||
|
* In kADC_HardwareCompareMode2, Value1 <= Value2, compare true if the result is less than value1 Or the result is
|
||||||
|
* Greater than value2.
|
||||||
|
* Value1 > Value2, compare true if the result is less than value1 And the result is
|
||||||
|
* Greater than value2.
|
||||||
|
* In kADC_HardwareCompareMode3, Value1 <= Value2, compare true if the result is greater than or equal to value1 And the
|
||||||
|
* result is less than or equal to value2.
|
||||||
|
* Value1 > Value2, compare true if the result is greater than or equal to value1 Or the
|
||||||
|
* result is less than or equal to value2.
|
||||||
|
*/
|
||||||
|
typedef struct _adc_hardware_compare_config
|
||||||
|
{
|
||||||
|
adc_hardware_compare_mode_t hardwareCompareMode; /*!< Select the hardware compare mode.
|
||||||
|
See "adc_hardware_compare_mode_t". */
|
||||||
|
uint16_t value1; /*!< Setting value1(0-4095) for hardware compare mode. */
|
||||||
|
uint16_t value2; /*!< Setting value2(0-4095) for hardware compare mode. */
|
||||||
|
} adc_hardware_compare_config_t;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief ADC channel conversion configuration.
|
||||||
|
*/
|
||||||
|
typedef struct _adc_channel_config
|
||||||
|
{
|
||||||
|
uint32_t channelNumber; /*!< Setting the conversion channel number. The available range is 0-31.
|
||||||
|
See channel connection information for each chip in Reference
|
||||||
|
Manual document. */
|
||||||
|
bool enableInterruptOnConversionCompleted; /*!< Generate an interrupt request once the conversion is completed. */
|
||||||
|
} adc_channel_config_t;
|
||||||
|
/*******************************************************************************
|
||||||
|
* API
|
||||||
|
******************************************************************************/
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @name Initialization
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Initialize the ADC module.
|
||||||
|
*
|
||||||
|
* @param base ADC peripheral base address.
|
||||||
|
* @param config Pointer to "adc_config_t" structure.
|
||||||
|
*/
|
||||||
|
void ADC_Init(ADC_Type *base, const adc_config_t *config);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief De-initializes the ADC module.
|
||||||
|
*
|
||||||
|
* @param base ADC peripheral base address.
|
||||||
|
*/
|
||||||
|
void ADC_Deinit(ADC_Type *base);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Gets an available pre-defined settings for the converter's configuration.
|
||||||
|
*
|
||||||
|
* This function initializes the converter configuration structure with available settings. The default values are:
|
||||||
|
* @code
|
||||||
|
* config->enableAsynchronousClockOutput = true;
|
||||||
|
* config->enableOverWrite = false;
|
||||||
|
* config->enableContinuousConversion = false;
|
||||||
|
* config->enableHighSpeed = false;
|
||||||
|
* config->enableLowPower = false;
|
||||||
|
* config->enableLongSample = false;
|
||||||
|
* config->referenceVoltageSource = kADC_ReferenceVoltageSourceAlt0;
|
||||||
|
* config->samplePeriodMode = kADC_SamplePeriod2or12Clocks;
|
||||||
|
* config->clockSource = kADC_ClockSourceAD;
|
||||||
|
* config->clockDriver = kADC_ClockDriver1;
|
||||||
|
* config->resolution = kADC_Resolution12Bit;
|
||||||
|
* @endcode
|
||||||
|
* @param base ADC peripheral base address.
|
||||||
|
* @param config Pointer to the configuration structure.
|
||||||
|
*/
|
||||||
|
void ADC_GetDefaultConfig(adc_config_t *config);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Configures the conversion channel.
|
||||||
|
*
|
||||||
|
* This operation triggers the conversion when in software trigger mode. When in hardware trigger mode, this API
|
||||||
|
* configures the channel while the external trigger source helps to trigger the conversion.
|
||||||
|
*
|
||||||
|
* Note that the "Channel Group" has a detailed description.
|
||||||
|
* To allow sequential conversions of the ADC to be triggered by internal peripherals, the ADC has more than one
|
||||||
|
* group of status and control registers, one for each conversion. The channel group parameter indicates which group of
|
||||||
|
* registers are used, for example channel group 0 is for Group A registers and channel group 1 is for Group B
|
||||||
|
* registers. The
|
||||||
|
* channel groups are used in a "ping-pong" approach to control the ADC operation. At any point, only one of
|
||||||
|
* the channel groups is actively controlling ADC conversions. The channel group 0 is used for both software and
|
||||||
|
* hardware
|
||||||
|
* trigger modes. Channel groups 1 and greater indicate potentially multiple channel group registers for
|
||||||
|
* use only in hardware trigger mode. See the chip configuration information in the appropriate MCU reference manual
|
||||||
|
* about the
|
||||||
|
* number of SC1n registers (channel groups) specific to this device. None of the channel groups 1 or greater are used
|
||||||
|
* for software trigger operation. Therefore, writing to these channel groups does not initiate a new conversion.
|
||||||
|
* Updating the channel group 0 while a different channel group is actively controlling a conversion is allowed and
|
||||||
|
* vice versa. Writing any of the channel group registers while that specific channel group is actively controlling a
|
||||||
|
* conversion aborts the current conversion.
|
||||||
|
*
|
||||||
|
* @param base ADC peripheral base address.
|
||||||
|
* @param channelGroup Channel group index.
|
||||||
|
* @param config Pointer to the "adc_channel_config_t" structure for the conversion channel.
|
||||||
|
*/
|
||||||
|
void ADC_SetChannelConfig(ADC_Type *base, uint32_t channelGroup, const adc_channel_config_t *config);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Gets the conversion value.
|
||||||
|
*
|
||||||
|
* @param base ADC peripheral base address.
|
||||||
|
* @param channelGroup Channel group index.
|
||||||
|
*
|
||||||
|
* @return Conversion value.
|
||||||
|
*/
|
||||||
|
static inline uint32_t ADC_GetChannelConversionValue(ADC_Type *base, uint32_t channelGroup)
|
||||||
|
{
|
||||||
|
assert(channelGroup < FSL_FEATURE_ADC_CONVERSION_CONTROL_COUNT);
|
||||||
|
|
||||||
|
return base->R[channelGroup];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Gets the status flags of channel.
|
||||||
|
*
|
||||||
|
* A conversion is completed when the result of the conversion is transferred into the data
|
||||||
|
* result registers. (provided the compare function & hardware averaging is disabled), this is
|
||||||
|
* indicated by the setting of COCOn. If hardware averaging is enabled, COCOn sets only,
|
||||||
|
* if the last of the selected number of conversions is complete. If the compare function is
|
||||||
|
* enabled, COCOn sets and conversion result data is transferred only if the compare
|
||||||
|
* condition is true. If both hardware averaging and compare functions are enabled, then
|
||||||
|
* COCOn sets only if the last of the selected number of conversions is complete and the
|
||||||
|
* compare condition is true.
|
||||||
|
*
|
||||||
|
* @param base ADC peripheral base address.
|
||||||
|
* @param channelGroup Channel group index.
|
||||||
|
*
|
||||||
|
* @return Status flags of channel.return 0 means COCO flag is 0,return 1 means COCOflag is 1.
|
||||||
|
*/
|
||||||
|
static inline uint32_t ADC_GetChannelStatusFlags(ADC_Type *base, uint32_t channelGroup)
|
||||||
|
{
|
||||||
|
assert(channelGroup < FSL_FEATURE_ADC_CONVERSION_CONTROL_COUNT);
|
||||||
|
|
||||||
|
/* If flag is set,return 1,otherwise, return 0. */
|
||||||
|
return (((base->HS) & (1U << channelGroup)) >> channelGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Automates the hardware calibration.
|
||||||
|
*
|
||||||
|
* This auto calibration helps to adjust the plus/minus side gain automatically.
|
||||||
|
* Execute the calibration before using the converter. Note that the software trigger should be used
|
||||||
|
* during calibration.
|
||||||
|
*
|
||||||
|
* @param base ADC peripheral base address.
|
||||||
|
*
|
||||||
|
* @return Execution status.
|
||||||
|
* @retval kStatus_Success Calibration is done successfully.
|
||||||
|
* @retval kStatus_Fail Calibration has failed.
|
||||||
|
*/
|
||||||
|
status_t ADC_DoAutoCalibration(ADC_Type *base);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Set user defined offset.
|
||||||
|
*
|
||||||
|
* @param base ADC peripheral base address.
|
||||||
|
* @param config Pointer to "adc_offest_config_t" structure.
|
||||||
|
*/
|
||||||
|
void ADC_SetOffsetConfig(ADC_Type *base, const adc_offest_config_t *config);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Enables generating the DMA trigger when the conversion is complete.
|
||||||
|
*
|
||||||
|
* @param base ADC peripheral base address.
|
||||||
|
* @param enable Switcher of the DMA feature. "true" means enabled, "false" means not enabled.
|
||||||
|
*/
|
||||||
|
static inline void ADC_EnableDMA(ADC_Type *base, bool enable)
|
||||||
|
{
|
||||||
|
if (enable)
|
||||||
|
{
|
||||||
|
base->GC |= ADC_GC_DMAEN_MASK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
base->GC &= ~ADC_GC_DMAEN_MASK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Enables the hardware trigger mode.
|
||||||
|
*
|
||||||
|
* @param base ADC peripheral base address.
|
||||||
|
* @param enable Switcher of the trigger mode. "true" means hardware tirgger mode,"false" means software mode.
|
||||||
|
*/
|
||||||
|
#if !(defined(FSL_FEATURE_ADC_SUPPORT_HARDWARE_TRIGGER_REMOVE) && FSL_FEATURE_ADC_SUPPORT_HARDWARE_TRIGGER_REMOVE)
|
||||||
|
static inline void ADC_EnableHardwareTrigger(ADC_Type *base, bool enable)
|
||||||
|
{
|
||||||
|
if (enable)
|
||||||
|
{
|
||||||
|
base->CFG |= ADC_CFG_ADTRG_MASK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
base->CFG &= ~ADC_CFG_ADTRG_MASK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Configures the hardware compare mode.
|
||||||
|
*
|
||||||
|
* The hardware compare mode provides a way to process the conversion result automatically by using hardware. Only the
|
||||||
|
* result
|
||||||
|
* in the compare range is available. To compare the range, see "adc_hardware_compare_mode_t" or the appopriate
|
||||||
|
* reference
|
||||||
|
* manual for more information.
|
||||||
|
*
|
||||||
|
* @param base ADC peripheral base address.
|
||||||
|
* @param Pointer to "adc_hardware_compare_config_t" structure.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void ADC_SetHardwareCompareConfig(ADC_Type *base, const adc_hardware_compare_config_t *config);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Configures the hardware average mode.
|
||||||
|
*
|
||||||
|
* The hardware average mode provides a way to process the conversion result automatically by using hardware. The
|
||||||
|
* multiple
|
||||||
|
* conversion results are accumulated and averaged internally making them easier to read.
|
||||||
|
*
|
||||||
|
* @param base ADC peripheral base address.
|
||||||
|
* @param mode Setting the hardware average mode. See "adc_hardware_average_mode_t".
|
||||||
|
*/
|
||||||
|
void ADC_SetHardwareAverageConfig(ADC_Type *base, adc_hardware_average_mode_t mode);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Gets the converter's status flags.
|
||||||
|
*
|
||||||
|
* @param base ADC peripheral base address.
|
||||||
|
*
|
||||||
|
* @return Flags' mask if indicated flags are asserted. See "adc_status_flags_t".
|
||||||
|
*/
|
||||||
|
static inline uint32_t ADC_GetStatusFlags(ADC_Type *base)
|
||||||
|
{
|
||||||
|
return base->GS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Clears the converter's status falgs.
|
||||||
|
*
|
||||||
|
* @param base ADC peripheral base address.
|
||||||
|
* @param mask Mask value for the cleared flags. See "adc_status_flags_t".
|
||||||
|
*/
|
||||||
|
void ADC_ClearStatusFlags(ADC_Type *base, uint32_t mask);
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _FSL_ADC_H_ */
|
|
@ -6,18 +6,6 @@
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
* 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 fsl_cache.c
|
* @file fsl_cache.c
|
||||||
* @brief cache drivers
|
* @brief cache drivers
|
||||||
|
@ -45,9 +33,9 @@
|
||||||
#define L2CACHE_1KBCOVERTOB 1024U
|
#define L2CACHE_1KBCOVERTOB 1024U
|
||||||
#define L2CACHE_SAMLLWAYS_SIZE 16U
|
#define L2CACHE_SAMLLWAYS_SIZE 16U
|
||||||
#define L2CACHE_LOCKDOWN_REGNUM 8 /*!< Lock down register numbers.*/
|
#define L2CACHE_LOCKDOWN_REGNUM 8 /*!< Lock down register numbers.*/
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Prototypes
|
* Prototypes
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
* @brief Set for all ways and waiting for the operation finished.
|
* @brief Set for all ways and waiting for the operation finished.
|
||||||
* This is provided for all the background operations.
|
* This is provided for all the background operations.
|
||||||
|
|
|
@ -5,18 +5,6 @@
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
* 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 fsl_clock.c
|
* @file fsl_clock.c
|
||||||
* @brief clock drivers
|
* @brief clock drivers
|
||||||
|
|
|
@ -7,18 +7,6 @@
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
* 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 fsl_common.c
|
* @file fsl_common.c
|
||||||
* @brief common drivers
|
* @brief common drivers
|
||||||
|
|
|
@ -749,6 +749,115 @@ BOARD_InitPins:
|
||||||
* Description : Configures pin routing and optionally pin electrical features.
|
* Description : Configures pin routing and optionally pin electrical features.
|
||||||
*
|
*
|
||||||
* END ****************************************************************************************************************/
|
* END ****************************************************************************************************************/
|
||||||
|
|
||||||
|
void BOARD_InitSPIPins ( void )
|
||||||
|
{
|
||||||
|
IOMUXC_SetPinMux (
|
||||||
|
IOMUXC_GPIO_AD_B1_15_LPSPI3_SCK, /* GPIO_AD_B0_00 is configured as LPSPI3_SCK */
|
||||||
|
0U ); /* Software Input On Field: Input Path is determined by functionality */
|
||||||
|
IOMUXC_SetPinMux (
|
||||||
|
IOMUXC_GPIO_AD_B1_14_LPSPI3_SDO, /* GPIO_AD_B0_01 is configured as LPSPI3_SDO */
|
||||||
|
0U ); /* Software Input On Field: Input Path is determined by functionality */
|
||||||
|
IOMUXC_SetPinMux (
|
||||||
|
IOMUXC_GPIO_AD_B1_13_LPSPI3_SDI, /* GPIO_AD_B0_02 is configured as LPSPI3_SDI */
|
||||||
|
0U ); /* Software Input On Field: Input Path is determined by functionality */
|
||||||
|
IOMUXC_SetPinMux (
|
||||||
|
IOMUXC_GPIO_AD_B1_12_LPSPI3_PCS0, /* GPIO_AD_B0_03 is configured as LPSPI3_PCS0 */
|
||||||
|
0U ); /* Software Input On Field: Input Path is determined by functionality */
|
||||||
|
IOMUXC_SetPinMux (
|
||||||
|
IOMUXC_GPIO_SD_B0_00_LPSPI1_SCK, /* GPIO_SD_B0_00 is configured as LPSPI1_SCK */
|
||||||
|
0U ); /* Software Input On Field: Input Path is determined by functionality */
|
||||||
|
IOMUXC_SetPinMux (
|
||||||
|
IOMUXC_GPIO_SD_B0_01_LPSPI1_PCS0, /* GPIO_SD_B0_01 is configured as LPSPI1_PCS0 */
|
||||||
|
0U ); /* Software Input On Field: Input Path is determined by functionality */
|
||||||
|
IOMUXC_SetPinMux (
|
||||||
|
IOMUXC_GPIO_SD_B0_02_LPSPI1_SDO, /* GPIO_SD_B0_02 is configured as LPSPI1_SDO */
|
||||||
|
0U ); /* Software Input On Field: Input Path is determined by functionality */
|
||||||
|
IOMUXC_SetPinMux (
|
||||||
|
IOMUXC_GPIO_SD_B0_03_LPSPI1_SDI, /* GPIO_SD_B0_03 is configured as LPSPI1_SDI */
|
||||||
|
0U ); /* Software Input On Field: Input Path is determined by functionality */
|
||||||
|
|
||||||
|
IOMUXC_SetPinConfig (
|
||||||
|
IOMUXC_GPIO_SD_B0_00_LPSPI1_SCK, /* GPIO_AD_B0_00 PAD functional properties : */
|
||||||
|
0x10B0u ); /* Slew Rate Field: Slow Slew Rate
|
||||||
|
Drive Strength Field: R0/6
|
||||||
|
Speed Field: medium(100MHz)
|
||||||
|
Open Drain Enable Field: Open Drain Disabled
|
||||||
|
Pull / Keep Enable Field: Pull/Keeper Enabled
|
||||||
|
Pull / Keep Select Field: Keeper
|
||||||
|
Pull Up / Down Config. Field: 100K Ohm Pull Down
|
||||||
|
Hyst. Enable Field: Hysteresis Disabled */
|
||||||
|
IOMUXC_SetPinConfig (
|
||||||
|
IOMUXC_GPIO_AD_B1_14_LPSPI3_SDO, /* GPIO_AD_B0_01 PAD functional properties : */
|
||||||
|
0x10B0u ); /* Slew Rate Field: Slow Slew Rate
|
||||||
|
Drive Strength Field: R0/6
|
||||||
|
Speed Field: medium(100MHz)
|
||||||
|
Open Drain Enable Field: Open Drain Disabled
|
||||||
|
Pull / Keep Enable Field: Pull/Keeper Enabled
|
||||||
|
Pull / Keep Select Field: Keeper
|
||||||
|
Pull Up / Down Config. Field: 100K Ohm Pull Down
|
||||||
|
Hyst. Enable Field: Hysteresis Disabled */
|
||||||
|
IOMUXC_SetPinConfig (
|
||||||
|
IOMUXC_GPIO_AD_B1_13_LPSPI3_SDI, /* GPIO_AD_B0_02 PAD functional properties : */
|
||||||
|
0x10B0u ); /* Slew Rate Field: Slow Slew Rate
|
||||||
|
Drive Strength Field: R0/6
|
||||||
|
Speed Field: medium(100MHz)
|
||||||
|
Open Drain Enable Field: Open Drain Disabled
|
||||||
|
Pull / Keep Enable Field: Pull/Keeper Enabled
|
||||||
|
Pull / Keep Select Field: Keeper
|
||||||
|
Pull Up / Down Config. Field: 100K Ohm Pull Down
|
||||||
|
Hyst. Enable Field: Hysteresis Disabled */
|
||||||
|
IOMUXC_SetPinConfig (
|
||||||
|
IOMUXC_GPIO_AD_B1_12_LPSPI3_PCS0, /* GPIO_AD_B0_03 PAD functional properties : */
|
||||||
|
0x10B0u ); /* Slew Rate Field: Slow Slew Rate
|
||||||
|
Drive Strength Field: R0/6
|
||||||
|
Speed Field: medium(100MHz)
|
||||||
|
Open Drain Enable Field: Open Drain Disabled
|
||||||
|
Pull / Keep Enable Field: Pull/Keeper Enabled
|
||||||
|
Pull / Keep Select Field: Keeper
|
||||||
|
Pull Up / Down Config. Field: 100K Ohm Pull Down
|
||||||
|
Hyst. Enable Field: Hysteresis Disabled */
|
||||||
|
IOMUXC_SetPinConfig (
|
||||||
|
IOMUXC_GPIO_SD_B0_00_LPSPI1_SCK, /* GPIO_SD_B0_00 PAD functional properties : */
|
||||||
|
0x10B0u ); /* Slew Rate Field: Slow Slew Rate
|
||||||
|
Drive Strength Field: R0/6
|
||||||
|
Speed Field: medium(100MHz)
|
||||||
|
Open Drain Enable Field: Open Drain Disabled
|
||||||
|
Pull / Keep Enable Field: Pull/Keeper Enabled
|
||||||
|
Pull / Keep Select Field: Keeper
|
||||||
|
Pull Up / Down Config. Field: 100K Ohm Pull Down
|
||||||
|
Hyst. Enable Field: Hysteresis Disabled */
|
||||||
|
IOMUXC_SetPinConfig (
|
||||||
|
IOMUXC_GPIO_SD_B0_01_LPSPI1_PCS0, /* GPIO_SD_B0_01 PAD functional properties : */
|
||||||
|
0x10B0u ); /* Slew Rate Field: Slow Slew Rate
|
||||||
|
Drive Strength Field: R0/6
|
||||||
|
Speed Field: medium(100MHz)
|
||||||
|
Open Drain Enable Field: Open Drain Disabled
|
||||||
|
Pull / Keep Enable Field: Pull/Keeper Enabled
|
||||||
|
Pull / Keep Select Field: Keeper
|
||||||
|
Pull Up / Down Config. Field: 100K Ohm Pull Down
|
||||||
|
Hyst. Enable Field: Hysteresis Disabled */
|
||||||
|
IOMUXC_SetPinConfig (
|
||||||
|
IOMUXC_GPIO_SD_B0_02_LPSPI1_SDO, /* GPIO_SD_B0_02 PAD functional properties : */
|
||||||
|
0x10B0u ); /* Slew Rate Field: Slow Slew Rate
|
||||||
|
Drive Strength Field: R0/6
|
||||||
|
Speed Field: medium(100MHz)
|
||||||
|
Open Drain Enable Field: Open Drain Disabled
|
||||||
|
Pull / Keep Enable Field: Pull/Keeper Enabled
|
||||||
|
Pull / Keep Select Field: Keeper
|
||||||
|
Pull Up / Down Config. Field: 100K Ohm Pull Down
|
||||||
|
Hyst. Enable Field: Hysteresis Disabled */
|
||||||
|
IOMUXC_SetPinConfig (
|
||||||
|
IOMUXC_GPIO_SD_B0_03_LPSPI1_SDI, /* GPIO_SD_B0_03 PAD functional properties : */
|
||||||
|
0x10B0u ); /* Slew Rate Field: Slow Slew Rate
|
||||||
|
Drive Strength Field: R0/6
|
||||||
|
Speed Field: medium(100MHz)
|
||||||
|
Open Drain Enable Field: Open Drain Disabled
|
||||||
|
Pull / Keep Enable Field: Pull/Keeper Enabled
|
||||||
|
Pull / Keep Select Field: Keeper
|
||||||
|
Pull Up / Down Config. Field: 100K Ohm Pull Down
|
||||||
|
Hyst. Enable Field: Hysteresis Disabled */
|
||||||
|
}
|
||||||
void BOARD_InitPins(void) {
|
void BOARD_InitPins(void) {
|
||||||
CLOCK_EnableClock(kCLOCK_Iomuxc); /* iomuxc clock (iomuxc_clk_enable): 0x03u */
|
CLOCK_EnableClock(kCLOCK_Iomuxc); /* iomuxc clock (iomuxc_clk_enable): 0x03u */
|
||||||
|
|
||||||
|
@ -964,6 +1073,36 @@ void BOARD_InitPins(void) {
|
||||||
Hyst. Enable Field: Hysteresis Disabled */
|
Hyst. Enable Field: Hysteresis Disabled */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BOARD_InitI2C1Pins ( void )
|
||||||
|
{
|
||||||
|
CLOCK_EnableClock ( kCLOCK_Iomuxc ); /* iomuxc clock (iomuxc_clk_enable): 0x03u */
|
||||||
|
IOMUXC_SetPinMux (
|
||||||
|
IOMUXC_GPIO_AD_B1_00_LPI2C1_SCL, /* GPIO_AD_B1_00 is configured as LPI2C1_SCL */
|
||||||
|
1U ); /* Software Input On Field: Force input path of pad GPIO_AD_B1_00 */
|
||||||
|
IOMUXC_SetPinMux (
|
||||||
|
IOMUXC_GPIO_AD_B1_01_LPI2C1_SDA, /* GPIO_AD_B1_01 is configured as LPI2C1_SDA */
|
||||||
|
1U ); /* Software Input On Field: Force input path of pad GPIO_AD_B1_01 */
|
||||||
|
IOMUXC_SetPinConfig (
|
||||||
|
IOMUXC_GPIO_AD_B1_00_LPI2C1_SCL, /* GPIO_AD_B1_00 PAD functional properties : */
|
||||||
|
0xD8B0u ); /* Slew Rate Field: Slow Slew Rate
|
||||||
|
Drive Strength Field: R0/6
|
||||||
|
Speed Field: medium(100MHz)
|
||||||
|
Open Drain Enable Field: Open Drain Enabled
|
||||||
|
Pull / Keep Enable Field: Pull/Keeper Enabled
|
||||||
|
Pull / Keep Select Field: Keeper
|
||||||
|
Pull Up / Down Config. Field: 22K Ohm Pull Up
|
||||||
|
Hyst. Enable Field: Hysteresis Disabled */
|
||||||
|
IOMUXC_SetPinConfig (
|
||||||
|
IOMUXC_GPIO_AD_B1_01_LPI2C1_SDA, /* GPIO_AD_B1_01 PAD functional properties : */
|
||||||
|
0xD8B0u ); /* Slew Rate Field: Slow Slew Rate
|
||||||
|
Drive Strength Field: R0/6
|
||||||
|
Speed Field: medium(100MHz)
|
||||||
|
Open Drain Enable Field: Open Drain Enabled
|
||||||
|
Pull / Keep Enable Field: Pull/Keeper Enabled
|
||||||
|
Pull / Keep Select Field: Keeper
|
||||||
|
Pull Up / Down Config. Field: 22K Ohm Pull Up
|
||||||
|
Hyst. Enable Field: Hysteresis Disabled */
|
||||||
|
}
|
||||||
/***********************************************************************************************************************
|
/***********************************************************************************************************************
|
||||||
* EOF
|
* EOF
|
||||||
**********************************************************************************************************************/
|
**********************************************************************************************************************/
|
||||||
|
|
|
@ -38,18 +38,6 @@
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
* 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 enet_ethernetif.c
|
* @file enet_ethernetif.c
|
||||||
* @brief ethernet drivers
|
* @brief ethernet drivers
|
||||||
|
@ -90,7 +78,6 @@
|
||||||
* Definitions
|
* Definitions
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Code
|
* Code
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
|
@ -38,18 +38,6 @@
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
* 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 enet_ethernetif_kinetis.c
|
* @file enet_ethernetif_kinetis.c
|
||||||
* @brief ethernet drivers
|
* @brief ethernet drivers
|
||||||
|
|
|
@ -38,18 +38,6 @@
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
* 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 enet_ethernetif_lpc.c
|
* @file enet_ethernetif_lpc.c
|
||||||
* @brief ethernet drivers
|
* @brief ethernet drivers
|
||||||
|
|
|
@ -6,18 +6,6 @@
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
* 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 fsl_enet.c
|
* @file fsl_enet.c
|
||||||
* @brief ethernet drivers
|
* @brief ethernet drivers
|
||||||
|
|
|
@ -6,18 +6,6 @@
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
* 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 fsl_phy.c
|
* @file fsl_phy.c
|
||||||
* @brief phy drivers for ksz8081
|
* @brief phy drivers for ksz8081
|
||||||
|
|
|
@ -6,18 +6,6 @@
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
* 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 fsl_phy.h
|
* @file fsl_phy.h
|
||||||
* @brief phy drivers for ksz8081
|
* @brief phy drivers for ksz8081
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
|
||||||
|
config PIN_BUS_NAME
|
||||||
|
string "pin bus name"
|
||||||
|
default "pin"
|
||||||
|
|
||||||
|
config PIN_DRIVER_NAME
|
||||||
|
string "pin driver name"
|
||||||
|
default "pin_drv"
|
||||||
|
|
||||||
|
config PIN_DEVICE_NAME
|
||||||
|
string "pin device name"
|
||||||
|
default "pin_dev"
|
|
@ -1,3 +1,3 @@
|
||||||
SRC_FILES := fsl_gpio.c
|
SRC_FILES := connect_gpio.c fsl_gpio.c
|
||||||
|
|
||||||
include $(KERNEL_ROOT)/compiler.mk
|
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -0,0 +1,544 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020 RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2018-11-06 balanceTWK first version
|
||||||
|
* 2019-04-23 WillianChan Fix GPIO serial number disorder
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file connect_gpio.c
|
||||||
|
* @brief support gpio function using bus driver framework
|
||||||
|
* @version 1.0
|
||||||
|
* @author AIIT XUOS Lab
|
||||||
|
* @date 2021-04-25
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
File name: connect_gpio.c
|
||||||
|
Description: support gpio configure and register to bus framework
|
||||||
|
Others: take RT-Thread v4.0.2/bsp/stm32/libraries/HAL_Drivers/drv_gpio.c for references
|
||||||
|
https://github.com/RT-Thread/rt-thread/tree/v4.0.2
|
||||||
|
History:
|
||||||
|
1. Date: 2021-04-25
|
||||||
|
Author: AIIT XUOS Lab
|
||||||
|
Modification: add bus driver framework support for gpio
|
||||||
|
*************************************************/
|
||||||
|
|
||||||
|
#include <device.h>
|
||||||
|
#include <board.h>
|
||||||
|
|
||||||
|
#define STM32_PIN_NUMBERS 100 // [48, 64, 100, 144]
|
||||||
|
|
||||||
|
#define ITEM_NUM(items) sizeof(items)/sizeof(items[0])
|
||||||
|
|
||||||
|
struct PinIndex
|
||||||
|
{
|
||||||
|
int index;
|
||||||
|
GPIO_Type *gpio;
|
||||||
|
uint32_t pin;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PinIrq
|
||||||
|
{
|
||||||
|
uint8 port_source;
|
||||||
|
uint8 pin_source;
|
||||||
|
enum IRQn irq_exti_channel;
|
||||||
|
uint32 exti_line;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct PinIndex pins[] = {
|
||||||
|
{0, GPIO1, 0},
|
||||||
|
{1, GPIO1, 1},
|
||||||
|
{2, GPIO1, 2},
|
||||||
|
{3, GPIO1, 3},
|
||||||
|
{4, GPIO1, 4},
|
||||||
|
{5, GPIO1, 5},
|
||||||
|
{6, GPIO1, 6},
|
||||||
|
{7, GPIO1, 7},
|
||||||
|
{8, GPIO1, 8},
|
||||||
|
{9, GPIO1, 9},
|
||||||
|
{10, GPIO1, 10},
|
||||||
|
{11, GPIO1, 11},
|
||||||
|
{12, GPIO1, 12},
|
||||||
|
{13, GPIO1, 13},
|
||||||
|
{14, GPIO1, 14},
|
||||||
|
{15, GPIO1, 15},
|
||||||
|
{16, GPIO2, 0},
|
||||||
|
{17, GPIO2, 1},
|
||||||
|
{18, GPIO2, 2},
|
||||||
|
{19, GPIO2, 3},
|
||||||
|
{20, GPIO2, 4},
|
||||||
|
{21, GPIO2, 5},
|
||||||
|
{22, GPIO2, 6},
|
||||||
|
{23, GPIO2, 7},
|
||||||
|
{24, GPIO2, 8},
|
||||||
|
{25, GPIO2, 9},
|
||||||
|
{26, GPIO2, 10},
|
||||||
|
{27, GPIO2, 11},
|
||||||
|
{28, GPIO2, 12},
|
||||||
|
{29, GPIO2, 13},
|
||||||
|
{30, GPIO2, 14},
|
||||||
|
{31, GPIO2, 15},
|
||||||
|
{32, GPIO3, 0},
|
||||||
|
{33, GPIO3, 1},
|
||||||
|
{34, GPIO3, 2},
|
||||||
|
{35, GPIO3, 3},
|
||||||
|
{36, GPIO3, 4},
|
||||||
|
{37, GPIO3, 5},
|
||||||
|
{38, GPIO3, 6},
|
||||||
|
{39, GPIO3, 7},
|
||||||
|
{40, GPIO3, 8},
|
||||||
|
{41, GPIO3, 9},
|
||||||
|
{42, GPIO3, 10},
|
||||||
|
{43, GPIO3, 11},
|
||||||
|
{44, GPIO3, 12},
|
||||||
|
{45, GPIO3, 13},
|
||||||
|
{46, GPIO3, 14},
|
||||||
|
{47, GPIO3, 15},
|
||||||
|
{-1, 0u, -1}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PinIrqHdr pin_irq_hdr_tab[] = {};
|
||||||
|
|
||||||
|
const struct PinIndex *GetPin(uint8_t pin)
|
||||||
|
{
|
||||||
|
const struct PinIndex *index;
|
||||||
|
|
||||||
|
if (pin < ITEM_NUM(pins)){
|
||||||
|
index = &pins[pin];
|
||||||
|
if (index->index == -1)
|
||||||
|
index = NONE;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
index = NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32 GpioConfigMode(int mode, const struct PinIndex* index)
|
||||||
|
{
|
||||||
|
gpio_pin_config_t gpio_config;
|
||||||
|
NULL_PARAM_CHECK(index);
|
||||||
|
|
||||||
|
switch (mode)
|
||||||
|
{
|
||||||
|
case GPIO_CFG_OUTPUT:
|
||||||
|
gpio_config.direction = kGPIO_DigitalOutput;
|
||||||
|
gpio_config.interruptMode = kGPIO_NoIntmode;
|
||||||
|
break;
|
||||||
|
case GPIO_CFG_INPUT:
|
||||||
|
gpio_config.direction = kGPIO_DigitalInput;
|
||||||
|
gpio_config.interruptMode = kGPIO_NoIntmode;
|
||||||
|
break;
|
||||||
|
case GPIO_CFG_INPUT_PULLUP:
|
||||||
|
gpio_config.direction = kGPIO_DigitalInput;
|
||||||
|
gpio_config.interruptMode = kGPIO_IntRisingEdge;
|
||||||
|
break;
|
||||||
|
case GPIO_CFG_INPUT_PULLDOWN:
|
||||||
|
gpio_config.direction = kGPIO_DigitalInput;
|
||||||
|
gpio_config.interruptMode = kGPIO_IntFallingEdge;
|
||||||
|
break;
|
||||||
|
case GPIO_CFG_OUTPUT_OD:
|
||||||
|
gpio_config.direction = kGPIO_DigitalOutput;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
GPIO_PinInit(index->gpio, index->pin, &gpio_config);
|
||||||
|
return EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline int32 Bit2Bitnum(uint32 bit)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 32; i++){
|
||||||
|
if ((1UL << i) == bit){
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline int32 Bitno2Bit(uint32 bitno)
|
||||||
|
{
|
||||||
|
if (bitno <= 32) {
|
||||||
|
return 1UL << bitno;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static const struct PinIrq *GetPinIrq(uint16_t pin)
|
||||||
|
{
|
||||||
|
static struct PinIrq irq;
|
||||||
|
const struct PinIndex* index = GetPin(pin);
|
||||||
|
|
||||||
|
if (index == NONE) {
|
||||||
|
return NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
irq.exti_line = index->pin;
|
||||||
|
irq.pin_source = Bit2Bitnum(index->pin);
|
||||||
|
irq.port_source = ((uint32_t)index->gpio - GPIO1_BASE) / (GPIO2_BASE - GPIO1_BASE);
|
||||||
|
switch (irq.pin_source)
|
||||||
|
{
|
||||||
|
case 0 :
|
||||||
|
irq.irq_exti_channel = GPIO1_INT0_IRQn;
|
||||||
|
break;
|
||||||
|
case 1 :
|
||||||
|
irq.irq_exti_channel = GPIO1_INT1_IRQn;
|
||||||
|
break;
|
||||||
|
case 2 :
|
||||||
|
irq.irq_exti_channel = GPIO1_INT2_IRQn;
|
||||||
|
break;
|
||||||
|
case 3 :
|
||||||
|
irq.irq_exti_channel = GPIO1_INT3_IRQn;
|
||||||
|
break;
|
||||||
|
case 4 :
|
||||||
|
irq.irq_exti_channel = GPIO1_INT4_IRQn;
|
||||||
|
break;
|
||||||
|
case 5 :
|
||||||
|
irq.irq_exti_channel = GPIO1_INT5_IRQn;
|
||||||
|
break;
|
||||||
|
case 6 :
|
||||||
|
irq.irq_exti_channel = GPIO1_INT6_IRQn;
|
||||||
|
break;
|
||||||
|
case 7 :
|
||||||
|
irq.irq_exti_channel = GPIO1_INT7_IRQn;
|
||||||
|
break;
|
||||||
|
default :
|
||||||
|
return NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return &irq;
|
||||||
|
};
|
||||||
|
static int32 GpioIrqRegister(int32 pin, int32 mode, void (*hdr)(void *args), void *args)
|
||||||
|
{
|
||||||
|
const struct PinIndex* index = GetPin(pin);
|
||||||
|
int32 irqindex = -1;
|
||||||
|
|
||||||
|
irqindex = Bit2Bitnum(index->pin);
|
||||||
|
if (irqindex < 0 || irqindex >= ITEM_NUM(pin_irq_hdr_tab)) {
|
||||||
|
return -ENONESYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
x_base level = CriticalAreaLock();
|
||||||
|
if (pin_irq_hdr_tab[irqindex].pin == pin &&
|
||||||
|
pin_irq_hdr_tab[irqindex].hdr == hdr &&
|
||||||
|
pin_irq_hdr_tab[irqindex].mode == mode &&
|
||||||
|
pin_irq_hdr_tab[irqindex].args == args
|
||||||
|
)
|
||||||
|
{
|
||||||
|
CriticalAreaUnLock(level);
|
||||||
|
return EOK;
|
||||||
|
}
|
||||||
|
if (pin_irq_hdr_tab[irqindex].pin != -1) {
|
||||||
|
CriticalAreaUnLock(level);
|
||||||
|
return -EDEV_BUSY;
|
||||||
|
}
|
||||||
|
pin_irq_hdr_tab[irqindex].pin = pin;
|
||||||
|
pin_irq_hdr_tab[irqindex].hdr = hdr;
|
||||||
|
pin_irq_hdr_tab[irqindex].mode = mode;
|
||||||
|
pin_irq_hdr_tab[irqindex].args = args;
|
||||||
|
CriticalAreaUnLock(level);
|
||||||
|
|
||||||
|
return EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32 GpioIrqFree(int32 pin)
|
||||||
|
{
|
||||||
|
const struct PinIndex* index = GetPin(pin);
|
||||||
|
int32 irqindex = -1;
|
||||||
|
|
||||||
|
irqindex = Bit2Bitnum(index->pin);
|
||||||
|
if (irqindex < 0 || irqindex >= ITEM_NUM(pin_irq_hdr_tab)) {
|
||||||
|
return -ENONESYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
x_base level = CriticalAreaLock();
|
||||||
|
if (pin_irq_hdr_tab[irqindex].pin == -1){
|
||||||
|
CriticalAreaUnLock(level);
|
||||||
|
return EOK;
|
||||||
|
}
|
||||||
|
pin_irq_hdr_tab[irqindex].pin = -1;
|
||||||
|
pin_irq_hdr_tab[irqindex].hdr = NONE;
|
||||||
|
pin_irq_hdr_tab[irqindex].mode = 0;
|
||||||
|
pin_irq_hdr_tab[irqindex].args = NONE;
|
||||||
|
CriticalAreaUnLock(level);
|
||||||
|
|
||||||
|
return EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32 GpioIrqEnable(x_base pin)
|
||||||
|
{
|
||||||
|
const struct PinIndex* index = GetPin(pin);
|
||||||
|
int32 irqindex = -1;
|
||||||
|
const struct PinIrq *irq;
|
||||||
|
gpio_pin_config_t gpio_config;
|
||||||
|
|
||||||
|
irqindex = Bit2Bitnum(index->pin);
|
||||||
|
if (irqindex < 0 || irqindex >= ITEM_NUM(pin_irq_hdr_tab)){
|
||||||
|
return -ENONESYS;
|
||||||
|
}
|
||||||
|
x_base level = CriticalAreaLock();
|
||||||
|
if (pin_irq_hdr_tab[irqindex].pin == -1) {
|
||||||
|
CriticalAreaUnLock(level);
|
||||||
|
return -ENONESYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
irq = GetPinIrq(pin);
|
||||||
|
if (irq == NONE){
|
||||||
|
CriticalAreaUnLock(level);
|
||||||
|
return -ENONESYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (pin_irq_hdr_tab[irqindex].mode)
|
||||||
|
{
|
||||||
|
case GPIO_IRQ_EDGE_RISING:
|
||||||
|
gpio_config.direction = kGPIO_DigitalInput;
|
||||||
|
gpio_config.interruptMode = kGPIO_IntRisingEdge;
|
||||||
|
break;
|
||||||
|
case GPIO_IRQ_EDGE_FALLING:
|
||||||
|
gpio_config.direction = kGPIO_DigitalInput;
|
||||||
|
gpio_config.interruptMode = kGPIO_IntFallingEdge;
|
||||||
|
break;
|
||||||
|
case GPIO_IRQ_EDGE_BOTH:
|
||||||
|
gpio_config.direction = kGPIO_DigitalInput;
|
||||||
|
gpio_config.interruptMode = kGPIO_IntRisingOrFallingEdge;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
GPIO_PinInit(index->gpio, index->pin, &gpio_config);
|
||||||
|
GPIO_PortEnableInterrupts(index->gpio, index->pin);
|
||||||
|
CriticalAreaUnLock(level);
|
||||||
|
return EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32 GpioIrqDisable(x_base pin)
|
||||||
|
{
|
||||||
|
const struct PinIndex* index = GetPin(pin);
|
||||||
|
const struct PinIrq *irq;
|
||||||
|
|
||||||
|
irq = GetPinIrq(index->pin);
|
||||||
|
NULL_PARAM_CHECK(irq);
|
||||||
|
|
||||||
|
GPIO_PortDisableInterrupts(index->gpio, index->pin);
|
||||||
|
return EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32 Stm32PinConfigure(struct PinParam *param)
|
||||||
|
{
|
||||||
|
NULL_PARAM_CHECK(param);
|
||||||
|
int ret = EOK;
|
||||||
|
|
||||||
|
const struct PinIndex *index = GetPin(param->pin);
|
||||||
|
switch(param->cmd)
|
||||||
|
{
|
||||||
|
case GPIO_CONFIG_MODE:
|
||||||
|
GpioConfigMode(param->mode, index);
|
||||||
|
break;
|
||||||
|
case GPIO_IRQ_REGISTER:
|
||||||
|
ret = GpioIrqRegister(param->pin,param->irq_set.irq_mode,param->irq_set.hdr,param->irq_set.args);
|
||||||
|
break;
|
||||||
|
case GPIO_IRQ_FREE:
|
||||||
|
ret = GpioIrqFree(param->pin);
|
||||||
|
break;
|
||||||
|
case GPIO_IRQ_ENABLE:
|
||||||
|
ret = GpioIrqEnable(param->pin);
|
||||||
|
break;
|
||||||
|
case GPIO_IRQ_DISABLE:
|
||||||
|
ret = GpioIrqDisable(param->pin);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ret = -EINVALED;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32 Stm32PinInit(void)
|
||||||
|
{
|
||||||
|
static x_bool pin_init_flag = RET_FALSE;
|
||||||
|
|
||||||
|
if (!pin_init_flag) {
|
||||||
|
pin_init_flag = RET_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32 Stm32GpioDrvConfigure(void *drv, struct BusConfigureInfo *configure_info)
|
||||||
|
{
|
||||||
|
NULL_PARAM_CHECK(drv);
|
||||||
|
NULL_PARAM_CHECK(configure_info);
|
||||||
|
|
||||||
|
x_err_t ret = EOK;
|
||||||
|
struct PinParam *param;
|
||||||
|
|
||||||
|
switch (configure_info->configure_cmd)
|
||||||
|
{
|
||||||
|
case OPE_INT:
|
||||||
|
ret = Stm32PinInit();
|
||||||
|
break;
|
||||||
|
case OPE_CFG:
|
||||||
|
param = (struct PinParam *)configure_info->private_data;
|
||||||
|
ret = Stm32PinConfigure(param);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 Stm32PinWrite(void *dev, struct BusBlockWriteParam *write_param)
|
||||||
|
{
|
||||||
|
NULL_PARAM_CHECK(dev);
|
||||||
|
NULL_PARAM_CHECK(write_param);
|
||||||
|
struct PinStat *pinstat = (struct PinStat *)write_param->buffer;
|
||||||
|
const struct PinIndex* index = GetPin(pinstat->pin);
|
||||||
|
NULL_PARAM_CHECK(index);
|
||||||
|
|
||||||
|
if (GPIO_LOW == pinstat->val) {
|
||||||
|
GPIO_PinWrite(index->gpio, index->pin, 0);
|
||||||
|
} else {
|
||||||
|
GPIO_PinWrite(index->gpio, index->pin, 1);
|
||||||
|
}
|
||||||
|
return EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 Stm32PinRead(void *dev, struct BusBlockReadParam *read_param)
|
||||||
|
{
|
||||||
|
NULL_PARAM_CHECK(dev);
|
||||||
|
NULL_PARAM_CHECK(read_param);
|
||||||
|
struct PinStat *pinstat = (struct PinStat *)read_param->buffer;
|
||||||
|
const struct PinIndex* index = GetPin(pinstat->pin);
|
||||||
|
NULL_PARAM_CHECK(index);
|
||||||
|
|
||||||
|
if(GPIO_PinRead(index->gpio, index->pin) == GPIO_LOW) {
|
||||||
|
pinstat->val = GPIO_LOW;
|
||||||
|
} else {
|
||||||
|
pinstat->val = GPIO_HIGH;
|
||||||
|
}
|
||||||
|
return pinstat->val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct PinDevDone dev_done =
|
||||||
|
{
|
||||||
|
.open = NONE,
|
||||||
|
.close = NONE,
|
||||||
|
.write = Stm32PinWrite,
|
||||||
|
.read = Stm32PinRead,
|
||||||
|
};
|
||||||
|
|
||||||
|
int Stm32HwGpioInit(void)
|
||||||
|
{
|
||||||
|
x_err_t ret = EOK;
|
||||||
|
|
||||||
|
static struct PinBus pin;
|
||||||
|
|
||||||
|
ret = PinBusInit(&pin, PIN_BUS_NAME);
|
||||||
|
if (ret != EOK) {
|
||||||
|
KPrintf("gpio bus init error %d\n", ret);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct PinDriver drv;
|
||||||
|
drv.configure = &Stm32GpioDrvConfigure;
|
||||||
|
|
||||||
|
ret = PinDriverInit(&drv, PIN_DRIVER_NAME, NONE);
|
||||||
|
if (ret != EOK) {
|
||||||
|
KPrintf("pin driver init error %d\n", ret);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
ret = PinDriverAttachToBus(PIN_DRIVER_NAME, PIN_BUS_NAME);
|
||||||
|
if (ret != EOK) {
|
||||||
|
KPrintf("pin driver attach error %d\n", ret);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct PinHardwareDevice dev;
|
||||||
|
dev.dev_done = &dev_done;
|
||||||
|
|
||||||
|
ret = PinDeviceRegister(&dev, NONE, PIN_DEVICE_NAME);
|
||||||
|
if (ret != EOK) {
|
||||||
|
KPrintf("pin device register error %d\n", ret);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
ret = PinDeviceAttachToBus(PIN_DEVICE_NAME, PIN_BUS_NAME);
|
||||||
|
if (ret != EOK) {
|
||||||
|
KPrintf("pin device register error %d\n", ret);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline void PinIrqHdr(int irqno)
|
||||||
|
{
|
||||||
|
const struct PinIndex* index = GetPin(irqno);
|
||||||
|
const struct PinIrq *irq;
|
||||||
|
|
||||||
|
irq = GetPinIrq(index->pin);
|
||||||
|
NULL_PARAM_CHECK(irq);
|
||||||
|
|
||||||
|
GPIO_ClearPinsInterruptFlags(index->gpio, index->pin);
|
||||||
|
|
||||||
|
if (pin_irq_hdr_tab[irqno].hdr){
|
||||||
|
pin_irq_hdr_tab[irqno].hdr(pin_irq_hdr_tab[irqno].args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EXTI0_IRQHandler(int irq_num, void *arg)
|
||||||
|
{
|
||||||
|
PinIrqHdr(0);
|
||||||
|
}
|
||||||
|
DECLARE_HW_IRQ(GPIO1_INT0_IRQn, EXTI0_IRQHandler, NONE);
|
||||||
|
|
||||||
|
void EXTI1_IRQHandler(int irq_num, void *arg)
|
||||||
|
{
|
||||||
|
PinIrqHdr(1);
|
||||||
|
}
|
||||||
|
DECLARE_HW_IRQ(GPIO1_INT1_IRQn, EXTI1_IRQHandler, NONE);
|
||||||
|
|
||||||
|
void EXTI2_IRQHandler(int irq_num, void *arg)
|
||||||
|
{
|
||||||
|
PinIrqHdr(2);
|
||||||
|
}
|
||||||
|
DECLARE_HW_IRQ(GPIO1_INT2_IRQn, EXTI2_IRQHandler, NONE);
|
||||||
|
|
||||||
|
void EXTI3_IRQHandler(int irq_num, void *arg)
|
||||||
|
{
|
||||||
|
PinIrqHdr(3);
|
||||||
|
}
|
||||||
|
DECLARE_HW_IRQ(GPIO1_INT3_IRQn, EXTI3_IRQHandler, NONE);
|
||||||
|
|
||||||
|
void EXTI4_IRQHandler(int irq_num, void *arg)
|
||||||
|
{
|
||||||
|
PinIrqHdr(4);
|
||||||
|
}
|
||||||
|
DECLARE_HW_IRQ(GPIO1_INT4_IRQn, EXTI4_IRQHandler, NONE);
|
||||||
|
|
||||||
|
void EXTI5_IRQHandler(int irq_num, void *arg)
|
||||||
|
{
|
||||||
|
PinIrqHdr(5);
|
||||||
|
}
|
||||||
|
DECLARE_HW_IRQ(GPIO1_INT5_IRQn, EXTI5_IRQHandler, NONE);
|
||||||
|
|
||||||
|
void EXTI6_IRQHandler(int irq_num, void *arg)
|
||||||
|
{
|
||||||
|
PinIrqHdr(6);
|
||||||
|
}
|
||||||
|
DECLARE_HW_IRQ(GPIO1_INT6_IRQn, EXTI6_IRQHandler, NONE);
|
||||||
|
|
||||||
|
void EXTI7_IRQHandler(int irq_num, void *arg)
|
||||||
|
{
|
||||||
|
PinIrqHdr(7);
|
||||||
|
}
|
||||||
|
DECLARE_HW_IRQ(GPIO1_INT7_IRQn, EXTI7_IRQHandler, NONE);
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
if BSP_USING_I2C
|
||||||
|
config I2C_BUS_NAME_1
|
||||||
|
string "i2c bus 1 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"
|
||||||
|
endif
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
SRC_FILES := connect_i2c.c connect_i2c_eeprom.c hardware_i2c.c fsl_lpi2c.c
|
||||||
|
|
||||||
|
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -0,0 +1,194 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020 RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2012-04-25 weety first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file connect_i2c.c
|
||||||
|
* @brief support ok1052-c i2c function and register to bus framework
|
||||||
|
* @version 1.0
|
||||||
|
* @author AIIT XUOS Lab
|
||||||
|
* @date 2022-03-01
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
File name: connect_i2c.c
|
||||||
|
Description: support ok1052-c i2c configure and i2c bus register function
|
||||||
|
Others: take RT-Thread v4.0.2/components/drivers/i2c/i2c-bit-ops.c for references
|
||||||
|
https://github.com/RT-Thread/rt-thread/tree/v4.0.2
|
||||||
|
History:
|
||||||
|
1. Date: 2022-03-01
|
||||||
|
Author: AIIT XUOS Lab
|
||||||
|
Modification:
|
||||||
|
1. support ok1052-c i2c bit configure, write and read
|
||||||
|
2. support ok1052-c i2c bus device and driver register
|
||||||
|
*************************************************/
|
||||||
|
|
||||||
|
#include <board.h>
|
||||||
|
#include "bus_serial.h"
|
||||||
|
#include "connect_i2c.h"
|
||||||
|
#include "fsl_lpi2c.h"
|
||||||
|
|
||||||
|
#ifndef BSP_USING_I2C1
|
||||||
|
#define BSP_USING_I2C1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static uint32 I2cWriteData(struct I2cHardwareDevice *i2c_dev, struct I2cDataStandard *msg)
|
||||||
|
{
|
||||||
|
status_t ret;
|
||||||
|
Stm32I2cType *param = (Stm32I2cType *)i2c_dev->haldev.private_data;
|
||||||
|
ret = I2cHardwareWrite(param->base, param->slave_addr, param->sub_addr, msg->buf, msg->len);
|
||||||
|
if(kStatus_Success == ret)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32 I2cReadData(struct I2cHardwareDevice *i2c_dev, struct I2cDataStandard *msg)
|
||||||
|
{
|
||||||
|
status_t ret;
|
||||||
|
Stm32I2cType *param = (Stm32I2cType *)i2c_dev->haldev.private_data;
|
||||||
|
ret = I2cHardwareRead(param->base, i2c_dev->i2c_dev_addr, param->sub_addr, msg->buf, msg->len);
|
||||||
|
if(kStatus_Success == ret)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
if (configure_info->private_data) {
|
||||||
|
i2c_dev->i2c_dev_addr = *((uint16 *)configure_info->private_data);
|
||||||
|
return EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
i2c_print("I2cInit need set i2c dev addr\n");
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*manage the i2c device operations*/
|
||||||
|
static const struct I2cDevDone i2c_dev_done =
|
||||||
|
{
|
||||||
|
.dev_open = NONE,
|
||||||
|
.dev_close = NONE,
|
||||||
|
.dev_write = I2cWriteData,
|
||||||
|
.dev_read = I2cReadData,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*Init i2c bus*/
|
||||||
|
static int BoardI2cBusInit(struct I2cBus *i2c_bus, struct I2cDriver *i2c_driver)
|
||||||
|
{
|
||||||
|
x_err_t ret = EOK;
|
||||||
|
|
||||||
|
/*Init the i2c bus */
|
||||||
|
i2c_bus->private_data = (void *)NULL;
|
||||||
|
ret = I2cBusInit(i2c_bus, I2C_BUS_NAME_1);
|
||||||
|
if (EOK != ret) {
|
||||||
|
i2c_print("BoardI2cBusInit I2cBusInit error %d\n", ret);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Init the i2c driver*/
|
||||||
|
i2c_driver->private_data = (void *)NULL;
|
||||||
|
ret = I2cDriverInit(i2c_driver, I2C_DRV_NAME_1);
|
||||||
|
if (EOK != ret) {
|
||||||
|
i2c_print("BoardI2cBusInit 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) {
|
||||||
|
i2c_print("BoardI2cBusInit 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) {
|
||||||
|
i2c_print("BoardI2cDevBend 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) {
|
||||||
|
i2c_print("BoardI2cDevBend I2cDeviceAttachToBus device %s error %d\n", I2C_1_DEVICE_NAME_0, ret);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*BOARD I2C INIT*/
|
||||||
|
int Stm32HwI2cInit(void)
|
||||||
|
{
|
||||||
|
static int init_flag = 0;
|
||||||
|
x_err_t ret = EOK;
|
||||||
|
|
||||||
|
if(init_flag)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
init_flag = 1;
|
||||||
|
|
||||||
|
static struct I2cBus i2c_bus;
|
||||||
|
memset(&i2c_bus, 0, sizeof(struct I2cBus));
|
||||||
|
static struct I2cDriver i2c_driver;
|
||||||
|
memset(&i2c_driver, 0, sizeof(struct I2cDriver));
|
||||||
|
|
||||||
|
#ifdef BSP_USING_I2C1
|
||||||
|
i2c_driver.configure = I2cDrvConfigure;
|
||||||
|
|
||||||
|
ret = BoardI2cBusInit(&i2c_bus, &i2c_driver);
|
||||||
|
if (EOK != ret) {
|
||||||
|
i2c_print("board_i2c_Init error ret %u\n", ret);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = BoardI2cDevBend();
|
||||||
|
if (EOK != ret) {
|
||||||
|
i2c_print("board_i2c_Init error ret %u\n", ret);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
|
@ -0,0 +1,99 @@
|
||||||
|
/*
|
||||||
|
* The Clear BSD License
|
||||||
|
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||||
|
* Copyright 2016-2017 NXP
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted (subject to the limitations in the disclaimer below) provided
|
||||||
|
* that the following conditions are met:
|
||||||
|
*
|
||||||
|
* o Redistributions of source code must retain the above copyright notice, this list
|
||||||
|
* of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer in the documentation and/or
|
||||||
|
* other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* o Neither the name of the copyright holder nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from this
|
||||||
|
* software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file connect_i2c_eeprom.h
|
||||||
|
* @brief ok1052-c eeprom relative codes
|
||||||
|
* @version 1.0
|
||||||
|
* @author AIIT XUOS Lab
|
||||||
|
* @date 2022-03-01
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "board.h"
|
||||||
|
#include "connect_i2c.h"
|
||||||
|
#include "fsl_lpi2c.h"
|
||||||
|
#include "pin_mux.h"
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Definitions
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#define I2C_EEPROM_BASE LPI2C1
|
||||||
|
#define I2C_EEPROM_ADDR (0xA0 >> 1)
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Code
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
void I2cEEpromTestWrite(void)
|
||||||
|
{
|
||||||
|
uint8_t dat[8] = {0};
|
||||||
|
|
||||||
|
if(I2cHardwareRead(I2C_EEPROM_BASE, I2C_EEPROM_ADDR, 0, dat, 8) == kStatus_Success)
|
||||||
|
{
|
||||||
|
i2c_print("Read from EEPROM %d %d %d %d %d %d %d %d\r\n",
|
||||||
|
dat[0], dat[1], dat[2], dat[3], dat[4], dat[5], dat[6], dat[7]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(uint8_t i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
|
dat[i] ++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(I2cHardwareWrite(I2C_EEPROM_BASE, I2C_EEPROM_ADDR, 0, dat, 8) == kStatus_Success)
|
||||||
|
{
|
||||||
|
i2c_print("Write to EEPROM %d %d %d %d %d %d %d %d\r\n",
|
||||||
|
dat[0], dat[1], dat[2], dat[3], dat[4], dat[5], dat[6], dat[7]);
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(dat, 0, 8);
|
||||||
|
if(I2cHardwareRead(I2C_EEPROM_BASE, I2C_EEPROM_ADDR, 0, dat, 8) == kStatus_Success)
|
||||||
|
{
|
||||||
|
i2c_print("Read from EEPROM %d %d %d %d %d %d %d %d\r\n",
|
||||||
|
dat[0], dat[1], dat[2], dat[3], dat[4], dat[5], dat[6], dat[7]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int I2cEEpromTest(void)
|
||||||
|
{
|
||||||
|
Stm32HwI2cInit();
|
||||||
|
BOARD_InitI2C1Pins();
|
||||||
|
I2cHardwareInit();
|
||||||
|
I2cEEpromTestWrite();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)| SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN)| SHELL_CMD_PARAM_NUM(0),
|
||||||
|
eeprom, I2cEEpromTest, test i2c eeprom);
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,94 @@
|
||||||
|
/*
|
||||||
|
* The Clear BSD License
|
||||||
|
* Copyright (c) 2016, Freescale Semiconductor, Inc.
|
||||||
|
* Copyright 2016-2017 NXP
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted (subject to the limitations in the disclaimer below) provided
|
||||||
|
* that the following conditions are met:
|
||||||
|
*
|
||||||
|
* o Redistributions of source code must retain the above copyright notice, this list
|
||||||
|
* of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer in the documentation and/or
|
||||||
|
* other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* o Neither the name of the copyright holder nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from this
|
||||||
|
* software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file hardware_i2c.c
|
||||||
|
* @brief ok1052-c i2c relative codes
|
||||||
|
* @version 1.0
|
||||||
|
* @author AIIT XUOS Lab
|
||||||
|
* @date 2022-03-01
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "fsl_common.h"
|
||||||
|
#include "fsl_lpi2c.h"
|
||||||
|
|
||||||
|
#define I2C_BASE LPI2C1
|
||||||
|
|
||||||
|
/* Select USB1 PLL (480 MHz) as master lpi2c clock source */
|
||||||
|
#define LPI2C_CLOCK_SOURCE_SELECT (0U)
|
||||||
|
/* Clock divider for master lpi2c clock source */
|
||||||
|
#define LPI2C_CLOCK_SOURCE_DIVIDER (5U)
|
||||||
|
|
||||||
|
#define I2C_CLOCK_FREQ ((CLOCK_GetFreq(kCLOCK_Usb1PllClk) / 8) / (LPI2C_CLOCK_SOURCE_DIVIDER + 1U))
|
||||||
|
#define I2C_BAUDRATE 100000U
|
||||||
|
|
||||||
|
void I2cHardwareInit(void)
|
||||||
|
{
|
||||||
|
lpi2c_master_config_t masterConfig = {0};
|
||||||
|
|
||||||
|
LPI2C_MasterGetDefaultConfig(&masterConfig);
|
||||||
|
|
||||||
|
/* Change the default baudrate configuration */
|
||||||
|
masterConfig.baudRate_Hz = I2C_BAUDRATE;
|
||||||
|
|
||||||
|
/* Initialize the LPI2C master peripheral */
|
||||||
|
LPI2C_MasterInit(I2C_BASE, &masterConfig, I2C_CLOCK_FREQ);
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t I2cHardwareWrite(LPI2C_Type* base, uint16_t slave_addr, uint32_t subAdd, uint8_t* dataBuff, uint16_t dataLen)
|
||||||
|
{
|
||||||
|
lpi2c_master_transfer_t xfer;
|
||||||
|
xfer.slaveAddress = slave_addr;
|
||||||
|
xfer.direction = kLPI2C_Write;
|
||||||
|
xfer.subaddress = subAdd;
|
||||||
|
xfer.subaddressSize = 0x01;
|
||||||
|
xfer.data = dataBuff;
|
||||||
|
xfer.dataSize = dataLen;
|
||||||
|
xfer.flags = kLPI2C_TransferDefaultFlag;
|
||||||
|
return LPI2C_MasterTransferBlocking(base, &xfer);
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t I2cHardwareRead(LPI2C_Type* base, uint16_t slave_addr, uint32_t subAdd, uint8_t* dataBuffer, uint16_t dataLen)
|
||||||
|
{
|
||||||
|
lpi2c_master_transfer_t masterXfer = {0};
|
||||||
|
masterXfer.slaveAddress = slave_addr;
|
||||||
|
masterXfer.direction = kLPI2C_Read;
|
||||||
|
masterXfer.subaddress = subAdd;
|
||||||
|
masterXfer.subaddressSize = 0x01;
|
||||||
|
masterXfer.data = dataBuffer;
|
||||||
|
masterXfer.dataSize = dataLen;
|
||||||
|
masterXfer.flags = kLPI2C_TransferDefaultFlag;
|
||||||
|
return LPI2C_MasterTransferBlocking(base, &masterXfer);
|
||||||
|
}
|
||||||
|
|
|
@ -144,6 +144,8 @@
|
||||||
#define FSL_FEATURE_ADC_SUPPORT_HARDWARE_TRIGGER_REMOVE (0)
|
#define FSL_FEATURE_ADC_SUPPORT_HARDWARE_TRIGGER_REMOVE (0)
|
||||||
/* @brief Remove ALT Clock selection feature. */
|
/* @brief Remove ALT Clock selection feature. */
|
||||||
#define FSL_FEATURE_ADC_SUPPORT_ALTCLK_REMOVE (1)
|
#define FSL_FEATURE_ADC_SUPPORT_ALTCLK_REMOVE (1)
|
||||||
|
/* @brief Conversion control count (related to number of registers HCn and Rn). */
|
||||||
|
#define FSL_FEATURE_ADC_CONVERSION_CONTROL_COUNT (8)
|
||||||
|
|
||||||
/* ADC_ETC module features */
|
/* ADC_ETC module features */
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
/*
|
||||||
|
* 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.h
|
||||||
|
* @brief define stm32f407-st-discovery adc function and struct
|
||||||
|
* @version 1.1
|
||||||
|
* @author AIIT XUOS Lab
|
||||||
|
* @date 2021-12-28
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CONNECT_ADC_H
|
||||||
|
#define CONNECT_ADC_H
|
||||||
|
|
||||||
|
#include <device.h>
|
||||||
|
|
||||||
|
struct Imrt1052HwAdc
|
||||||
|
{
|
||||||
|
void *ADCx;
|
||||||
|
uint8 adc_channel;
|
||||||
|
};
|
||||||
|
|
||||||
|
int Imrt1052HwAdcInit(void);
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,26 +1,5 @@
|
||||||
/**
|
/*
|
||||||
******************************************************************************
|
* Copyright (c) 2021 AIIT XUOS Lab
|
||||||
* @file connect_ethernet.h
|
|
||||||
* @author MCD Application Team
|
|
||||||
* @version V1.0.0
|
|
||||||
* @date 31-October-2011
|
|
||||||
* @brief STM32F4x7 Ethernet hardware configuration.
|
|
||||||
******************************************************************************
|
|
||||||
* @attention
|
|
||||||
*
|
|
||||||
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
|
|
||||||
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
|
|
||||||
* TIME. AS A RESULT, STMICROELECTRONICS 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.
|
|
||||||
*
|
|
||||||
* <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>
|
|
||||||
******************************************************************************
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (c) 2020 AIIT XUOS Lab
|
|
||||||
* XiUOS is licensed under Mulan PSL v2.
|
* XiUOS is licensed under Mulan PSL v2.
|
||||||
* You can use this software according to the terms and conditions of the 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:
|
* You may obtain a copy of Mulan PSL v2 at:
|
||||||
|
@ -39,37 +18,22 @@
|
||||||
* @date 2021-12-7
|
* @date 2021-12-7
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
#ifndef __CONNECT_ETHERNET_H_
|
||||||
#ifndef __ETH_BSP_H
|
#define __CONNECT_ETHERNET_H_
|
||||||
#define __ETH_BSP_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Includes ------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Exported types ------------------------------------------------------------*/
|
|
||||||
/* Exported constants --------------------------------------------------------*/
|
|
||||||
|
|
||||||
|
|
||||||
/* Exported macro ------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifndef sourceClock
|
#ifndef sourceClock
|
||||||
#define sourceClock CLOCK_GetFreq(kCLOCK_CoreSysClk)
|
#define sourceClock CLOCK_GetFreq(kCLOCK_CoreSysClk)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Exported functions ------------------------------------------------------- */
|
|
||||||
|
|
||||||
void enet_delay(void);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* __STM32F4x7_ETH_BSP_H */
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
|
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 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_gpio.h
|
||||||
|
* @brief define ok1052-c gpio function and struct
|
||||||
|
* @version 1.0
|
||||||
|
* @author AIIT XUOS Lab
|
||||||
|
* @date 2022-03-01
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __CONNECT_GPIO_H_
|
||||||
|
#define __CONNECT_GPIO_H_
|
||||||
|
|
||||||
|
#include <device.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int Stm32HwGpioInit(void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
* 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 stm32f407-st-discovery-board i2c function and struct
|
||||||
|
* @version 1.0
|
||||||
|
* @author AIIT XUOS Lab
|
||||||
|
* @date 2021-04-25
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CONNECT_I2C_H
|
||||||
|
#define CONNECT_I2C_H
|
||||||
|
|
||||||
|
#include <device.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct Stm32I2c
|
||||||
|
{
|
||||||
|
LPI2C_Type* base;
|
||||||
|
uint16_t slave_addr;
|
||||||
|
uint32_t sub_addr;
|
||||||
|
}Stm32I2cType;
|
||||||
|
|
||||||
|
#define i2c_print KPrintf
|
||||||
|
|
||||||
|
int Stm32HwI2cInit(void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 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 ok1052-c rtc function and structure
|
||||||
|
* @version 1.0
|
||||||
|
* @author AIIT XUOS Lab
|
||||||
|
* @date 2022-03-01
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __CONNECT_RTC_H_
|
||||||
|
#define __CONNECT_RTC_H_
|
||||||
|
|
||||||
|
#include "fsl_common.h"
|
||||||
|
#include "fsl_lpi2c.h"
|
||||||
|
|
||||||
|
#define I2C_RTC_BASE LPI2C1
|
||||||
|
#define I2C_RTC_ADDR 0x32
|
||||||
|
|
||||||
|
void RtcI2cInit(void);
|
||||||
|
status_t RtcI2cWrite(LPI2C_Type *base, uint32_t sub_addr, uint8_t *buf, uint16_t size);
|
||||||
|
uint32_t RtcI2cRead(LPI2C_Type *base, uint32_t sub_addr, uint8_t *buf, uint16_t size);
|
||||||
|
|
||||||
|
int Imrt1052HwRtcInit(void);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
* 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.h
|
||||||
|
* @brief define stm32f407-st-discovery-board spi function and struct
|
||||||
|
* @version 1.0
|
||||||
|
* @author AIIT XUOS Lab
|
||||||
|
* @date 2021-04-25
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CONNECT_SPI_H
|
||||||
|
#define CONNECT_SPI_H
|
||||||
|
|
||||||
|
#include <device.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define SPI_USING_RX_DMA_FLAG (1<<0)
|
||||||
|
#define SPI_USING_TX_DMA_FLAG (1<<1)
|
||||||
|
|
||||||
|
struct Stm32HwSpi
|
||||||
|
{
|
||||||
|
LPSPI_Type *base;
|
||||||
|
uint8_t irq;
|
||||||
|
uint8_t mode;
|
||||||
|
void *priv_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Stm32Spi
|
||||||
|
{
|
||||||
|
LPSPI_Type *instance;
|
||||||
|
char *bus_name;
|
||||||
|
struct SpiBus spi_bus;
|
||||||
|
};
|
||||||
|
|
||||||
|
int Imrt1052HwSpiInit(void);
|
||||||
|
x_err_t HwSpiDeviceAttach(const char *bus_name, const char *device_name);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -38,18 +38,6 @@
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
* 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 enet_ethernetif.h
|
* @file enet_ethernetif.h
|
||||||
* @brief ethernet drivers
|
* @brief ethernet drivers
|
||||||
|
|
|
@ -5,18 +5,6 @@
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
* 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 enet_ethernetif_priv.h
|
* @file enet_ethernetif_priv.h
|
||||||
* @brief ethernet drivers
|
* @brief ethernet drivers
|
||||||
|
|
|
@ -6,18 +6,6 @@
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
* 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 fsl_cache.h
|
* @file fsl_cache.h
|
||||||
* @brief cache drivers
|
* @brief cache drivers
|
||||||
|
|
|
@ -5,18 +5,6 @@
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
* 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 fsl_clock.h
|
* @file fsl_clock.h
|
||||||
* @brief clock drivers
|
* @brief clock drivers
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
#define _FSL_DEBUGCONSOLE_H_
|
#define _FSL_DEBUGCONSOLE_H_
|
||||||
|
|
||||||
#include "fsl_common.h"
|
#include "fsl_common.h"
|
||||||
//#include "serial_manager.h"
|
#include "serial_manager.h"
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @addtogroup debugconsole
|
* @addtogroup debugconsole
|
||||||
|
|
|
@ -6,18 +6,6 @@
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
* 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 fsl_enet.h
|
* @file fsl_enet.h
|
||||||
* @brief ethernet drivers
|
* @brief ethernet drivers
|
||||||
|
|
|
@ -6,18 +6,6 @@
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
* 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 fsl_iomuxc.h
|
* @file fsl_iomuxc.h
|
||||||
* @brief io mux drivers
|
* @brief io mux drivers
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -6,18 +6,6 @@
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
* 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 fsl_lpuart.h
|
* @file fsl_lpuart.h
|
||||||
* @brief fsl uart drivers
|
* @brief fsl uart drivers
|
||||||
|
|
|
@ -0,0 +1,548 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2018 NXP
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __SERIAL_MANAGER_H__
|
||||||
|
#define __SERIAL_MANAGER_H__
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @addtogroup serialmanager
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Definitions
|
||||||
|
******************************************************************************/
|
||||||
|
#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING
|
||||||
|
/*! @brief Enable or disable serial manager non-blocking mode (1 - enable, 0 - disable) */
|
||||||
|
#define SERIAL_MANAGER_NON_BLOCKING_MODE (1U)
|
||||||
|
#else
|
||||||
|
#ifndef SERIAL_MANAGER_NON_BLOCKING_MODE
|
||||||
|
#define SERIAL_MANAGER_NON_BLOCKING_MODE (0U)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*! @brief Enable or disable uart port (1 - enable, 0 - disable) */
|
||||||
|
#ifndef SERIAL_PORT_TYPE_UART
|
||||||
|
#define SERIAL_PORT_TYPE_UART (1U)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*! @brief Enable or disable USB CDC port (1 - enable, 0 - disable) */
|
||||||
|
#ifndef SERIAL_PORT_TYPE_USBCDC
|
||||||
|
#define SERIAL_PORT_TYPE_USBCDC (0U)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*! @brief Enable or disable SWO port (1 - enable, 0 - disable) */
|
||||||
|
#ifndef SERIAL_PORT_TYPE_SWO
|
||||||
|
#define SERIAL_PORT_TYPE_SWO (0U)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*! @brief Enable or disable USB CDC virtual port (1 - enable, 0 - disable) */
|
||||||
|
#ifndef SERIAL_PORT_TYPE_USBCDC_VIRTUAL
|
||||||
|
#define SERIAL_PORT_TYPE_USBCDC_VIRTUAL (0U)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*! @brief Set serial manager write handle size */
|
||||||
|
#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
|
||||||
|
#define SERIAL_MANAGER_WRITE_HANDLE_SIZE (44U)
|
||||||
|
#define SERIAL_MANAGER_READ_HANDLE_SIZE (44U)
|
||||||
|
#else
|
||||||
|
#define SERIAL_MANAGER_WRITE_HANDLE_SIZE (4U)
|
||||||
|
#define SERIAL_MANAGER_READ_HANDLE_SIZE (4U)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (defined(SERIAL_PORT_TYPE_UART) && (SERIAL_PORT_TYPE_UART > 0U))
|
||||||
|
#include "serial_port_uart.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (defined(SERIAL_PORT_TYPE_USBCDC) && (SERIAL_PORT_TYPE_USBCDC > 0U))
|
||||||
|
|
||||||
|
#if !(defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
|
||||||
|
#error The serial manager blocking mode cannot be supported for USB CDC.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "serial_port_usb.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (defined(SERIAL_PORT_TYPE_SWO) && (SERIAL_PORT_TYPE_SWO > 0U))
|
||||||
|
#include "serial_port_swo.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (defined(SERIAL_PORT_TYPE_USBCDC_VIRTUAL) && (SERIAL_PORT_TYPE_USBCDC_VIRTUAL > 0U))
|
||||||
|
|
||||||
|
#if !(defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
|
||||||
|
#error The serial manager blocking mode cannot be supported for USB CDC.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "serial_port_usb_virtual.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define SERIAL_MANAGER_HANDLE_SIZE_TEMP 0U
|
||||||
|
#if (defined(SERIAL_PORT_TYPE_UART) && (SERIAL_PORT_TYPE_UART > 0U))
|
||||||
|
|
||||||
|
#if (SERIAL_PORT_UART_HANDLE_SIZE > SERIAL_MANAGER_HANDLE_SIZE_TEMP)
|
||||||
|
#undef SERIAL_MANAGER_HANDLE_SIZE_TEMP
|
||||||
|
#define SERIAL_MANAGER_HANDLE_SIZE_TEMP SERIAL_PORT_UART_HANDLE_SIZE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (defined(SERIAL_PORT_TYPE_USBCDC) && (SERIAL_PORT_TYPE_USBCDC > 0U))
|
||||||
|
|
||||||
|
#if (SERIAL_PORT_USB_CDC_HANDLE_SIZE > SERIAL_MANAGER_HANDLE_SIZE_TEMP)
|
||||||
|
#undef SERIAL_MANAGER_HANDLE_SIZE_TEMP
|
||||||
|
#define SERIAL_MANAGER_HANDLE_SIZE_TEMP SERIAL_PORT_USB_CDC_HANDLE_SIZE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (defined(SERIAL_PORT_TYPE_SWO) && (SERIAL_PORT_TYPE_SWO > 0U))
|
||||||
|
|
||||||
|
#if (SERIAL_PORT_SWO_HANDLE_SIZE > SERIAL_MANAGER_HANDLE_SIZE_TEMP)
|
||||||
|
#undef SERIAL_MANAGER_HANDLE_SIZE_TEMP
|
||||||
|
#define SERIAL_MANAGER_HANDLE_SIZE_TEMP SERIAL_PORT_SWO_HANDLE_SIZE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (defined(SERIAL_PORT_TYPE_USBCDC_VIRTUAL) && (SERIAL_PORT_TYPE_USBCDC_VIRTUAL > 0U))
|
||||||
|
|
||||||
|
#if (SERIAL_PORT_USB_VIRTUAL_HANDLE_SIZE > SERIAL_MANAGER_HANDLE_SIZE_TEMP)
|
||||||
|
#undef SERIAL_MANAGER_HANDLE_SIZE_TEMP
|
||||||
|
#define SERIAL_MANAGER_HANDLE_SIZE_TEMP SERIAL_PORT_USB_VIRTUAL_HANDLE_SIZE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*! @brief SERIAL_PORT_UART_HANDLE_SIZE/SERIAL_PORT_USB_CDC_HANDLE_SIZE + serial manager dedicated size */
|
||||||
|
#if ((defined(SERIAL_MANAGER_HANDLE_SIZE_TEMP) && (SERIAL_MANAGER_HANDLE_SIZE_TEMP > 0U)))
|
||||||
|
#else
|
||||||
|
#error SERIAL_PORT_TYPE_UART, SERIAL_PORT_TYPE_USBCDC, SERIAL_PORT_TYPE_SWO and SERIAL_PORT_TYPE_USBCDC_VIRTUAL should not be cleared at same time.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
|
||||||
|
#define SERIAL_MANAGER_HANDLE_SIZE (SERIAL_MANAGER_HANDLE_SIZE_TEMP + 120U)
|
||||||
|
#else
|
||||||
|
#define SERIAL_MANAGER_HANDLE_SIZE (SERIAL_MANAGER_HANDLE_SIZE_TEMP + 12U)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define SERIAL_MANAGER_USE_COMMON_TASK (1U)
|
||||||
|
#define SERIAL_MANAGER_TASK_PRIORITY (2U)
|
||||||
|
#define SERIAL_MANAGER_TASK_STACK_SIZE (1000U)
|
||||||
|
|
||||||
|
typedef void *serial_handle_t;
|
||||||
|
typedef void *serial_write_handle_t;
|
||||||
|
typedef void *serial_read_handle_t;
|
||||||
|
|
||||||
|
/*! @brief serial port type*/
|
||||||
|
typedef enum _serial_port_type
|
||||||
|
{
|
||||||
|
kSerialPort_Uart = 1U, /*!< Serial port UART */
|
||||||
|
kSerialPort_UsbCdc, /*!< Serial port USB CDC */
|
||||||
|
kSerialPort_Swo, /*!< Serial port SWO */
|
||||||
|
kSerialPort_UsbCdcVirtual, /*!< Serial port USB CDC Virtual */
|
||||||
|
} serial_port_type_t;
|
||||||
|
|
||||||
|
/*! @brief serial manager config structure*/
|
||||||
|
typedef struct _serial_manager_config
|
||||||
|
{
|
||||||
|
uint8_t *ringBuffer; /*!< Ring buffer address, it is used to buffer data received by the hardware.
|
||||||
|
Besides, the memory space cannot be free during the lifetime of the serial
|
||||||
|
manager module. */
|
||||||
|
uint32_t ringBufferSize; /*!< The size of the ring buffer */
|
||||||
|
serial_port_type_t type; /*!< Serial port type */
|
||||||
|
void *portConfig; /*!< Serial port configuration */
|
||||||
|
} serial_manager_config_t;
|
||||||
|
|
||||||
|
/*! @brief serial manager error code*/
|
||||||
|
typedef enum _serial_manager_status
|
||||||
|
{
|
||||||
|
kStatus_SerialManager_Success = kStatus_Success, /*!< Success */
|
||||||
|
kStatus_SerialManager_Error = MAKE_STATUS(kStatusGroup_SERIALMANAGER, 1), /*!< Failed */
|
||||||
|
kStatus_SerialManager_Busy = MAKE_STATUS(kStatusGroup_SERIALMANAGER, 2), /*!< Busy */
|
||||||
|
kStatus_SerialManager_Notify = MAKE_STATUS(kStatusGroup_SERIALMANAGER, 3), /*!< Ring buffer is not empty */
|
||||||
|
kStatus_SerialManager_Canceled =
|
||||||
|
MAKE_STATUS(kStatusGroup_SERIALMANAGER, 4), /*!< the non-blocking request is canceled */
|
||||||
|
kStatus_SerialManager_HandleConflict = MAKE_STATUS(kStatusGroup_SERIALMANAGER, 5), /*!< The handle is opened */
|
||||||
|
kStatus_SerialManager_RingBufferOverflow =
|
||||||
|
MAKE_STATUS(kStatusGroup_SERIALMANAGER, 6), /*!< The ring buffer is overflowed */
|
||||||
|
} serial_manager_status_t;
|
||||||
|
|
||||||
|
/*! @brief Callback message structure */
|
||||||
|
typedef struct _serial_manager_callback_message
|
||||||
|
{
|
||||||
|
uint8_t *buffer; /*!< Transferred buffer */
|
||||||
|
uint32_t length; /*!< Transferred data length */
|
||||||
|
} serial_manager_callback_message_t;
|
||||||
|
|
||||||
|
/*! @brief callback function */
|
||||||
|
typedef void (*serial_manager_callback_t)(void *callbackParam,
|
||||||
|
serial_manager_callback_message_t *message,
|
||||||
|
serial_manager_status_t status);
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* API
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
extern "C" {
|
||||||
|
#endif /* _cplusplus */
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Initializes a serial manager module with the serial manager handle and the user configuration structure.
|
||||||
|
*
|
||||||
|
* This function configures the Serial Manager module with user-defined settings. The user can configure the
|
||||||
|
* configuration
|
||||||
|
* structure. The parameter serialHandle is a pointer to point to a memory space of size #SERIAL_MANAGER_HANDLE_SIZE
|
||||||
|
* allocated by the caller.
|
||||||
|
* The Serial Manager module supports two types of serial port, UART (includes UART, USART, LPSCI, LPUART, etc) and USB
|
||||||
|
* CDC.
|
||||||
|
* Please refer to #serial_port_type_t for serial port setting. These two types can be set by using
|
||||||
|
* #serial_manager_config_t.
|
||||||
|
*
|
||||||
|
* Example below shows how to use this API to configure the Serial Manager.
|
||||||
|
* For UART,
|
||||||
|
* @code
|
||||||
|
* #define SERIAL_MANAGER_RING_BUFFER_SIZE (256U)
|
||||||
|
* static uint8_t s_serialHandleBuffer[SERIAL_MANAGER_HANDLE_SIZE];
|
||||||
|
* static serial_handle_t s_serialHandle = &s_serialHandleBuffer[0];
|
||||||
|
* static uint8_t s_ringBuffer[SERIAL_MANAGER_RING_BUFFER_SIZE];
|
||||||
|
*
|
||||||
|
* serial_manager_config_t config;
|
||||||
|
* serial_port_uart_config_t uartConfig;
|
||||||
|
* config.type = kSerialPort_Uart;
|
||||||
|
* config.ringBuffer = &s_ringBuffer[0];
|
||||||
|
* config.ringBufferSize = SERIAL_MANAGER_RING_BUFFER_SIZE;
|
||||||
|
* uartConfig.instance = 0;
|
||||||
|
* uartConfig.clockRate = 24000000;
|
||||||
|
* uartConfig.baudRate = 115200;
|
||||||
|
* uartConfig.parityMode = kSerialManager_UartParityDisabled;
|
||||||
|
* uartConfig.stopBitCount = kSerialManager_UartOneStopBit;
|
||||||
|
* uartConfig.enableRx = 1;
|
||||||
|
* uartConfig.enableTx = 1;
|
||||||
|
* config.portConfig = &uartConfig;
|
||||||
|
* SerialManager_Init(s_serialHandle, &config);
|
||||||
|
* @endcode
|
||||||
|
* For USB CDC,
|
||||||
|
* @code
|
||||||
|
* #define SERIAL_MANAGER_RING_BUFFER_SIZE (256U)
|
||||||
|
* static uint8_t s_serialHandleBuffer[SERIAL_MANAGER_HANDLE_SIZE];
|
||||||
|
* static serial_handle_t s_serialHandle = &s_serialHandleBuffer[0];
|
||||||
|
* static uint8_t s_ringBuffer[SERIAL_MANAGER_RING_BUFFER_SIZE];
|
||||||
|
*
|
||||||
|
* serial_manager_config_t config;
|
||||||
|
* serial_port_usb_cdc_config_t usbCdcConfig;
|
||||||
|
* config.type = kSerialPort_UsbCdc;
|
||||||
|
* config.ringBuffer = &s_ringBuffer[0];
|
||||||
|
* config.ringBufferSize = SERIAL_MANAGER_RING_BUFFER_SIZE;
|
||||||
|
* usbCdcConfig.controllerIndex = kSerialManager_UsbControllerKhci0;
|
||||||
|
* config.portConfig = &usbCdcConfig;
|
||||||
|
* SerialManager_Init(s_serialHandle, &config);
|
||||||
|
* @endcode
|
||||||
|
*
|
||||||
|
* @param serialHandle Pointer to point to a memory space of size #SERIAL_MANAGER_HANDLE_SIZE allocated by the caller.
|
||||||
|
* @param config Pointer to user-defined configuration structure.
|
||||||
|
* @retval kStatus_SerialManager_Error An error occurred.
|
||||||
|
* @retval kStatus_SerialManager_Success The Serial Manager module initialization succeed.
|
||||||
|
*/
|
||||||
|
serial_manager_status_t SerialManager_Init(serial_handle_t serialHandle, serial_manager_config_t *config);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief De-initializes the serial manager module instance.
|
||||||
|
*
|
||||||
|
* This function de-initializes the serial manager module instance. If the opened writing or
|
||||||
|
* reading handle is not closed, the function will return kStatus_SerialManager_Busy.
|
||||||
|
*
|
||||||
|
* @param serialHandle The serial manager module handle pointer.
|
||||||
|
* @retval kStatus_SerialManager_Success The serial manager de-initialization succeed.
|
||||||
|
* @retval kStatus_SerialManager_Busy Opened reading or writing handle is not closed.
|
||||||
|
*/
|
||||||
|
serial_manager_status_t SerialManager_Deinit(serial_handle_t serialHandle);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Opens a writing handle for the serial manager module.
|
||||||
|
*
|
||||||
|
* This function Opens a writing handle for the serial manager module. If the serial manager needs to
|
||||||
|
* be used in different tasks, the task should open a dedicated write handle for itself by calling
|
||||||
|
* #SerialManager_OpenWriteHandle. Since there can only one buffer for transmission for the writing
|
||||||
|
* handle at the same time, multiple writing handles need to be opened when the multiple transmission
|
||||||
|
* is needed for a task.
|
||||||
|
*
|
||||||
|
* @param serialHandle The serial manager module handle pointer.
|
||||||
|
* @param writeHandle The serial manager module writing handle pointer.
|
||||||
|
* @retval kStatus_SerialManager_Error An error occurred.
|
||||||
|
* @retval kStatus_SerialManager_HandleConflict The writing handle was opened.
|
||||||
|
* @retval kStatus_SerialManager_Success The writing handle is opened.
|
||||||
|
*
|
||||||
|
* Example below shows how to use this API to write data.
|
||||||
|
* For task 1,
|
||||||
|
* @code
|
||||||
|
* static uint8_t s_serialWriteHandleBuffer1[SERIAL_MANAGER_WRITE_HANDLE_SIZE];
|
||||||
|
* static serial_write_handle_t s_serialWriteHandle1 = &s_serialWriteHandleBuffer1[0];
|
||||||
|
* static uint8_t s_nonBlockingWelcome1[] = "This is non-blocking writing log for task1!\r\n";
|
||||||
|
* SerialManager_OpenWriteHandle(serialHandle, s_serialWriteHandle1);
|
||||||
|
* SerialManager_InstallTxCallback(s_serialWriteHandle1, Task1_SerialManagerTxCallback, s_serialWriteHandle1);
|
||||||
|
* SerialManager_WriteNonBlocking(s_serialWriteHandle1, s_nonBlockingWelcome1, sizeof(s_nonBlockingWelcome1) - 1);
|
||||||
|
* @endcode
|
||||||
|
* For task 2,
|
||||||
|
* @code
|
||||||
|
* static uint8_t s_serialWriteHandleBuffer2[SERIAL_MANAGER_WRITE_HANDLE_SIZE];
|
||||||
|
* static serial_write_handle_t s_serialWriteHandle2 = &s_serialWriteHandleBuffer2[0];
|
||||||
|
* static uint8_t s_nonBlockingWelcome2[] = "This is non-blocking writing log for task2!\r\n";
|
||||||
|
* SerialManager_OpenWriteHandle(serialHandle, s_serialWriteHandle2);
|
||||||
|
* SerialManager_InstallTxCallback(s_serialWriteHandle2, Task2_SerialManagerTxCallback, s_serialWriteHandle2);
|
||||||
|
* SerialManager_WriteNonBlocking(s_serialWriteHandle2, s_nonBlockingWelcome2, sizeof(s_nonBlockingWelcome2) - 1);
|
||||||
|
* @endcode
|
||||||
|
*/
|
||||||
|
serial_manager_status_t SerialManager_OpenWriteHandle(serial_handle_t serialHandle, serial_write_handle_t writeHandle);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Closes a writing handle for the serial manager module.
|
||||||
|
*
|
||||||
|
* This function Closes a writing handle for the serial manager module.
|
||||||
|
*
|
||||||
|
* @param writeHandle The serial manager module writing handle pointer.
|
||||||
|
* @retval kStatus_SerialManager_Success The writing handle is closed.
|
||||||
|
*/
|
||||||
|
serial_manager_status_t SerialManager_CloseWriteHandle(serial_write_handle_t writeHandle);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Opens a reading handle for the serial manager module.
|
||||||
|
*
|
||||||
|
* This function Opens a reading handle for the serial manager module. The reading handle can not be
|
||||||
|
* opened multiple at the same time. The error code kStatus_SerialManager_Busy would be returned when
|
||||||
|
* the previous reading handle is not closed. And There can only be one buffer for receiving for the
|
||||||
|
* reading handle at the same time.
|
||||||
|
*
|
||||||
|
* @param serialHandle The serial manager module handle pointer.
|
||||||
|
* @param readHandle The serial manager module reading handle pointer.
|
||||||
|
* @retval kStatus_SerialManager_Error An error occurred.
|
||||||
|
* @retval kStatus_SerialManager_Success The reading handle is opened.
|
||||||
|
* @retval kStatus_SerialManager_Busy Previous reading handle is not closed.
|
||||||
|
*
|
||||||
|
* Example below shows how to use this API to read data.
|
||||||
|
* @code
|
||||||
|
* static uint8_t s_serialReadHandleBuffer[SERIAL_MANAGER_READ_HANDLE_SIZE];
|
||||||
|
* static serial_read_handle_t s_serialReadHandle = &s_serialReadHandleBuffer[0];
|
||||||
|
* SerialManager_OpenReadHandle(serialHandle, s_serialReadHandle);
|
||||||
|
* static uint8_t s_nonBlockingBuffer[64];
|
||||||
|
* SerialManager_InstallRxCallback(s_serialReadHandle, APP_SerialManagerRxCallback, s_serialReadHandle);
|
||||||
|
* SerialManager_ReadNonBlocking(s_serialReadHandle, s_nonBlockingBuffer, sizeof(s_nonBlockingBuffer));
|
||||||
|
* @endcode
|
||||||
|
*/
|
||||||
|
serial_manager_status_t SerialManager_OpenReadHandle(serial_handle_t serialHandle, serial_read_handle_t readHandle);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Closes a reading for the serial manager module.
|
||||||
|
*
|
||||||
|
* This function Closes a reading for the serial manager module.
|
||||||
|
*
|
||||||
|
* @param readHandle The serial manager module reading handle pointer.
|
||||||
|
* @retval kStatus_SerialManager_Success The reading handle is closed.
|
||||||
|
*/
|
||||||
|
serial_manager_status_t SerialManager_CloseReadHandle(serial_read_handle_t readHandle);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Transmits data with the blocking mode.
|
||||||
|
*
|
||||||
|
* This is a blocking function, which polls the sending queue, waits for the sending queue to be empty.
|
||||||
|
* This function sends data using an interrupt method. The interrupt of the hardware could not be disabled.
|
||||||
|
* And There can only one buffer for transmission for the writing handle at the same time.
|
||||||
|
*
|
||||||
|
* @note The function #SerialManager_WriteBlocking and the function #SerialManager_WriteNonBlocking
|
||||||
|
* cannot be used at the same time.
|
||||||
|
* And, the function #SerialManager_CancelWriting cannot be used to abort the transmission of this function.
|
||||||
|
*
|
||||||
|
* @param writeHandle The serial manager module handle pointer.
|
||||||
|
* @param buffer Start address of the data to write.
|
||||||
|
* @param length Length of the data to write.
|
||||||
|
* @retval kStatus_SerialManager_Success Successfully sent all data.
|
||||||
|
* @retval kStatus_SerialManager_Busy Previous transmission still not finished; data not all sent yet.
|
||||||
|
* @retval kStatus_SerialManager_Error An error occurred.
|
||||||
|
*/
|
||||||
|
serial_manager_status_t SerialManager_WriteBlocking(serial_write_handle_t writeHandle,
|
||||||
|
uint8_t *buffer,
|
||||||
|
uint32_t length);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Reads data with the blocking mode.
|
||||||
|
*
|
||||||
|
* This is a blocking function, which polls the receiving buffer, waits for the receiving buffer to be full.
|
||||||
|
* This function receives data using an interrupt method. The interrupt of the hardware could not be disabled.
|
||||||
|
* And There can only one buffer for receiving for the reading handle at the same time.
|
||||||
|
*
|
||||||
|
* @note The function #SerialManager_ReadBlocking and the function #SerialManager_ReadNonBlocking
|
||||||
|
* cannot be used at the same time.
|
||||||
|
* And, the function #SerialManager_CancelReading cannot be used to abort the transmission of this function.
|
||||||
|
*
|
||||||
|
* @param readHandle The serial manager module handle pointer.
|
||||||
|
* @param buffer Start address of the data to store the received data.
|
||||||
|
* @param length The length of the data to be received.
|
||||||
|
* @retval kStatus_SerialManager_Success Successfully received all data.
|
||||||
|
* @retval kStatus_SerialManager_Busy Previous transmission still not finished; data not all received yet.
|
||||||
|
* @retval kStatus_SerialManager_Error An error occurred.
|
||||||
|
*/
|
||||||
|
serial_manager_status_t SerialManager_ReadBlocking(serial_read_handle_t readHandle, uint8_t *buffer, uint32_t length);
|
||||||
|
|
||||||
|
#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
|
||||||
|
/*!
|
||||||
|
* @brief Transmits data with the non-blocking mode.
|
||||||
|
*
|
||||||
|
* This is a non-blocking function, which returns directly without waiting for all data to be sent.
|
||||||
|
* When all data is sent, the module notifies the upper layer through a TX callback function and passes
|
||||||
|
* the status parameter @ref kStatus_SerialManager_Success.
|
||||||
|
* This function sends data using an interrupt method. The interrupt of the hardware could not be disabled.
|
||||||
|
* And There can only one buffer for transmission for the writing handle at the same time.
|
||||||
|
*
|
||||||
|
* @note The function #SerialManager_WriteBlocking and the function #SerialManager_WriteNonBlocking
|
||||||
|
* cannot be used at the same time. And, the TX callback is mandatory before the function could be used.
|
||||||
|
*
|
||||||
|
* @param writeHandle The serial manager module handle pointer.
|
||||||
|
* @param buffer Start address of the data to write.
|
||||||
|
* @param length Length of the data to write.
|
||||||
|
* @retval kStatus_SerialManager_Success Successfully sent all data.
|
||||||
|
* @retval kStatus_SerialManager_Busy Previous transmission still not finished; data not all sent yet.
|
||||||
|
* @retval kStatus_SerialManager_Error An error occurred.
|
||||||
|
*/
|
||||||
|
serial_manager_status_t SerialManager_WriteNonBlocking(serial_write_handle_t writeHandle,
|
||||||
|
uint8_t *buffer,
|
||||||
|
uint32_t length);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Reads data with the non-blocking mode.
|
||||||
|
*
|
||||||
|
* This is a non-blocking function, which returns directly without waiting for all data to be received.
|
||||||
|
* When all data is received, the module driver notifies the upper layer
|
||||||
|
* through a RX callback function and passes the status parameter @ref kStatus_SerialManager_Success.
|
||||||
|
* This function receives data using an interrupt method. The interrupt of the hardware could not be disabled.
|
||||||
|
* And There can only one buffer for receiving for the reading handle at the same time.
|
||||||
|
*
|
||||||
|
* @note The function #SerialManager_ReadBlocking and the function #SerialManager_ReadNonBlocking
|
||||||
|
* cannot be used at the same time. And, the RX callback is mandatory before the function could be used.
|
||||||
|
*
|
||||||
|
* @param readHandle The serial manager module handle pointer.
|
||||||
|
* @param buffer Start address of the data to store the received data.
|
||||||
|
* @param length The length of the data to be received.
|
||||||
|
* @retval kStatus_SerialManager_Success Successfully received all data.
|
||||||
|
* @retval kStatus_SerialManager_Busy Previous transmission still not finished; data not all received yet.
|
||||||
|
* @retval kStatus_SerialManager_Error An error occurred.
|
||||||
|
*/
|
||||||
|
serial_manager_status_t SerialManager_ReadNonBlocking(serial_read_handle_t readHandle,
|
||||||
|
uint8_t *buffer,
|
||||||
|
uint32_t length);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Tries to read data.
|
||||||
|
*
|
||||||
|
* The function tries to read data from internal ring buffer. If the ring buffer is not empty, the data will be
|
||||||
|
* copied from ring buffer to up layer buffer. The copied length is the minimum of the ring buffer and up layer length.
|
||||||
|
* After the data is copied, the actual data length is passed by the parameter length.
|
||||||
|
* And There can only one buffer for receiving for the reading handle at the same time.
|
||||||
|
*
|
||||||
|
* @param readHandle The serial manager module handle pointer.
|
||||||
|
* @param buffer Start address of the data to store the received data.
|
||||||
|
* @param length The length of the data to be received.
|
||||||
|
* @param receivedLength Length received from the ring buffer directly.
|
||||||
|
* @retval kStatus_SerialManager_Success Successfully received all data.
|
||||||
|
* @retval kStatus_SerialManager_Busy Previous transmission still not finished; data not all received yet.
|
||||||
|
* @retval kStatus_SerialManager_Error An error occurred.
|
||||||
|
*/
|
||||||
|
serial_manager_status_t SerialManager_TryRead(serial_read_handle_t readHandle,
|
||||||
|
uint8_t *buffer,
|
||||||
|
uint32_t length,
|
||||||
|
uint32_t *receivedLength);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Cancels unfinished send transmission.
|
||||||
|
*
|
||||||
|
* The function cancels unfinished send transmission. When the transfer is canceled, the module notifies the upper layer
|
||||||
|
* through a TX callback function and passes the status parameter @ref kStatus_SerialManager_Canceled.
|
||||||
|
*
|
||||||
|
* @note The function #SerialManager_CancelWriting cannot be used to abort the transmission of
|
||||||
|
* the function #SerialManager_WriteBlocking.
|
||||||
|
*
|
||||||
|
* @param writeHandle The serial manager module handle pointer.
|
||||||
|
* @retval kStatus_SerialManager_Success Get successfully abort the sending.
|
||||||
|
* @retval kStatus_SerialManager_Error An error occurred.
|
||||||
|
*/
|
||||||
|
serial_manager_status_t SerialManager_CancelWriting(serial_write_handle_t writeHandle);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Cancels unfinished receive transmission.
|
||||||
|
*
|
||||||
|
* The function cancels unfinished receive transmission. When the transfer is canceled, the module notifies the upper
|
||||||
|
* layer
|
||||||
|
* through a RX callback function and passes the status parameter @ref kStatus_SerialManager_Canceled.
|
||||||
|
*
|
||||||
|
* @note The function #SerialManager_CancelReading cannot be used to abort the transmission of
|
||||||
|
* the function #SerialManager_ReadBlocking.
|
||||||
|
*
|
||||||
|
* @param readHandle The serial manager module handle pointer.
|
||||||
|
* @retval kStatus_SerialManager_Success Get successfully abort the receiving.
|
||||||
|
* @retval kStatus_SerialManager_Error An error occurred.
|
||||||
|
*/
|
||||||
|
serial_manager_status_t SerialManager_CancelReading(serial_read_handle_t readHandle);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Installs a TX callback and callback parameter.
|
||||||
|
*
|
||||||
|
* This function is used to install the TX callback and callback parameter for the serial manager module.
|
||||||
|
* When any status of TX transmission changed, the driver will notify the upper layer by the installed callback
|
||||||
|
* function. And the status is also passed as status parameter when the callback is called.
|
||||||
|
*
|
||||||
|
* @param writeHandle The serial manager module handle pointer.
|
||||||
|
* @param callback The callback function.
|
||||||
|
* @param callbackParam The parameter of the callback function.
|
||||||
|
* @retval kStatus_SerialManager_Success Successfully install the callback.
|
||||||
|
*/
|
||||||
|
serial_manager_status_t SerialManager_InstallTxCallback(serial_write_handle_t writeHandle,
|
||||||
|
serial_manager_callback_t callback,
|
||||||
|
void *callbackParam);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Installs a RX callback and callback parameter.
|
||||||
|
*
|
||||||
|
* This function is used to install the RX callback and callback parameter for the serial manager module.
|
||||||
|
* When any status of RX transmission changed, the driver will notify the upper layer by the installed callback
|
||||||
|
* function. And the status is also passed as status parameter when the callback is called.
|
||||||
|
*
|
||||||
|
* @param readHandle The serial manager module handle pointer.
|
||||||
|
* @param callback The callback function.
|
||||||
|
* @param callbackParam The parameter of the callback function.
|
||||||
|
* @retval kStatus_SerialManager_Success Successfully install the callback.
|
||||||
|
*/
|
||||||
|
serial_manager_status_t SerialManager_InstallRxCallback(serial_read_handle_t readHandle,
|
||||||
|
serial_manager_callback_t callback,
|
||||||
|
void *callbackParam);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Prepares to enter low power consumption.
|
||||||
|
*
|
||||||
|
* This function is used to prepare to enter low power consumption.
|
||||||
|
*
|
||||||
|
* @param serialHandle The serial manager module handle pointer.
|
||||||
|
* @retval kStatus_SerialManager_Success Successful operation.
|
||||||
|
*/
|
||||||
|
serial_manager_status_t SerialManager_EnterLowpower(serial_handle_t serialHandle);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Restores from low power consumption.
|
||||||
|
*
|
||||||
|
* This function is used to restore from low power consumption.
|
||||||
|
*
|
||||||
|
* @param serialHandle The serial manager module handle pointer.
|
||||||
|
* @retval kStatus_SerialManager_Success Successful operation.
|
||||||
|
*/
|
||||||
|
serial_manager_status_t SerialManager_ExitLowpower(serial_handle_t serialHandle);
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/*! @} */
|
||||||
|
#endif /* __SERIAL_MANAGER_H__ */
|
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2018 NXP
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __SERIAL_PORT_UART_H__
|
||||||
|
#define __SERIAL_PORT_UART_H__
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @addtogroup serial_port_uart
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Definitions
|
||||||
|
******************************************************************************/
|
||||||
|
/*! @brief serial port uart handle size*/
|
||||||
|
#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
|
||||||
|
#define SERIAL_PORT_UART_HANDLE_SIZE (166U)
|
||||||
|
#else
|
||||||
|
#define SERIAL_PORT_UART_HANDLE_SIZE (4U)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*! @brief serial port uart parity mode*/
|
||||||
|
typedef enum _serial_port_uart_parity_mode
|
||||||
|
{
|
||||||
|
kSerialManager_UartParityDisabled = 0x0U, /*!< Parity disabled */
|
||||||
|
kSerialManager_UartParityEven = 0x1U, /*!< Parity even enabled */
|
||||||
|
kSerialManager_UartParityOdd = 0x2U, /*!< Parity odd enabled */
|
||||||
|
} serial_port_uart_parity_mode_t;
|
||||||
|
|
||||||
|
/*! @brief serial port uart stop bit count*/
|
||||||
|
typedef enum _serial_port_uart_stop_bit_count
|
||||||
|
{
|
||||||
|
kSerialManager_UartOneStopBit = 0U, /*!< One stop bit */
|
||||||
|
kSerialManager_UartTwoStopBit = 1U, /*!< Two stop bits */
|
||||||
|
} serial_port_uart_stop_bit_count_t;
|
||||||
|
|
||||||
|
/*! @brief serial port uart config struct*/
|
||||||
|
typedef struct _serial_port_uart_config
|
||||||
|
{
|
||||||
|
uint32_t clockRate; /*!< clock rate */
|
||||||
|
uint32_t baudRate; /*!< baud rate */
|
||||||
|
serial_port_uart_parity_mode_t parityMode; /*!< Parity mode, disabled (default), even, odd */
|
||||||
|
serial_port_uart_stop_bit_count_t stopBitCount; /*!< Number of stop bits, 1 stop bit (default) or 2 stop bits */
|
||||||
|
uint8_t instance; /*!< Instance (0 - UART0, 1 - UART1, ...), detail information
|
||||||
|
please refer to the SOC corresponding RM. */
|
||||||
|
uint8_t enableRx; /*!< Enable RX */
|
||||||
|
uint8_t enableTx; /*!< Enable TX */
|
||||||
|
} serial_port_uart_config_t;
|
||||||
|
/*! @} */
|
||||||
|
#endif /* __SERIAL_PORT_UART_H__ */
|
|
@ -0,0 +1,76 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
|
||||||
|
* Copyright 2016 - 2018 NXP
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __SERIAL_PORT_USB_H__
|
||||||
|
#define __SERIAL_PORT_USB_H__
|
||||||
|
|
||||||
|
#if defined(FSL_RTOS_FREE_RTOS)
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @addtogroup serial_port_usb
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Definitions
|
||||||
|
******************************************************************************/
|
||||||
|
/*! @brief serial port usb handle size*/
|
||||||
|
#define SERIAL_PORT_USB_CDC_HANDLE_SIZE (72)
|
||||||
|
|
||||||
|
/*! @brief USB interrupt priority*/
|
||||||
|
#if defined(__GIC_PRIO_BITS)
|
||||||
|
#define USB_DEVICE_INTERRUPT_PRIORITY (25U)
|
||||||
|
#else
|
||||||
|
#if defined(configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY)
|
||||||
|
#define USB_DEVICE_INTERRUPT_PRIORITY (configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY)
|
||||||
|
#else
|
||||||
|
/* The default value 3 is used to support different ARM Core, such as CM0P, CM4, CM7, and CM33, etc.
|
||||||
|
* The minimum number of priority bits implemented in the NVIC is 2 on these SOCs. The value of mininum
|
||||||
|
* priority is 3 (2^2 - 1). So, the default value is 3.
|
||||||
|
*/
|
||||||
|
#define USB_DEVICE_INTERRUPT_PRIORITY (3U)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*! @brief USB controller ID */
|
||||||
|
typedef enum _serial_port_usb_cdc_controller_index
|
||||||
|
{
|
||||||
|
kSerialManager_UsbControllerKhci0 = 0U, /*!< KHCI 0U */
|
||||||
|
kSerialManager_UsbControllerKhci1 = 1U, /*!< KHCI 1U, Currently, there are no platforms which have two KHCI IPs,
|
||||||
|
this is reserved to be used in the future. */
|
||||||
|
kSerialManager_UsbControllerEhci0 = 2U, /*!< EHCI 0U */
|
||||||
|
kSerialManager_UsbControllerEhci1 = 3U, /*!< EHCI 1U, Currently, there are no platforms which have two EHCI IPs,
|
||||||
|
this is reserved to be used in the future. */
|
||||||
|
|
||||||
|
kSerialManager_UsbControllerLpcIp3511Fs0 = 4U, /*!< LPC USB IP3511 FS controller 0 */
|
||||||
|
kSerialManager_UsbControllerLpcIp3511Fs1 = 5U, /*!< LPC USB IP3511 FS controller 1, there are no platforms which
|
||||||
|
have two IP3511 IPs, this is reserved to be used in the future. */
|
||||||
|
|
||||||
|
kSerialManager_UsbControllerLpcIp3511Hs0 = 6U, /*!< LPC USB IP3511 HS controller 0 */
|
||||||
|
kSerialManager_UsbControllerLpcIp3511Hs1 = 7U, /*!< LPC USB IP3511 HS controller 1, there are no platforms which
|
||||||
|
have two IP3511 IPs, this is reserved to be used in the future. */
|
||||||
|
|
||||||
|
kSerialManager_UsbControllerOhci0 = 8U, /*!< OHCI 0U */
|
||||||
|
kSerialManager_UsbControllerOhci1 = 9U, /*!< OHCI 1U, Currently, there are no platforms which have two OHCI IPs,
|
||||||
|
this is reserved to be used in the future. */
|
||||||
|
|
||||||
|
kSerialManager_UsbControllerIp3516Hs0 = 10U, /*!< IP3516HS 0U */
|
||||||
|
kSerialManager_UsbControllerIp3516Hs1 = 11U, /*!< IP3516HS 1U, Currently, there are no platforms which have two
|
||||||
|
IP3516HS IPs, this is reserved to be used in the future. */
|
||||||
|
} serial_port_usb_cdc_controller_index_t;
|
||||||
|
|
||||||
|
/*! @brief serial port usb config struct*/
|
||||||
|
typedef struct _serial_port_usb_cdc_config
|
||||||
|
{
|
||||||
|
serial_port_usb_cdc_controller_index_t controllerIndex; /*!< controller index */
|
||||||
|
} serial_port_usb_cdc_config_t;
|
||||||
|
|
||||||
|
/*! @} */
|
||||||
|
#endif /* __SERIAL_PORT_USB_H__ */
|
|
@ -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
|
|
@ -0,0 +1,3 @@
|
||||||
|
SRC_FILES := hardware_rtc.c connect_rtc.c
|
||||||
|
|
||||||
|
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -0,0 +1,452 @@
|
||||||
|
/*
|
||||||
|
* The Clear BSD License
|
||||||
|
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||||
|
* Copyright 2016-2017 NXP
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted (subject to the limitations in the disclaimer below) provided
|
||||||
|
* that the following conditions are met:
|
||||||
|
*
|
||||||
|
* o Redistributions of source code must retain the above copyright notice, this list
|
||||||
|
* of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer in the documentation and/or
|
||||||
|
* other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* o Neither the name of the copyright holder nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from this
|
||||||
|
* software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file connect_rtc.c
|
||||||
|
* @brief ok1052-c rtc function and structure
|
||||||
|
* @version 1.0
|
||||||
|
* @author AIIT XUOS Lab
|
||||||
|
* @date 2022-03-01
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
File name: connect_rtc.c
|
||||||
|
Description: support ok1052-c rtc configure and spi bus register function
|
||||||
|
|
||||||
|
History:
|
||||||
|
1. Date: 2022-03-01
|
||||||
|
Author: AIIT XUOS Lab
|
||||||
|
Modification:
|
||||||
|
1. change command for XUOS
|
||||||
|
*************************************************/
|
||||||
|
|
||||||
|
#include "board.h"
|
||||||
|
#include "bus_rtc.h"
|
||||||
|
#include "pin_mux.h"
|
||||||
|
#include "dev_rtc.h"
|
||||||
|
#include "connect_rtc.h"
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Definitions
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#define rtc_print KPrintf
|
||||||
|
|
||||||
|
#define MAX_TIME_STR_SIZE 50
|
||||||
|
|
||||||
|
///////////RX8010///////////
|
||||||
|
|
||||||
|
#define RX8010_SEC 0x10
|
||||||
|
#define RX8010_MIN 0x11
|
||||||
|
#define RX8010_HOUR 0x12
|
||||||
|
#define RX8010_WDAY 0x13
|
||||||
|
#define RX8010_MDAY 0x14
|
||||||
|
#define RX8010_MONTH 0x15
|
||||||
|
#define RX8010_YEAR 0x16
|
||||||
|
#define RX8010_YEAR 0x16
|
||||||
|
#define RX8010_RESV17 0x17
|
||||||
|
#define RX8010_ALMIN 0x18
|
||||||
|
#define RX8010_ALHOUR 0x19
|
||||||
|
#define RX8010_ALWDAY 0x1A
|
||||||
|
#define RX8010_TCOUNT0 0x1B
|
||||||
|
#define RX8010_TCOUNT1 0x1C
|
||||||
|
#define RX8010_EXT 0x1D
|
||||||
|
#define RX8010_FLAG 0x1E
|
||||||
|
#define RX8010_CTRL 0x1F
|
||||||
|
|
||||||
|
/* 0x20 to 0x2F are user registers */
|
||||||
|
#define RX8010_RESV30 0x30
|
||||||
|
#define RX8010_RESV31 0x31
|
||||||
|
#define RX8010_IRQ 0x32
|
||||||
|
|
||||||
|
#define RX8010_EXT_WADA 0x04 //BIT(3)
|
||||||
|
|
||||||
|
#define RX8010_FLAG_VLF 0x02 //BIT(1)
|
||||||
|
#define RX8010_FLAG_AF 0x04 //BIT(3)
|
||||||
|
#define RX8010_FLAG_TF 0x08 //BIT(4)
|
||||||
|
#define RX8010_FLAG_UF 0x10 //BIT(5)
|
||||||
|
|
||||||
|
#define RX8010_CTRL_AIE 0x04 //BIT(3)
|
||||||
|
#define RX8010_CTRL_UIE 0x10 //BIT(5)
|
||||||
|
#define RX8010_CTRL_STOP 0x20 //BIT(6)
|
||||||
|
#define RX8010_CTRL_TEST 0x40 //BIT(7)
|
||||||
|
|
||||||
|
#define RX8010_ALARM_AE 0x40 //BIT(7)
|
||||||
|
|
||||||
|
#define RX8010_TEST_TIME 10000
|
||||||
|
|
||||||
|
#define BCD_DATA_LEN 20
|
||||||
|
|
||||||
|
// change BIN format to BCD format
|
||||||
|
#define TO_BCD(_n) (((_n / 10) << 4) | (_n % 10))
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Prototypes
|
||||||
|
******************************************************************************/
|
||||||
|
/*******************************************************************************
|
||||||
|
* Variables
|
||||||
|
******************************************************************************/
|
||||||
|
/*******************************************************************************
|
||||||
|
* Code
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
// change BCD format date to BIN format
|
||||||
|
uint8_t bcd2bin(uint8_t data)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
uint8_t ret = 0;
|
||||||
|
uint8_t mask[4] = {0x01, 0x02, 0x04, 0x08};
|
||||||
|
|
||||||
|
//LOW
|
||||||
|
for(i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
if(mask[i] & data)
|
||||||
|
{
|
||||||
|
ret += mask[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//HIGH
|
||||||
|
for(i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
if(mask[i] & (data >> 4))
|
||||||
|
{
|
||||||
|
ret += (mask[i] * 10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 8010 initialization
|
||||||
|
int RtcInit(void)
|
||||||
|
{
|
||||||
|
uint8_t flag = 0;
|
||||||
|
uint8_t data = 0;
|
||||||
|
uint8_t ctrl[2];
|
||||||
|
int need_clear = 0, err = 0;
|
||||||
|
err = RtcI2cRead(I2C_RTC_BASE, RX8010_FLAG, &flag, 1);
|
||||||
|
flag &= ~(RX8010_FLAG_VLF);
|
||||||
|
err = RtcI2cWrite(I2C_RTC_BASE, RX8010_FLAG, &flag, 1);
|
||||||
|
/* Initialize reserved registers as specified in datasheet */
|
||||||
|
data = 0xD8;
|
||||||
|
err = RtcI2cWrite(I2C_RTC_BASE, RX8010_RESV17, &data, 1);
|
||||||
|
data = 0x00;
|
||||||
|
err = RtcI2cWrite(I2C_RTC_BASE, RX8010_RESV30, &data, 1);
|
||||||
|
data = 0x08;
|
||||||
|
err = RtcI2cWrite(I2C_RTC_BASE, RX8010_RESV31, &data, 1);
|
||||||
|
data = 0x00;
|
||||||
|
err = RtcI2cWrite(I2C_RTC_BASE, RX8010_IRQ, &data, 1);
|
||||||
|
err = RtcI2cRead(I2C_RTC_BASE, RX8010_FLAG, ctrl, 2);
|
||||||
|
|
||||||
|
if(ctrl[0] & RX8010_FLAG_VLF)
|
||||||
|
{
|
||||||
|
rtc_print("\r\n Frequency stop was detected\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ctrl[0] & RX8010_FLAG_AF)
|
||||||
|
{
|
||||||
|
rtc_print("\r\n Alarm was detected\r\n");
|
||||||
|
need_clear = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ctrl[0] & RX8010_FLAG_TF)
|
||||||
|
{
|
||||||
|
need_clear = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ctrl[0] & RX8010_FLAG_UF)
|
||||||
|
{
|
||||||
|
need_clear = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(need_clear)
|
||||||
|
{
|
||||||
|
ctrl[0] &= ~(RX8010_FLAG_AF | RX8010_FLAG_TF | RX8010_FLAG_UF);
|
||||||
|
err = RtcI2cWrite(I2C_RTC_BASE, RX8010_FLAG, ctrl,1);
|
||||||
|
|
||||||
|
if(!err)
|
||||||
|
{
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check format and get BCD format date like 2018-06-21 16:29:30
|
||||||
|
int RtcGetBcdDate(uint8_t* date, uint8_t* bcd_date)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int temp_date[6];
|
||||||
|
|
||||||
|
if(sscanf(date, "20%2d-%2d-%2d %2d:%2d:%2d",
|
||||||
|
&temp_date[5],
|
||||||
|
&temp_date[4],
|
||||||
|
&temp_date[3],
|
||||||
|
&temp_date[2],
|
||||||
|
&temp_date[1],
|
||||||
|
&temp_date[0]) == EOF)
|
||||||
|
{
|
||||||
|
rtc_print("i2c %s failed\n", __func__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
bcd_date[i] = TO_BCD(temp_date[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// setup time
|
||||||
|
int RtcSetTime(uint8_t* asc_date)
|
||||||
|
{
|
||||||
|
uint8_t bcd_date[6];
|
||||||
|
int ret, err;
|
||||||
|
|
||||||
|
if(RtcGetBcdDate(asc_date, bcd_date))
|
||||||
|
{
|
||||||
|
rtc_print("\r\n Date format error! \r\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = RtcI2cWrite(I2C_RTC_BASE, RX8010_SEC, bcd_date, 3);
|
||||||
|
err |= RtcI2cWrite(I2C_RTC_BASE, RX8010_MDAY, &bcd_date[3], 3);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get rx8010 time
|
||||||
|
int RtcGetTime(struct tm *ct)
|
||||||
|
{
|
||||||
|
uint8_t rtc_data[7];
|
||||||
|
uint8_t time_str[7];
|
||||||
|
uint8_t flag_reg;
|
||||||
|
int err;
|
||||||
|
err = RtcI2cRead(I2C_RTC_BASE, RX8010_FLAG, &flag_reg, 1);
|
||||||
|
|
||||||
|
if(flag_reg & RX8010_FLAG_VLF)
|
||||||
|
{
|
||||||
|
rtc_print("\r\n Frequency stop was detected\r\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = RtcI2cRead(I2C_RTC_BASE, RX8010_SEC, rtc_data, 7);
|
||||||
|
time_str[0] = bcd2bin(rtc_data[RX8010_SEC - RX8010_SEC] & 0x7f);
|
||||||
|
time_str[1] = bcd2bin(rtc_data[RX8010_MIN - RX8010_SEC] & 0x7f);
|
||||||
|
time_str[2] = bcd2bin(rtc_data[RX8010_HOUR - RX8010_SEC] & 0x3f);
|
||||||
|
time_str[4] = bcd2bin(rtc_data[RX8010_MDAY - RX8010_SEC] & 0x3f);
|
||||||
|
time_str[5] = bcd2bin(rtc_data[RX8010_MONTH - RX8010_SEC] & 0x1f);
|
||||||
|
time_str[6] = bcd2bin(rtc_data[RX8010_YEAR - RX8010_SEC]);
|
||||||
|
time_str[3] = rtc_data[RX8010_WDAY - RX8010_SEC] & 0x7f;
|
||||||
|
|
||||||
|
rtc_print("RX8010 Time: 20%d%d-%d%d-%d%d %d%d:%d%d:%d%d\r\n",
|
||||||
|
time_str[6]/10, time_str[6]%10, time_str[5]/10, time_str[5]%10, time_str[4]/10, time_str[4]%10,
|
||||||
|
time_str[2]/10, time_str[2]%10, time_str[1]/10, time_str[1]%10, time_str[0]/10, time_str[0]%10);
|
||||||
|
|
||||||
|
ct->tm_year = time_str[6];
|
||||||
|
ct->tm_mon = time_str[5];
|
||||||
|
ct->tm_mday = time_str[4];
|
||||||
|
ct->tm_wday = time_str[3];
|
||||||
|
ct->tm_hour = time_str[2];
|
||||||
|
ct->tm_min = time_str[1];
|
||||||
|
ct->tm_sec = time_str[0];
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int GetWeekDay(int year, int month, int day)
|
||||||
|
{
|
||||||
|
if(month==1||month==2)
|
||||||
|
{
|
||||||
|
year -=1;
|
||||||
|
month +=12;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (day+1+2*month+3*(month+1)/5+year+(year/4)-year/100+year/400)%7+1;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
RtcGetTime(&ct);
|
||||||
|
*time = mktime(&ct);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OPER_RTC_SET_TIME:
|
||||||
|
{
|
||||||
|
char time_str[MAX_TIME_STR_SIZE] = {0};
|
||||||
|
struct tm *ct = localtime(time);
|
||||||
|
strftime(time_str, MAX_TIME_STR_SIZE, "%y-%m-%d %H:%M:%S", ct);
|
||||||
|
RtcSetTime(time_str);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int RtcConfiguration(void)
|
||||||
|
{
|
||||||
|
BOARD_InitI2C1Pins();
|
||||||
|
RtcI2cInit();
|
||||||
|
RtcInit();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*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("hw_rtc_init RtcBusInit error %d\n", ret);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Init the rtc driver*/
|
||||||
|
ret = RtcDriverInit(rtc_driver, RTC_DRV_NAME);
|
||||||
|
|
||||||
|
if(EOK != ret)
|
||||||
|
{
|
||||||
|
KPrintf("hw_rtc_init 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("hw_rtc_init 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("hw_rtc_init RtcDeviceInit device %s error %d\n", RTC_DEVICE_NAME, ret);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = RtcDeviceAttachToBus(RTC_DEVICE_NAME, RTC_BUS_NAME);
|
||||||
|
|
||||||
|
if(EOK != ret)
|
||||||
|
{
|
||||||
|
KPrintf("hw_rtc_init RtcDeviceAttachToBus device %s error %d\n", RTC_DEVICE_NAME, ret);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Imrt1052HwRtcInit(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("hw_rtc_init error ret %u\n", ret);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = BoardRtcDevBend();
|
||||||
|
|
||||||
|
if(EOK != ret)
|
||||||
|
{
|
||||||
|
KPrintf("hw_rtc_init error ret %u\n", ret);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
RtcConfiguration();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RtcTestRx8010(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
if(argc == 2)
|
||||||
|
{
|
||||||
|
if(RtcSetTime(argv[1]) == 0)
|
||||||
|
{
|
||||||
|
RtcGetTime(NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RtcGetTime(NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)| SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN)| SHELL_CMD_PARAM_NUM(3),
|
||||||
|
rtc, RtcTestRx8010, i2c rtc "date time");
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
/*
|
||||||
|
* The Clear BSD License
|
||||||
|
* Copyright (c) 2016, Freescale Semiconductor, Inc.
|
||||||
|
* Copyright 2016-2017 NXP
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted (subject to the limitations in the disclaimer below) provided
|
||||||
|
* that the following conditions are met:
|
||||||
|
*
|
||||||
|
* o Redistributions of source code must retain the above copyright notice, this list
|
||||||
|
* of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer in the documentation and/or
|
||||||
|
* other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* o Neither the name of the copyright holder nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from this
|
||||||
|
* software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file hardware_rtc.c
|
||||||
|
* @brief I2C RTC drivers
|
||||||
|
* @version 1.0
|
||||||
|
* @author AIIT XUOS Lab
|
||||||
|
* @date 2022.1.18
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
File name: hardware_rtc.c
|
||||||
|
Description: support ok1052-c rtc driver I2C function
|
||||||
|
|
||||||
|
History:
|
||||||
|
1. Date: 2022-01-18
|
||||||
|
Author: AIIT XUOS Lab
|
||||||
|
Modification:
|
||||||
|
1. support ok1052-c rtc
|
||||||
|
*************************************************/
|
||||||
|
|
||||||
|
#include "connect_rtc.h"
|
||||||
|
#include "connect_i2c.h"
|
||||||
|
|
||||||
|
void RtcI2cInit()
|
||||||
|
{
|
||||||
|
I2cHardwareInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t RtcI2cWrite(LPI2C_Type *base, uint32_t sub_addr, uint8_t *buf, uint16_t size)
|
||||||
|
{
|
||||||
|
return I2cHardwareWrite(base, I2C_RTC_ADDR, sub_addr, buf, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t RtcI2cRead(LPI2C_Type *base,uint32_t sub_addr,uint8_t* buf, uint16_t size)
|
||||||
|
{
|
||||||
|
return I2cHardwareRead(base, I2C_RTC_ADDR, sub_addr, buf, size);
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
config BSP_USING_SPI1
|
||||||
|
bool "Enable SPI1"
|
||||||
|
default y
|
||||||
|
if BSP_USING_SPI1
|
||||||
|
config SPI_1_BUS_NAME
|
||||||
|
string "spi1 bus name"
|
||||||
|
default "spi1"
|
||||||
|
config SPI_1_DRV_NAME
|
||||||
|
string "spi bus 1 driver name"
|
||||||
|
default "spi1_drv"
|
||||||
|
config SPI_1_DEV_NAME_0
|
||||||
|
string "spi bus 1 device name"
|
||||||
|
default "spi1_dev"
|
||||||
|
endif
|
||||||
|
|
||||||
|
config BSP_USING_SPI2
|
||||||
|
bool "Enable SPI2"
|
||||||
|
default y
|
||||||
|
if BSP_USING_SPI2
|
||||||
|
config SPI_2_BUS_NAME
|
||||||
|
string "spi2 bus name"
|
||||||
|
default "spi2"
|
||||||
|
config SPI_2_DRV_NAME
|
||||||
|
string "spi bus 2 driver name"
|
||||||
|
default "spi2_drv"
|
||||||
|
config SPI_2_DEV_NAME_0
|
||||||
|
string "spi bus 2 device name"
|
||||||
|
default "spi2_dev"
|
||||||
|
endif
|
||||||
|
|
||||||
|
config BSP_USING_SPI3
|
||||||
|
bool "Enable SPI3"
|
||||||
|
default y
|
||||||
|
if BSP_USING_SPI3
|
||||||
|
config SPI_3_BUS_NAME
|
||||||
|
string "spi3 bus name"
|
||||||
|
default "spi3"
|
||||||
|
config SPI_3_DRV_NAME
|
||||||
|
string "spi bus 3 driver name"
|
||||||
|
default "spi3_drv"
|
||||||
|
config SPI_3_DEV_NAME_0
|
||||||
|
string "spi bus 3 device name"
|
||||||
|
default "spi3_dev"
|
||||||
|
endif
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
SRC_FILES := fsl_lpspi.c connect_spi.c connect_flash_spi.c
|
||||||
|
|
||||||
|
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2018-11-27 SummerGift add spi flash port file
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file connect_flash_spi.c
|
||||||
|
* @brief support ok1052-c-board spi flash function and register to bus framework
|
||||||
|
* @version 1.0
|
||||||
|
* @author AIIT XUOS Lab
|
||||||
|
* @date 2022-03-01
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
File name: connect_flash_spi.c
|
||||||
|
Description: support ok1052-c-board spi flash bus register function
|
||||||
|
Others: take RT-Thread v4.0.2/bsp/stm32/stm32f407-atk-explorer/board/ports/spi-flash-init.c
|
||||||
|
https://github.com/RT-Thread/rt-thread/tree/v4.0.2
|
||||||
|
History:
|
||||||
|
1. Date: 2022-03-01
|
||||||
|
Author: AIIT XUOS Lab
|
||||||
|
Modification:
|
||||||
|
1. for ok1052-c compilation
|
||||||
|
*************************************************/
|
||||||
|
|
||||||
|
#include "flash_spi.h"
|
||||||
|
|
||||||
|
int FlashW25qxxSpiDeviceInit(void)
|
||||||
|
{
|
||||||
|
#ifdef BSP_USING_SPI1
|
||||||
|
|
||||||
|
#endif
|
||||||
|
return EOK;
|
||||||
|
}
|
|
@ -0,0 +1,959 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020 RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2018-11-5 SummerGift first version
|
||||||
|
* 2018-12-11 greedyhao Porting for stm32f7xx
|
||||||
|
* 2019-01-03 zylx modify DMA initialization and spixfer function
|
||||||
|
* 2020-01-15 whj4674672 Porting for stm32h7xx
|
||||||
|
* 2020-06-18 thread-liu Porting for stm32mp1xx
|
||||||
|
* 2020-10-14 Dozingfiretruck Porting for stm32wbxx
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file connect_spi.c
|
||||||
|
* @brief support ok1052-c spi function and register to bus framework
|
||||||
|
* @version 1.0
|
||||||
|
* @author AIIT XUOS Lab
|
||||||
|
* @date 2022-03-01
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
File name: connect_spi.c
|
||||||
|
Description: support ok1052-c spi configure and spi bus register function
|
||||||
|
Others: take RT-Thread v4.0.2/bsp/stm32/libraries/HAL_Drivers/drv_spi.c for references
|
||||||
|
https://github.com/RT-Thread/rt-thread/tree/v4.0.2
|
||||||
|
History:
|
||||||
|
1. Date: 2022-03-01
|
||||||
|
Author: AIIT XUOS Lab
|
||||||
|
Modification:
|
||||||
|
1. support ok1052-c spi configure, write and read
|
||||||
|
2. support ok1052-c spi bus device and driver register
|
||||||
|
3. add ok1052-c spi test letter command
|
||||||
|
*************************************************/
|
||||||
|
|
||||||
|
#include "board.h"
|
||||||
|
#include "connect_spi.h"
|
||||||
|
#include "fsl_lpspi.h"
|
||||||
|
#include "pin_mux.h"
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Definitions
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#define SPI_PCS_FOR_INIT (kLPSPI_Pcs0)
|
||||||
|
|
||||||
|
/* Select USB1 PLL PFD0 (720 MHz) as lpspi clock source */
|
||||||
|
#define SPI_CLOCK_SOURCE_SELECT (1U)
|
||||||
|
|
||||||
|
/* Clock divider for master lpspi clock source */
|
||||||
|
#define SPI_CLOCK_SOURCE_DIVIDER (7U)
|
||||||
|
|
||||||
|
#define SPI_CLOCK_FREQ (CLOCK_GetFreq(kCLOCK_Usb1PllPfd0Clk) / (SPI_CLOCK_SOURCE_DIVIDER + 1U))
|
||||||
|
|
||||||
|
#define TRANSFER_SIZE (512U) /*! Transfer dataSize .*/
|
||||||
|
#define TRANSFER_BAUDRATE (500000U) /*! Transfer baudrate - 500k */
|
||||||
|
|
||||||
|
#define spi_print KPrintf
|
||||||
|
#define spi_trace() KPrintf("lw: [%s][%d] passed!\n", __func__, __LINE__)
|
||||||
|
|
||||||
|
typedef struct __spi_transfer_t
|
||||||
|
{
|
||||||
|
uint32_t size;
|
||||||
|
volatile uint32_t cnt;
|
||||||
|
uint8_t water;
|
||||||
|
uint8_t fifo;
|
||||||
|
volatile bool completed;
|
||||||
|
uint8_t buf[TRANSFER_SIZE];
|
||||||
|
}spi_transfer_t;
|
||||||
|
|
||||||
|
#if defined(BSP_USING_SPI1)
|
||||||
|
struct Stm32Spi spi1;
|
||||||
|
spi_transfer_t spi1_rx_data;
|
||||||
|
spi_transfer_t spi1_tx_data;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(BSP_USING_SPI2)
|
||||||
|
struct Stm32Spi spi2;
|
||||||
|
spi_transfer_t spi2_rx_data;
|
||||||
|
spi_transfer_t spi2_tx_data;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(BSP_USING_SPI3)
|
||||||
|
struct Stm32Spi spi3;
|
||||||
|
spi_transfer_t spi3_rx_data;
|
||||||
|
spi_transfer_t spi3_tx_data;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Code
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
void LPSPI1_IRQHandler(int vector, void *param)
|
||||||
|
{
|
||||||
|
LPSPI_Type *spi_base = LPSPI1;
|
||||||
|
int rx_size = spi1_rx_data.size < TRANSFER_SIZE ? spi1_rx_data.size : TRANSFER_SIZE;
|
||||||
|
int tx_size = spi1_tx_data.size < TRANSFER_SIZE ? spi1_tx_data.size : TRANSFER_SIZE;
|
||||||
|
|
||||||
|
if (spi1_rx_data.cnt < rx_size)
|
||||||
|
{
|
||||||
|
/* First, disable the interrupts to avoid potentially triggering another interrupt
|
||||||
|
* while reading out the RX FIFO as more data may be coming into the RX FIFO. We'll
|
||||||
|
* re-enable the interrupts on the LPSPI state after reading out the FIFO.
|
||||||
|
*/
|
||||||
|
LPSPI_DisableInterrupts(spi_base, kLPSPI_RxInterruptEnable);
|
||||||
|
|
||||||
|
while (LPSPI_GetRxFifoCount(spi_base))
|
||||||
|
{
|
||||||
|
/*Read out the data*/
|
||||||
|
spi1_rx_data.buf[spi1_rx_data.cnt] = LPSPI_ReadData(spi_base);
|
||||||
|
spi1_rx_data.cnt++;
|
||||||
|
|
||||||
|
if (spi1_rx_data.cnt == rx_size)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Re-enable the interrupts only if rxCount indicates there is more data to receive,
|
||||||
|
* else we may get a spurious interrupt.
|
||||||
|
* */
|
||||||
|
if (spi1_rx_data.cnt < rx_size)
|
||||||
|
{
|
||||||
|
/* Set the TDF and RDF interrupt enables simultaneously to avoid race conditions */
|
||||||
|
LPSPI_EnableInterrupts(spi_base, kLPSPI_RxInterruptEnable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Update rxWatermark. There isn't RX interrupt for the last datas if the RX count is not greater than rxWatermark.*/
|
||||||
|
if ((rx_size - spi1_rx_data.cnt) <= spi1_rx_data.water)
|
||||||
|
{
|
||||||
|
spi_base->FCR =
|
||||||
|
(spi_base->FCR & (~LPSPI_FCR_RXWATER_MASK)) |
|
||||||
|
LPSPI_FCR_RXWATER(((rx_size - spi1_rx_data.cnt) > 1) ? ((rx_size - spi1_rx_data.cnt) - 1U) : (0U));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (spi1_tx_data.cnt < tx_size)
|
||||||
|
{
|
||||||
|
while ((LPSPI_GetTxFifoCount(spi_base) < spi1_tx_data.fifo) &&
|
||||||
|
(spi1_tx_data.cnt - spi1_rx_data.cnt < spi1_tx_data.fifo))
|
||||||
|
{
|
||||||
|
/*Write the word to TX register*/
|
||||||
|
LPSPI_WriteData(spi_base, spi1_tx_data.buf[spi1_tx_data.cnt]);
|
||||||
|
spi1_tx_data.cnt++;
|
||||||
|
|
||||||
|
if (spi1_tx_data.cnt == tx_size)
|
||||||
|
{
|
||||||
|
spi1_tx_data.completed = true;
|
||||||
|
/* Complete the transfer and disable the interrupts */
|
||||||
|
LPSPI_DisableInterrupts(spi_base, kLPSPI_AllInterruptEnable);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if we're done with this transfer.*/
|
||||||
|
if ((spi1_tx_data.cnt == tx_size) && (spi1_rx_data.cnt == tx_size))
|
||||||
|
{
|
||||||
|
spi1_tx_data.completed = true;
|
||||||
|
/* Complete the transfer and disable the interrupts */
|
||||||
|
LPSPI_DisableInterrupts(spi_base, kLPSPI_AllInterruptEnable);
|
||||||
|
}
|
||||||
|
/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
|
||||||
|
exception return operation might vector to incorrect interrupt */
|
||||||
|
#if defined __CORTEX_M && (__CORTEX_M == 4U)
|
||||||
|
__DSB();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
DECLARE_HW_IRQ(LPSPI1_IRQn, LPSPI1_IRQHandler, NONE);
|
||||||
|
|
||||||
|
void LPSPI2_IRQHandler(int vector, void *param)
|
||||||
|
{
|
||||||
|
LPSPI_Type *spi_base = LPSPI2;
|
||||||
|
int rx_size = spi2_rx_data.size < TRANSFER_SIZE ? spi2_rx_data.size : TRANSFER_SIZE;
|
||||||
|
int tx_size = spi2_tx_data.size < TRANSFER_SIZE ? spi2_tx_data.size : TRANSFER_SIZE;
|
||||||
|
|
||||||
|
if (spi2_rx_data.cnt < rx_size)
|
||||||
|
{
|
||||||
|
/* First, disable the interrupts to avoid potentially triggering another interrupt
|
||||||
|
* while reading out the RX FIFO as more data may be coming into the RX FIFO. We'll
|
||||||
|
* re-enable the interrupts on the LPSPI state after reading out the FIFO.
|
||||||
|
*/
|
||||||
|
LPSPI_DisableInterrupts(spi_base, kLPSPI_RxInterruptEnable);
|
||||||
|
|
||||||
|
while (LPSPI_GetRxFifoCount(spi_base))
|
||||||
|
{
|
||||||
|
/*Read out the data*/
|
||||||
|
spi2_rx_data.buf[spi2_rx_data.cnt] = LPSPI_ReadData(spi_base);
|
||||||
|
spi2_rx_data.cnt++;
|
||||||
|
|
||||||
|
if (spi2_rx_data.cnt == rx_size)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Re-enable the interrupts only if rxCount indicates there is more data to receive,
|
||||||
|
* else we may get a spurious interrupt.
|
||||||
|
* */
|
||||||
|
if (spi2_rx_data.cnt < rx_size)
|
||||||
|
{
|
||||||
|
/* Set the TDF and RDF interrupt enables simultaneously to avoid race conditions */
|
||||||
|
LPSPI_EnableInterrupts(spi_base, kLPSPI_RxInterruptEnable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Update rxWatermark. There isn't RX interrupt for the last datas if the RX count is not greater than rxWatermark.*/
|
||||||
|
if ((rx_size - spi2_rx_data.cnt) <= spi2_rx_data.water)
|
||||||
|
{
|
||||||
|
spi_base->FCR =
|
||||||
|
(spi_base->FCR & (~LPSPI_FCR_RXWATER_MASK)) |
|
||||||
|
LPSPI_FCR_RXWATER(((rx_size - spi2_rx_data.cnt) > 1) ? ((rx_size - spi2_rx_data.cnt) - 1U) : (0U));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (spi2_tx_data.cnt < tx_size)
|
||||||
|
{
|
||||||
|
while ((LPSPI_GetTxFifoCount(spi_base) < spi2_tx_data.fifo) &&
|
||||||
|
(spi2_tx_data.cnt - spi2_rx_data.cnt < spi2_tx_data.fifo))
|
||||||
|
{
|
||||||
|
/*Write the word to TX register*/
|
||||||
|
LPSPI_WriteData(spi_base, spi2_tx_data.buf[spi2_tx_data.cnt]);
|
||||||
|
spi2_tx_data.cnt++;
|
||||||
|
|
||||||
|
if (spi2_tx_data.cnt == tx_size)
|
||||||
|
{
|
||||||
|
spi2_tx_data.completed = true;
|
||||||
|
/* Complete the transfer and disable the interrupts */
|
||||||
|
LPSPI_DisableInterrupts(spi_base, kLPSPI_AllInterruptEnable);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if we're done with this transfer.*/
|
||||||
|
if ((spi2_tx_data.cnt == tx_size) && (spi2_rx_data.cnt == tx_size))
|
||||||
|
{
|
||||||
|
spi2_tx_data.completed = true;
|
||||||
|
/* Complete the transfer and disable the interrupts */
|
||||||
|
LPSPI_DisableInterrupts(spi_base, kLPSPI_AllInterruptEnable);
|
||||||
|
}
|
||||||
|
/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
|
||||||
|
exception return operation might vector to incorrect interrupt */
|
||||||
|
#if defined __CORTEX_M && (__CORTEX_M == 4U)
|
||||||
|
__DSB();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
DECLARE_HW_IRQ(LPSPI2_IRQn, LPSPI2_IRQHandler, NONE);
|
||||||
|
|
||||||
|
void LPSPI3_IRQHandler(int vector, void *param)
|
||||||
|
{
|
||||||
|
LPSPI_Type *spi_base = LPSPI3;
|
||||||
|
int rx_size = spi3_rx_data.size < TRANSFER_SIZE ? spi3_rx_data.size : TRANSFER_SIZE;
|
||||||
|
int tx_size = spi3_tx_data.size < TRANSFER_SIZE ? spi3_tx_data.size : TRANSFER_SIZE;
|
||||||
|
|
||||||
|
if (spi3_rx_data.cnt < rx_size)
|
||||||
|
{
|
||||||
|
/* First, disable the interrupts to avoid potentially triggering another interrupt
|
||||||
|
* while reading out the RX FIFO as more data may be coming into the RX FIFO. We'll
|
||||||
|
* re-enable the interrupts on the LPSPI state after reading out the FIFO.
|
||||||
|
*/
|
||||||
|
LPSPI_DisableInterrupts(spi_base, kLPSPI_RxInterruptEnable);
|
||||||
|
|
||||||
|
while (LPSPI_GetRxFifoCount(spi_base))
|
||||||
|
{
|
||||||
|
/*Read out the data*/
|
||||||
|
spi3_rx_data.buf[spi3_rx_data.cnt] = LPSPI_ReadData(spi_base);
|
||||||
|
spi3_rx_data.cnt++;
|
||||||
|
|
||||||
|
if (spi3_rx_data.cnt == rx_size)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Re-enable the interrupts only if rxCount indicates there is more data to receive,
|
||||||
|
* else we may get a spurious interrupt.
|
||||||
|
* */
|
||||||
|
if (spi3_rx_data.cnt < rx_size)
|
||||||
|
{
|
||||||
|
/* Set the TDF and RDF interrupt enables simultaneously to avoid race conditions */
|
||||||
|
LPSPI_EnableInterrupts(spi_base, kLPSPI_RxInterruptEnable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Update rxWatermark. There isn't RX interrupt for the last datas if the RX count is not greater than rxWatermark.*/
|
||||||
|
if ((rx_size - spi3_rx_data.cnt) <= spi3_rx_data.water)
|
||||||
|
{
|
||||||
|
spi_base->FCR =
|
||||||
|
(spi_base->FCR & (~LPSPI_FCR_RXWATER_MASK)) |
|
||||||
|
LPSPI_FCR_RXWATER(((rx_size - spi3_rx_data.cnt) > 1) ? ((rx_size - spi3_rx_data.cnt) - 1U) : (0U));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (spi3_tx_data.cnt < tx_size)
|
||||||
|
{
|
||||||
|
while ((LPSPI_GetTxFifoCount(spi_base) < spi3_tx_data.fifo) &&
|
||||||
|
(spi3_tx_data.cnt - spi3_rx_data.cnt < spi3_tx_data.fifo))
|
||||||
|
{
|
||||||
|
/*Write the word to TX register*/
|
||||||
|
LPSPI_WriteData(spi_base, spi3_tx_data.buf[spi3_tx_data.cnt]);
|
||||||
|
spi3_tx_data.cnt++;
|
||||||
|
|
||||||
|
if (spi3_tx_data.cnt == tx_size)
|
||||||
|
{
|
||||||
|
spi3_tx_data.completed = true;
|
||||||
|
/* Complete the transfer and disable the interrupts */
|
||||||
|
LPSPI_DisableInterrupts(spi_base, kLPSPI_AllInterruptEnable);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if we're done with this transfer.*/
|
||||||
|
if ((spi3_tx_data.cnt == tx_size) && (spi3_rx_data.cnt == tx_size))
|
||||||
|
{
|
||||||
|
spi3_tx_data.completed = true;
|
||||||
|
/* Complete the transfer and disable the interrupts */
|
||||||
|
LPSPI_DisableInterrupts(spi_base, kLPSPI_AllInterruptEnable);
|
||||||
|
}
|
||||||
|
/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
|
||||||
|
exception return operation might vector to incorrect interrupt */
|
||||||
|
#if defined __CORTEX_M && (__CORTEX_M == 4U)
|
||||||
|
__DSB();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
DECLARE_HW_IRQ(LPSPI3_IRQn, LPSPI3_IRQHandler, NONE);
|
||||||
|
|
||||||
|
void SpiMasterInit(LPSPI_Type *base)
|
||||||
|
{
|
||||||
|
lpspi_master_config_t cfg;
|
||||||
|
|
||||||
|
/*Master config*/
|
||||||
|
cfg.baudRate = TRANSFER_BAUDRATE;
|
||||||
|
cfg.bitsPerFrame = 8;
|
||||||
|
cfg.cpol = kLPSPI_ClockPolarityActiveHigh;
|
||||||
|
cfg.cpha = kLPSPI_ClockPhaseFirstEdge;
|
||||||
|
cfg.direction = kLPSPI_MsbFirst;
|
||||||
|
|
||||||
|
cfg.pcsToSckDelayInNanoSec = 1000000000 / cfg.baudRate;
|
||||||
|
cfg.lastSckToPcsDelayInNanoSec = 1000000000 / cfg.baudRate;
|
||||||
|
cfg.betweenTransferDelayInNanoSec = 1000000000 / cfg.baudRate;
|
||||||
|
|
||||||
|
cfg.whichPcs = SPI_PCS_FOR_INIT;
|
||||||
|
cfg.pcsActiveHighOrLow = kLPSPI_PcsActiveLow;
|
||||||
|
|
||||||
|
cfg.pinCfg = kLPSPI_SdiInSdoOut;
|
||||||
|
cfg.dataOutConfig = kLpspiDataOutRetained;
|
||||||
|
|
||||||
|
LPSPI_MasterInit(base, &cfg, SPI_CLOCK_FREQ);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpiSlaveInit(LPSPI_Type *base)
|
||||||
|
{
|
||||||
|
lpspi_slave_config_t cfg;
|
||||||
|
|
||||||
|
/*Slave config*/
|
||||||
|
cfg.bitsPerFrame = 8;
|
||||||
|
cfg.cpol = kLPSPI_ClockPolarityActiveHigh;
|
||||||
|
cfg.cpha = kLPSPI_ClockPhaseFirstEdge;
|
||||||
|
cfg.direction = kLPSPI_MsbFirst;
|
||||||
|
|
||||||
|
cfg.whichPcs = SPI_PCS_FOR_INIT;
|
||||||
|
cfg.pcsActiveHighOrLow = kLPSPI_PcsActiveLow;
|
||||||
|
|
||||||
|
cfg.pinCfg = kLPSPI_SdiInSdoOut;
|
||||||
|
cfg.dataOutConfig = kLpspiDataOutRetained;
|
||||||
|
|
||||||
|
LPSPI_SlaveInit(base, &cfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
int SpiHwParamInit(struct Stm32HwSpi *spi_param)
|
||||||
|
{
|
||||||
|
LPSPI_Type *spi_base = spi_param->base;
|
||||||
|
uint32_t whichPcs = kLPSPI_Pcs0;
|
||||||
|
uint8_t fifo_size, tx_water, rx_water;
|
||||||
|
|
||||||
|
/*The TX and RX FIFO sizes are always the same*/
|
||||||
|
fifo_size = LPSPI_GetRxFifoSize(spi_base);
|
||||||
|
|
||||||
|
/*Set the RX and TX watermarks to reduce the ISR times.*/
|
||||||
|
if (fifo_size > 1)
|
||||||
|
{
|
||||||
|
tx_water = 1;
|
||||||
|
rx_water = fifo_size - 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tx_water = 0;
|
||||||
|
rx_water = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
LPSPI_SetFifoWatermarks(spi_base, tx_water, rx_water);
|
||||||
|
|
||||||
|
LPSPI_Enable(spi_base, false);
|
||||||
|
spi_base->CFGR1 &= (~LPSPI_CFGR1_NOSTALL_MASK);
|
||||||
|
LPSPI_Enable(spi_base, true);
|
||||||
|
|
||||||
|
/*Flush FIFO , clear status , disable all the inerrupts.*/
|
||||||
|
LPSPI_FlushFifo(spi_base, true, true);
|
||||||
|
LPSPI_ClearStatusFlags(spi_base, kLPSPI_AllStatusFlag);
|
||||||
|
LPSPI_DisableInterrupts(spi_base, kLPSPI_AllInterruptEnable);
|
||||||
|
|
||||||
|
spi_base->TCR =
|
||||||
|
(spi_base->TCR &
|
||||||
|
~(LPSPI_TCR_CONT_MASK | LPSPI_TCR_CONTC_MASK | LPSPI_TCR_RXMSK_MASK | LPSPI_TCR_PCS_MASK)) |
|
||||||
|
LPSPI_TCR_CONT(0) | LPSPI_TCR_CONTC(0) | LPSPI_TCR_RXMSK(0) | LPSPI_TCR_TXMSK(0) | LPSPI_TCR_PCS(whichPcs);
|
||||||
|
|
||||||
|
/* Enable the NVIC for LPSPI peripheral. Note that below code is useless if the LPSPI interrupt is in INTMUX ,
|
||||||
|
* and you should also enable the INTMUX interupt in your application.
|
||||||
|
*/
|
||||||
|
EnableIRQ(spi_param->irq);
|
||||||
|
LPSPI_EnableInterrupts(spi_base, kLPSPI_RxInterruptEnable);
|
||||||
|
}
|
||||||
|
|
||||||
|
int SpiReadData(struct Stm32HwSpi *spi_param, uint8_t *buf, int len)
|
||||||
|
{
|
||||||
|
int fifo_size;
|
||||||
|
int timeout = 50; // wait for read SPI data
|
||||||
|
LPSPI_Type *spi_base = spi_param->base;
|
||||||
|
|
||||||
|
BOARD_InitSPIPins();
|
||||||
|
|
||||||
|
/*Set clock source for LPSPI*/
|
||||||
|
CLOCK_SetMux(kCLOCK_LpspiMux, SPI_CLOCK_SOURCE_SELECT);
|
||||||
|
CLOCK_SetDiv(kCLOCK_LpspiDiv, SPI_CLOCK_SOURCE_DIVIDER);
|
||||||
|
|
||||||
|
uint32_t errorCount;
|
||||||
|
uint32_t i;
|
||||||
|
uint32_t whichPcs;
|
||||||
|
uint8_t txWatermark;
|
||||||
|
|
||||||
|
BOARD_InitSPIPins();
|
||||||
|
|
||||||
|
/*Set clock source for LPSPI*/
|
||||||
|
CLOCK_SetMux(kCLOCK_LpspiMux, SPI_CLOCK_SOURCE_SELECT);
|
||||||
|
CLOCK_SetDiv(kCLOCK_LpspiDiv, SPI_CLOCK_SOURCE_DIVIDER);
|
||||||
|
|
||||||
|
/*Set up the transfer data*/
|
||||||
|
for (i = 0; i < TRANSFER_SIZE; i++)
|
||||||
|
{
|
||||||
|
spi1_rx_data.buf[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
SpiSlaveInit(spi_base);
|
||||||
|
|
||||||
|
/******************Set up slave first ******************/
|
||||||
|
spi1_rx_data.completed = false;
|
||||||
|
spi1_rx_data.cnt = 0;
|
||||||
|
spi1_rx_data.size = len;
|
||||||
|
whichPcs = SPI_PCS_FOR_INIT;
|
||||||
|
|
||||||
|
/*The TX and RX FIFO sizes are always the same*/
|
||||||
|
spi1_rx_data.fifo = LPSPI_GetRxFifoSize(spi_base);
|
||||||
|
|
||||||
|
/*Set the RX and TX watermarks to reduce the ISR times.*/
|
||||||
|
if (spi1_rx_data.fifo > 1)
|
||||||
|
{
|
||||||
|
txWatermark = 1;
|
||||||
|
spi1_rx_data.water = spi1_rx_data.fifo - 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
txWatermark = 0;
|
||||||
|
spi1_rx_data.water = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
LPSPI_SetFifoWatermarks(spi_base, txWatermark, spi1_rx_data.water);
|
||||||
|
|
||||||
|
LPSPI_Enable(spi_base, false);
|
||||||
|
spi_base->CFGR1 &= (~LPSPI_CFGR1_NOSTALL_MASK);
|
||||||
|
LPSPI_Enable(spi_base, true);
|
||||||
|
|
||||||
|
/*Flush FIFO , clear status , disable all the interrupts.*/
|
||||||
|
LPSPI_FlushFifo(spi_base, true, true);
|
||||||
|
LPSPI_ClearStatusFlags(spi_base, kLPSPI_AllStatusFlag);
|
||||||
|
LPSPI_DisableInterrupts(spi_base, kLPSPI_AllInterruptEnable);
|
||||||
|
|
||||||
|
spi_base->TCR =
|
||||||
|
(spi_base->TCR &
|
||||||
|
~(LPSPI_TCR_CONT_MASK | LPSPI_TCR_CONTC_MASK | LPSPI_TCR_RXMSK_MASK | LPSPI_TCR_PCS_MASK)) |
|
||||||
|
LPSPI_TCR_CONT(0) | LPSPI_TCR_CONTC(0) | LPSPI_TCR_RXMSK(0) | LPSPI_TCR_TXMSK(0) | LPSPI_TCR_PCS(whichPcs);
|
||||||
|
|
||||||
|
/* Enable the NVIC for LPSPI peripheral. Note that below code is useless if the LPSPI interrupt is in INTMUX ,
|
||||||
|
* and you should also enable the INTMUX interrupt in your application.
|
||||||
|
*/
|
||||||
|
EnableIRQ(spi_param->irq);
|
||||||
|
LPSPI_EnableInterrupts(spi_base, kLPSPI_RxInterruptEnable);
|
||||||
|
|
||||||
|
/******************Wait for slave transfer completed.******************/
|
||||||
|
while((spi1_rx_data.cnt < (len - 1)) && (timeout--))
|
||||||
|
{
|
||||||
|
MdelayKTask(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(buf && (len <= TRANSFER_SIZE))
|
||||||
|
{
|
||||||
|
memcpy(buf, spi1_rx_data.buf, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
LPSPI_Deinit(spi_base);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpiWriteData(struct Stm32HwSpi *spi_param, const uint8_t *buf, uint16_t len)
|
||||||
|
{
|
||||||
|
uint32_t errorCount;
|
||||||
|
uint32_t i;
|
||||||
|
uint32_t whichPcs;
|
||||||
|
uint8_t txWatermark;
|
||||||
|
LPSPI_Type *spi_base = spi_param->base;
|
||||||
|
int timeout = 1000; // wait for write SPI data
|
||||||
|
|
||||||
|
BOARD_InitSPIPins();
|
||||||
|
|
||||||
|
/*Set clock source for LPSPI*/
|
||||||
|
CLOCK_SetMux(kCLOCK_LpspiMux, SPI_CLOCK_SOURCE_SELECT);
|
||||||
|
CLOCK_SetDiv(kCLOCK_LpspiDiv, SPI_CLOCK_SOURCE_DIVIDER);
|
||||||
|
/*Set up the transfer data*/
|
||||||
|
memcpy(spi1_tx_data.buf, buf, len);
|
||||||
|
|
||||||
|
SpiMasterInit(spi_base);
|
||||||
|
|
||||||
|
spi1_rx_data.size = len;
|
||||||
|
spi1_tx_data.size = len;
|
||||||
|
spi1_tx_data.completed = false;
|
||||||
|
spi1_tx_data.cnt = 0;
|
||||||
|
spi1_rx_data.cnt = 0;
|
||||||
|
whichPcs = SPI_PCS_FOR_INIT;
|
||||||
|
|
||||||
|
/*The TX and RX FIFO sizes are always the same*/
|
||||||
|
spi1_tx_data.fifo = LPSPI_GetRxFifoSize(spi_base);
|
||||||
|
|
||||||
|
/*Set the RX and TX watermarks to reduce the ISR times.*/
|
||||||
|
if (spi1_tx_data.fifo > 1)
|
||||||
|
{
|
||||||
|
txWatermark = 1;
|
||||||
|
spi1_rx_data.water = spi1_tx_data.fifo - 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
txWatermark = 0;
|
||||||
|
spi1_rx_data.water = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
LPSPI_SetFifoWatermarks(spi_base, txWatermark, spi1_rx_data.water);
|
||||||
|
|
||||||
|
LPSPI_Enable(spi_base, false);
|
||||||
|
spi_base->CFGR1 &= (~LPSPI_CFGR1_NOSTALL_MASK);
|
||||||
|
LPSPI_Enable(spi_base, true);
|
||||||
|
|
||||||
|
/*Flush FIFO , clear status , disable all the inerrupts.*/
|
||||||
|
LPSPI_FlushFifo(spi_base, true, true);
|
||||||
|
LPSPI_ClearStatusFlags(spi_base, kLPSPI_AllStatusFlag);
|
||||||
|
LPSPI_DisableInterrupts(spi_base, kLPSPI_AllInterruptEnable);
|
||||||
|
|
||||||
|
spi_base->TCR =
|
||||||
|
(spi_base->TCR &
|
||||||
|
~(LPSPI_TCR_CONT_MASK | LPSPI_TCR_CONTC_MASK | LPSPI_TCR_RXMSK_MASK | LPSPI_TCR_PCS_MASK)) |
|
||||||
|
LPSPI_TCR_CONT(0) | LPSPI_TCR_CONTC(0) | LPSPI_TCR_RXMSK(0) | LPSPI_TCR_TXMSK(0) | LPSPI_TCR_PCS(whichPcs);
|
||||||
|
|
||||||
|
/* Enable the NVIC for LPSPI peripheral. Note that below code is useless if the LPSPI interrupt is in INTMUX ,
|
||||||
|
* and you should also enable the INTMUX interupt in your application.
|
||||||
|
*/
|
||||||
|
EnableIRQ(spi_param->irq);
|
||||||
|
LPSPI_EnableInterrupts(spi_base, kLPSPI_AllInterruptEnable);
|
||||||
|
|
||||||
|
while((spi1_tx_data.cnt < (spi1_tx_data.size - 1)) && (timeout--))
|
||||||
|
{
|
||||||
|
MdelayKTask(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
spi_print("SPI: master rx %d tx %d size %d completed s %d m %d!\r\n", spi1_rx_data.cnt,
|
||||||
|
spi1_tx_data.cnt, spi1_tx_data.size, spi1_rx_data.completed, spi1_tx_data.completed);
|
||||||
|
|
||||||
|
LPSPI_Deinit(spi_base);
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32 Stm32SpiWriteData(struct SpiHardwareDevice *spi_dev, struct SpiDataStandard *spi_datacfg)
|
||||||
|
{
|
||||||
|
int state;
|
||||||
|
x_size_t message_length, already_send_length;
|
||||||
|
uint16 send_length;
|
||||||
|
const uint8 *write_buf;
|
||||||
|
|
||||||
|
NULL_PARAM_CHECK(spi_dev);
|
||||||
|
NULL_PARAM_CHECK(spi_datacfg);
|
||||||
|
|
||||||
|
struct Stm32Spi *StmSpi = CONTAINER_OF(spi_dev->haldev.owner_bus, struct Stm32Spi, spi_bus);
|
||||||
|
struct Stm32HwSpi *StmCfg = (struct Stm32HwSpi *) spi_dev->haldev.private_data;
|
||||||
|
|
||||||
|
while(NONE != spi_datacfg) {
|
||||||
|
|
||||||
|
message_length = spi_datacfg->length;
|
||||||
|
write_buf = spi_datacfg->tx_buff;
|
||||||
|
while (message_length) {
|
||||||
|
if (message_length > 65535){
|
||||||
|
send_length = 65535;
|
||||||
|
message_length = message_length - 65535;
|
||||||
|
} else {
|
||||||
|
send_length = message_length;
|
||||||
|
message_length = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* calculate the start address */
|
||||||
|
already_send_length = spi_datacfg->length - send_length - message_length;
|
||||||
|
write_buf = (uint8 *)spi_datacfg->tx_buff + already_send_length;
|
||||||
|
|
||||||
|
if (spi_datacfg->tx_buff) {
|
||||||
|
SpiWriteData(StmCfg, spi_datacfg->tx_buff, send_length);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state != 0) {
|
||||||
|
KPrintf("spi write error : %d\n", state);
|
||||||
|
spi_datacfg->length = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
spi_datacfg = spi_datacfg->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32 Stm32SpiReadData(struct SpiHardwareDevice *spi_dev, struct SpiDataStandard *spi_datacfg)
|
||||||
|
{
|
||||||
|
int state;
|
||||||
|
x_size_t message_length, already_send_length;
|
||||||
|
uint16 read_length, spi_read_length = 0;
|
||||||
|
uint8 *read_buf;
|
||||||
|
|
||||||
|
NULL_PARAM_CHECK(spi_dev);
|
||||||
|
NULL_PARAM_CHECK(spi_datacfg);
|
||||||
|
|
||||||
|
struct Stm32Spi *StmSpi = CONTAINER_OF(spi_dev->haldev.owner_bus, struct Stm32Spi, spi_bus);
|
||||||
|
struct Stm32HwSpi *StmCfg = (struct Stm32HwSpi *) spi_dev->haldev.private_data;
|
||||||
|
|
||||||
|
while (NONE != spi_datacfg) {
|
||||||
|
message_length = spi_datacfg->length;
|
||||||
|
read_buf = spi_datacfg->rx_buff;
|
||||||
|
while (message_length) {
|
||||||
|
if (message_length > 65535) {
|
||||||
|
read_length = 65535;
|
||||||
|
message_length = message_length - 65535;
|
||||||
|
} else {
|
||||||
|
read_length = message_length;
|
||||||
|
message_length = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* calculate the start address */
|
||||||
|
already_send_length = spi_datacfg->length - read_length - message_length;
|
||||||
|
read_buf = (uint8 *)spi_datacfg->rx_buff + already_send_length;
|
||||||
|
|
||||||
|
if (spi_datacfg->rx_buff) {
|
||||||
|
memset(read_buf, 0xff, read_length);
|
||||||
|
SpiReadData(StmCfg, read_buf, read_length);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state != 0) {
|
||||||
|
KPrintf("spi read error : %d\n", state);
|
||||||
|
spi_datacfg->length = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
spi_read_length += spi_datacfg->length;
|
||||||
|
spi_datacfg = spi_datacfg->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return spi_read_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct SpiDevDone spi_dev_done =
|
||||||
|
{
|
||||||
|
.dev_open = NONE,
|
||||||
|
.dev_close = NONE,
|
||||||
|
.dev_write = Stm32SpiWriteData,
|
||||||
|
.dev_read = Stm32SpiReadData,
|
||||||
|
};
|
||||||
|
|
||||||
|
static x_err_t Stm32SpiInit(struct Stm32Spi *spi_drv, struct SpiMasterParam *cfg)
|
||||||
|
{
|
||||||
|
NULL_PARAM_CHECK(spi_drv);
|
||||||
|
NULL_PARAM_CHECK(cfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32 SpiDrvInit(struct SpiDriver *spi_drv)
|
||||||
|
{
|
||||||
|
NULL_PARAM_CHECK(spi_drv);
|
||||||
|
|
||||||
|
SpiDeviceParam *dev_param = (SpiDeviceParam *)(spi_drv->driver.private_data);
|
||||||
|
|
||||||
|
struct Stm32Spi *StmSpi = CONTAINER_OF(spi_drv->driver.owner_bus, struct Stm32Spi, spi_bus);
|
||||||
|
|
||||||
|
return Stm32SpiInit(StmSpi, dev_param->spi_master_param);
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32 SpiDrvConfigure(struct SpiDriver *spi_drv, struct SpiMasterParam *spi_param)
|
||||||
|
{
|
||||||
|
NULL_PARAM_CHECK(spi_drv);
|
||||||
|
NULL_PARAM_CHECK(spi_param);
|
||||||
|
|
||||||
|
SpiDeviceParam *dev_param = (SpiDeviceParam *)(spi_drv->driver.private_data);
|
||||||
|
|
||||||
|
dev_param->spi_master_param = spi_param;
|
||||||
|
dev_param->spi_master_param->spi_work_mode = dev_param->spi_master_param->spi_work_mode & SPI_MODE_MASK;
|
||||||
|
|
||||||
|
return EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Configure the spi device param, make sure struct (configure_info->private_data) = (SpiMasterParam)*/
|
||||||
|
static uint32 Stm32SpiDrvConfigure(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:
|
||||||
|
ret = SpiDrvInit(spi_drv);
|
||||||
|
break;
|
||||||
|
case OPE_CFG:
|
||||||
|
spi_param = (struct SpiMasterParam *)configure_info->private_data;
|
||||||
|
ret = SpiDrvConfigure(spi_drv, spi_param);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int BoardSpiBusInit(struct Stm32Spi *stm32spi_bus, struct SpiDriver *spi_driver, char* drv_name)
|
||||||
|
{
|
||||||
|
x_err_t ret = EOK;
|
||||||
|
|
||||||
|
/*Init the spi bus */
|
||||||
|
ret = SpiBusInit(&stm32spi_bus->spi_bus, stm32spi_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, stm32spi_bus->bus_name);
|
||||||
|
if (EOK != ret) {
|
||||||
|
KPrintf("Board_Spi_init SpiDriverAttachToBus error %d\n", ret);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int Stm32HwSpiBusInit(void)
|
||||||
|
{
|
||||||
|
x_err_t ret = EOK;
|
||||||
|
struct Stm32Spi *StmSpiBus;
|
||||||
|
|
||||||
|
#ifdef BSP_USING_SPI1
|
||||||
|
StmSpiBus = &spi1;
|
||||||
|
StmSpiBus->instance = LPSPI1;
|
||||||
|
StmSpiBus->bus_name = SPI_1_BUS_NAME;
|
||||||
|
StmSpiBus->spi_bus.private_data = &spi1;
|
||||||
|
|
||||||
|
static struct SpiDriver spi_driver_1;
|
||||||
|
memset(&spi_driver_1, 0, sizeof(struct SpiDriver));
|
||||||
|
|
||||||
|
spi_driver_1.configure = &(Stm32SpiDrvConfigure);
|
||||||
|
|
||||||
|
ret = BoardSpiBusInit(StmSpiBus, &spi_driver_1, SPI_1_DRV_NAME);
|
||||||
|
if (EOK != ret) {
|
||||||
|
KPrintf("Board_Spi_Init spi_bus_init %s error ret %u\n", StmSpiBus->bus_name, ret);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct SpiHardwareDevice spi1_dev;
|
||||||
|
static struct Stm32HwSpi spi1_cfg;
|
||||||
|
|
||||||
|
spi1_cfg.base = StmSpiBus->instance;
|
||||||
|
spi1_cfg.irq = LPSPI1_IRQn;
|
||||||
|
spi1_dev.spi_dev_done = &spi_dev_done;
|
||||||
|
|
||||||
|
ret = SpiDeviceRegister(&spi1_dev, (void *)&spi1_cfg, SPI_1_DEV_NAME_0);
|
||||||
|
if (ret != EOK) {
|
||||||
|
KPrintf("ADC1 device register error %d\n", ret);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = SpiDeviceAttachToBus(SPI_1_DEV_NAME_0, SPI_1_BUS_NAME);
|
||||||
|
if (ret != EOK) {
|
||||||
|
KPrintf("ADC1 device register error %d\n", ret);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef BSP_USING_SPI2
|
||||||
|
StmSpiBus = &spi2;
|
||||||
|
StmSpiBus->instance = LPSPI2;
|
||||||
|
StmSpiBus->bus_name = SPI_2_BUS_NAME;
|
||||||
|
StmSpiBus->spi_bus.private_data = &spi2;
|
||||||
|
|
||||||
|
static struct SpiDriver spi_driver_2;
|
||||||
|
memset(&spi_driver_2, 0, sizeof(struct SpiDriver));
|
||||||
|
|
||||||
|
spi_driver_2.configure = &(Stm32SpiDrvConfigure);
|
||||||
|
|
||||||
|
ret = BoardSpiBusInit(StmSpiBus, &spi_driver_2, SPI_2_DRV_NAME);
|
||||||
|
if (EOK != ret) {
|
||||||
|
KPrintf("Board_Spi_Init spi_bus_init %s error ret %u\n", StmSpiBus->bus_name, ret);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct SpiHardwareDevice spi2_dev;
|
||||||
|
static struct Stm32HwSpi spi2_cfg;
|
||||||
|
|
||||||
|
spi2_cfg.base = StmSpiBus->instance;
|
||||||
|
spi2_cfg.irq = LPSPI2_IRQn;
|
||||||
|
spi2_dev.spi_dev_done = &spi_dev_done;
|
||||||
|
|
||||||
|
ret = SpiDeviceRegister(&spi2_dev, (void *)&spi2_cfg, SPI_2_DEV_NAME_0);
|
||||||
|
if (ret != EOK) {
|
||||||
|
KPrintf("ADC1 device register error %d\n", ret);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = SpiDeviceAttachToBus(SPI_2_DEV_NAME_0, SPI_2_BUS_NAME);
|
||||||
|
if (ret != EOK) {
|
||||||
|
KPrintf("ADC1 device register error %d\n", ret);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef BSP_USING_SPI3
|
||||||
|
StmSpiBus = &spi3;
|
||||||
|
StmSpiBus->instance = LPSPI3;
|
||||||
|
StmSpiBus->bus_name = SPI_3_BUS_NAME;
|
||||||
|
StmSpiBus->spi_bus.private_data = &spi3;
|
||||||
|
|
||||||
|
static struct SpiDriver spi_driver_3;
|
||||||
|
memset(&spi_driver_3, 0, sizeof(struct SpiDriver));
|
||||||
|
|
||||||
|
spi_driver_3.configure = &(Stm32SpiDrvConfigure);
|
||||||
|
|
||||||
|
ret = BoardSpiBusInit(StmSpiBus, &spi_driver_3, SPI_3_DRV_NAME);
|
||||||
|
if (EOK != ret) {
|
||||||
|
KPrintf("Board_Spi_Init spi_bus_init %s error ret %u\n", StmSpiBus->bus_name, ret);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct SpiHardwareDevice spi3_dev;
|
||||||
|
static struct Stm32HwSpi spi3_cfg;
|
||||||
|
|
||||||
|
spi3_cfg.base = StmSpiBus->instance;
|
||||||
|
spi3_cfg.irq = LPSPI3_IRQn;
|
||||||
|
spi3_dev.spi_dev_done = &spi_dev_done;
|
||||||
|
|
||||||
|
ret = SpiDeviceRegister(&spi3_dev, (void *)&spi3_cfg, SPI_3_DEV_NAME_0);
|
||||||
|
if (ret != EOK) {
|
||||||
|
KPrintf("ADC1 device register error %d\n", ret);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = SpiDeviceAttachToBus(SPI_3_DEV_NAME_0, SPI_3_BUS_NAME);
|
||||||
|
if (ret != EOK) {
|
||||||
|
KPrintf("ADC1 device register error %d\n", ret);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
x_err_t HwSpiDeviceAttach(const char *bus_name, const char *device_name)
|
||||||
|
{
|
||||||
|
NULL_PARAM_CHECK(bus_name);
|
||||||
|
NULL_PARAM_CHECK(device_name);
|
||||||
|
|
||||||
|
x_err_t result;
|
||||||
|
struct SpiHardwareDevice *spi_device;
|
||||||
|
static SpiDeviceParam spi_dev_param;
|
||||||
|
memset(&spi_dev_param, 0, sizeof(SpiDeviceParam));
|
||||||
|
|
||||||
|
/* attach the device to spi bus*/
|
||||||
|
spi_device = (struct SpiHardwareDevice *)x_malloc(sizeof(struct SpiHardwareDevice));
|
||||||
|
CHECK(spi_device);
|
||||||
|
memset(spi_device, 0, sizeof(struct SpiHardwareDevice));
|
||||||
|
|
||||||
|
spi_device->spi_dev_done = &spi_dev_done;
|
||||||
|
|
||||||
|
result = SpiDeviceRegister(spi_device, (void *)&spi_dev_param, device_name);
|
||||||
|
if (result != EOK) {
|
||||||
|
SYS_ERR("%s device %p register faild, %d\n", device_name, spi_device, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
result = SpiDeviceAttachToBus(device_name, bus_name);
|
||||||
|
if (result != EOK) {
|
||||||
|
SYS_ERR("%s attach to %s faild, %d\n", device_name, bus_name, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
CHECK(result == EOK);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Imrt1052HwSpiInit(void)
|
||||||
|
{
|
||||||
|
return Stm32HwSpiBusInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpiReadTest(void *arg)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
uint8_t test_buf[32] = {0};
|
||||||
|
struct Stm32HwSpi spi_param;
|
||||||
|
spi_param.base = LPSPI1;
|
||||||
|
spi_param.irq = LPSPI1_IRQn;
|
||||||
|
|
||||||
|
SpiReadData(&spi_param, test_buf, 32);
|
||||||
|
|
||||||
|
for(i = 0; i < sizeof(test_buf) ;i ++)
|
||||||
|
{
|
||||||
|
spi_print("%d - %x\n", i, test_buf[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SHELL_EXPORT_CMD (SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(0),
|
||||||
|
spiread, SpiReadTest, SPI Read);
|
||||||
|
|
||||||
|
void SpiWriteTest(void *arg)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
uint8_t test_buf[100] = {0};
|
||||||
|
struct Stm32HwSpi spi_param;
|
||||||
|
spi_param.base = LPSPI1;
|
||||||
|
spi_param.irq = LPSPI1_IRQn;
|
||||||
|
|
||||||
|
for(i = 0; i < sizeof(test_buf) ;i ++)
|
||||||
|
{
|
||||||
|
test_buf[i] = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
SpiWriteData(&spi_param, test_buf, 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
SHELL_EXPORT_CMD (SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(0),
|
||||||
|
spiwrite, SpiWriteTest, SPI Write );
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -6,18 +6,6 @@
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
* 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 fsl_lpuart.c
|
* @file fsl_lpuart.c
|
||||||
* @brief fsl uart drivers
|
* @brief fsl uart drivers
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2020 AIIT XUOS Lab
|
* Copyright (c) 2022 AIIT XUOS Lab
|
||||||
* XiUOS is licensed under Mulan PSL v2.
|
* XiUOS is licensed under Mulan PSL v2.
|
||||||
* You can use this software according to the terms and conditions of the 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:
|
* You may obtain a copy of Mulan PSL v2 at:
|
||||||
|
@ -12,14 +12,14 @@
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file connect_gpio.h
|
* @file connect_gpio.h
|
||||||
* @brief define stm32f407-st-discovery-board gpio function and struct
|
* @brief define ok1052-c gpio function and struct
|
||||||
* @version 1.0
|
* @version 1.0
|
||||||
* @author AIIT XUOS Lab
|
* @author AIIT XUOS Lab
|
||||||
* @date 2021-04-25
|
* @date 2022-03-01
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef CONNECT_GPIO_H
|
#ifndef __CONNECT_GPIO_H_
|
||||||
#define CONNECT_GPIO_H
|
#define __CONNECT_GPIO_H_
|
||||||
|
|
||||||
#include <device.h>
|
#include <device.h>
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,8 @@
|
||||||
#include <xs_waitqueue.h>
|
#include <xs_waitqueue.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
typedef unsigned long NfdsType;
|
||||||
|
|
||||||
#if !defined(POLLIN) && !defined(POLLOUT)
|
#if !defined(POLLIN) && !defined(POLLOUT)
|
||||||
|
|
||||||
#define POLLIN 0x001
|
#define POLLIN 0x001
|
||||||
|
@ -36,8 +38,6 @@
|
||||||
|
|
||||||
#define POLLMASK_DEFAULT (POLLIN | POLLOUT )
|
#define POLLMASK_DEFAULT (POLLIN | POLLOUT )
|
||||||
|
|
||||||
typedef unsigned long NfdsType;
|
|
||||||
|
|
||||||
struct pollfd
|
struct pollfd
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
|
@ -54,6 +54,7 @@ typedef struct Pollreq
|
||||||
} pollreqType;
|
} pollreqType;
|
||||||
|
|
||||||
void PollAdd(WaitQueueType *wq, pollreqType *req);
|
void PollAdd(WaitQueueType *wq, pollreqType *req);
|
||||||
|
#ifndef poll
|
||||||
int poll(struct pollfd *fds, NfdsType nfds, int timeout);
|
int poll(struct pollfd *fds, NfdsType nfds, int timeout);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -205,6 +205,7 @@ KERNELPATHS :=-I$(BSP_ROOT) \
|
||||||
-I$(KERNEL_ROOT)/resources/ethernet/LwIP/include/lwip/priv \
|
-I$(KERNEL_ROOT)/resources/ethernet/LwIP/include/lwip/priv \
|
||||||
-I$(KERNEL_ROOT)/resources/ethernet/LwIP/include/lwip/prot \
|
-I$(KERNEL_ROOT)/resources/ethernet/LwIP/include/lwip/prot \
|
||||||
-I$(KERNEL_ROOT)/resources/ethernet/LwIP/arch \
|
-I$(KERNEL_ROOT)/resources/ethernet/LwIP/arch \
|
||||||
|
-I$(KERNEL_ROOT)/resources/include \
|
||||||
-I$(BSP_ROOT)/include #
|
-I$(BSP_ROOT)/include #
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
@ -291,6 +292,8 @@ endif
|
||||||
ifeq ($(CONFIG_SUPPORT_CONTROL_FRAMEWORK), y)
|
ifeq ($(CONFIG_SUPPORT_CONTROL_FRAMEWORK), y)
|
||||||
KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/Framework/control #
|
KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/Framework/control #
|
||||||
KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/Framework/control/plc/interoperability/opcua #
|
KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/Framework/control/plc/interoperability/opcua #
|
||||||
|
KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/Framework/control/plc/shared #
|
||||||
|
KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/lib/cJSON
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(CONFIG_CRYPTO), y)
|
ifeq ($(CONFIG_CRYPTO), y)
|
||||||
|
|
|
@ -120,3 +120,4 @@ int AdcDriverAttachToBus(const char *drv_name, const char *bus_name)
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -117,3 +117,4 @@ int AdcDeviceAttachToBus(const char *dev_name, const char *bus_name)
|
||||||
|
|
||||||
return EOK;
|
return EOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -67,3 +67,4 @@ int AdcDriverRegister(struct Driver *driver)
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,8 +12,7 @@
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file bus.c
|
* @file bus.c
|
||||||
* @brief 1、support bus driver framework;2、provide bus API。
|
* @brief Support bus driver framework provide bus API version 1.0
|
||||||
* @version 1.0
|
|
||||||
* @author AIIT XUOS Lab
|
* @author AIIT XUOS Lab
|
||||||
* @date 2021-04-24
|
* @date 2021-04-24
|
||||||
*/
|
*/
|
||||||
|
@ -71,7 +70,7 @@ static int BusMatchDrvDev(struct Driver *driver, struct HardwareDev *device)
|
||||||
* @param dev - dev pointer
|
* @param dev - dev pointer
|
||||||
* @param drv_name - drv name
|
* @param drv_name - drv name
|
||||||
* @param configure_info - BusConfigureInfo pointer
|
* @param configure_info - BusConfigureInfo pointer
|
||||||
* @return successful:EOK,failed:ERROR
|
* @return successful:EOK,failed:ERROR
|
||||||
*/
|
*/
|
||||||
int DeviceObtainBus(struct Bus *bus, struct HardwareDev *dev, const char *drv_name, struct BusConfigureInfo *configure_info)
|
int DeviceObtainBus(struct Bus *bus, struct HardwareDev *dev, const char *drv_name, struct BusConfigureInfo *configure_info)
|
||||||
{
|
{
|
||||||
|
@ -104,7 +103,7 @@ int DeviceObtainBus(struct Bus *bus, struct HardwareDev *dev, const char *drv_na
|
||||||
/**
|
/**
|
||||||
* @Description: support to register bus pointer with linklist
|
* @Description: support to register bus pointer with linklist
|
||||||
* @param bus - bus pointer
|
* @param bus - bus pointer
|
||||||
* @return successful:EOK,failed:NONE
|
* @return successful:EOK,failed:NONE
|
||||||
*/
|
*/
|
||||||
int BusRegister(struct Bus *bus)
|
int BusRegister(struct Bus *bus)
|
||||||
{
|
{
|
||||||
|
@ -125,7 +124,7 @@ int BusRegister(struct Bus *bus)
|
||||||
/**
|
/**
|
||||||
* @Description: support to release bus pointer in linklist
|
* @Description: support to release bus pointer in linklist
|
||||||
* @param bus - bus pointer
|
* @param bus - bus pointer
|
||||||
* @return successful:EOK,failed:NONE
|
* @return successful:EOK,failed:NONE
|
||||||
*/
|
*/
|
||||||
int BusRelease(struct Bus *bus)
|
int BusRelease(struct Bus *bus)
|
||||||
{
|
{
|
||||||
|
@ -147,7 +146,7 @@ int BusRelease(struct Bus *bus)
|
||||||
/**
|
/**
|
||||||
* @Description: support to unregister bus pointer and delete its linklist node
|
* @Description: support to unregister bus pointer and delete its linklist node
|
||||||
* @param bus - bus pointer
|
* @param bus - bus pointer
|
||||||
* @return successful:EOK,failed:NONE
|
* @return successful:EOK,failed:NONE
|
||||||
*/
|
*/
|
||||||
int BusUnregister(struct Bus *bus)
|
int BusUnregister(struct Bus *bus)
|
||||||
{
|
{
|
||||||
|
@ -164,7 +163,7 @@ int BusUnregister(struct Bus *bus)
|
||||||
* @Description: support to register driver pointer to bus pointer
|
* @Description: support to register driver pointer to bus pointer
|
||||||
* @param bus - bus pointer
|
* @param bus - bus pointer
|
||||||
* @param driver - driver pointer
|
* @param driver - driver pointer
|
||||||
* @return successful:EOK,failed:NONE
|
* @return successful:EOK,failed:NONE
|
||||||
*/
|
*/
|
||||||
int DriverRegisterToBus(struct Bus *bus, struct Driver *driver)
|
int DriverRegisterToBus(struct Bus *bus, struct Driver *driver)
|
||||||
{
|
{
|
||||||
|
@ -183,7 +182,7 @@ int DriverRegisterToBus(struct Bus *bus, struct Driver *driver)
|
||||||
* @Description: support to register dev pointer to bus pointer
|
* @Description: support to register dev pointer to bus pointer
|
||||||
* @param bus - bus pointer
|
* @param bus - bus pointer
|
||||||
* @param device - device pointer
|
* @param device - device pointer
|
||||||
* @return successful:EOK,failed:NONE
|
* @return successful:EOK,failed:NONE
|
||||||
*/
|
*/
|
||||||
int DeviceRegisterToBus(struct Bus *bus, struct HardwareDev *device)
|
int DeviceRegisterToBus(struct Bus *bus, struct HardwareDev *device)
|
||||||
{
|
{
|
||||||
|
@ -202,7 +201,7 @@ int DeviceRegisterToBus(struct Bus *bus, struct HardwareDev *device)
|
||||||
* @Description: support to delete driver pointer from bus pointer
|
* @Description: support to delete driver pointer from bus pointer
|
||||||
* @param bus - bus pointer
|
* @param bus - bus pointer
|
||||||
* @param driver - driver pointer
|
* @param driver - driver pointer
|
||||||
* @return successful:EOK,failed:NONE
|
* @return successful:EOK,failed:NONE
|
||||||
*/
|
*/
|
||||||
int DriverDeleteFromBus(struct Bus *bus, struct Driver *driver)
|
int DriverDeleteFromBus(struct Bus *bus, struct Driver *driver)
|
||||||
{
|
{
|
||||||
|
@ -222,7 +221,7 @@ int DriverDeleteFromBus(struct Bus *bus, struct Driver *driver)
|
||||||
* @Description: support to delete dev pointer from bus pointer
|
* @Description: support to delete dev pointer from bus pointer
|
||||||
* @param bus - bus pointer
|
* @param bus - bus pointer
|
||||||
* @param device - device pointer
|
* @param device - device pointer
|
||||||
* @return successful:EOK,failed:NONE
|
* @return successful:EOK,failed:NONE
|
||||||
*/
|
*/
|
||||||
int DeviceDeleteFromBus(struct Bus *bus, struct HardwareDev *device)
|
int DeviceDeleteFromBus(struct Bus *bus, struct HardwareDev *device)
|
||||||
{
|
{
|
||||||
|
@ -241,7 +240,7 @@ int DeviceDeleteFromBus(struct Bus *bus, struct HardwareDev *device)
|
||||||
/**
|
/**
|
||||||
* @Description: support to find bus pointer by bus name
|
* @Description: support to find bus pointer by bus name
|
||||||
* @param bus_name - bus name
|
* @param bus_name - bus name
|
||||||
* @return successful:bus pointer,failed:NONE
|
* @return successful:bus pointer,failed:NONE
|
||||||
*/
|
*/
|
||||||
BusType BusFind(const char *bus_name)
|
BusType BusFind(const char *bus_name)
|
||||||
{
|
{
|
||||||
|
@ -266,7 +265,7 @@ BusType BusFind(const char *bus_name)
|
||||||
* @Description: support to find driver pointer of certain bus by driver name
|
* @Description: support to find driver pointer of certain bus by driver name
|
||||||
* @param bus - bus pointer
|
* @param bus - bus pointer
|
||||||
* @param driver_name - driver name
|
* @param driver_name - driver name
|
||||||
* @return successful:EOK,failed:NONE
|
* @return successful:EOK,failed:NONE
|
||||||
*/
|
*/
|
||||||
DriverType BusFindDriver(struct Bus *bus, const char *driver_name)
|
DriverType BusFindDriver(struct Bus *bus, const char *driver_name)
|
||||||
{
|
{
|
||||||
|
@ -292,7 +291,7 @@ DriverType BusFindDriver(struct Bus *bus, const char *driver_name)
|
||||||
* @Description: support to find device pointer of certain bus by device name
|
* @Description: support to find device pointer of certain bus by device name
|
||||||
* @param bus - bus pointer
|
* @param bus - bus pointer
|
||||||
* @param device_name - device name
|
* @param device_name - device name
|
||||||
* @return successful:EOK,failed:NONE
|
* @return successful:EOK,failed:NONE
|
||||||
*/
|
*/
|
||||||
HardwareDevType BusFindDevice(struct Bus *bus, const char *device_name)
|
HardwareDevType BusFindDevice(struct Bus *bus, const char *device_name)
|
||||||
{
|
{
|
||||||
|
@ -319,7 +318,7 @@ HardwareDevType BusFindDevice(struct Bus *bus, const char *device_name)
|
||||||
* @Description: support to set dev receive function callback
|
* @Description: support to set dev receive function callback
|
||||||
* @param dev - dev pointer
|
* @param dev - dev pointer
|
||||||
* @param dev_recv_callback - callback function
|
* @param dev_recv_callback - callback function
|
||||||
* @return successful:EOK,failed:ERROR
|
* @return successful:EOK,failed:ERROR
|
||||||
*/
|
*/
|
||||||
uint32 BusDevRecvCallback(struct HardwareDev *dev, int (*dev_recv_callback) (void *dev, x_size_t length))
|
uint32 BusDevRecvCallback(struct HardwareDev *dev, int (*dev_recv_callback) (void *dev, x_size_t length))
|
||||||
{
|
{
|
||||||
|
@ -333,7 +332,7 @@ uint32 BusDevRecvCallback(struct HardwareDev *dev, int (*dev_recv_callback) (voi
|
||||||
/**
|
/**
|
||||||
* @Description: support to open dev
|
* @Description: support to open dev
|
||||||
* @param dev - dev pointer
|
* @param dev - dev pointer
|
||||||
* @return successful:EOK,failed:ERROR
|
* @return successful:EOK,failed:ERROR
|
||||||
*/
|
*/
|
||||||
uint32 BusDevOpen(struct HardwareDev *dev)
|
uint32 BusDevOpen(struct HardwareDev *dev)
|
||||||
{
|
{
|
||||||
|
@ -355,7 +354,7 @@ uint32 BusDevOpen(struct HardwareDev *dev)
|
||||||
/**
|
/**
|
||||||
* @Description: support to close dev
|
* @Description: support to close dev
|
||||||
* @param dev - dev pointer
|
* @param dev - dev pointer
|
||||||
* @return successful:EOK,failed:ERROR
|
* @return successful:EOK,failed:ERROR
|
||||||
*/
|
*/
|
||||||
uint32 BusDevClose(struct HardwareDev *dev)
|
uint32 BusDevClose(struct HardwareDev *dev)
|
||||||
{
|
{
|
||||||
|
@ -378,7 +377,7 @@ uint32 BusDevClose(struct HardwareDev *dev)
|
||||||
* @Description: support to write data to dev
|
* @Description: support to write data to dev
|
||||||
* @param dev - dev pointer
|
* @param dev - dev pointer
|
||||||
* @param write_param - BusBlockWriteParam
|
* @param write_param - BusBlockWriteParam
|
||||||
* @return successful:EOK,failed:NONE
|
* @return successful:EOK,failed:NONE
|
||||||
*/
|
*/
|
||||||
uint32 BusDevWriteData(struct HardwareDev *dev, struct BusBlockWriteParam *write_param)
|
uint32 BusDevWriteData(struct HardwareDev *dev, struct BusBlockWriteParam *write_param)
|
||||||
{
|
{
|
||||||
|
@ -395,7 +394,7 @@ uint32 BusDevWriteData(struct HardwareDev *dev, struct BusBlockWriteParam *write
|
||||||
* @Description: support to read data from dev
|
* @Description: support to read data from dev
|
||||||
* @param dev - dev pointer
|
* @param dev - dev pointer
|
||||||
* @param read_param - BusBlockReadParam
|
* @param read_param - BusBlockReadParam
|
||||||
* @return successful:EOK,failed:NONE
|
* @return successful:EOK,failed:NONE
|
||||||
*/
|
*/
|
||||||
uint32 BusDevReadData(struct HardwareDev *dev, struct BusBlockReadParam *read_param)
|
uint32 BusDevReadData(struct HardwareDev *dev, struct BusBlockReadParam *read_param)
|
||||||
{
|
{
|
||||||
|
@ -412,7 +411,7 @@ uint32 BusDevReadData(struct HardwareDev *dev, struct BusBlockReadParam *read_pa
|
||||||
* @Description: support to configure drv, include OPE_CFG and OPE_INT
|
* @Description: support to configure drv, include OPE_CFG and OPE_INT
|
||||||
* @param drv - drv pointer
|
* @param drv - drv pointer
|
||||||
* @param configure_info - BusConfigureInfo
|
* @param configure_info - BusConfigureInfo
|
||||||
* @return successful:EOK,failed:NONE
|
* @return successful:EOK,failed:NONE
|
||||||
*/
|
*/
|
||||||
uint32 BusDrvConfigure(struct Driver *drv, struct BusConfigureInfo *configure_info)
|
uint32 BusDrvConfigure(struct Driver *drv, struct BusConfigureInfo *configure_info)
|
||||||
{
|
{
|
||||||
|
|
|
@ -29,17 +29,6 @@
|
||||||
* Author: Simon Goldschmidt
|
* Author: Simon Goldschmidt
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
/*
|
|
||||||
* 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 sys_arch.c
|
* @file sys_arch.c
|
||||||
|
@ -463,9 +452,9 @@ void lwip_input_thread(void *param)
|
||||||
|
|
||||||
void lwip_config_input(struct netif *net)
|
void lwip_config_input(struct netif *net)
|
||||||
{
|
{
|
||||||
pthread_t th_id = 0;
|
sys_thread_t th_id = 0;
|
||||||
|
|
||||||
th_id = sys_thread_new("eth_input", lwip_input_thread, net, 4096, 15);
|
th_id = sys_thread_new("eth_input", lwip_input_thread, net, LWIP_TASK_STACK_SIZE, 15);
|
||||||
|
|
||||||
if (th_id >= 0) {
|
if (th_id >= 0) {
|
||||||
lw_print("%s %d successfully!\n", __func__, th_id);
|
lw_print("%s %d successfully!\n", __func__, th_id);
|
||||||
|
@ -489,6 +478,8 @@ void lwip_config_net(char *ip, char *mask, char *gw)
|
||||||
#endif /* FSL_FEATURE_SOC_LPC_ENET_COUNT */
|
#endif /* FSL_FEATURE_SOC_LPC_ENET_COUNT */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ETH_BSP_Config();
|
||||||
|
|
||||||
if(chk_lwip_bit(LWIP_INIT_FLAG))
|
if(chk_lwip_bit(LWIP_INIT_FLAG))
|
||||||
{
|
{
|
||||||
lw_print("lw: [%s] already ...\n", __func__);
|
lw_print("lw: [%s] already ...\n", __func__);
|
||||||
|
@ -551,6 +542,8 @@ void lwip_config_tcp(char *ip, char *mask, char *gw)
|
||||||
#endif /* FSL_FEATURE_SOC_LPC_ENET_COUNT */
|
#endif /* FSL_FEATURE_SOC_LPC_ENET_COUNT */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ETH_BSP_Config();
|
||||||
|
|
||||||
if(chk_lwip_bit(LWIP_INIT_FLAG))
|
if(chk_lwip_bit(LWIP_INIT_FLAG))
|
||||||
{
|
{
|
||||||
lw_print("lw: [%s] already ...\n", __func__);
|
lw_print("lw: [%s] already ...\n", __func__);
|
||||||
|
|
|
@ -29,17 +29,6 @@
|
||||||
* Author: Simon Goldschmidt
|
* Author: Simon Goldschmidt
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
/*
|
|
||||||
* 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 sys_arch.h
|
* @file sys_arch.h
|
||||||
|
|
|
@ -1763,7 +1763,7 @@
|
||||||
* sys_thread_new() when the thread is created.
|
* sys_thread_new() when the thread is created.
|
||||||
*/
|
*/
|
||||||
#if !defined TCPIP_THREAD_PRIO || defined __DOXYGEN__
|
#if !defined TCPIP_THREAD_PRIO || defined __DOXYGEN__
|
||||||
#define TCPIP_THREAD_PRIO 25
|
#define TCPIP_THREAD_PRIO 15
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue