forked from xuos/xiuos
Merge branch 'prepare_for_master' of https://git.trustie.net/xuos/xiuos into develop
This commit is contained in:
commit
1f97dd3d77
|
@ -2,7 +2,7 @@ include $(KERNEL_ROOT)/.config
|
||||||
|
|
||||||
ifeq ($(CONFIG_ADD_NUTTX_FETURES),y)
|
ifeq ($(CONFIG_ADD_NUTTX_FETURES),y)
|
||||||
include $(APPDIR)/Make.defs
|
include $(APPDIR)/Make.defs
|
||||||
CSRCS += framework_init.c
|
CSRCS +=
|
||||||
include $(APPDIR)/Application.mk
|
include $(APPDIR)/Application.mk
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ endif
|
||||||
ifeq ($(CONFIG_ADD_XIZI_FETURES),y)
|
ifeq ($(CONFIG_ADD_XIZI_FETURES),y)
|
||||||
SRC_DIR := general_functions app_test
|
SRC_DIR := general_functions app_test
|
||||||
|
|
||||||
SRC_FILES := main.c framework_init.c
|
SRC_FILES := main.c
|
||||||
ifeq ($(CONFIG_LIB_LV),y)
|
ifeq ($(CONFIG_LIB_LV),y)
|
||||||
SRC_DIR += lv_app
|
SRC_DIR += lv_app
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -105,6 +105,8 @@ menu "test app"
|
||||||
menuconfig USER_TEST_HWTIMER
|
menuconfig USER_TEST_HWTIMER
|
||||||
select BSP_USING_HWTIMER
|
select BSP_USING_HWTIMER
|
||||||
select BSP_USING_GPIO
|
select BSP_USING_GPIO
|
||||||
|
select RESOURCES_PIN
|
||||||
|
select BSP_USING_LED
|
||||||
bool "Config test hwtimer"
|
bool "Config test hwtimer"
|
||||||
default n
|
default n
|
||||||
if USER_TEST_HWTIMER
|
if USER_TEST_HWTIMER
|
||||||
|
@ -139,6 +141,21 @@ menu "test app"
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
menuconfig USER_TEST_TOUCH
|
||||||
|
select BSP_USING_TOUCH
|
||||||
|
bool "Config test touch"
|
||||||
|
default n
|
||||||
|
if USER_TEST_TOUCH
|
||||||
|
if ADD_XIZI_FETURES
|
||||||
|
config TOUCH_DEV_DRIVER
|
||||||
|
string "Set touch dev path"
|
||||||
|
default "/dev/touch_dev"
|
||||||
|
config TOUCH_LCD_DEV_DRIVER
|
||||||
|
string "Set lcd dev path"
|
||||||
|
default "/dev/lcd_dev"
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
menuconfig USER_TEST_I2C
|
menuconfig USER_TEST_I2C
|
||||||
select BSP_USING_I2C
|
select BSP_USING_I2C
|
||||||
bool "Config test i2c"
|
bool "Config test i2c"
|
||||||
|
@ -151,6 +168,22 @@ menu "test app"
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
menuconfig USER_TEST_CAMERA
|
||||||
|
select BSP_USING_CAMERA
|
||||||
|
select BSP_USING_LCD
|
||||||
|
bool "Config test camera with lcd"
|
||||||
|
default n
|
||||||
|
if USER_TEST_CAMERA
|
||||||
|
if ADD_XIZI_FETURES
|
||||||
|
config CAMERA_DEV_DRIVER
|
||||||
|
string "Set camera dev path"
|
||||||
|
default "/dev/camera_dev"
|
||||||
|
config CAMERA_LCD_DEV_DRIVER
|
||||||
|
string "Set lcd dev path"
|
||||||
|
default "/dev/lcd_dev"
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
config USER_TEST_SEMC
|
config USER_TEST_SEMC
|
||||||
bool "Config test semc sdram"
|
bool "Config test semc sdram"
|
||||||
default n
|
default n
|
||||||
|
|
|
@ -77,5 +77,13 @@ ifeq ($(CONFIG_ADD_XIZI_FETURES),y)
|
||||||
SRC_FILES += test_wdt.c
|
SRC_FILES += test_wdt.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_USER_TEST_TOUCH),y)
|
||||||
|
SRC_FILES += test_touch.c
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_USER_TEST_CAMERA),y)
|
||||||
|
SRC_FILES += test_camera.c
|
||||||
|
endif
|
||||||
|
|
||||||
include $(KERNEL_ROOT)/compiler.mk
|
include $(KERNEL_ROOT)/compiler.mk
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -0,0 +1,108 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <transform.h>
|
||||||
|
|
||||||
|
#define NULL_PARAMETER 0
|
||||||
|
|
||||||
|
#define DVP_INIT 0x00U
|
||||||
|
#define REG_SCCB_READ 0x12U
|
||||||
|
#define REG_SCCB_WRITE 0x13U
|
||||||
|
#define OUTPUT_CONFIG 0x20U
|
||||||
|
#define LCD_STRING_TYPE 0
|
||||||
|
#define LCD_DOT_TYPE 1
|
||||||
|
#define LCD_SIZE 320
|
||||||
|
|
||||||
|
static uint16_t image_buff[384000];
|
||||||
|
|
||||||
|
void TestCamera(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int frame_counter = 10000;
|
||||||
|
if (argc > 1)
|
||||||
|
{
|
||||||
|
frame_counter = atoi(argv[1]);
|
||||||
|
}
|
||||||
|
printf("This test will refresh %d frames\n", frame_counter);
|
||||||
|
|
||||||
|
int camera_fd = PrivOpen(CAMERA_DEV_DRIVER, O_RDWR);
|
||||||
|
if (camera_fd < 0)
|
||||||
|
{
|
||||||
|
printf("open camera fd error:%d\n", camera_fd);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int lcd_fd = PrivOpen(CAMERA_LCD_DEV_DRIVER, O_RDWR);
|
||||||
|
if (lcd_fd < 0)
|
||||||
|
{
|
||||||
|
printf("open lcd fd error:%d\n", lcd_fd);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//configure the camera's output address
|
||||||
|
struct PrivIoctlCfg ioctl_cfg;
|
||||||
|
ioctl_cfg.ioctl_driver_type = CAMERA_TYPE;
|
||||||
|
struct CameraCfg camera_cfg ={
|
||||||
|
.gain_manu_enable = 0,
|
||||||
|
.gain = 0xFF,
|
||||||
|
.window_w = 800,
|
||||||
|
.window_h = 600,
|
||||||
|
.output_w = IMAGE_WIDTH,
|
||||||
|
.output_h = IMAGE_HEIGHT,
|
||||||
|
.window_xoffset = 0,
|
||||||
|
.window_yoffset = 0
|
||||||
|
};
|
||||||
|
ioctl_cfg.args = &camera_cfg;
|
||||||
|
if (0 != PrivIoctl(camera_fd, OPE_CFG, &ioctl_cfg))
|
||||||
|
{
|
||||||
|
printf("camera pin fd error %d\n", camera_fd);
|
||||||
|
PrivClose(camera_fd);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ioctl_cfg.args = (void *)image_buff;
|
||||||
|
|
||||||
|
if (0 != PrivRead(camera_fd, image_buff, NULL_PARAMETER))
|
||||||
|
{
|
||||||
|
printf("camera pin fd error %d\n", camera_fd);
|
||||||
|
PrivClose(camera_fd);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("address buff is %x\n", image_buff);
|
||||||
|
|
||||||
|
|
||||||
|
LcdWriteParam graph_param;
|
||||||
|
graph_param.type = LCD_DOT_TYPE;
|
||||||
|
|
||||||
|
//clear the LCD
|
||||||
|
uint16_t back_color[LCD_SIZE];
|
||||||
|
memset(back_color,0,sizeof(back_color));
|
||||||
|
for (int i = 0; i < LCD_SIZE; i++)
|
||||||
|
{
|
||||||
|
graph_param.pixel_info.pixel_color = &back_color;
|
||||||
|
graph_param.pixel_info.x_startpos = 0;
|
||||||
|
graph_param.pixel_info.y_startpos = i;
|
||||||
|
graph_param.pixel_info.x_endpos = LCD_SIZE -1;
|
||||||
|
graph_param.pixel_info.y_endpos = i;
|
||||||
|
PrivWrite(lcd_fd, &graph_param, NULL_PARAMETER);
|
||||||
|
}
|
||||||
|
|
||||||
|
//refresh the LCD using photo of camera
|
||||||
|
while (frame_counter--)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < IMAGE_HEIGHT; i++)
|
||||||
|
{
|
||||||
|
graph_param.pixel_info.pixel_color = image_buff + i * IMAGE_WIDTH;
|
||||||
|
graph_param.pixel_info.x_startpos = 0;
|
||||||
|
graph_param.pixel_info.y_startpos = i + (LCD_SIZE - IMAGE_HEIGHT) / 2;
|
||||||
|
graph_param.pixel_info.x_endpos = IMAGE_WIDTH - 1;
|
||||||
|
graph_param.pixel_info.y_endpos = i + (LCD_SIZE - IMAGE_HEIGHT) / 2;
|
||||||
|
PrivWrite(lcd_fd, &graph_param, NULL_PARAMETER);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// close test
|
||||||
|
PrivClose(lcd_fd);
|
||||||
|
PrivClose(camera_fd);
|
||||||
|
printf("The camera test is finished successfully\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
PRIV_SHELL_CMD_FUNCTION(TestCamera, a camera test sample, PRIV_SHELL_CMD_MAIN_ATTR);
|
|
@ -6,28 +6,23 @@
|
||||||
#define NULL_PARAMETER 0
|
#define NULL_PARAMETER 0
|
||||||
|
|
||||||
static uint16_t pinval=0;
|
static uint16_t pinval=0;
|
||||||
|
static uint16_t pin_fd=0;
|
||||||
|
|
||||||
void ledflip(void *parameter)
|
void ledflip(void *parameter)
|
||||||
{
|
{
|
||||||
int tmp_fd = *(int*)parameter;
|
|
||||||
struct PinStat pin_led;
|
struct PinStat pin_led;
|
||||||
pin_led.pin = BSP_LED_PIN;
|
pin_led.pin = BSP_LED_PIN;
|
||||||
pin_led.val = !pinval;
|
pin_led.val = !pinval;
|
||||||
pinval = !pinval;
|
pinval = !pinval;
|
||||||
PrivWrite(tmp_fd,&pin_led,NULL_PARAMETER);
|
PrivWrite(pin_fd,&pin_led,NULL_PARAMETER);
|
||||||
printf("Timer has callback once\n");
|
// printf("Timer has callback once:%d\n",pinval);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestHwTimer(int argc, char *argv[])
|
void TestHwTimer(void)
|
||||||
{
|
{
|
||||||
x_ticks_t period = 100;//uint:10ms
|
x_ticks_t period = 100;//uint:10ms
|
||||||
|
|
||||||
if(argc>1){
|
pin_fd = PrivOpen(HWTIMER_PIN_DEV_DRIVER, O_RDWR);
|
||||||
period = (x_ticks_t)atoi(argv[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int pin_fd = PrivOpen(HWTIMER_PIN_DEV_DRIVER, O_RDWR);
|
|
||||||
if(pin_fd<0){
|
if(pin_fd<0){
|
||||||
printf("open pin fd error:%d\n",pin_fd);
|
printf("open pin fd error:%d\n",pin_fd);
|
||||||
return;
|
return;
|
||||||
|
@ -52,10 +47,6 @@ void TestHwTimer(int argc, char *argv[])
|
||||||
int32 timer_handle = KCreateTimer("LED on and off by 1s",&ledflip,&pin_fd,period,TIMER_TRIGGER_PERIODIC);
|
int32 timer_handle = KCreateTimer("LED on and off by 1s",&ledflip,&pin_fd,period,TIMER_TRIGGER_PERIODIC);
|
||||||
|
|
||||||
KTimerStartRun(timer_handle);
|
KTimerStartRun(timer_handle);
|
||||||
PrivTaskDelay(10000);
|
|
||||||
KTimerQuitRun(timer_handle);
|
|
||||||
|
|
||||||
KDeleteTimer(timer_handle);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,3 +41,71 @@ void TestTouch(void)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <transform.h>
|
||||||
|
|
||||||
|
#define NULL_PARAMETER 0
|
||||||
|
#define LCD_DOT_TYPE 1
|
||||||
|
#define LCD_SIZE 320
|
||||||
|
|
||||||
|
|
||||||
|
void TestTouch(void)
|
||||||
|
{
|
||||||
|
int touch_fd = PrivOpen(TOUCH_DEV_DRIVER, O_RDWR);
|
||||||
|
if (touch_fd < 0)
|
||||||
|
{
|
||||||
|
printf("open touch fd error:%d\n", touch_fd);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int lcd_fd = PrivOpen(TOUCH_LCD_DEV_DRIVER, O_RDWR);
|
||||||
|
if (lcd_fd < 0)
|
||||||
|
{
|
||||||
|
printf("open lcd fd error:%d\n", lcd_fd);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// draw text
|
||||||
|
struct TouchDataStandard touch_pixel;
|
||||||
|
memset(&touch_pixel,0,sizeof(touch_pixel));
|
||||||
|
LcdWriteParam graph_param;
|
||||||
|
|
||||||
|
|
||||||
|
graph_param.type = LCD_DOT_TYPE;
|
||||||
|
|
||||||
|
uint16_t back_color[LCD_SIZE];
|
||||||
|
memset(back_color,0x00,sizeof(back_color));
|
||||||
|
for (int i = 0; i < LCD_SIZE; i++)
|
||||||
|
{
|
||||||
|
graph_param.pixel_info.pixel_color = &back_color;
|
||||||
|
graph_param.pixel_info.x_startpos = 0;
|
||||||
|
graph_param.pixel_info.y_startpos = i;
|
||||||
|
graph_param.pixel_info.x_endpos = LCD_SIZE -1;
|
||||||
|
graph_param.pixel_info.y_endpos = i;
|
||||||
|
PrivWrite(lcd_fd, &graph_param, NULL_PARAMETER);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16 color_select[LCD_SIZE];
|
||||||
|
memset(color_select,0xff,sizeof(color_select));
|
||||||
|
graph_param.pixel_info.pixel_color = &color_select;
|
||||||
|
while(1){
|
||||||
|
if(0 > PrivRead(touch_fd, &touch_pixel, NULL_PARAMETER)){
|
||||||
|
printf("read touch error\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
printf("touch pixel position x:%d,y:%d\n",touch_pixel.x,touch_pixel.y);
|
||||||
|
graph_param.pixel_info.x_startpos = touch_pixel.x-10>0?touch_pixel.x-10:0;
|
||||||
|
graph_param.pixel_info.y_startpos = touch_pixel.y;
|
||||||
|
graph_param.pixel_info.x_endpos = touch_pixel.x+10;
|
||||||
|
graph_param.pixel_info.y_endpos = touch_pixel.y;
|
||||||
|
PrivWrite(lcd_fd, &graph_param, NULL_PARAMETER);
|
||||||
|
graph_param.pixel_info.x_startpos = touch_pixel.x;
|
||||||
|
graph_param.pixel_info.y_startpos = touch_pixel.y-10>0?touch_pixel.y-10:0;
|
||||||
|
graph_param.pixel_info.x_endpos = touch_pixel.x;
|
||||||
|
graph_param.pixel_info.y_endpos = touch_pixel.y+10;
|
||||||
|
PrivWrite(lcd_fd, &graph_param, NULL_PARAMETER);
|
||||||
|
}
|
||||||
|
PrivClose(touch_fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
PRIV_SHELL_CMD_FUNCTION(TestTouch, a touch test sample, PRIV_SHELL_CMD_MAIN_ATTR);
|
|
@ -164,7 +164,7 @@ void TcpSocketRecvTest(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ADD_XIZI_FETURES
|
#ifdef ADD_XIZI_FETURES
|
||||||
lwip_config_tcp(lwip_ipaddr, lwip_netmask, tcp_socket_ip);
|
lwip_config_tcp(0, lwip_ipaddr, lwip_netmask, tcp_socket_ip);
|
||||||
sys_thread_new("TcpSocketRecvTask", TcpSocketRecvTask, NULL, LWIP_TASK_STACK_SIZE, LWIP_DEMO_TASK_PRIO);
|
sys_thread_new("TcpSocketRecvTask", TcpSocketRecvTask, NULL, LWIP_TASK_STACK_SIZE, LWIP_DEMO_TASK_PRIO);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -231,7 +231,7 @@ void TcpSocketSendTest(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ADD_XIZI_FETURES
|
#ifdef ADD_XIZI_FETURES
|
||||||
lwip_config_tcp(lwip_ipaddr, lwip_netmask, tcp_socket_ip);
|
lwip_config_tcp(0, lwip_ipaddr, lwip_netmask, tcp_socket_ip);
|
||||||
sys_thread_new("Tcp Socket Send", TcpSocketSendTask, NULL, LWIP_TASK_STACK_SIZE, LWIP_DEMO_TASK_PRIO);
|
sys_thread_new("Tcp Socket Send", TcpSocketSendTask, NULL, LWIP_TASK_STACK_SIZE, LWIP_DEMO_TASK_PRIO);
|
||||||
#endif
|
#endif
|
||||||
#ifdef ADD_NUTTX_FETURES
|
#ifdef ADD_NUTTX_FETURES
|
||||||
|
|
|
@ -144,7 +144,7 @@ void UdpSocketRecvTest(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ADD_XIZI_FETURES
|
#ifdef ADD_XIZI_FETURES
|
||||||
lwip_config_tcp(lwip_ipaddr, lwip_netmask, udp_socket_ip);
|
lwip_config_tcp(0, lwip_ipaddr, lwip_netmask, udp_socket_ip);
|
||||||
sys_thread_new("UdpSocketRecvTask", UdpSocketRecvTask, NULL,
|
sys_thread_new("UdpSocketRecvTask", UdpSocketRecvTask, NULL,
|
||||||
LWIP_TASK_STACK_SIZE, LWIP_DEMO_TASK_PRIO);
|
LWIP_TASK_STACK_SIZE, LWIP_DEMO_TASK_PRIO);
|
||||||
#endif
|
#endif
|
||||||
|
@ -207,7 +207,7 @@ void UdpSocketSendTest(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ADD_XIZI_FETURES
|
#ifdef ADD_XIZI_FETURES
|
||||||
lwip_config_tcp(lwip_ipaddr, lwip_netmask, udp_socket_ip);
|
lwip_config_tcp(0, lwip_ipaddr, lwip_netmask, udp_socket_ip);
|
||||||
sys_thread_new("UdpSocketSendTask", UdpSocketSendTask, NULL, LWIP_TASK_STACK_SIZE,
|
sys_thread_new("UdpSocketSendTask", UdpSocketSendTask, NULL, LWIP_TASK_STACK_SIZE,
|
||||||
LWIP_DEMO_TASK_PRIO);
|
LWIP_DEMO_TASK_PRIO);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -18,6 +18,32 @@
|
||||||
* @date 2022.9.27
|
* @date 2022.9.27
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <control.h>
|
||||||
|
|
||||||
|
void ControlOmronTest(void)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
uint16_t read_data_length = 0;
|
||||||
|
uint8_t read_data[1024] = {0};
|
||||||
|
ControlProtocolType fins_protocol = ControlProtocolFind();
|
||||||
|
if (NULL == fins_protocol) {
|
||||||
|
printf("%s get fins protocol %p failed\n", __func__, fins_protocol);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("%s get fins protocol %p successfull\n", __func__, fins_protocol);
|
||||||
|
|
||||||
|
if (CONTROL_REGISTERED == fins_protocol->protocol_status) {
|
||||||
|
ControlProtocolOpen(fins_protocol);
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
read_data_length = ControlProtocolRead(fins_protocol, read_data, sizeof(read_data));
|
||||||
|
printf("%s read [%d] fins data %d using receipe file\n", __func__, i, read_data_length);
|
||||||
|
i++;
|
||||||
|
PrivTaskDelay(100000);
|
||||||
|
}
|
||||||
|
|
||||||
|
//ControlProtocolClose(fins_protocol);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PRIV_SHELL_CMD_FUNCTION(ControlOmronTest, Omron Plc FINS Demo, PRIV_SHELL_CMD_MAIN_ATTR);
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
SRC_DIR := list
|
SRC_DIR := list circular_area
|
||||||
|
|
||||||
include $(KERNEL_ROOT)/compiler.mk
|
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -0,0 +1,11 @@
|
||||||
|
include $(KERNEL_ROOT)/.config
|
||||||
|
ifeq ($(CONFIG_ADD_NUTTX_FETURES),y)
|
||||||
|
include $(APPDIR)/Make.defs
|
||||||
|
CSRCS += circular_area_app.c
|
||||||
|
include $(APPDIR)/Application.mk
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_ADD_XIZI_FETURES),y)
|
||||||
|
SRC_FILES := circular_area_app.c
|
||||||
|
include $(KERNEL_ROOT)/compiler.mk
|
||||||
|
endif
|
|
@ -0,0 +1,11 @@
|
||||||
|
import os
|
||||||
|
from building import *
|
||||||
|
Import('RTT_ROOT')
|
||||||
|
Import('rtconfig')
|
||||||
|
cwd = GetCurrentDir()
|
||||||
|
DEPENDS = [""]
|
||||||
|
|
||||||
|
SOURCES = ['circular_area_app.c']
|
||||||
|
path = [cwd]
|
||||||
|
objs = DefineGroup('circular_area', src = SOURCES, depend = DEPENDS,CPPPATH = path)
|
||||||
|
Return("objs")
|
|
@ -0,0 +1,281 @@
|
||||||
|
/*
|
||||||
|
* 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: circular_area_app.c
|
||||||
|
* @brief: circular area file for applications
|
||||||
|
* @version: 3.0
|
||||||
|
* @author: AIIT XUOS Lab
|
||||||
|
* @date: 2022/11/21
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "circular_area_app.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will return whether the circular_area is full or not
|
||||||
|
*
|
||||||
|
* @param circular_area CircularAreaApp descriptor
|
||||||
|
*/
|
||||||
|
int CircularAreaAppIsFull(CircularAreaAppType circular_area)
|
||||||
|
{
|
||||||
|
CA_PARAM_CHECK(circular_area);
|
||||||
|
|
||||||
|
if((circular_area->readidx == circular_area->writeidx) && (circular_area->b_status)) {
|
||||||
|
printf("the circular area is full\n");
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will return whether the circular_area is empty or not
|
||||||
|
*
|
||||||
|
* @param circular_area CircularAreaApp descriptor
|
||||||
|
*/
|
||||||
|
int CircularAreaAppIsEmpty(CircularAreaAppType circular_area)
|
||||||
|
{
|
||||||
|
CA_PARAM_CHECK(circular_area);
|
||||||
|
|
||||||
|
if((circular_area->readidx == circular_area->writeidx) && (!circular_area->b_status)) {
|
||||||
|
printf("the circular area is empty\n");
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will reset the circular_area and set the descriptor to default
|
||||||
|
*
|
||||||
|
* @param circular_area CircularAreaApp descriptor
|
||||||
|
*/
|
||||||
|
void CircularAreaAppReset(CircularAreaAppType circular_area)
|
||||||
|
{
|
||||||
|
circular_area->writeidx = 0;
|
||||||
|
circular_area->readidx = 0;
|
||||||
|
circular_area->b_status = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will release the circular_area descriptor and free the memory
|
||||||
|
*
|
||||||
|
* @param circular_area CircularAreaApp descriptor
|
||||||
|
*/
|
||||||
|
void CircularAreaAppRelease(CircularAreaAppType circular_area)
|
||||||
|
{
|
||||||
|
circular_area->readidx = 0;
|
||||||
|
circular_area->writeidx = 0;
|
||||||
|
circular_area->p_head = NULL;
|
||||||
|
circular_area->p_tail = NULL;
|
||||||
|
circular_area->b_status = 0;
|
||||||
|
circular_area->area_length = 0;
|
||||||
|
|
||||||
|
PrivFree(circular_area->data_buffer);
|
||||||
|
PrivFree(circular_area);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will get the circual_area max length
|
||||||
|
*
|
||||||
|
* @param circular_area CircularAreaApp descriptor
|
||||||
|
*/
|
||||||
|
uint32_t CircularAreaAppGetMaxLength(CircularAreaAppType circular_area)
|
||||||
|
{
|
||||||
|
CA_PARAM_CHECK(circular_area);
|
||||||
|
|
||||||
|
return circular_area->area_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will get the data length of the circular_area
|
||||||
|
*
|
||||||
|
* @param circular_area CircularAreaApp descriptor
|
||||||
|
*/
|
||||||
|
uint32_t CircularAreaAppGetDataLength(CircularAreaAppType circular_area)
|
||||||
|
{
|
||||||
|
CA_PARAM_CHECK(circular_area);
|
||||||
|
|
||||||
|
if(CircularAreaAppIsFull(circular_area)) {
|
||||||
|
return circular_area->area_length;
|
||||||
|
} else {
|
||||||
|
return (circular_area->writeidx - circular_area->readidx + circular_area->area_length) % circular_area->area_length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will return whether it is need to divide the read data into two parts or not
|
||||||
|
*
|
||||||
|
* @param circular_area CircularAreaApp descriptor
|
||||||
|
* @param data_length output data length
|
||||||
|
*/
|
||||||
|
static uint32_t CircularAreaAppDivideRdData(CircularAreaAppType circular_area, uint32_t data_length)
|
||||||
|
{
|
||||||
|
CA_PARAM_CHECK(circular_area);
|
||||||
|
|
||||||
|
if(circular_area->readidx + data_length <= circular_area->area_length) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will return whether it is need to divide the write data into two parts or not
|
||||||
|
*
|
||||||
|
* @param circular_area CircularAreaApp descriptor
|
||||||
|
* @param data_length input data length
|
||||||
|
*/
|
||||||
|
static uint32_t CircularAreaAppDivideWrData(CircularAreaAppType circular_area, uint32_t data_length)
|
||||||
|
{
|
||||||
|
CA_PARAM_CHECK(circular_area);
|
||||||
|
|
||||||
|
if(circular_area->writeidx + data_length <= circular_area->area_length) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will read data from the circular_area
|
||||||
|
*
|
||||||
|
* @param circular_area CircularAreaApp descriptor
|
||||||
|
* @param output_buffer output data buffer poniter
|
||||||
|
* @param data_length output data length
|
||||||
|
*/
|
||||||
|
int CircularAreaAppRead(CircularAreaAppType circular_area, uint8_t *output_buffer, uint32_t data_length)
|
||||||
|
{
|
||||||
|
CA_PARAM_CHECK(circular_area);
|
||||||
|
CA_PARAM_CHECK(output_buffer);
|
||||||
|
CHECK(data_length > 0);
|
||||||
|
|
||||||
|
if(CircularAreaAppIsEmpty(circular_area)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t read_length = (data_length > CircularAreaAppGetDataLength(circular_area)) ? CircularAreaAppGetDataLength(circular_area) : data_length;
|
||||||
|
// if (data_length > CircularAreaAppGetDataLength(circular_area)) {
|
||||||
|
// return -1;
|
||||||
|
// }
|
||||||
|
|
||||||
|
if(CircularAreaAppDivideRdData(circular_area, read_length)) {
|
||||||
|
uint32_t read_len_up = circular_area->area_length - circular_area->readidx;
|
||||||
|
uint32_t read_len_down = read_length - read_len_up;
|
||||||
|
|
||||||
|
memcpy(output_buffer, &circular_area->data_buffer[circular_area->readidx], read_len_up);
|
||||||
|
memcpy(output_buffer + read_len_up, circular_area->p_head, read_len_down);
|
||||||
|
|
||||||
|
circular_area->readidx = read_len_down;
|
||||||
|
} else {
|
||||||
|
memcpy(output_buffer, &circular_area->data_buffer[circular_area->readidx], read_length);
|
||||||
|
circular_area->readidx = (circular_area->readidx + read_length) % circular_area->area_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
circular_area->b_status = 0;
|
||||||
|
|
||||||
|
return read_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will write data to the circular_area
|
||||||
|
*
|
||||||
|
* @param circular_area CircularAreaApp descriptor
|
||||||
|
* @param input_buffer input data buffer poniter
|
||||||
|
* @param data_length input data length
|
||||||
|
* @param b_force whether to force to write data disregard the length limit
|
||||||
|
*/
|
||||||
|
int CircularAreaAppWrite(CircularAreaAppType circular_area, uint8_t *input_buffer, uint32_t data_length, int b_force)
|
||||||
|
{
|
||||||
|
CA_PARAM_CHECK(circular_area);
|
||||||
|
CA_PARAM_CHECK(input_buffer);
|
||||||
|
CHECK(data_length > 0);
|
||||||
|
|
||||||
|
if(CircularAreaAppIsFull(circular_area) && (!b_force)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t write_data_length = circular_area->area_length - CircularAreaAppGetDataLength(circular_area);
|
||||||
|
//data_length = (data_length > write_data_length) ? write_data_length : data_length;
|
||||||
|
if (data_length > write_data_length) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(CircularAreaAppDivideWrData(circular_area, data_length)) {
|
||||||
|
uint32_t write_len_up = circular_area->area_length - circular_area->writeidx;
|
||||||
|
uint32_t write_len_down = data_length - write_len_up;
|
||||||
|
|
||||||
|
memcpy(&circular_area->data_buffer[circular_area->writeidx], input_buffer, write_len_up);
|
||||||
|
memcpy(circular_area->p_head, input_buffer + write_len_up, write_len_down);
|
||||||
|
|
||||||
|
circular_area->writeidx = write_len_down;
|
||||||
|
} else {
|
||||||
|
memcpy(&circular_area->data_buffer[circular_area->writeidx], input_buffer, data_length);
|
||||||
|
circular_area->writeidx = (circular_area->writeidx + data_length) % circular_area->area_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
circular_area->b_status = 1;
|
||||||
|
|
||||||
|
if(b_force) {
|
||||||
|
circular_area->readidx = circular_area->writeidx;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct CircularAreaAppOps CircularAreaAppOperations =
|
||||||
|
{
|
||||||
|
CircularAreaAppRead,
|
||||||
|
CircularAreaAppWrite,
|
||||||
|
CircularAreaAppRelease,
|
||||||
|
CircularAreaAppReset,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will initialize the circular_area
|
||||||
|
*
|
||||||
|
* @param circular_area_length circular_area length
|
||||||
|
*/
|
||||||
|
CircularAreaAppType CircularAreaAppInit(uint32_t circular_area_length)
|
||||||
|
{
|
||||||
|
CHECK(circular_area_length > 0);
|
||||||
|
|
||||||
|
circular_area_length = CA_ALIGN_DOWN(circular_area_length, 8);
|
||||||
|
|
||||||
|
CircularAreaAppType circular_area = PrivMalloc(sizeof(struct CircularAreaApp));
|
||||||
|
if(NULL == circular_area) {
|
||||||
|
printf("CircularAreaAppInit malloc struct circular_area failed\n");
|
||||||
|
PrivFree(circular_area);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
CircularAreaAppReset(circular_area);
|
||||||
|
|
||||||
|
circular_area->data_buffer = PrivMalloc(circular_area_length);
|
||||||
|
if(NULL == circular_area->data_buffer) {
|
||||||
|
printf("CircularAreaAppInit malloc circular_area data_buffer failed\n");
|
||||||
|
PrivFree(circular_area->data_buffer);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
circular_area->p_head = circular_area->data_buffer;
|
||||||
|
circular_area->p_tail = circular_area->data_buffer + circular_area_length;
|
||||||
|
circular_area->area_length = circular_area_length;
|
||||||
|
|
||||||
|
printf("CircularAreaAppInit done p_head %8p p_tail %8p length %u\n",
|
||||||
|
circular_area->p_head, circular_area->p_tail, circular_area->area_length);
|
||||||
|
|
||||||
|
circular_area->CircularAreaAppOperations = &CircularAreaAppOperations;
|
||||||
|
|
||||||
|
return circular_area;
|
||||||
|
}
|
|
@ -0,0 +1,100 @@
|
||||||
|
/*
|
||||||
|
* 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: circular_area_app.h
|
||||||
|
* @brief: function declaration and structure defintion of circular area for applications
|
||||||
|
* @version: 3.0
|
||||||
|
* @author: AIIT XUOS Lab
|
||||||
|
* @date: 2022/11/21
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CIRCULAR_AREA_APP_H
|
||||||
|
#define CIRCULAR_AREA_APP_H
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <transform.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define CA_PARAM_CHECK(param) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
if(param == NULL) { \
|
||||||
|
KPrintf("PARAM CHECK FAILED ...%s %d %s is NULL.\n", __func__, __LINE__, #param); \
|
||||||
|
while(1); \
|
||||||
|
} \
|
||||||
|
}while (0)
|
||||||
|
|
||||||
|
#define CA_ALIGN_DOWN(size, align) ((size)/(align)*(align))
|
||||||
|
|
||||||
|
typedef struct CircularAreaApp *CircularAreaAppType;
|
||||||
|
|
||||||
|
struct CircularAreaAppOps
|
||||||
|
{
|
||||||
|
int (*read) (CircularAreaAppType circular_area, uint8_t *output_buffer, uint32_t data_length);
|
||||||
|
int (*write) (CircularAreaAppType circular_area, uint8_t *input_buffer, uint32_t data_length, int b_force);
|
||||||
|
void (*release) (CircularAreaAppType circular_area);
|
||||||
|
void (*reset) (CircularAreaAppType circular_area);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CircularAreaApp
|
||||||
|
{
|
||||||
|
uint8_t *data_buffer;
|
||||||
|
|
||||||
|
uint32_t readidx;
|
||||||
|
uint32_t writeidx;
|
||||||
|
|
||||||
|
uint8_t *p_head;
|
||||||
|
uint8_t *p_tail;
|
||||||
|
|
||||||
|
uint32_t area_length;
|
||||||
|
int b_status;
|
||||||
|
|
||||||
|
struct CircularAreaAppOps *CircularAreaAppOperations;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*This function will return whether the circular_area is full or not*/
|
||||||
|
int CircularAreaAppIsFull(CircularAreaAppType circular_area);
|
||||||
|
|
||||||
|
/*This function will return whether the circular_area is empty or not*/
|
||||||
|
int CircularAreaAppIsEmpty(CircularAreaAppType circular_area);
|
||||||
|
|
||||||
|
/*This function will reset the circular_area and set the descriptor to default*/
|
||||||
|
void CircularAreaAppReset(CircularAreaAppType circular_area);
|
||||||
|
|
||||||
|
/*This function will release the circular_area descriptor and free the memory*/
|
||||||
|
void CircularAreaAppRelease(CircularAreaAppType circular_area);
|
||||||
|
|
||||||
|
/*This function will read data from the circular_area*/
|
||||||
|
int CircularAreaAppRead(CircularAreaAppType circular_area, uint8_t *output_buffer, uint32_t data_length);
|
||||||
|
|
||||||
|
/*This function will write data to the circular_area*/
|
||||||
|
int CircularAreaAppWrite(CircularAreaAppType circular_area, uint8_t *input_buffer, uint32_t data_length, int b_force);
|
||||||
|
|
||||||
|
/*This function will get the circual_area max length*/
|
||||||
|
uint32_t CircularAreaAppGetMaxLength(CircularAreaAppType circular_area);
|
||||||
|
|
||||||
|
/*This function will get the data length of the circular_area*/
|
||||||
|
uint32_t CircularAreaAppGetDataLength(CircularAreaAppType circular_area);
|
||||||
|
|
||||||
|
/*This function will initialize the circular_area*/
|
||||||
|
CircularAreaAppType CircularAreaAppInit(uint32_t circular_area_length);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -30,10 +30,10 @@ void HumiHs300x(void)
|
||||||
int32_t humidity;
|
int32_t humidity;
|
||||||
struct SensorQuantity *humi = SensorQuantityFind(SENSOR_QUANTITY_HS300X_HUMIDITY, SENSOR_QUANTITY_HUMI);
|
struct SensorQuantity *humi = SensorQuantityFind(SENSOR_QUANTITY_HS300X_HUMIDITY, SENSOR_QUANTITY_HUMI);
|
||||||
SensorQuantityOpen(humi);
|
SensorQuantityOpen(humi);
|
||||||
for (i = 0; i < 100; i ++) {
|
for (i = 0; i < 10; i ++) {
|
||||||
humidity = SensorQuantityReadValue(humi);
|
humidity = SensorQuantityReadValue(humi);
|
||||||
printf("Humidity : %d.%d %%RH\n", humidity/10, humidity%10);
|
printf("Humidity : %d.%d %%RH\n", humidity/10, humidity%10);
|
||||||
PrivTaskDelay(5000);
|
PrivTaskDelay(500);
|
||||||
}
|
}
|
||||||
SensorQuantityClose(humi);
|
SensorQuantityClose(humi);
|
||||||
}
|
}
|
|
@ -30,14 +30,14 @@ void TempHs300x(void)
|
||||||
int32_t temperature;
|
int32_t temperature;
|
||||||
struct SensorQuantity *temp = SensorQuantityFind(SENSOR_QUANTITY_HS300X_TEMPERATURE, SENSOR_QUANTITY_TEMP);
|
struct SensorQuantity *temp = SensorQuantityFind(SENSOR_QUANTITY_HS300X_TEMPERATURE, SENSOR_QUANTITY_TEMP);
|
||||||
SensorQuantityOpen(temp);
|
SensorQuantityOpen(temp);
|
||||||
for (i = 0; i < 100; i ++) {
|
for (i = 0; i < 10; i ++) {
|
||||||
temperature = SensorQuantityReadValue(temp);
|
temperature = SensorQuantityReadValue(temp);
|
||||||
if (temperature > 0)
|
if (temperature > 0)
|
||||||
printf("Temperature : %d.%d ℃\n", temperature/10, temperature%10);
|
printf("Temperature : %d.%d ℃\n", temperature/10, temperature%10);
|
||||||
else
|
else
|
||||||
printf("Temperature : %d.%d ℃\n", temperature/10, -temperature%10);
|
printf("Temperature : %d.%d ℃\n", temperature/10, -temperature%10);
|
||||||
|
|
||||||
PrivTaskDelay(5000);
|
PrivTaskDelay(500);
|
||||||
}
|
}
|
||||||
|
|
||||||
SensorQuantityClose(temp);
|
SensorQuantityClose(temp);
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
SRC_FILES := framework_init.c
|
||||||
SRC_DIR := transform_layer
|
SRC_DIR := transform_layer
|
||||||
|
|
||||||
ifeq ($(CONFIG_SUPPORT_SENSOR_FRAMEWORK),y)
|
ifeq ($(CONFIG_SUPPORT_SENSOR_FRAMEWORK),y)
|
||||||
|
|
|
@ -21,11 +21,8 @@
|
||||||
#include <adapter.h>
|
#include <adapter.h>
|
||||||
|
|
||||||
static DoublelistType adapter_list;
|
static DoublelistType adapter_list;
|
||||||
#ifdef ADD_XIZI_FETURES
|
|
||||||
static int adapter_list_lock;
|
|
||||||
#else
|
|
||||||
static pthread_mutex_t adapter_list_lock;
|
static pthread_mutex_t adapter_list_lock;
|
||||||
#endif
|
|
||||||
/**
|
/**
|
||||||
* @description: Init adapter framework
|
* @description: Init adapter framework
|
||||||
* @return 0
|
* @return 0
|
||||||
|
|
|
@ -17,5 +17,9 @@ ifeq ($(CONFIG_ADAPTER_ESP07S_WIFI),y)
|
||||||
SRC_DIR += esp07s_wifi
|
SRC_DIR += esp07s_wifi
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_ADAPTER_ESP8285_WIFI),y)
|
||||||
|
SRC_DIR += esp8285_wifi
|
||||||
|
endif
|
||||||
|
|
||||||
include $(KERNEL_ROOT)/compiler.mk
|
include $(KERNEL_ROOT)/compiler.mk
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -8,3 +8,9 @@ if ADD_NUTTX_FETURES
|
||||||
default "/dev/ttyS1"
|
default "/dev/ttyS1"
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if ADD_XIZI_FETURES
|
||||||
|
config ADAPTER_ESP8285_DRIVER
|
||||||
|
string "ESP8285 device uart driver path"
|
||||||
|
default "/dev/uart1_dev1"
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
|
@ -5,3 +5,8 @@ ifeq ($(CONFIG_ADD_NUTTX_FETURES),y)
|
||||||
include $(APPDIR)/Application.mk
|
include $(APPDIR)/Application.mk
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_ADD_XIZI_FETURES),y)
|
||||||
|
SRC_FILES := esp8285_wifi.c
|
||||||
|
include $(KERNEL_ROOT)/compiler.mk
|
||||||
|
endif
|
|
@ -205,16 +205,16 @@ static int Esp8285WifiSetUp(struct Adapter *adapter)
|
||||||
PrivTaskDelay(2000);
|
PrivTaskDelay(2000);
|
||||||
/* connect the router */
|
/* connect the router */
|
||||||
memset(cmd,0,sizeof(cmd));
|
memset(cmd,0,sizeof(cmd));
|
||||||
strncpy(cmd,"AT+CWJAP=",strlen("AT+CWJAP="));
|
strcat(cmd,"AT+CWJAP=");
|
||||||
strncat(cmd,"\"",1);
|
strcat(cmd,"\"");
|
||||||
strncat(cmd,param->wifi_ssid,strlen(param->wifi_ssid));
|
strcat(cmd,param->wifi_ssid);
|
||||||
|
|
||||||
strncat(cmd,"\"",1);
|
strcat(cmd,"\"");
|
||||||
strncat(cmd,",",1);
|
strcat(cmd,",");
|
||||||
strncat(cmd,"\"",1);
|
strcat(cmd,"\"");
|
||||||
strncat(cmd,param->wifi_pwd,strlen(param->wifi_pwd));
|
strcat(cmd,param->wifi_pwd);
|
||||||
|
|
||||||
strncat(cmd,"\"",1);
|
strcat(cmd,"\"");
|
||||||
strcat(cmd,"\r\n");
|
strcat(cmd,"\r\n");
|
||||||
|
|
||||||
ret = AtCmdConfigAndCheck(agent, cmd, "OK");
|
ret = AtCmdConfigAndCheck(agent, cmd, "OK");
|
||||||
|
@ -279,17 +279,17 @@ static int Esp8285WifiSetAddr(struct Adapter *adapter, const char *ip, const cha
|
||||||
/* e.g. AT+CIPSTA_DEF="192.168.6.100","192.168.6.1","255.255.255.0" */
|
/* e.g. AT+CIPSTA_DEF="192.168.6.100","192.168.6.1","255.255.255.0" */
|
||||||
memset(cmd,0,sizeof(cmd));
|
memset(cmd,0,sizeof(cmd));
|
||||||
strncpy(cmd,"AT+CIPAP_DEF=",strlen(" AT+CIPAP_DEF="));
|
strncpy(cmd,"AT+CIPAP_DEF=",strlen(" AT+CIPAP_DEF="));
|
||||||
strncat(cmd,"\"",1);
|
strcat(cmd,"\"");
|
||||||
strncat(cmd,ip,strlen(ip));
|
strcat(cmd,ip);
|
||||||
strncat(cmd,"\"",1);
|
strcat(cmd,"\"");
|
||||||
strncat(cmd,",",1);
|
strcat(cmd,",");
|
||||||
strncat(cmd,"\"",1);
|
strcat(cmd,"\"");
|
||||||
strncat(cmd,gateway,strlen(gateway));
|
strcat(cmd,gateway);
|
||||||
strncat(cmd,"\"",1);
|
strcat(cmd,"\"");
|
||||||
strncat(cmd,",",1);
|
strcat(cmd,",");
|
||||||
strncat(cmd,"\"",1);
|
strcat(cmd,"\"");
|
||||||
strncat(cmd,netmask,strlen(netmask));
|
strcat(cmd,netmask);
|
||||||
strncat(cmd,"\"",1);
|
strcat(cmd,"\"");
|
||||||
strcat(cmd,"\r\n");
|
strcat(cmd,"\r\n");
|
||||||
|
|
||||||
ret = AtCmdConfigAndCheck(adapter->agent, cmd, "OK");
|
ret = AtCmdConfigAndCheck(adapter->agent, cmd, "OK");
|
||||||
|
@ -314,9 +314,9 @@ static int Esp8285WifiPing(struct Adapter *adapter, const char *destination)
|
||||||
|
|
||||||
memset(cmd,0,sizeof(cmd));
|
memset(cmd,0,sizeof(cmd));
|
||||||
strncpy(cmd,"AT+PING=",strlen("AT+PING="));
|
strncpy(cmd,"AT+PING=",strlen("AT+PING="));
|
||||||
strncat(cmd,"\"",1);
|
strcat(cmd,"\"");
|
||||||
strncat(cmd,destination,strlen(destination));
|
strcat(cmd,destination);
|
||||||
strncat(cmd,"\"",1);
|
strcat(cmd,"\"");
|
||||||
strcat(cmd,"\r\n");
|
strcat(cmd,"\r\n");
|
||||||
|
|
||||||
ret = AtCmdConfigAndCheck(adapter->agent, cmd, "OK"); ///< config as softAP+station mode
|
ret = AtCmdConfigAndCheck(adapter->agent, cmd, "OK"); ///< config as softAP+station mode
|
||||||
|
@ -387,15 +387,15 @@ static int Esp8285WifiConnect(struct Adapter *adapter, enum NetRoleType net_role
|
||||||
{
|
{
|
||||||
//e.g. AT+CIPSTART="TCP","192.168.3.116",8080 protocol, server IP and port
|
//e.g. AT+CIPSTART="TCP","192.168.3.116",8080 protocol, server IP and port
|
||||||
strncpy(cmd,"AT+CIPSTART=",strlen("AT+CIPSTART="));
|
strncpy(cmd,"AT+CIPSTART=",strlen("AT+CIPSTART="));
|
||||||
strncat(cmd,"\"",1);
|
strcat(cmd,"\"");
|
||||||
strncat(cmd,"TCP",strlen("TCP"));
|
strcat(cmd,"TCP");
|
||||||
strncat(cmd,"\"",1);
|
strcat(cmd,"\"");
|
||||||
strncat(cmd, ",", 1);
|
strcat(cmd, ",");
|
||||||
strncat(cmd,"\"",1);
|
strcat(cmd,"\"");
|
||||||
strncat(cmd, ip, strlen(ip));
|
strcat(cmd, ip);
|
||||||
strncat(cmd, "\"", 1);
|
strcat(cmd, "\"");
|
||||||
strncat(cmd, ",", 1);
|
strcat(cmd, ",");
|
||||||
strncat(cmd, port, strlen(port));
|
strcat(cmd, port);
|
||||||
strcat(cmd,"\r\n");
|
strcat(cmd,"\r\n");
|
||||||
|
|
||||||
ret = AtCmdConfigAndCheck(agent, cmd, "OK");
|
ret = AtCmdConfigAndCheck(agent, cmd, "OK");
|
||||||
|
@ -408,19 +408,19 @@ static int Esp8285WifiConnect(struct Adapter *adapter, enum NetRoleType net_role
|
||||||
{
|
{
|
||||||
//e.g. AT+CIPSTART="UDP","192.168.3.116",8080,2233,0 UDP protocol, server IP, port,local port,udp mode
|
//e.g. AT+CIPSTART="UDP","192.168.3.116",8080,2233,0 UDP protocol, server IP, port,local port,udp mode
|
||||||
strncpy(cmd,"AT+CIPSTART=",strlen("AT+CIPSTART="));
|
strncpy(cmd,"AT+CIPSTART=",strlen("AT+CIPSTART="));
|
||||||
strncat(cmd,"\"",1);
|
strcat(cmd,"\"");
|
||||||
strncat(cmd,"UDP",strlen("UDP"));
|
strcat(cmd,"UDP");
|
||||||
strncat(cmd,"\"",1);
|
strcat(cmd,"\"");
|
||||||
strncat(cmd, ",", 1);
|
strcat(cmd, ",");
|
||||||
strncat(cmd,"\"",1);
|
strcat(cmd,"\"");
|
||||||
strncat(cmd, ip, strlen(ip));
|
strcat(cmd, ip);
|
||||||
strncat(cmd, "\"", 1);
|
strcat(cmd, "\"");
|
||||||
strncat(cmd, ",", 1);
|
strcat(cmd, ",");
|
||||||
strncat(cmd, port, strlen(port));
|
strcat(cmd, port);
|
||||||
strncat(cmd, ",", 1);
|
strcat(cmd, ",");
|
||||||
strncat(cmd, "2233", strlen("2233")); ///< local port
|
strcat(cmd, "2233"); ///< local port
|
||||||
strncat(cmd, ",", 1);
|
strcat(cmd, ",");
|
||||||
strncat(cmd, "0", 1); ///< udp transparent transmission mode must be 0
|
strcat(cmd, "0"); ///< udp transparent transmission mode must be 0
|
||||||
strcat(cmd,"\r\n");
|
strcat(cmd,"\r\n");
|
||||||
|
|
||||||
ret = AtCmdConfigAndCheck(agent, cmd, "OK");
|
ret = AtCmdConfigAndCheck(agent, cmd, "OK");
|
||||||
|
@ -523,15 +523,15 @@ static int Esp8285WifiIoctl(struct Adapter *adapter, int cmd, void *args)
|
||||||
itoa(baud_rate, baud_str, 10);
|
itoa(baud_rate, baud_str, 10);
|
||||||
|
|
||||||
strncpy(at_cmd, "AT+UART_DEF=", strlen("AT+UART_DEF="));
|
strncpy(at_cmd, "AT+UART_DEF=", strlen("AT+UART_DEF="));
|
||||||
strncat(at_cmd, baud_str, strlen(baud_str));
|
strcat(at_cmd, baud_str);
|
||||||
strncat(at_cmd, ",", 1);
|
strcat(at_cmd, ",");
|
||||||
strncat(at_cmd, "8", 1);
|
strcat(at_cmd, "8");
|
||||||
strncat(at_cmd, ",", 1);
|
strcat(at_cmd, ",");
|
||||||
strncat(at_cmd, "1", 1);
|
strcat(at_cmd, "1");
|
||||||
strncat(at_cmd, ",", 1);
|
strcat(at_cmd, ",");
|
||||||
strncat(at_cmd, "0", 1);
|
strcat(at_cmd, "0");
|
||||||
strncat(at_cmd, ",", 1);
|
strcat(at_cmd, ",");
|
||||||
strncat(at_cmd, "3", 1);
|
strcat(at_cmd, "3");
|
||||||
strcat(at_cmd,"\r\n");
|
strcat(at_cmd,"\r\n");
|
||||||
|
|
||||||
ret = AtCmdConfigAndCheck(adapter->agent, at_cmd, "OK");
|
ret = AtCmdConfigAndCheck(adapter->agent, at_cmd, "OK");
|
||||||
|
|
|
@ -2,8 +2,28 @@ menuconfig SUPPORT_CONTROL_FRAMEWORK
|
||||||
bool "support control framework"
|
bool "support control framework"
|
||||||
default n
|
default n
|
||||||
select TRANSFORM_LAYER_ATTRIUBUTE
|
select TRANSFORM_LAYER_ATTRIUBUTE
|
||||||
|
select BSP_USING_LWIP
|
||||||
|
select BSP_USING_SDIO
|
||||||
|
select MOUNT_SDCARD_FS
|
||||||
|
select LIB_USING_CJSON
|
||||||
|
|
||||||
if SUPPORT_CONTROL_FRAMEWORK
|
if SUPPORT_CONTROL_FRAMEWORK
|
||||||
|
config CONTROL_RECIPE_FILE
|
||||||
|
string "control framework recipe file name"
|
||||||
|
default "test_recipe.json"
|
||||||
|
|
||||||
|
menuconfig CONTROL_IPC_PROTOCOL
|
||||||
|
bool "Using ipc protocol"
|
||||||
|
default n
|
||||||
|
if CONTROL_IPC_PROTOCOL
|
||||||
source "$APP_DIR/Framework/control/ipc_protocol/Kconfig"
|
source "$APP_DIR/Framework/control/ipc_protocol/Kconfig"
|
||||||
|
endif
|
||||||
|
|
||||||
|
menuconfig CONTROL_PLC_PROTOCOL
|
||||||
|
bool "Using plc protocol"
|
||||||
|
default n
|
||||||
|
if CONTROL_PLC_PROTOCOL
|
||||||
source "$APP_DIR/Framework/control/plc_protocol/Kconfig"
|
source "$APP_DIR/Framework/control/plc_protocol/Kconfig"
|
||||||
|
endif
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -1,3 +1,11 @@
|
||||||
SRC_DIR := ipc_protocol plc_protocol shared
|
SRC_DIR := shared
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_CONTROL_IPC_PROTOCOL), y)
|
||||||
|
SRC_DIR += ipc_protocol
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_CONTROL_PLC_PROTOCOL), y)
|
||||||
|
SRC_DIR += plc_protocol
|
||||||
|
endif
|
||||||
|
|
||||||
include $(KERNEL_ROOT)/compiler.mk
|
include $(KERNEL_ROOT)/compiler.mk
|
||||||
|
|
|
@ -1,2 +1,8 @@
|
||||||
|
config CONTROL_PROTOCOL_MODBUS_TCP
|
||||||
|
bool "Using modbus_tcp control protocol"
|
||||||
|
default n
|
||||||
|
|
||||||
|
config CONTROL_PROTOCOL_MODBUS_UART
|
||||||
|
bool "Using modbus_uart control protocol"
|
||||||
|
default n
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,10 @@
|
||||||
SRC_DIR := modbus_tcp modbus_uart
|
ifeq ($(CONFIG_CONTROL_PROTOCOL_MODBUS_TCP), y)
|
||||||
|
SRC_DIR := modbus_tcp
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_CONTROL_PROTOCOL_MODBUS_UART), y)
|
||||||
|
SRC_DIR := modbus_uart
|
||||||
|
endif
|
||||||
|
|
||||||
include $(KERNEL_ROOT)/compiler.mk
|
include $(KERNEL_ROOT)/compiler.mk
|
||||||
|
|
||||||
|
|
|
@ -1,365 +0,0 @@
|
||||||
/*
|
|
||||||
* 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_socket.c
|
|
||||||
* @brief Demo for PLC socket communication function
|
|
||||||
* @version 1.0
|
|
||||||
* @author AIIT XUOS Lab
|
|
||||||
* @date 2022.03.16
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "transform.h"
|
|
||||||
#include "plc_socket.h"
|
|
||||||
#include "sys_arch.h"
|
|
||||||
#include "lwip/sockets.h"
|
|
||||||
#include "control_file.h"
|
|
||||||
|
|
||||||
// max support plc socket test commands number
|
|
||||||
#define PLC_SOCK_CMD_NUM CTL_CMD_NUM
|
|
||||||
#define PLC_SOCK_TIMEOUT 50000
|
|
||||||
|
|
||||||
// for saving PLC command index
|
|
||||||
int plc_cmd_index = 0;
|
|
||||||
|
|
||||||
// only for test
|
|
||||||
#define SUPPORT_PLC_SIEMENS
|
|
||||||
|
|
||||||
//siemens test
|
|
||||||
PlcBinCmdType TestPlcCmd[PLC_SOCK_CMD_NUM] = {0};
|
|
||||||
|
|
||||||
//Test information
|
|
||||||
//SIEMENS ip: 192.168.250.9 port: 102
|
|
||||||
//S7-200 ip: 192.168.250.8 port: 102
|
|
||||||
//S7-1200 ip: 192.168.250.6 port: 102
|
|
||||||
//OML ip: 192.168.250.3 port: 9600
|
|
||||||
|
|
||||||
PlcSocketParamType plc_socket_demo_data = {
|
|
||||||
#ifdef SUPPORT_PLC_SIEMENS
|
|
||||||
.ip = {192, 168, 250, 6},
|
|
||||||
.port = 102,
|
|
||||||
.device_type = PLC_DEV_TYPE_SIEMENS,
|
|
||||||
.socket_type = SOCK_STREAM,
|
|
||||||
.cmd_num = 3,
|
|
||||||
#else
|
|
||||||
.ip = {192, 168, 250, 3},
|
|
||||||
.port = 9600,
|
|
||||||
.device_type = PLC_DEV_TYPE_OML,
|
|
||||||
.socket_type = SOCK_DGRAM,
|
|
||||||
.cmd_num = 1,
|
|
||||||
#endif
|
|
||||||
.recv_len = PLC_RECV_BUF_LEN,
|
|
||||||
.recv_buf = NULL,
|
|
||||||
};
|
|
||||||
|
|
||||||
#define OML_HEADER_LEN 78
|
|
||||||
#define CHECK_OML_HEADER(_s) ((0xC0 == *(_s)) && (0x00 == *(_s + 1)) && (0x02 == *(_s + 2)) && (0x00 == *(_s + 3)))
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
static void plc_print_array(char *title, int size, uint8_t *cmd)
|
|
||||||
{
|
|
||||||
lw_notice("%s : %d - ", title, size);
|
|
||||||
for(int i = 0; i < size; i++)
|
|
||||||
{
|
|
||||||
lw_notice(" %#x", cmd[i]);
|
|
||||||
}
|
|
||||||
lw_notice("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *PlcSocketStart(void *arg)
|
|
||||||
{
|
|
||||||
int fd = -1;
|
|
||||||
int timeout, recv_len;
|
|
||||||
struct sockaddr_in sock_addr;
|
|
||||||
socklen_t addr_len = sizeof(struct sockaddr_in);
|
|
||||||
PlcSocketParamType *param = (PlcSocketParamType *)&plc_socket_demo_data;
|
|
||||||
|
|
||||||
plc_print("start %d.%d.%d.%d:%d dev %d sock %d\n",
|
|
||||||
param->ip[0],
|
|
||||||
param->ip[1],
|
|
||||||
param->ip[2],
|
|
||||||
param->ip[3],
|
|
||||||
param->port,
|
|
||||||
param->device_type,
|
|
||||||
param->socket_type);
|
|
||||||
|
|
||||||
param->recv_len = PLC_RECV_BUF_LEN;
|
|
||||||
|
|
||||||
//malloc memory
|
|
||||||
param->recv_buf = (char *)malloc(param->recv_len);
|
|
||||||
if (param->recv_buf == NULL)
|
|
||||||
{
|
|
||||||
plc_error("No memory\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
fd = socket(AF_INET, param->socket_type, 0);
|
|
||||||
if (fd < 0)
|
|
||||||
{
|
|
||||||
plc_error("Socket error %d\n", param->socket_type);
|
|
||||||
free(param->recv_buf);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
plc_print("start %d.%d.%d.%d:%d\n", param->ip[0], param->ip[1], param->ip[2], param->ip[3], param->port);
|
|
||||||
|
|
||||||
sock_addr.sin_family = AF_INET;
|
|
||||||
sock_addr.sin_port = htons(param->port);
|
|
||||||
sock_addr.sin_addr.s_addr = PP_HTONL(LWIP_MAKEU32(param->ip[0], param->ip[1], param->ip[2], param->ip[3]));
|
|
||||||
memset(&(sock_addr.sin_zero), 0, sizeof(sock_addr.sin_zero));
|
|
||||||
|
|
||||||
if (connect(fd, (struct sockaddr *)&sock_addr, sizeof(struct sockaddr)) < 0)
|
|
||||||
{
|
|
||||||
plc_error("Unable to connect\n");
|
|
||||||
closesocket(fd);
|
|
||||||
free(param->recv_buf);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
lw_notice("client %s connected\n", inet_ntoa(sock_addr.sin_addr));
|
|
||||||
|
|
||||||
for(int i = 0; i < param->cmd_num; i ++)
|
|
||||||
{
|
|
||||||
PlcBinCmdType *cmd = &TestPlcCmd[i];
|
|
||||||
sendto(fd, cmd->cmd, cmd->cmd_len, 0, (struct sockaddr*)&sock_addr, addr_len);
|
|
||||||
plc_print_array("Send cmd", cmd->cmd_len, cmd->cmd);
|
|
||||||
|
|
||||||
MdelayKTask(cmd->delay_ms);
|
|
||||||
timeout = PLC_SOCK_TIMEOUT;
|
|
||||||
memset(param->recv_buf, 0, param->recv_len);
|
|
||||||
while(timeout --)
|
|
||||||
{
|
|
||||||
recv_len = recvfrom(fd, param->recv_buf, param->recv_len, 0, (struct sockaddr *)&sock_addr, &addr_len);
|
|
||||||
if(recv_len > 0)
|
|
||||||
{
|
|
||||||
if(param->device_type == PLC_DEV_TYPE_OML)
|
|
||||||
{
|
|
||||||
if((recv_len == OML_HEADER_LEN) && (CHECK_OML_HEADER(param->recv_buf)))
|
|
||||||
{
|
|
||||||
lw_notice("This is Oml package!!!\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lw_notice("Receive from : %s\n", inet_ntoa(sock_addr.sin_addr));
|
|
||||||
plc_print_array("Receive data", recv_len, param->recv_buf);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
closesocket(fd);
|
|
||||||
free(param->recv_buf);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PlcGetParamCmd(char *cmd)
|
|
||||||
{
|
|
||||||
const char s[2] = ",";
|
|
||||||
char *token;
|
|
||||||
uint16_t cmd_index = 0;
|
|
||||||
char bin_cmd[PLC_BIN_CMD_LEN] = {0};
|
|
||||||
token = strtok(cmd, s);
|
|
||||||
while(token != NULL)
|
|
||||||
{
|
|
||||||
sscanf(token, "%x", &bin_cmd[cmd_index]);
|
|
||||||
plc_print("%d - %s %d\n", cmd_index, token, bin_cmd[cmd_index]);
|
|
||||||
token = strtok(NULL, s);
|
|
||||||
cmd_index ++;
|
|
||||||
}
|
|
||||||
TestPlcCmd[plc_cmd_index].cmd_len = cmd_index;
|
|
||||||
memcpy(TestPlcCmd[plc_cmd_index].cmd, bin_cmd, cmd_index);
|
|
||||||
plc_print("get %d cmd len %d\n", plc_cmd_index, TestPlcCmd[plc_cmd_index].cmd_len);
|
|
||||||
plc_cmd_index ++;
|
|
||||||
plc_socket_demo_data.cmd_num = plc_cmd_index;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PlcShowUsage(void)
|
|
||||||
{
|
|
||||||
plc_notice("------------------------------------\n");
|
|
||||||
plc_notice("PlcSocket [ip].[ip].[ip].[ip]:[port]\n");
|
|
||||||
plc_notice("PlcSocket support other param:\n");
|
|
||||||
plc_notice("plc=[] 0: OML 1:SIEMENS\n");
|
|
||||||
plc_notice("tcp=[] 0: udp 1:tcp\n");
|
|
||||||
plc_notice("ip=[ip.ip.ip.ip]\n");
|
|
||||||
plc_notice("port=port\n");
|
|
||||||
plc_notice("file: use %s\n", PLC_SOCK_FILE_NAME);
|
|
||||||
plc_notice("------------------------------------\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(MOUNT_SDCARD) && defined(LIB_USING_CJSON)
|
|
||||||
void PlcGetParamFromFile(char *file_name)
|
|
||||||
{
|
|
||||||
PlcSocketParamType *param = &plc_socket_demo_data;
|
|
||||||
|
|
||||||
char *file_buf = malloc(CTL_FILE_LEN);
|
|
||||||
if(file_buf == NULL)
|
|
||||||
{
|
|
||||||
plc_error("No enough buffer %d\n", CTL_FILE_LEN);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
memset(file_buf, 0, CTL_FILE_LEN);
|
|
||||||
|
|
||||||
if(CtlFileReadWithFilename(file_name, CTL_FILE_LEN, file_buf) != EOK)
|
|
||||||
{
|
|
||||||
plc_error("Can't open file %s\n", file_name);
|
|
||||||
//try again default file
|
|
||||||
if(strcmp(file_name, PLC_SOCK_FILE_NAME) != 0)
|
|
||||||
{
|
|
||||||
if(CtlFileReadWithFilename(PLC_SOCK_FILE_NAME, CTL_FILE_LEN, file_buf) != EOK)
|
|
||||||
{
|
|
||||||
plc_error("Can't open file %s\n", file_name);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
CtlParseJsonData(file_buf);
|
|
||||||
|
|
||||||
memcpy(param->ip, ctl_file_param.ip, 4);
|
|
||||||
param->port = ctl_file_param.port;
|
|
||||||
param->cmd_num = ctl_file_param.cmd_num;
|
|
||||||
param->socket_type = ctl_file_param.tcp ? SOCK_STREAM : SOCK_DGRAM;
|
|
||||||
|
|
||||||
for(int i = 0; i < param->cmd_num; i++)
|
|
||||||
{
|
|
||||||
TestPlcCmd[i].cmd_len = ctl_file_param.cmd_len[i];
|
|
||||||
memcpy(TestPlcCmd[i].cmd, ctl_file_param.cmd[i], TestPlcCmd[i].cmd_len);
|
|
||||||
}
|
|
||||||
|
|
||||||
plc_print("ip: %d.%d.%d.%d\n", param->ip[0], param->ip[1], param->ip[2], param->ip[3]);
|
|
||||||
plc_print("port: %d", param->port);
|
|
||||||
plc_print("tcp: %d", param->socket_type);
|
|
||||||
plc_print("cmd number: %d\n", param->cmd_num);
|
|
||||||
|
|
||||||
for(int i = 0; i < param->cmd_num; i++)
|
|
||||||
{
|
|
||||||
plc_print_array("cmd", TestPlcCmd[i].cmd_len, TestPlcCmd[i].cmd);
|
|
||||||
}
|
|
||||||
free(file_buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void PlcCheckParam(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
PlcSocketParamType *param = &plc_socket_demo_data;
|
|
||||||
plc_cmd_index = 0;
|
|
||||||
|
|
||||||
for(i = 0; i < argc; i++)
|
|
||||||
{
|
|
||||||
char *str = argv[i];
|
|
||||||
int is_tcp = 0;
|
|
||||||
char cmd_str[PLC_BIN_CMD_LEN] = {0};
|
|
||||||
|
|
||||||
plc_print("check %d %s\n", i, str);
|
|
||||||
|
|
||||||
#if defined(MOUNT_SDCARD) && defined(LIB_USING_CJSON)
|
|
||||||
if(strncmp(str, "file", 4) == 0)
|
|
||||||
{
|
|
||||||
char file_name[CTL_FILE_NAME_LEN] = {0};
|
|
||||||
if(sscanf(str, "file=%s", file_name) == EOF)
|
|
||||||
{
|
|
||||||
strcpy(file_name, PLC_SOCK_FILE_NAME);
|
|
||||||
}
|
|
||||||
plc_notice("get %s parameter file %s\n", str, file_name);
|
|
||||||
PlcGetParamFromFile(file_name);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if(sscanf(str, "ip=%d.%d.%d.%d",
|
|
||||||
¶m->ip[0],
|
|
||||||
¶m->ip[1],
|
|
||||||
¶m->ip[2],
|
|
||||||
¶m->ip[3]) == 4)
|
|
||||||
{
|
|
||||||
plc_print("find ip %d %d %d %d\n", param->ip[0], param->ip[1], param->ip[2], param->ip[3]);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(sscanf(str, "port=%d", ¶m->port) == 1)
|
|
||||||
{
|
|
||||||
plc_print("find port %d\n", param->port);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(sscanf(str, "tcp=%d", &is_tcp) == 1)
|
|
||||||
{
|
|
||||||
plc_print("find tcp %d\n", is_tcp);
|
|
||||||
param->socket_type = is_tcp ? SOCK_STREAM:SOCK_DGRAM;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(sscanf(str, "plc=%d", ¶m->device_type) == 1)
|
|
||||||
{
|
|
||||||
plc_print("find device %d\n", param->device_type);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(sscanf(str, "cmd=%s", cmd_str) == 1)
|
|
||||||
{
|
|
||||||
plc_print("find cmd %s\n", cmd_str);
|
|
||||||
PlcGetParamCmd(cmd_str);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(argc >= 2)
|
|
||||||
{
|
|
||||||
if(sscanf(argv[1], "%d.%d.%d.%d:%d",
|
|
||||||
¶m->ip[0],
|
|
||||||
¶m->ip[1],
|
|
||||||
¶m->ip[2],
|
|
||||||
¶m->ip[3],
|
|
||||||
¶m->port) != EOF)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(sscanf(argv[1], "%d.%d.%d.%d",
|
|
||||||
¶m->ip[0],
|
|
||||||
¶m->ip[1],
|
|
||||||
¶m->ip[2],
|
|
||||||
¶m->ip[3]) != EOF)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PlcShowUsage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PlcSocketTask(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
int result = 0;
|
|
||||||
pthread_t th_id;
|
|
||||||
uint8_t enet_port = 0; ///< test enet port 0
|
|
||||||
|
|
||||||
pthread_attr_t attr;
|
|
||||||
attr.schedparam.sched_priority = LWIP_DEMO_TASK_PRIO;
|
|
||||||
attr.stacksize = LWIP_TASK_STACK_SIZE;
|
|
||||||
PlcSocketParamType *param = &plc_socket_demo_data;
|
|
||||||
|
|
||||||
PlcCheckParam(argc, argv);
|
|
||||||
|
|
||||||
lwip_config_net(enet_port, lwip_ipaddr, lwip_netmask, param->ip);
|
|
||||||
PrivTaskCreate(&th_id, &attr, PlcSocketStart, param);
|
|
||||||
}
|
|
||||||
|
|
||||||
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(3),
|
|
||||||
PlcSocket, PlcSocketTask, Test PLC Socket);
|
|
||||||
|
|
|
@ -1,2 +1,15 @@
|
||||||
|
config CONTROL_PROTOCOL_FINS
|
||||||
|
bool "Using fins control protocol"
|
||||||
|
default n
|
||||||
|
|
||||||
|
config CONTROL_PROTOCOL_MELSEC
|
||||||
|
bool "Using melsec control protocol"
|
||||||
|
default n
|
||||||
|
|
||||||
|
config CONTROL_PROTOCOL_OPCUA
|
||||||
|
bool "Using opcua control protocol"
|
||||||
|
default n
|
||||||
|
|
||||||
|
config CONTROL_PROTOCOL_S7
|
||||||
|
bool "Using s7 control protocol"
|
||||||
|
default n
|
||||||
|
|
|
@ -1,4 +1,17 @@
|
||||||
SRC_DIR := fins melsec opcua s7
|
ifeq ($(CONFIG_CONTROL_PROTOCOL_FINS), y)
|
||||||
|
SRC_DIR := fins
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_CONTROL_PROTOCOL_MELSEC), y)
|
||||||
|
SRC_DIR := melsec
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_CONTROL_PROTOCOL_OPCUA), y)
|
||||||
|
SRC_DIR := opcua
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_CONTROL_PROTOCOL_S7), y)
|
||||||
|
SRC_DIR := s7
|
||||||
|
endif
|
||||||
|
|
||||||
include $(KERNEL_ROOT)/compiler.mk
|
include $(KERNEL_ROOT)/compiler.mk
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
SRC_FILES :=
|
SRC_FILES := fins.c
|
||||||
|
|
||||||
include $(KERNEL_ROOT)/compiler.mk
|
include $(KERNEL_ROOT)/compiler.mk
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,436 @@
|
||||||
|
/*
|
||||||
|
* 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 fins.c
|
||||||
|
* @brief plc protocol fins
|
||||||
|
* @version 3.0
|
||||||
|
* @author AIIT XUOS Lab
|
||||||
|
* @date 2022-10-08
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <fins.h>
|
||||||
|
|
||||||
|
#define FINS_COMMAND_LENGTH 34
|
||||||
|
|
||||||
|
static BasicSocketPlc plc_socket = {0};
|
||||||
|
|
||||||
|
static uint8_t handshake_require_command[] = {0x46, 0x49, 0x4E, 0x53, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||||
|
static uint8_t handshake_respond_buff[24] = {0};
|
||||||
|
static uint8_t recv_buff[1024] = {0};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: Fins Get Area Code
|
||||||
|
* @param area_char - area char
|
||||||
|
* @param type - fins data type
|
||||||
|
* @return success : area_char error : 0
|
||||||
|
*/
|
||||||
|
static uint8_t FinsAreaCode(char area_char, FinsDataType type)
|
||||||
|
{
|
||||||
|
uint8_t area_code = 0;
|
||||||
|
if (area_char == 'C')
|
||||||
|
area_code = (type == FINS_DATA_TYPE_BIT ? 0x30 : 0xB0);
|
||||||
|
if (area_char == 'W')
|
||||||
|
area_code = (type == FINS_DATA_TYPE_BIT ? 0x31 : 0xB1);
|
||||||
|
if (area_char == 'H')
|
||||||
|
area_code = (type == FINS_DATA_TYPE_BIT ? 0x32 : 0xB2);
|
||||||
|
if (area_char == 'D')
|
||||||
|
area_code = (type == FINS_DATA_TYPE_BIT ? 0x02 : 0x82);
|
||||||
|
return area_code;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: Fins Cmd Genetare
|
||||||
|
* @param p_command - command pointer
|
||||||
|
* @param plc_ip_4 - last plc ip
|
||||||
|
* @param local_ip_4 - last local ip
|
||||||
|
* @param p_read_item - p_read_item pointer
|
||||||
|
* @return success : index error : 0
|
||||||
|
*/
|
||||||
|
static uint16_t FinsCommandGenerate(uint8_t *p_command, uint16_t plc_ip_4, uint16_t local_ip_4, FinsReadItem *p_read_item)
|
||||||
|
{
|
||||||
|
uint8_t index = 0;
|
||||||
|
uint16_t command_code = p_read_item->data_info.command_code;
|
||||||
|
uint8_t area_char = p_read_item->area_char;
|
||||||
|
uint16_t data_type = p_read_item->data_type;
|
||||||
|
uint16_t start_address = p_read_item->start_address;
|
||||||
|
uint8_t bit_address = p_read_item->bit_address;
|
||||||
|
uint16_t data_length = p_read_item->data_length;
|
||||||
|
|
||||||
|
p_command[index++] = (uint8_t)(FINS_HEADER_HEAD >> (3 * 8));
|
||||||
|
p_command[index++] = (uint8_t)(FINS_HEADER_HEAD >> (2 * 8));
|
||||||
|
p_command[index++] = (uint8_t)(FINS_HEADER_HEAD >> (1 * 8));
|
||||||
|
p_command[index++] = (uint8_t)FINS_HEADER_HEAD;
|
||||||
|
p_command[index++] = (uint8_t)FINS_HEADER_READ_COMMAND_LENGTH >> (3 * 8);
|
||||||
|
p_command[index++] = (uint32_t)FINS_HEADER_READ_COMMAND_LENGTH >> (2 * 8);
|
||||||
|
p_command[index++] = (uint32_t)FINS_HEADER_READ_COMMAND_LENGTH >> (1 * 8);
|
||||||
|
p_command[index++] = (uint32_t)FINS_HEADER_READ_COMMAND_LENGTH;
|
||||||
|
p_command[index++] = (uint32_t)FINS_HEADER_COMMAND >> (3 * 8);
|
||||||
|
p_command[index++] = (uint32_t)FINS_HEADER_COMMAND >> (2 * 8);
|
||||||
|
p_command[index++] = (uint32_t)FINS_HEADER_COMMAND >> (1 * 8);
|
||||||
|
p_command[index++] = (uint32_t)FINS_HEADER_COMMAND;
|
||||||
|
p_command[index++] = (uint32_t)FINS_HEADER_ERROR_CODE >> (3 * 8);
|
||||||
|
p_command[index++] = (uint32_t)FINS_HEADER_ERROR_CODE >> (2 * 8);
|
||||||
|
p_command[index++] = (uint32_t)FINS_HEADER_ERROR_CODE >> (1 * 8);
|
||||||
|
p_command[index++] = (uint32_t)FINS_HEADER_ERROR_CODE;
|
||||||
|
p_command[index++] = FINS_ICF;
|
||||||
|
p_command[index++] = FINS_RSV;
|
||||||
|
p_command[index++] = FINS_GCT;
|
||||||
|
|
||||||
|
p_command[index++] = FINS_DNA;
|
||||||
|
p_command[index++] = plc_ip_4;
|
||||||
|
p_command[index++] = FINS_DA2;
|
||||||
|
|
||||||
|
p_command[index++] = FINS_SNA;
|
||||||
|
p_command[index++] = local_ip_4;
|
||||||
|
p_command[index++] = FINS_SA2;
|
||||||
|
|
||||||
|
p_command[index++] = FINS_SID;
|
||||||
|
|
||||||
|
p_command[index++] = command_code >> 8;
|
||||||
|
p_command[index++] = command_code;
|
||||||
|
p_command[index++] = FinsAreaCode(area_char, data_type);
|
||||||
|
p_command[index++] = start_address >> 8;
|
||||||
|
p_command[index++] = start_address;
|
||||||
|
p_command[index++] = bit_address;
|
||||||
|
p_command[index++] = data_length >> 8;
|
||||||
|
p_command[index++] = data_length;
|
||||||
|
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: Fins Data Transform from Receive Buffer To Control-Data
|
||||||
|
* @param p_read_item - read item pointer
|
||||||
|
* @param recv_buff - receive buff
|
||||||
|
* @return success : 0 error : -1
|
||||||
|
*/
|
||||||
|
static int FinsTransformRecvBuffToData(FinsReadItem *p_read_item, uint8_t *recv_buff)
|
||||||
|
{
|
||||||
|
FinsDataInfo *p_fins_data_info = &(p_read_item->data_info);
|
||||||
|
uint8_t error_code = recv_buff[15];
|
||||||
|
if (error_code) {
|
||||||
|
printf("Data abnormal, abnormal error code is 0x%x!\n", error_code);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
recv_buff += 30;
|
||||||
|
|
||||||
|
FinsCommandCode command_code = p_fins_data_info->command_code;
|
||||||
|
if (FINS_COMMAND_CODE_READ == command_code) {
|
||||||
|
|
||||||
|
uint16_t data_length = p_read_item->data_length;
|
||||||
|
ControlPrintfList("DATA", recv_buff, data_length * (FINS_DATA_TYPE_BIT == p_read_item->data_type ? 1 : 2));
|
||||||
|
printf("Receive data is ");
|
||||||
|
|
||||||
|
if (FINS_DATA_TYPE_BIT == p_read_item->data_type) {
|
||||||
|
memcpy(p_fins_data_info->base_data_info.p_data, recv_buff, data_length);
|
||||||
|
|
||||||
|
printf("0x%x", p_fins_data_info->base_data_info.p_data[0]);
|
||||||
|
} else {
|
||||||
|
uint8_t *p_data = p_fins_data_info->base_data_info.p_data;
|
||||||
|
|
||||||
|
for (uint16_t i = 0; i < data_length; i ++) {
|
||||||
|
p_data[2 * i] = recv_buff[2 * (data_length - i - 1)];
|
||||||
|
p_data[2 * i + 1] = recv_buff[2 * (data_length - i - 1) + 1];
|
||||||
|
printf("0x%x 0x%x", p_data[2 * i], p_data[2 * i + 1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\nRead fins plc data success!\n");
|
||||||
|
} else if (FINS_COMMAND_CODE_WRITE == command_code) {
|
||||||
|
/*to do*/
|
||||||
|
printf("Write fins plc cmd success!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: Fins Protocol Handshake
|
||||||
|
* @param socket - socket
|
||||||
|
* @param local_ip_4 - last local ip
|
||||||
|
* @return success : 0 error : -1 -2
|
||||||
|
*/
|
||||||
|
static int FinsHandshake(int32_t socket, uint16_t local_ip_4)
|
||||||
|
{
|
||||||
|
handshake_require_command[18] = (uint8_t)(local_ip_4 >> 8);
|
||||||
|
handshake_require_command[19] = (uint8_t)local_ip_4;
|
||||||
|
uint8_t try_count = 0;
|
||||||
|
|
||||||
|
while (try_count < 10) {
|
||||||
|
ControlPrintfList("SEND", (uint8_t *)handshake_require_command, sizeof(handshake_require_command));
|
||||||
|
int32_t write_error = socket_write(socket, handshake_require_command, sizeof(handshake_require_command));
|
||||||
|
if (write_error < 0) {
|
||||||
|
printf("Write socket error, errno is %d!", errno);
|
||||||
|
} else {
|
||||||
|
int32_t recv_length = socket_read(socket, (uint8_t *)handshake_respond_buff, sizeof(handshake_respond_buff));
|
||||||
|
if (recv_length < 0) {
|
||||||
|
printf("Read socket error, errno is %d!", errno);
|
||||||
|
} else {
|
||||||
|
ControlPrintfList("RECV", (uint8_t *)handshake_respond_buff, recv_length);
|
||||||
|
|
||||||
|
/*check fins handshake respond*/
|
||||||
|
uint8_t error_code = handshake_respond_buff[15];
|
||||||
|
if (error_code == 0 || error_code == 0x21) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
printf("Fins handshake failed, errno is %05x!", handshake_respond_buff[15]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((errno == EINTR) || (errno == EAGAIN) || (errno == EWOULDBLOCK)) {
|
||||||
|
printf("Send plc command failed, errno is %d!", errno);
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: Fins Get Data From Socket
|
||||||
|
* @param socket - socket
|
||||||
|
* @param p_read_item - read item pointer
|
||||||
|
* @return success : 0 error : -1 -2
|
||||||
|
*/
|
||||||
|
static int FinsGetData(int32_t socket, FinsReadItem *p_read_item)
|
||||||
|
{
|
||||||
|
uint8_t try_count = 0;
|
||||||
|
int32_t write_error = 0;
|
||||||
|
|
||||||
|
FinsDataInfo *p_fins_data_info = &(p_read_item->data_info);
|
||||||
|
BasicPlcDataInfo *p_base_data_info = &(p_fins_data_info->base_data_info);
|
||||||
|
|
||||||
|
memset(recv_buff, 0, sizeof(recv_buff));
|
||||||
|
|
||||||
|
while (try_count < 10) {
|
||||||
|
ControlPrintfList("SEND", p_base_data_info->p_command, p_base_data_info->command_length);
|
||||||
|
try_count++;
|
||||||
|
|
||||||
|
write_error = socket_write(socket, p_base_data_info->p_command, p_base_data_info->command_length);
|
||||||
|
if (write_error < 0) {
|
||||||
|
printf("Write socket error, errno is %d!", errno);
|
||||||
|
} else {
|
||||||
|
PrivTaskDelay(20);
|
||||||
|
|
||||||
|
int32_t recv_length = socket_read(socket, recv_buff, sizeof(recv_buff));
|
||||||
|
if (recv_length < 0) {
|
||||||
|
printf("Read socket error, errno is %d!", errno);
|
||||||
|
} else {
|
||||||
|
ControlPrintfList("RECV", recv_buff, recv_length);
|
||||||
|
return FinsTransformRecvBuffToData(p_read_item, recv_buff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((errno == EINTR) || (errno == EAGAIN) || (errno == EWOULDBLOCK)) {
|
||||||
|
printf("Send plc command failed, errno is %d!", errno);
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: Fins Data Info Init
|
||||||
|
* @param p_read_item - read item pointer
|
||||||
|
* @param plc_ip_4 - last plc ip
|
||||||
|
* @param local_ip_4 - last local ip
|
||||||
|
* @param p_data - control-data pointer
|
||||||
|
* @return success : 0 error : -1
|
||||||
|
*/
|
||||||
|
static int FinsInitialDataInfo(FinsReadItem *p_read_item, uint16_t plc_ip_4, uint16_t local_ip_4, uint8_t *p_data)
|
||||||
|
{
|
||||||
|
uint16_t data_length = p_read_item->data_length;
|
||||||
|
|
||||||
|
BasicPlcDataInfo *p_base_data_info = &(p_read_item->data_info.base_data_info);
|
||||||
|
switch (p_read_item->data_info.command_code)
|
||||||
|
{
|
||||||
|
case FINS_COMMAND_CODE_READ:
|
||||||
|
data_length *= (p_read_item->data_type == FINS_DATA_TYPE_BIT ? 1 : 2);
|
||||||
|
p_base_data_info->command_length = FINS_COMMAND_LENGTH;
|
||||||
|
p_base_data_info->p_command = PrivMalloc(FINS_COMMAND_LENGTH);
|
||||||
|
p_base_data_info->data_size = data_length;
|
||||||
|
p_base_data_info->p_data = p_data;
|
||||||
|
break;
|
||||||
|
case FINS_COMMAND_CODE_WRITE:
|
||||||
|
//To Do
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
FinsCommandGenerate(p_base_data_info->p_command, plc_ip_4, local_ip_4, p_read_item);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: Fins Receive Plc Data Task
|
||||||
|
* @param parameter - parameter pointer
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
void *ReceivePlcDataTask(void *parameter)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
uint8_t try_count = 0;
|
||||||
|
uint16_t data_length = 0;
|
||||||
|
uint8_t *fins_data;
|
||||||
|
uint16_t read_item_size = sizeof(FinsReadItem);
|
||||||
|
|
||||||
|
struct ControlProtocol *control_protocol = (struct ControlProtocol *)parameter;
|
||||||
|
struct CircularAreaApp *circular_area = (struct CircularAreaApp *)control_protocol->args;
|
||||||
|
FinsReadItem *fins_read_item = (FinsReadItem *)control_protocol->recipe->read_item;
|
||||||
|
fins_data = control_protocol->recipe->protocol_data.data;
|
||||||
|
data_length = control_protocol->recipe->protocol_data.data_length;
|
||||||
|
|
||||||
|
memset(&plc_socket, 0, sizeof(BasicSocketPlc));
|
||||||
|
memcpy(plc_socket.ip, control_protocol->recipe->socket_config.plc_ip, 4);
|
||||||
|
plc_socket.port = control_protocol->recipe->socket_config.port;
|
||||||
|
plc_socket.socket = -1;
|
||||||
|
plc_socket.secondary_connect_flag = 0;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
for (i = 0; i < control_protocol->recipe->read_item_count; i ++) {
|
||||||
|
/*only connect socket when close socket or init*/
|
||||||
|
while (ControlConnectSocket(&plc_socket) < 0) {
|
||||||
|
PrivTaskDelay(1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*need to handshake after connect socket using FINS protocol*/
|
||||||
|
if (0 == plc_socket.secondary_connect_flag) {
|
||||||
|
if (FinsHandshake(plc_socket.socket, control_protocol->recipe->socket_config.local_ip[3]) < 0) {
|
||||||
|
plc_socket.secondary_connect_flag = 0;
|
||||||
|
ControlDisconnectSocket(&plc_socket);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
plc_socket.secondary_connect_flag = 1;
|
||||||
|
|
||||||
|
FinsGetData(plc_socket.socket, (FinsReadItem *)fins_read_item + i);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*read all variable item data, put them into circular_area*/
|
||||||
|
if (i == control_protocol->recipe->read_item_count) {
|
||||||
|
printf("%s get %d item %d length\n", __func__, i, data_length);
|
||||||
|
CircularAreaAppWrite(circular_area, fins_data, data_length, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*read data every single 200ms*/
|
||||||
|
PrivTaskDelay(control_protocol->recipe->read_period);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: Fins Protocol Open
|
||||||
|
* @param control_protocol - control protocol pointer
|
||||||
|
* @return success : 0 error
|
||||||
|
*/
|
||||||
|
int FinsOpen(struct ControlProtocol *control_protocol)
|
||||||
|
{
|
||||||
|
ControlProtocolOpenDef(control_protocol);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: Fins Protocol Close
|
||||||
|
* @param control_protocol - control protocol pointer
|
||||||
|
* @return success : 0 error
|
||||||
|
*/
|
||||||
|
int FinsClose(struct ControlProtocol *control_protocol)
|
||||||
|
{
|
||||||
|
ControlDisconnectSocket(&plc_socket);
|
||||||
|
|
||||||
|
ControlProtocolCloseDef();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: Fins Protocol Read Data
|
||||||
|
* @param control_protocol - control protocol pointer
|
||||||
|
* @param buf - read data buffer
|
||||||
|
* @param len - read data length
|
||||||
|
* @return success : data length error : 0
|
||||||
|
*/
|
||||||
|
int FinsRead(struct ControlProtocol *control_protocol, void *buf, size_t len)
|
||||||
|
{
|
||||||
|
struct CircularAreaApp *circular_area = (struct CircularAreaApp *)control_protocol->args;
|
||||||
|
return CircularAreaAppRead(circular_area, buf, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct ControlDone fins_protocol_done =
|
||||||
|
{
|
||||||
|
._open = FinsOpen,
|
||||||
|
._close = FinsClose,
|
||||||
|
._read = FinsRead,
|
||||||
|
._write = NULL,
|
||||||
|
._ioctl = NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: Fins Protocol Cmd Generate
|
||||||
|
* @param p_recipe - recipe pointer
|
||||||
|
* @param protocol_format_info - protocol format info pointer
|
||||||
|
* @return success : 0 error : -1
|
||||||
|
*/
|
||||||
|
int FinsProtocolFormatCmd(struct ControlRecipe *p_recipe, ProtocolFormatInfo *protocol_format_info)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
FinsReadItem *fins_read_item = (FinsReadItem *)(p_recipe->read_item) + protocol_format_info->read_item_index;
|
||||||
|
|
||||||
|
fins_read_item->value_type = cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "value_type")->valueint;
|
||||||
|
strncpy(fins_read_item->value_name, cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "value_name")->valuestring, 20);
|
||||||
|
strncpy(&fins_read_item->area_char, cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "area_char")->valuestring, 1);
|
||||||
|
fins_read_item->data_type = cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "data_type")->valueint;
|
||||||
|
fins_read_item->data_info.command_code = FINS_COMMAND_CODE_READ;
|
||||||
|
fins_read_item->start_address = cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "start_address")->valueint;
|
||||||
|
fins_read_item->bit_address = cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "bit_address")->valueint;
|
||||||
|
fins_read_item->data_length = cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "data_length")->valueint;
|
||||||
|
|
||||||
|
ret = FinsInitialDataInfo(fins_read_item,
|
||||||
|
p_recipe->socket_config.plc_ip[3],
|
||||||
|
p_recipe->socket_config.local_ip[3],
|
||||||
|
protocol_format_info->p_read_item_data + protocol_format_info->last_item_size);
|
||||||
|
|
||||||
|
ControlPrintfList("CMD", fins_read_item->data_info.base_data_info.p_command, fins_read_item->data_info.base_data_info.command_length);
|
||||||
|
protocol_format_info->last_item_size = GetValueTypeMemorySize(fins_read_item->value_type);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: Fins Protocol Init
|
||||||
|
* @param p_recipe - recipe pointer
|
||||||
|
* @return success : 0 error : -1
|
||||||
|
*/
|
||||||
|
int FinsProtocolInit(struct ControlRecipe *p_recipe)
|
||||||
|
{
|
||||||
|
p_recipe->read_item = PrivMalloc(sizeof(FinsReadItem) * p_recipe->read_item_count);
|
||||||
|
if (NULL == p_recipe->read_item) {
|
||||||
|
PrivFree(p_recipe->read_item);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
p_recipe->ControlProtocolFormatCmd = FinsProtocolFormatCmd;
|
||||||
|
|
||||||
|
p_recipe->done = &fins_protocol_done;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,331 @@
|
||||||
|
{
|
||||||
|
"device_id": 769,
|
||||||
|
"device_name": "S01",
|
||||||
|
"communication_type": 0,
|
||||||
|
"socket_config": {
|
||||||
|
"plc_ip": "192.168.250.22",
|
||||||
|
"local_ip": "192.168.250.233",
|
||||||
|
"gateway": "192.168.250.1",
|
||||||
|
"netmask": "255.255.254.0",
|
||||||
|
"port": 9600
|
||||||
|
},
|
||||||
|
"protocol_type": 5,
|
||||||
|
"read_period": 100,
|
||||||
|
"read_item_list": [
|
||||||
|
{
|
||||||
|
"value_name": "启动",
|
||||||
|
"value_type": 1,
|
||||||
|
"area_char": "W",
|
||||||
|
"data_type": 0,
|
||||||
|
"start_address": 0,
|
||||||
|
"bit_address": 0,
|
||||||
|
"data_length": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value_name": "停止",
|
||||||
|
"value_type": 1,
|
||||||
|
"area_char": "W",
|
||||||
|
"data_type": 0,
|
||||||
|
"start_address": 0,
|
||||||
|
"bit_address": 1,
|
||||||
|
"data_length": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value_name": "使能",
|
||||||
|
"value_type": 1,
|
||||||
|
"area_char": "H",
|
||||||
|
"data_type": 0,
|
||||||
|
"start_address": 0,
|
||||||
|
"bit_address": 2,
|
||||||
|
"data_length": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value_name": "回零",
|
||||||
|
"value_type": 1,
|
||||||
|
"area_char": "D",
|
||||||
|
"data_type": 0,
|
||||||
|
"start_address": 0,
|
||||||
|
"bit_address": 3,
|
||||||
|
"data_length": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value_name": "急停",
|
||||||
|
"value_type": 1,
|
||||||
|
"area_char": "W",
|
||||||
|
"data_type": 0,
|
||||||
|
"start_address": 0,
|
||||||
|
"bit_address": 4,
|
||||||
|
"data_length": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value_name": "正限位",
|
||||||
|
"value_type": 1,
|
||||||
|
"area_char": "W",
|
||||||
|
"data_type": 0,
|
||||||
|
"start_address": 10,
|
||||||
|
"bit_address": 11,
|
||||||
|
"data_length": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value_name": "负限位",
|
||||||
|
"value_type": 1,
|
||||||
|
"area_char": "W",
|
||||||
|
"data_type": 0,
|
||||||
|
"start_address": 10,
|
||||||
|
"bit_address": 12,
|
||||||
|
"data_length": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value_name": "自动运行中",
|
||||||
|
"value_type": 1,
|
||||||
|
"area_char": "W",
|
||||||
|
"data_type": 0,
|
||||||
|
"start_address": 200,
|
||||||
|
"bit_address": 5,
|
||||||
|
"data_length": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value_name": "故障",
|
||||||
|
"value_type": 1,
|
||||||
|
"area_char": "W",
|
||||||
|
"data_type": 0,
|
||||||
|
"start_address": 200,
|
||||||
|
"bit_address": 6,
|
||||||
|
"data_length": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value_name": "待机",
|
||||||
|
"value_type": 1,
|
||||||
|
"area_char": "W",
|
||||||
|
"data_type": 0,
|
||||||
|
"start_address": 200,
|
||||||
|
"bit_address": 7,
|
||||||
|
"data_length": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value_name": "手动模式",
|
||||||
|
"value_type": 1,
|
||||||
|
"area_char": "W",
|
||||||
|
"data_type": 0,
|
||||||
|
"start_address": 300,
|
||||||
|
"bit_address": 0,
|
||||||
|
"data_length": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value_name": "自动模式",
|
||||||
|
"value_type": 1,
|
||||||
|
"area_char": "W",
|
||||||
|
"data_type": 0,
|
||||||
|
"start_address": 300,
|
||||||
|
"bit_address": 1,
|
||||||
|
"data_length": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value_name": "运行方向",
|
||||||
|
"value_type": 1,
|
||||||
|
"area_char": "W",
|
||||||
|
"data_type": 0,
|
||||||
|
"start_address": 300,
|
||||||
|
"bit_address": 2,
|
||||||
|
"data_length": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value_name": "复位",
|
||||||
|
"value_type": 1,
|
||||||
|
"area_char": "W",
|
||||||
|
"data_type": 0,
|
||||||
|
"start_address": 400,
|
||||||
|
"bit_address": 3,
|
||||||
|
"data_length": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value_name": "备用1",
|
||||||
|
"value_type": 1,
|
||||||
|
"area_char": "W",
|
||||||
|
"data_type": 0,
|
||||||
|
"start_address": 400,
|
||||||
|
"bit_address": 4,
|
||||||
|
"data_length": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value_name": "产量",
|
||||||
|
"value_type": 3,
|
||||||
|
"area_char": "D",
|
||||||
|
"data_type": 1,
|
||||||
|
"start_address": 10,
|
||||||
|
"bit_address": 0,
|
||||||
|
"data_length": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value_name": "整型1",
|
||||||
|
"value_type": 3,
|
||||||
|
"area_char": "D",
|
||||||
|
"data_type": 1,
|
||||||
|
"start_address": 11,
|
||||||
|
"bit_address": 0,
|
||||||
|
"data_length": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value_name": "整型2",
|
||||||
|
"value_type": 3,
|
||||||
|
"area_char": "D",
|
||||||
|
"data_type": 1,
|
||||||
|
"start_address": 20,
|
||||||
|
"bit_address": 0,
|
||||||
|
"data_length": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value_name": "整型3",
|
||||||
|
"value_type": 3,
|
||||||
|
"area_char": "D",
|
||||||
|
"data_type": 1,
|
||||||
|
"start_address": 100,
|
||||||
|
"bit_address": 0,
|
||||||
|
"data_length": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value_name": "整型4",
|
||||||
|
"value_type": 3,
|
||||||
|
"area_char": "W",
|
||||||
|
"data_type": 1,
|
||||||
|
"start_address": 100,
|
||||||
|
"bit_address": 0,
|
||||||
|
"data_length": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value_name": "整型5",
|
||||||
|
"value_type": 3,
|
||||||
|
"area_char": "W",
|
||||||
|
"data_type": 1,
|
||||||
|
"start_address": 101,
|
||||||
|
"bit_address": 0,
|
||||||
|
"data_length": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value_name": "整型6",
|
||||||
|
"value_type": 3,
|
||||||
|
"area_char": "W",
|
||||||
|
"data_type": 1,
|
||||||
|
"start_address": 110,
|
||||||
|
"bit_address": 0,
|
||||||
|
"data_length": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value_name": "整型7",
|
||||||
|
"value_type": 3,
|
||||||
|
"area_char": "H",
|
||||||
|
"data_type": 1,
|
||||||
|
"start_address": 10,
|
||||||
|
"bit_address": 0,
|
||||||
|
"data_length": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value_name": "整型8",
|
||||||
|
"value_type": 3,
|
||||||
|
"area_char": "H",
|
||||||
|
"data_type": 1,
|
||||||
|
"start_address": 20,
|
||||||
|
"bit_address": 0,
|
||||||
|
"data_length": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value_name": "整型9",
|
||||||
|
"value_type": 3,
|
||||||
|
"area_char": "H",
|
||||||
|
"data_type": 1,
|
||||||
|
"start_address": 21,
|
||||||
|
"bit_address": 0,
|
||||||
|
"data_length": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value_name": "速度",
|
||||||
|
"value_type": 9,
|
||||||
|
"area_char": "D",
|
||||||
|
"data_type": 1,
|
||||||
|
"start_address": 2000,
|
||||||
|
"bit_address": 0,
|
||||||
|
"data_length": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value_name": "加速度",
|
||||||
|
"value_type": 9,
|
||||||
|
"area_char": "D",
|
||||||
|
"data_type": 1,
|
||||||
|
"start_address": 2002,
|
||||||
|
"bit_address": 0,
|
||||||
|
"data_length": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value_name": "减速度",
|
||||||
|
"value_type": 9,
|
||||||
|
"area_char": "D",
|
||||||
|
"data_type": 1,
|
||||||
|
"start_address": 2004,
|
||||||
|
"bit_address": 0,
|
||||||
|
"data_length": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value_name": "起始位置",
|
||||||
|
"value_type": 9,
|
||||||
|
"area_char": "D",
|
||||||
|
"data_type": 1,
|
||||||
|
"start_address": 300,
|
||||||
|
"bit_address": 0,
|
||||||
|
"data_length": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value_name": "终点位置",
|
||||||
|
"value_type": 9,
|
||||||
|
"area_char": "D",
|
||||||
|
"data_type": 1,
|
||||||
|
"start_address": 302,
|
||||||
|
"bit_address": 0,
|
||||||
|
"data_length": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value_name": "张力值",
|
||||||
|
"value_type": 9,
|
||||||
|
"area_char": "W",
|
||||||
|
"data_type": 1,
|
||||||
|
"start_address": 80,
|
||||||
|
"bit_address": 0,
|
||||||
|
"data_length": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value_name": "浮点型1",
|
||||||
|
"value_type": 8,
|
||||||
|
"area_char": "H",
|
||||||
|
"data_type": 1,
|
||||||
|
"start_address": 100,
|
||||||
|
"bit_address": 0,
|
||||||
|
"data_length": 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value_name": "浮点型2",
|
||||||
|
"value_type": 8,
|
||||||
|
"area_char": "H",
|
||||||
|
"data_type": 1,
|
||||||
|
"start_address": 104,
|
||||||
|
"bit_address": 0,
|
||||||
|
"data_length": 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value_name": "浮点型3",
|
||||||
|
"value_type": 8,
|
||||||
|
"area_char": "H",
|
||||||
|
"data_type": 1,
|
||||||
|
"start_address": 108,
|
||||||
|
"bit_address": 0,
|
||||||
|
"data_length": 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value_name": "浮点型4",
|
||||||
|
"value_type": 8,
|
||||||
|
"area_char": "H",
|
||||||
|
"data_type": 1,
|
||||||
|
"start_address": 112,
|
||||||
|
"bit_address": 0,
|
||||||
|
"data_length": 4
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,86 @@
|
||||||
|
/*
|
||||||
|
* 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 fins.h
|
||||||
|
* @brief plc protocol fins
|
||||||
|
* @version 3.0
|
||||||
|
* @author AIIT XUOS Lab
|
||||||
|
* @date 2022-10-08
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef FINS_H
|
||||||
|
#define FINS_H
|
||||||
|
|
||||||
|
#include <control_def.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define FINS_HEADER_HEAD 0x46494E53
|
||||||
|
#define FINS_HEADER_READ_COMMAND_LENGTH 0x0000001A
|
||||||
|
#define FINS_HEADER_COMMAND 0x00000002
|
||||||
|
#define FINS_HEADER_ERROR_CODE 0x00000000
|
||||||
|
#define FINS_ICF 0x80
|
||||||
|
#define FINS_RSV 0x00
|
||||||
|
#define FINS_REPLY_ICF 0xC0
|
||||||
|
#define FINS_GCT 0x02
|
||||||
|
#define FINS_DNA 0x00
|
||||||
|
#define FINS_DA2 0x00
|
||||||
|
#define FINS_SNA 0x00
|
||||||
|
#define FINS_SA2 0x00
|
||||||
|
#define FINS_SID 0x00
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
FINS_COMMAND_CODE_READ = 0x0101,
|
||||||
|
FINS_COMMAND_CODE_WRITE = 0x0102
|
||||||
|
}FinsCommandCode;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
FINS_DATA_TYPE_BIT,
|
||||||
|
FINS_DATA_TYPE_WORD
|
||||||
|
}FinsDataType;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
BasicPlcDataInfo base_data_info;
|
||||||
|
FinsCommandCode command_code;
|
||||||
|
}FinsDataInfo;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int32_t socket;
|
||||||
|
uint16_t plc_ip_4;
|
||||||
|
}FinsHandshakeParameter;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
FinsDataInfo data_info;
|
||||||
|
|
||||||
|
UniformValueType value_type;
|
||||||
|
uint8_t value_name[20];
|
||||||
|
|
||||||
|
uint8_t area_char;
|
||||||
|
FinsDataType data_type;
|
||||||
|
uint16_t start_address;
|
||||||
|
uint8_t bit_address;
|
||||||
|
uint16_t data_length;
|
||||||
|
}FinsReadItem;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
8
APP_Framework/Framework/control/shared/control_file.c → APP_Framework/Framework/control/plc_protocol/include/melsec.h
Executable file → Normal file
8
APP_Framework/Framework/control/shared/control_file.c → APP_Framework/Framework/control/plc_protocol/include/melsec.h
Executable file → Normal file
|
@ -11,11 +11,9 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file control_file.c
|
* @file melsec.h
|
||||||
* @brief control relative file operation
|
* @brief plc protocol melsec
|
||||||
* @version 3.0
|
* @version 3.0
|
||||||
* @author AIIT XUOS Lab
|
* @author AIIT XUOS Lab
|
||||||
* @date 2022-09-37
|
* @date 2022-10-08
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
13
APP_Framework/Framework/control/shared/control_file.h → APP_Framework/Framework/control/plc_protocol/include/opcua.h
Executable file → Normal file
13
APP_Framework/Framework/control/shared/control_file.h → APP_Framework/Framework/control/plc_protocol/include/opcua.h
Executable file → Normal file
|
@ -11,16 +11,9 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file control_file.h
|
* @file opcua.h
|
||||||
* @brief control file function relative API
|
* @brief control protocol opcua
|
||||||
* @version 3.0
|
* @version 3.0
|
||||||
* @author AIIT XUOS Lab
|
* @author AIIT XUOS Lab
|
||||||
* @date 2022-09-27
|
* @date 2022-10-08
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef CONTROL_FILE_H
|
|
||||||
#define CONTROL_FILE_H
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
/*
|
||||||
|
* 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 s7.h
|
||||||
|
* @brief plc protocol s7
|
||||||
|
* @version 3.0
|
||||||
|
* @author AIIT XUOS Lab
|
||||||
|
* @date 2022-10-08
|
||||||
|
*/
|
|
@ -1,8 +1,4 @@
|
||||||
SRC_FILES := control.c
|
SRC_FILES := control.c control_def.c control_io.c
|
||||||
|
|
||||||
ifeq ($(CONFIG_MOUNT_SDCARD),y)
|
|
||||||
SRC_FILES += control_file.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
include $(KERNEL_ROOT)/compiler.mk
|
include $(KERNEL_ROOT)/compiler.mk
|
||||||
|
|
||||||
|
|
|
@ -1,38 +0,0 @@
|
||||||
{
|
|
||||||
"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"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -12,16 +12,278 @@
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file control.c
|
* @file control.c
|
||||||
* @brief control framework code
|
* @brief code for control framework app
|
||||||
* @version 3.0
|
* @version 3.0
|
||||||
* @author AIIT XUOS Lab
|
* @author AIIT XUOS Lab
|
||||||
* @date 2022-09-27
|
* @date 2022-09-27
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <control.h>
|
#include <control.h>
|
||||||
|
#include <control_def.h>
|
||||||
|
|
||||||
void control_init(void)
|
ControlProtocolType control_protocol;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: Control Framework Find certain Protocol
|
||||||
|
* @param void
|
||||||
|
* @return Control Protocol pointer
|
||||||
|
*/
|
||||||
|
ControlProtocolType ControlProtocolFind(void)
|
||||||
{
|
{
|
||||||
//to do
|
return control_protocol;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: Control Framework Protocol Init
|
||||||
|
* @param control_protocol - control protocol pointer
|
||||||
|
* @return success : 0 error : -1
|
||||||
|
*/
|
||||||
|
static int ControlProtocolInit(ControlProtocolType control_protocol)
|
||||||
|
{
|
||||||
|
CONTROL_PARAM_CHECK(control_protocol);
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
control_protocol->protocol_status = CONTROL_INIT;
|
||||||
|
|
||||||
|
ret = PrivMutexCreate(&control_protocol->lock, 0);
|
||||||
|
if(ret < 0) {
|
||||||
|
printf("ControlProtocolInit mutex create failed.\n");
|
||||||
|
goto _out;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = PrivSemaphoreCreate(&control_protocol->sem, 0, 0);
|
||||||
|
if (ret < 0) {
|
||||||
|
printf("ControlProtocolInit create sem error\n");
|
||||||
|
goto _out;
|
||||||
|
}
|
||||||
|
|
||||||
|
_out:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: Analyze Recipe
|
||||||
|
* @param control_protocol - Control Protocol pointer
|
||||||
|
* @param recipe_name - recipe name
|
||||||
|
* @return success : 0 error : -1
|
||||||
|
*/
|
||||||
|
static int ControlAnalyzeRecipe(ControlProtocolType control_protocol, const char *recipe_name)
|
||||||
|
{
|
||||||
|
int recipe_file_fd = -1;
|
||||||
|
struct stat recipe_file_status;
|
||||||
|
uint16_t recipe_file_length = 0;
|
||||||
|
char *recipe_file_buf;
|
||||||
|
|
||||||
|
/*wait for SD-card mount done*/
|
||||||
|
PrivTaskDelay(5000);
|
||||||
|
|
||||||
|
//Step1 : read recipe file data from SD card or other store device
|
||||||
|
recipe_file_fd = PrivOpen(recipe_name, O_RDONLY);
|
||||||
|
if (recipe_file_fd < 0) {
|
||||||
|
printf("Open recipe file %s failed\n", recipe_name);
|
||||||
|
PrivClose(recipe_file_fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 != fstat(recipe_file_fd, &recipe_file_status)) {
|
||||||
|
printf("Get recipe file information failed!\n");
|
||||||
|
PrivClose(recipe_file_fd);
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
recipe_file_length = recipe_file_status.st_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
recipe_file_buf = PrivMalloc(recipe_file_length);
|
||||||
|
if (NULL == recipe_file_buf) {
|
||||||
|
printf("Get recipe file memory failed!\n");
|
||||||
|
PrivFree(recipe_file_buf);
|
||||||
|
PrivClose(recipe_file_fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PrivRead(recipe_file_fd, recipe_file_buf, recipe_file_length) < 0) {
|
||||||
|
printf("Read recipe file failed!\n");
|
||||||
|
PrivFree(recipe_file_buf);
|
||||||
|
PrivClose(recipe_file_fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
PrivClose(recipe_file_fd);
|
||||||
|
|
||||||
|
//Step2 : CJSON analyze
|
||||||
|
#ifdef LIB_USING_CJSON
|
||||||
|
cJSON *recipe_file_json = cJSON_Parse(recipe_file_buf);
|
||||||
|
if (NULL == recipe_file_json) {
|
||||||
|
printf("Parse recipe_file_buf failed!\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
control_protocol->recipe = (struct ControlRecipe *)PrivMalloc(sizeof(struct ControlRecipe));
|
||||||
|
memset(control_protocol->recipe, 0, sizeof(struct ControlRecipe));
|
||||||
|
|
||||||
|
/*Get basic information from recipe file*/
|
||||||
|
if (RecipeBasicInformation(control_protocol->recipe, recipe_file_json) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
control_protocol->protocol_type = control_protocol->recipe->protocol_type;
|
||||||
|
|
||||||
|
/*Get the variable need to read from recipe file*/
|
||||||
|
RecipeReadVariableItem(control_protocol->recipe, recipe_file_json);
|
||||||
|
|
||||||
|
control_protocol->done = control_protocol->recipe->done;
|
||||||
|
|
||||||
|
cJSON_Delete(recipe_file_json);
|
||||||
|
|
||||||
|
PrivFree(recipe_file_buf);
|
||||||
|
printf("Read and parse recipe file done!\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: Control Framework Protocol Open
|
||||||
|
* @param control_protocol - Control Protocol pointer
|
||||||
|
* @return success : 0 error : -1
|
||||||
|
*/
|
||||||
|
int ControlProtocolOpen(struct ControlProtocol *control_protocol)
|
||||||
|
{
|
||||||
|
CONTROL_PARAM_CHECK(control_protocol);
|
||||||
|
CONTROL_PARAM_CHECK(control_protocol->done);
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
if (control_protocol->done->_open) {
|
||||||
|
ret = control_protocol->done->_open(control_protocol);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: Control Framework Protocol Close
|
||||||
|
* @param control_protocol - Control Protocol pointer
|
||||||
|
* @return success : 0 error : -1
|
||||||
|
*/
|
||||||
|
int ControlProtocolClose(struct ControlProtocol *control_protocol)
|
||||||
|
{
|
||||||
|
CONTROL_PARAM_CHECK(control_protocol);
|
||||||
|
CONTROL_PARAM_CHECK(control_protocol->done);
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
if (control_protocol->done->_close) {
|
||||||
|
ret = control_protocol->done->_close(control_protocol);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: Control Framework Protocol Read Data
|
||||||
|
* @param control_protocol - Control Protocol pointer
|
||||||
|
* @param buf - read buffer
|
||||||
|
* @param len - read data length
|
||||||
|
* @return success : data length error : -1
|
||||||
|
*/
|
||||||
|
int ControlProtocolRead(struct ControlProtocol *control_protocol, void *buf, size_t len)
|
||||||
|
{
|
||||||
|
CONTROL_PARAM_CHECK(control_protocol);
|
||||||
|
CONTROL_PARAM_CHECK(control_protocol->done);
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
if (control_protocol->done->_read) {
|
||||||
|
ret = control_protocol->done->_read(control_protocol, buf, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: Control Framework Protocol Write Cmd
|
||||||
|
* @param control_protocol - Control Protocol pointer
|
||||||
|
* @param buf - write buffer
|
||||||
|
* @param len - write data length
|
||||||
|
* @return success : data length error : -1
|
||||||
|
*/
|
||||||
|
int ControlProtocolWrite(struct ControlProtocol *control_protocol, const void *buf, size_t len)
|
||||||
|
{
|
||||||
|
CONTROL_PARAM_CHECK(control_protocol);
|
||||||
|
CONTROL_PARAM_CHECK(control_protocol->done);
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
if (control_protocol->done->_write) {
|
||||||
|
ret = control_protocol->done->_write(control_protocol, buf, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: Control Framework Protocol Ioctl
|
||||||
|
* @param control_protocol - Control Protocol pointer
|
||||||
|
* @param cmd - ioctl cmd
|
||||||
|
* @param args - args
|
||||||
|
* @return success : 0 error : -1
|
||||||
|
*/
|
||||||
|
int ControlProtocolIoctl(struct ControlProtocol *control_protocol, int cmd, void *args)
|
||||||
|
{
|
||||||
|
CONTROL_PARAM_CHECK(control_protocol);
|
||||||
|
CONTROL_PARAM_CHECK(control_protocol->done);
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
if (control_protocol->done->_ioctl) {
|
||||||
|
ret = control_protocol->done->_ioctl(control_protocol, cmd, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: Control Framework Init
|
||||||
|
* @param void
|
||||||
|
* @return success : 0 error : -1
|
||||||
|
*/
|
||||||
|
int ControlFrameworkInit(void)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
control_protocol = (struct ControlProtocol *)PrivMalloc(sizeof(struct ControlProtocol));
|
||||||
|
if (NULL == control_protocol) {
|
||||||
|
printf("%s malloc control protocol failed!\n", __func__);
|
||||||
|
PrivFree(control_protocol);
|
||||||
|
ret = -1;
|
||||||
|
goto _out;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Control Protocol Struct Init
|
||||||
|
ret = ControlProtocolInit(control_protocol);
|
||||||
|
if (ret < 0) {
|
||||||
|
printf("%s failed!\n", __func__);
|
||||||
|
PrivFree(control_protocol);
|
||||||
|
goto _out;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("%s malloc CONTROL_RECIPE_FILE %s\n", __func__, CONTROL_RECIPE_FILE);
|
||||||
|
|
||||||
|
//Read Recipe File, Get Control Protocol Configure Param
|
||||||
|
ret = ControlAnalyzeRecipe(control_protocol, CONTROL_RECIPE_FILE);
|
||||||
|
if (ret < 0) {
|
||||||
|
printf("%s failed!\n", __func__);
|
||||||
|
PrivFree(control_protocol);
|
||||||
|
goto _out;
|
||||||
|
}
|
||||||
|
|
||||||
|
control_protocol->protocol_status = CONTROL_REGISTERED;
|
||||||
|
|
||||||
|
ret = ControlPeripheralInit(control_protocol->recipe);
|
||||||
|
if (ret < 0) {
|
||||||
|
printf("%s failed!\n", __func__);
|
||||||
|
PrivFree(control_protocol);
|
||||||
|
goto _out;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("%s ControlPeripheralInit done\n", __func__);
|
||||||
|
|
||||||
|
_out:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
|
@ -12,13 +12,95 @@
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file control.h
|
* @file control.h
|
||||||
* @brief control framework code
|
* @brief DEFINE code for control framework app
|
||||||
* @version 3.0
|
* @version 3.0
|
||||||
* @author AIIT XUOS Lab
|
* @author AIIT XUOS Lab
|
||||||
* @date 2022-09-27
|
* @date 2022-09-27
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <control_file.h>
|
#ifndef CONTROL_H
|
||||||
#include <cJSON.h>
|
#define CONTROL_H
|
||||||
|
|
||||||
|
#include <transform.h>
|
||||||
|
#include <list.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct ControlProtocol;
|
||||||
|
typedef struct ControlProtocol *ControlProtocolType;
|
||||||
|
|
||||||
|
struct ControlDone
|
||||||
|
{
|
||||||
|
int (*_open)(struct ControlProtocol *control_protocol);
|
||||||
|
int (*_close)(struct ControlProtocol *control_protocol);
|
||||||
|
int (*_read)(struct ControlProtocol *control_protocol, void *buf, size_t len);
|
||||||
|
int (*_write)(struct ControlProtocol *control_protocol, const void *buf, size_t len);
|
||||||
|
int (*_ioctl)(struct ControlProtocol *control_protocol, int cmd, void *args);
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
PROTOCOL_S7 = 1,
|
||||||
|
PROTOCOL_MODBUS_TCP,
|
||||||
|
PROTOCOL_MODBUS_UART,
|
||||||
|
PROTOCOL_OPC_UA,
|
||||||
|
PROTOCOL_FINS,
|
||||||
|
PROTOCOL_MELSEC_1E,
|
||||||
|
PROTOCOL_MELSEC_3E_Q_L,
|
||||||
|
PROTOCOL_MELSEC_3E_IQ_R,
|
||||||
|
PROTOCOL_MELSEC_1C,
|
||||||
|
PROTOCOL_MELSEC_3C,
|
||||||
|
PROTOCOL_END
|
||||||
|
}ProtocolType;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
CONTROL_INIT,
|
||||||
|
CONTROL_REGISTERED,
|
||||||
|
CONTROL_UNREGISTERED,
|
||||||
|
}ProtocolStatus;
|
||||||
|
|
||||||
|
struct ControlProtocol
|
||||||
|
{
|
||||||
|
char *name;
|
||||||
|
ProtocolType protocol_type;
|
||||||
|
ProtocolStatus protocol_status;
|
||||||
|
|
||||||
|
struct ControlRecipe *recipe;
|
||||||
|
struct ControlDone *done;
|
||||||
|
|
||||||
|
void *args;
|
||||||
|
|
||||||
|
sem_t sem;
|
||||||
|
pthread_mutex_t lock;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*Control Framework Protocol Init*/
|
||||||
|
int ControlFrameworkInit(void);
|
||||||
|
|
||||||
|
/*Control Framework Find certain Protocol*/
|
||||||
|
ControlProtocolType ControlProtocolFind(void);
|
||||||
|
|
||||||
|
/*Control Framework Protocol Open*/
|
||||||
|
int ControlProtocolOpen(struct ControlProtocol *control_protocol);
|
||||||
|
|
||||||
|
/*Control Framework Protocol Close*/
|
||||||
|
int ControlProtocolClose(struct ControlProtocol *control_protocol);
|
||||||
|
|
||||||
|
/*Control Framework Protocol Read*/
|
||||||
|
int ControlProtocolRead(struct ControlProtocol *control_protocol, void *buf, size_t len);
|
||||||
|
|
||||||
|
/*Control Framework Protocol Write*/
|
||||||
|
int ControlProtocolWrite(struct ControlProtocol *control_protocol, const void *buf, size_t len);
|
||||||
|
|
||||||
|
/*Control Framework Protocol Ioctl*/
|
||||||
|
int ControlProtocolIoctl(struct ControlProtocol *control_protocol, int cmd, void *args);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,446 @@
|
||||||
|
/*
|
||||||
|
* 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 control_def.c
|
||||||
|
* @brief code for control framework
|
||||||
|
* @version 3.0
|
||||||
|
* @author AIIT XUOS Lab
|
||||||
|
* @date 2022-10-9
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <control_def.h>
|
||||||
|
#include <control_io.h>
|
||||||
|
|
||||||
|
/*using cirtular area to receive data*/
|
||||||
|
#define PLC_DATA_LENGTH 1024
|
||||||
|
struct CircularAreaApp *g_circular_area;
|
||||||
|
static pthread_t recv_plc_data_task;
|
||||||
|
|
||||||
|
/*extern function*/
|
||||||
|
extern void *ReceivePlcDataTask(void *parameter);
|
||||||
|
|
||||||
|
#ifdef CONTROL_PROTOCOL_FINS
|
||||||
|
extern int FinsProtocolInit(struct ControlRecipe *p_recipe);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
CONTROL FRAMEWORK READ DATA FORMAT:
|
||||||
|
| HEAD |device_id|read data length|read item count| data |
|
||||||
|
|2 Bytes| 2 Bytes | 2 Bytes | 2 Bytes |read data length Bytes|
|
||||||
|
*/
|
||||||
|
#define CONTROL_DATA_HEAD_LENGTH 8
|
||||||
|
#define CONTROL_DATA_HEAD_1 0xAA
|
||||||
|
#define CONTROL_DATA_HEAD_2 0xBB
|
||||||
|
|
||||||
|
typedef int (*ControlProtocolInitFunc)(struct ControlRecipe *p_recipe);
|
||||||
|
|
||||||
|
struct ControlProtocolInitParam
|
||||||
|
{
|
||||||
|
int protocol_type;
|
||||||
|
const ControlProtocolInitFunc fn;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct ControlProtocolInitParam protocol_init[] =
|
||||||
|
{
|
||||||
|
#ifdef CONTROL_PROTOCOL_FINS
|
||||||
|
{ PROTOCOL_FINS, FinsProtocolInit },
|
||||||
|
#endif
|
||||||
|
|
||||||
|
{ PROTOCOL_END, NULL },
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: Control Framework Sub_Protocol Desc Init
|
||||||
|
* @param p_recipe - Control recipe pointer
|
||||||
|
* @param sub_protocol_desc - sub_protocol desc
|
||||||
|
* @return success : 0 error : -1
|
||||||
|
*/
|
||||||
|
static int ControlProtocolInitDesc(struct ControlRecipe *p_recipe, struct ControlProtocolInitParam sub_protocol_desc[])
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
int ret = 0;
|
||||||
|
for( i = 0; sub_protocol_desc[i].fn != NULL; i++ ) {
|
||||||
|
if (p_recipe->protocol_type == sub_protocol_desc[i].protocol_type) {
|
||||||
|
ret = sub_protocol_desc[i].fn(p_recipe);
|
||||||
|
printf("%s initialize %d %s\n", __func__, sub_protocol_desc[i].protocol_type, ret == 0 ? "success" : "failed");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: Control Framework Protocol Data Header Format
|
||||||
|
* @param p_recipe - Control recipe pointer
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
static void FormatDataHeader(struct ControlRecipe *p_recipe)
|
||||||
|
{
|
||||||
|
uint16_t plc_read_data_length = CONTROL_DATA_HEAD_LENGTH + p_recipe->total_data_length;//Head length is CONTROL_DATA_HEAD_LENGTH
|
||||||
|
uint8_t *data = p_recipe->protocol_data.data;
|
||||||
|
|
||||||
|
data[0] = CONTROL_DATA_HEAD_1;
|
||||||
|
data[1] = CONTROL_DATA_HEAD_2;
|
||||||
|
data[2] = (uint8_t)(p_recipe->device_id >> 8);
|
||||||
|
data[3] = (uint8_t)p_recipe->device_id;
|
||||||
|
data[4] = (uint8_t)(plc_read_data_length >> 8);
|
||||||
|
data[5] = (uint8_t)plc_read_data_length;
|
||||||
|
data[6] = (uint8_t)(p_recipe->read_item_count >> 8);
|
||||||
|
data[7] = (uint8_t)p_recipe->read_item_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: Get Recipe Total Data Length
|
||||||
|
* @param read_item_list_json - read_item_list_json pointer
|
||||||
|
* @return success : total_data_length error : 0
|
||||||
|
*/
|
||||||
|
static uint16_t GetRecipeTotalDataLength(cJSON* read_item_list_json)
|
||||||
|
{
|
||||||
|
uint16_t read_item_count = cJSON_GetArraySize(read_item_list_json);
|
||||||
|
uint16_t total_data_length = 0;
|
||||||
|
for (uint16_t read_item_index = 0; read_item_index < read_item_count; read_item_index++) {
|
||||||
|
cJSON* read_item_json = cJSON_GetArrayItem(read_item_list_json, read_item_index);
|
||||||
|
UniformValueType value_type = cJSON_GetObjectItem(read_item_json, "value_type")->valueint;
|
||||||
|
total_data_length += GetValueTypeMemorySize(value_type);
|
||||||
|
}
|
||||||
|
return total_data_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: Control Framework Basic Serial Configure
|
||||||
|
* @param p_recipe - Control recipe pointer
|
||||||
|
* @param p_recipe_file_json - p_recipe_file_json pointer
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
static void ControlBasicSerialConfig(struct ControlRecipe *p_recipe, cJSON *p_recipe_file_json)
|
||||||
|
{
|
||||||
|
cJSON *p_serial_config_json = cJSON_GetObjectItem(p_recipe_file_json, "serial_config");
|
||||||
|
p_recipe->serial_config.baud_rate = cJSON_GetObjectItem(p_serial_config_json, "baud_rate")->valueint;
|
||||||
|
p_recipe->serial_config.data_bits = cJSON_GetObjectItem(p_serial_config_json, "data_bits")->valueint;
|
||||||
|
p_recipe->serial_config.stop_bits = cJSON_GetObjectItem(p_serial_config_json, "stop_bits")->valueint;
|
||||||
|
p_recipe->serial_config.check_mode = cJSON_GetObjectItem(p_serial_config_json, "check_mode")->valueint;
|
||||||
|
printf("Serial_config: baud_rate: %d, data_bits: %d, stop_bits: %d, check_mode is %d\n",
|
||||||
|
p_recipe->serial_config.baud_rate, p_recipe->serial_config.data_bits, p_recipe->serial_config.stop_bits, p_recipe->serial_config.check_mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: Control Framework Basic Socket Configure
|
||||||
|
* @param p_recipe - Control recipe pointer
|
||||||
|
* @param p_recipe_file_json - p_recipe_file_json pointer
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
static void ControlBasicSocketConfig(struct ControlRecipe *p_recipe, cJSON *p_recipe_file_json)
|
||||||
|
{
|
||||||
|
cJSON *p_socket_address_json = cJSON_GetObjectItem(p_recipe_file_json, "socket_config");
|
||||||
|
char *plc_ip_string = cJSON_GetObjectItem(p_socket_address_json, "plc_ip")->valuestring;
|
||||||
|
sscanf(plc_ip_string, "%d.%d.%d.%d",
|
||||||
|
p_recipe->socket_config.plc_ip,
|
||||||
|
p_recipe->socket_config.plc_ip + 1,
|
||||||
|
p_recipe->socket_config.plc_ip + 2,
|
||||||
|
p_recipe->socket_config.plc_ip + 3);
|
||||||
|
|
||||||
|
char *local_ip_string = cJSON_GetObjectItem(p_socket_address_json, "local_ip")->valuestring;
|
||||||
|
sscanf(local_ip_string, "%d.%d.%d.%d",
|
||||||
|
p_recipe->socket_config.local_ip,
|
||||||
|
p_recipe->socket_config.local_ip + 1,
|
||||||
|
p_recipe->socket_config.local_ip + 2,
|
||||||
|
p_recipe->socket_config.local_ip + 3);
|
||||||
|
|
||||||
|
char *gateway_ip_string = cJSON_GetObjectItem(p_socket_address_json, "gateway")->valuestring;
|
||||||
|
sscanf(gateway_ip_string, "%d.%d.%d.%d",
|
||||||
|
p_recipe->socket_config.gateway,
|
||||||
|
p_recipe->socket_config.gateway + 1,
|
||||||
|
p_recipe->socket_config.gateway + 2,
|
||||||
|
p_recipe->socket_config.gateway + 3);
|
||||||
|
|
||||||
|
char *netmask_string = cJSON_GetObjectItem(p_socket_address_json, "netmask")->valuestring;
|
||||||
|
sscanf(netmask_string, "%d.%d.%d.%d",
|
||||||
|
p_recipe->socket_config.netmask,
|
||||||
|
p_recipe->socket_config.netmask + 1,
|
||||||
|
p_recipe->socket_config.netmask + 2,
|
||||||
|
p_recipe->socket_config.netmask + 3);
|
||||||
|
|
||||||
|
p_recipe->socket_config.port = cJSON_GetObjectItem(p_socket_address_json, "port")->valueint;
|
||||||
|
printf("Socket_config: local ip is %s, plc ip is %s, gateway is %s, port is %d.\n",
|
||||||
|
local_ip_string, plc_ip_string, gateway_ip_string, p_recipe->socket_config.port);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: Control Framework Printf List Function
|
||||||
|
* @param name - printf function name
|
||||||
|
* @param number_list - number_list pointer
|
||||||
|
* @param length - number_list length
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
void ControlPrintfList(char name[5], uint8_t *number_list, uint16_t length)
|
||||||
|
{
|
||||||
|
printf("\n******************%5s****************\n", name);
|
||||||
|
for (int32_t i = 0;i < length;i ++) {
|
||||||
|
printf("0x%x ", number_list[i]);
|
||||||
|
}
|
||||||
|
printf("\n**************************************\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: Control Framework Connect Socket
|
||||||
|
* @param p_plc - basic socket plc pointer
|
||||||
|
* @return success : 0 error : -1 -2 -3 -4 -5
|
||||||
|
*/
|
||||||
|
int ControlConnectSocket(BasicSocketPlc *p_plc)
|
||||||
|
{
|
||||||
|
if (p_plc->socket >= 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
struct sockaddr_in plc_addr_in;
|
||||||
|
plc_addr_in.sin_family = AF_INET;
|
||||||
|
plc_addr_in.sin_port = htons(p_plc->port);
|
||||||
|
|
||||||
|
char ip_string[20] = {0};
|
||||||
|
sprintf(ip_string, "%u.%u.%u.%u", p_plc->ip[0], p_plc->ip[1], p_plc->ip[2], p_plc->ip[3]);
|
||||||
|
plc_addr_in.sin_addr.s_addr = inet_addr(ip_string);
|
||||||
|
memset(&(plc_addr_in.sin_zero), 0, sizeof(plc_addr_in.sin_zero));
|
||||||
|
|
||||||
|
int plc_socket = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
int flag = 1;
|
||||||
|
|
||||||
|
struct timeval timeout;
|
||||||
|
timeout.tv_sec = 10;
|
||||||
|
timeout.tv_usec = 0;
|
||||||
|
if (setsockopt(plc_socket, IPPROTO_TCP, TCP_NODELAY, (void*)&flag, sizeof(flag)) < 0) {
|
||||||
|
printf("Error setting TCP_NODELAY function!\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (setsockopt(plc_socket, SOL_SOCKET, SO_SNDTIMEO, (char*)&timeout, (socklen_t)sizeof(struct timeval)) < 0) {
|
||||||
|
printf("Error setting SO_SNDTIMEO function!\n");
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (setsockopt(plc_socket, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, (socklen_t)sizeof(struct timeval)) < 0) {
|
||||||
|
printf("Error setting SO_RCVTIMEO function!\n");
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (plc_socket < 0) {
|
||||||
|
printf("Get socket error!\n");
|
||||||
|
return -4;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("%s %d ip %u.%u.%u.%u port %d\n", __func__, __LINE__,
|
||||||
|
p_plc->ip[0], p_plc->ip[1], p_plc->ip[2], p_plc->ip[3],
|
||||||
|
p_plc->port);
|
||||||
|
|
||||||
|
if (connect(plc_socket, (struct sockaddr*)&plc_addr_in, sizeof(struct sockaddr)) == -1) {
|
||||||
|
printf("Connect plc socket failed!errno %d\n", errno);
|
||||||
|
closesocket(plc_socket);
|
||||||
|
return -5;
|
||||||
|
} else {
|
||||||
|
p_plc->socket = plc_socket;
|
||||||
|
printf("Connect plc socket success!\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: Control Framework Disconnect Socket
|
||||||
|
* @param p_plc - basic socket plc pointer
|
||||||
|
* @return success : 0 error : -1
|
||||||
|
*/
|
||||||
|
int ControlDisconnectSocket(BasicSocketPlc *p_plc)
|
||||||
|
{
|
||||||
|
if (p_plc->socket < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
int error = closesocket(p_plc->socket);
|
||||||
|
if (0 == error)
|
||||||
|
p_plc->socket = -1;
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: Control Framework Protocol Open for Sub_Protocol, Init Circular Area and Receive Data Task
|
||||||
|
* @param control_protocol - Control protocol pointer
|
||||||
|
* @return success : 0 error : -1
|
||||||
|
*/
|
||||||
|
int ControlProtocolOpenDef(struct ControlProtocol *control_protocol)
|
||||||
|
{
|
||||||
|
g_circular_area = CircularAreaAppInit(PLC_DATA_LENGTH);
|
||||||
|
if (NULL == g_circular_area) {
|
||||||
|
printf("%s CircularAreaInit error\n", __func__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
control_protocol->args = (void *)g_circular_area;
|
||||||
|
|
||||||
|
pthread_attr_t attr;
|
||||||
|
attr.schedparam.sched_priority = 19;
|
||||||
|
attr.stacksize = 2048;
|
||||||
|
|
||||||
|
PrivTaskCreate(&recv_plc_data_task, &attr, &ReceivePlcDataTask, control_protocol);
|
||||||
|
PrivTaskStartup(&recv_plc_data_task);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: Control Framework Protocol Open for Sub_Protocol, Release Circular Area and Delete Receive Data Task
|
||||||
|
* @param void
|
||||||
|
* @return success : 0 error : -1
|
||||||
|
*/
|
||||||
|
int ControlProtocolCloseDef(void)
|
||||||
|
{
|
||||||
|
CircularAreaAppRelease(g_circular_area);
|
||||||
|
|
||||||
|
PrivTaskDelete(recv_plc_data_task, 0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: Control Framework Get Value Memory Size From Recipe File
|
||||||
|
* @param uniform_value_type - uniform value type
|
||||||
|
* @return success : size error : 0
|
||||||
|
*/
|
||||||
|
uint8_t GetValueTypeMemorySize(UniformValueType uniform_value_type)
|
||||||
|
{
|
||||||
|
switch (uniform_value_type)
|
||||||
|
{
|
||||||
|
case UNIFORM_BOOL:
|
||||||
|
case UNIFORM_INT8:
|
||||||
|
case UNIFORM_UINT8:
|
||||||
|
return 1;
|
||||||
|
break;
|
||||||
|
case UNIFORM_INT16:
|
||||||
|
case UNIFORM_UINT16:
|
||||||
|
return 2;
|
||||||
|
break;
|
||||||
|
case UNIFORM_INT32:
|
||||||
|
case UNIFORM_UINT32:
|
||||||
|
case UNIFORM_FLOAT:
|
||||||
|
return 4;
|
||||||
|
break;
|
||||||
|
case UNIFORM_DOUBLE:
|
||||||
|
return 8;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: Control Framework Peripheral Device Init
|
||||||
|
* @param p_recipe - Control recipe pointer
|
||||||
|
* @return success : 0 error :
|
||||||
|
*/
|
||||||
|
int ControlPeripheralInit(struct ControlRecipe *p_recipe)
|
||||||
|
{
|
||||||
|
switch (p_recipe->communication_type)
|
||||||
|
{
|
||||||
|
case 0://Socket Init
|
||||||
|
SocketInit(p_recipe->socket_config.local_ip, p_recipe->socket_config.netmask, p_recipe->socket_config.gateway);
|
||||||
|
break;
|
||||||
|
case 1://Serial Init
|
||||||
|
SerialInit(p_recipe->serial_config.baud_rate, p_recipe->serial_config.data_bits, p_recipe->serial_config.stop_bits, p_recipe->serial_config.check_mode);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: Control Framework Get Recipe Basic Information
|
||||||
|
* @param p_recipe - Control recipe pointer
|
||||||
|
* @param p_recipe_file_json - recipe_file_json pointer
|
||||||
|
* @return success : 0 error : -1
|
||||||
|
*/
|
||||||
|
int RecipeBasicInformation(struct ControlRecipe *p_recipe, cJSON *p_recipe_file_json)
|
||||||
|
{
|
||||||
|
p_recipe->protocol_type = (ProtocolType)(cJSON_GetObjectItem(p_recipe_file_json, "protocol_type")->valueint);
|
||||||
|
|
||||||
|
p_recipe->device_id = cJSON_GetObjectItem(p_recipe_file_json, "device_id")->valueint;
|
||||||
|
strncpy(p_recipe->device_name, cJSON_GetObjectItem(p_recipe_file_json, "device_name")->valuestring, 20);
|
||||||
|
p_recipe->read_period = cJSON_GetObjectItem(p_recipe_file_json, "read_period")->valueint;
|
||||||
|
p_recipe->communication_type = cJSON_GetObjectItem(p_recipe_file_json, "communication_type")->valueint;
|
||||||
|
|
||||||
|
printf("\n**************** RECIPE BASIC INFORMATION ******************\n");
|
||||||
|
printf("\nprotocol_type: %d, communication_type: %d, device_id: %d, device_name: %s, read_period is %d\n",
|
||||||
|
p_recipe->protocol_type, p_recipe->communication_type, p_recipe->device_id, p_recipe->device_name, p_recipe->read_period);
|
||||||
|
|
||||||
|
switch (p_recipe->communication_type)
|
||||||
|
{
|
||||||
|
case 0://Get Socket Config
|
||||||
|
ControlBasicSocketConfig(p_recipe, p_recipe_file_json);
|
||||||
|
break;
|
||||||
|
case 1://Get Serial Config
|
||||||
|
ControlBasicSerialConfig(p_recipe, p_recipe_file_json);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\n************************************************************\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: Control Framework Read Variable Item Function
|
||||||
|
* @param p_recipe - Control recipe pointer
|
||||||
|
* @param p_recipe_file_json - recipe_file_json pointer
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
void RecipeReadVariableItem(struct ControlRecipe *p_recipe, cJSON *p_recipe_file_json)
|
||||||
|
{
|
||||||
|
int i, ret = 0;
|
||||||
|
|
||||||
|
ProtocolFormatInfo protocol_format_info;
|
||||||
|
memset(&protocol_format_info, 0, sizeof(ProtocolFormatInfo));
|
||||||
|
|
||||||
|
cJSON *read_item_list_json = cJSON_GetObjectItem(p_recipe_file_json, "read_item_list");
|
||||||
|
if (cJSON_IsArray(read_item_list_json)) {
|
||||||
|
/*Get Recipe Variable Item Count and total length*/
|
||||||
|
p_recipe->read_item_count = cJSON_GetArraySize(read_item_list_json);
|
||||||
|
p_recipe->total_data_length = GetRecipeTotalDataLength(read_item_list_json);
|
||||||
|
|
||||||
|
/*Malloc Read Data Pointer, Reference "CONTROL FRAMEWORK READ DATA FORMAT"*/
|
||||||
|
p_recipe->protocol_data.data = PrivMalloc(CONTROL_DATA_HEAD_LENGTH + p_recipe->total_data_length);
|
||||||
|
p_recipe->protocol_data.data_length = CONTROL_DATA_HEAD_LENGTH + p_recipe->total_data_length;
|
||||||
|
memset(p_recipe->protocol_data.data, 0, p_recipe->protocol_data.data_length);
|
||||||
|
|
||||||
|
protocol_format_info.p_read_item_data = p_recipe->protocol_data.data + CONTROL_DATA_HEAD_LENGTH;
|
||||||
|
|
||||||
|
/*Init The Control Protocol*/
|
||||||
|
ControlProtocolInitDesc(p_recipe, protocol_init);
|
||||||
|
|
||||||
|
/*Format Data Header, Reference "CONTROL FRAMEWORK READ DATA FORMAT"*/
|
||||||
|
FormatDataHeader(p_recipe);
|
||||||
|
|
||||||
|
uint16_t read_item_count = p_recipe->read_item_count;
|
||||||
|
|
||||||
|
for (i = 0; i < read_item_count; i ++) {
|
||||||
|
cJSON *read_single_item_json = cJSON_GetArrayItem(read_item_list_json, i);
|
||||||
|
|
||||||
|
protocol_format_info.read_single_item_json = read_single_item_json;
|
||||||
|
protocol_format_info.read_item_index = i;
|
||||||
|
|
||||||
|
/*Format Protocol Cmd By Analyze Variable Item One By One*/
|
||||||
|
ret = p_recipe->ControlProtocolFormatCmd(p_recipe, &protocol_format_info);
|
||||||
|
if (ret < 0) {
|
||||||
|
printf("%s read %d item failed!\n", __func__, i);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,161 @@
|
||||||
|
/*
|
||||||
|
* 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 control_def.h
|
||||||
|
* @brief DEFINE code for control framework
|
||||||
|
* @version 3.0
|
||||||
|
* @author AIIT XUOS Lab
|
||||||
|
* @date 2022-10-08
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CONTROL_DEF_H
|
||||||
|
#define CONTROL_DEF_H
|
||||||
|
|
||||||
|
#include <transform.h>
|
||||||
|
#include <list.h>
|
||||||
|
#include <circular_area_app.h>
|
||||||
|
#include <control.h>
|
||||||
|
#include <control_io.h>
|
||||||
|
|
||||||
|
#ifdef LIB_USING_CJSON
|
||||||
|
#include <cJSON.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define CONTROL_PARAM_CHECK(param) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
if(NULL == param) { \
|
||||||
|
KPrintf("CONTROL CHECK FAILED ...%s %d %s is NULL.\n", __FUNCTION__, __LINE__, #param); \
|
||||||
|
return -1; \
|
||||||
|
} \
|
||||||
|
}while (0)
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
UNIFORM_BOOL = 1,
|
||||||
|
UNIFORM_INT8,
|
||||||
|
UNIFORM_INT16,
|
||||||
|
UNIFORM_INT32,
|
||||||
|
UNIFORM_UINT8,
|
||||||
|
UNIFORM_UINT16,
|
||||||
|
UNIFORM_UINT32,
|
||||||
|
UNIFORM_DOUBLE,
|
||||||
|
UNIFORM_FLOAT
|
||||||
|
}UniformValueType;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint8_t ip[4];
|
||||||
|
uint16_t port;
|
||||||
|
int32_t socket;
|
||||||
|
int8_t secondary_connect_flag;//0: enble, no connected; 1: enable, connected; -1: disable
|
||||||
|
}BasicSocketPlc;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint16_t command_length;
|
||||||
|
uint16_t data_size;
|
||||||
|
uint8_t *p_command;
|
||||||
|
uint8_t *p_data;
|
||||||
|
}BasicPlcDataInfo;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
cJSON *read_single_item_json;
|
||||||
|
uint8_t *p_read_item_data;
|
||||||
|
uint16_t read_item_index;//Variable item index(1 ++)
|
||||||
|
uint8_t last_item_size;
|
||||||
|
}ProtocolFormatInfo;
|
||||||
|
|
||||||
|
struct ProtocolData
|
||||||
|
{
|
||||||
|
uint8_t *data;
|
||||||
|
uint16_t data_length;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SerialConfig
|
||||||
|
{
|
||||||
|
uint32_t baud_rate;
|
||||||
|
uint8_t data_bits;
|
||||||
|
uint8_t stop_bits;
|
||||||
|
uint8_t check_mode;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SocketConfig
|
||||||
|
{
|
||||||
|
uint16_t port;
|
||||||
|
uint8_t plc_ip[4];
|
||||||
|
uint8_t local_ip[4];
|
||||||
|
uint8_t gateway[4];
|
||||||
|
uint8_t netmask[4];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ControlRecipe
|
||||||
|
{
|
||||||
|
uint8_t device_name[20];
|
||||||
|
uint16_t device_id;
|
||||||
|
uint16_t read_period;
|
||||||
|
uint16_t read_item_count;
|
||||||
|
uint16_t total_data_length;
|
||||||
|
uint8_t communication_type;
|
||||||
|
|
||||||
|
ProtocolType protocol_type;
|
||||||
|
|
||||||
|
void *read_item;
|
||||||
|
struct ControlDone *done;
|
||||||
|
|
||||||
|
struct SerialConfig serial_config;
|
||||||
|
struct SocketConfig socket_config;
|
||||||
|
|
||||||
|
struct ProtocolData protocol_data;
|
||||||
|
|
||||||
|
int (*ControlProtocolFormatCmd)(struct ControlRecipe *p_recipe, ProtocolFormatInfo *protocol_format_info);
|
||||||
|
};
|
||||||
|
|
||||||
|
/*Get Value Type Memory Size*/
|
||||||
|
uint8_t GetValueTypeMemorySize(UniformValueType uniform_value_type);
|
||||||
|
|
||||||
|
/*Get basic information from recipe file*/
|
||||||
|
int RecipeBasicInformation(struct ControlRecipe *p_recipe, cJSON *p_recipe_file_json);
|
||||||
|
|
||||||
|
/*Get the variable need to read from recipe file*/
|
||||||
|
void RecipeReadVariableItem(struct ControlRecipe *p_recipe, cJSON *p_recipe_file_json);
|
||||||
|
|
||||||
|
/*Control Framework Peripheral Device Init*/
|
||||||
|
int ControlPeripheralInit(struct ControlRecipe *p_recipe);
|
||||||
|
|
||||||
|
/*Control Framework Printf List Function*/
|
||||||
|
void ControlPrintfList(char name[5], uint8_t *number_list, uint16_t length);
|
||||||
|
|
||||||
|
/*Control Framework Connect Socket*/
|
||||||
|
int ControlConnectSocket(BasicSocketPlc *p_plc);
|
||||||
|
|
||||||
|
/*Control Framework Disconnect Socket*/
|
||||||
|
int ControlDisconnectSocket(BasicSocketPlc *p_plc);
|
||||||
|
|
||||||
|
/*Control Framework Protocol Open for Sub_Protocol, Init Circular Area and Receive Data Task*/
|
||||||
|
int ControlProtocolOpenDef(struct ControlProtocol *control_protocol);
|
||||||
|
|
||||||
|
/*Control Framework Protocol Open for Sub_Protocol, Release Circular Area and Delete Receive Data Task*/
|
||||||
|
int ControlProtocolCloseDef(void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
* 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 control_io.c
|
||||||
|
* @brief low level io code for control framework
|
||||||
|
* @version 3.0
|
||||||
|
* @author AIIT XUOS Lab
|
||||||
|
* @date 2022-11-21
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <control_io.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: Control Framework Socket Init
|
||||||
|
* @param ip - local ip pointer
|
||||||
|
* @param mask - netmask pointer
|
||||||
|
* @param gw - gateway pointer
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
void SocketInit(char *ip, char *mask, char *gw)
|
||||||
|
{
|
||||||
|
printf("%s ip %d.%d.%d.%d mask %d.%d.%d.%d gw %d.%d.%d.%d\n", __func__,
|
||||||
|
ip[0], ip[1], ip[2], ip[3],
|
||||||
|
mask[0], mask[1], mask[2], mask[3],
|
||||||
|
gw[0], gw[1], gw[2], gw[3]);
|
||||||
|
#ifdef BSP_USING_LWIP
|
||||||
|
lwip_config_tcp(0, ip, mask, gw);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: Control Framework Serial Init
|
||||||
|
* @param baud_rate - baud rate
|
||||||
|
* @param data_bits - data bits
|
||||||
|
* @param stop_bits - stop bits
|
||||||
|
* @param check_mode - check mode
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
void SerialInit(uint32_t baud_rate, uint8_t data_bits, uint8_t stop_bits, uint8_t check_mode)
|
||||||
|
{
|
||||||
|
// Uart485Init(baud_rate, data_bits, stop_bits, check_mode);
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
* 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 control_io.h
|
||||||
|
* @brief code for control framework io adapter
|
||||||
|
* @version 3.0
|
||||||
|
* @author AIIT XUOS Lab
|
||||||
|
* @date 2022-11-21
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CONTROL_IO_H
|
||||||
|
#define CONTROL_IO_H
|
||||||
|
|
||||||
|
#include <transform.h>
|
||||||
|
#include <list.h>
|
||||||
|
|
||||||
|
#ifdef BSP_USING_LWIP
|
||||||
|
#include "lwip/sys.h"
|
||||||
|
#include "lwip/sockets.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef BSP_USING_LWIP
|
||||||
|
#define socket_write lwip_write
|
||||||
|
#define socket_read lwip_read
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*Control Framework Socket Init*/
|
||||||
|
void SocketInit(char *ip, char *mask, char *gw);
|
||||||
|
|
||||||
|
/*Control Framework Serial Init*/
|
||||||
|
void SerialInit(uint32_t baud_rate, uint8_t data_bits, uint8_t stop_bits, uint8_t check_mode);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -15,6 +15,7 @@
|
||||||
|
|
||||||
extern int SensorFrameworkInit(void);
|
extern int SensorFrameworkInit(void);
|
||||||
extern int AdapterFrameworkInit(void);
|
extern int AdapterFrameworkInit(void);
|
||||||
|
extern int ControlFrameworkInit(void);
|
||||||
|
|
||||||
extern int Adapter4GInit(void);
|
extern int Adapter4GInit(void);
|
||||||
extern int AdapterNbiotInit(void);
|
extern int AdapterNbiotInit(void);
|
||||||
|
@ -73,6 +74,10 @@ static struct InitDesc framework[] =
|
||||||
{ "connection_framework", AdapterFrameworkInit },
|
{ "connection_framework", AdapterFrameworkInit },
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef SUPPORT_CONTROL_FRAMEWORK
|
||||||
|
{ "control_framework", ControlFrameworkInit },
|
||||||
|
#endif
|
||||||
|
|
||||||
{ "NULL", NULL },
|
{ "NULL", NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -229,6 +234,10 @@ int FrameworkInit(void)
|
||||||
ConnectionDeviceFrameworkInit(framework);
|
ConnectionDeviceFrameworkInit(framework);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef SUPPORT_CONTROL_FRAMEWORK
|
||||||
|
ControlFrameworkInit();
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef LIB_LV
|
#ifdef LIB_LV
|
||||||
lv_port_init();
|
lv_port_init();
|
||||||
#endif
|
#endif
|
|
@ -6,6 +6,12 @@ ifeq ($(CONFIG_ADD_NUTTX_FETURES),y)
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(ADD_XIZI_FETURES),y)
|
||||||
|
include $(APPDIR)/Make.defs
|
||||||
|
CSRCS += sensor.c
|
||||||
|
include $(APPDIR)/Application.mk
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq ($(CONFIG_ADD_XIZI_FETURES),y)
|
ifeq ($(CONFIG_ADD_XIZI_FETURES),y)
|
||||||
SRC_FILES := sensor.c
|
SRC_FILES := sensor.c
|
||||||
|
|
||||||
|
|
|
@ -173,6 +173,7 @@ int PrivIoctl(int fd, int cmd, void *args)
|
||||||
case ADC_TYPE:
|
case ADC_TYPE:
|
||||||
case DAC_TYPE:
|
case DAC_TYPE:
|
||||||
case WDT_TYPE:
|
case WDT_TYPE:
|
||||||
|
case CAMERA_TYPE:
|
||||||
ret = ioctl(fd, cmd, ioctl_cfg->args);
|
ret = ioctl(fd, cmd, ioctl_cfg->args);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -150,9 +150,18 @@ enum IoctlDriverType
|
||||||
DAC_TYPE,
|
DAC_TYPE,
|
||||||
WDT_TYPE,
|
WDT_TYPE,
|
||||||
RTC_TYPE,
|
RTC_TYPE,
|
||||||
|
CAMERA_TYPE,
|
||||||
DEFAULT_TYPE,
|
DEFAULT_TYPE,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct DvpRegConfigureInfo
|
||||||
|
{
|
||||||
|
uint8_t device_addr;
|
||||||
|
uint16_t reg_addr;
|
||||||
|
uint8_t reg_value;
|
||||||
|
} ;
|
||||||
|
|
||||||
struct PrivIoctlCfg
|
struct PrivIoctlCfg
|
||||||
{
|
{
|
||||||
enum IoctlDriverType ioctl_driver_type;
|
enum IoctlDriverType ioctl_driver_type;
|
||||||
|
@ -180,6 +189,18 @@ typedef struct
|
||||||
void* pixel_color;
|
void* pixel_color;
|
||||||
}LcdPixelParam;
|
}LcdPixelParam;
|
||||||
|
|
||||||
|
struct CameraCfg
|
||||||
|
{
|
||||||
|
uint16_t window_w;
|
||||||
|
uint16_t window_h;
|
||||||
|
uint16_t window_xoffset;
|
||||||
|
uint16_t window_yoffset;
|
||||||
|
uint16_t output_w;
|
||||||
|
uint16_t output_h;
|
||||||
|
uint8_t gain;
|
||||||
|
uint8_t gain_manu_enable;
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
char type; // 0:write string;1:write dot
|
char type; // 0:write string;1:write dot
|
||||||
|
@ -194,6 +215,12 @@ typedef struct
|
||||||
uint16_t press;
|
uint16_t press;
|
||||||
}TouchDataParam;
|
}TouchDataParam;
|
||||||
|
|
||||||
|
struct TouchDataStandard
|
||||||
|
{
|
||||||
|
uint16 x;
|
||||||
|
uint16 y;
|
||||||
|
};
|
||||||
|
|
||||||
struct RtcDrvConfigureParam
|
struct RtcDrvConfigureParam
|
||||||
{
|
{
|
||||||
int rtc_operation_cmd;
|
int rtc_operation_cmd;
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*Copy this file as "lv_port_indev.c" and set this value to "1" to enable content*/
|
/*Copy this file as "lv_port_indev.c" and set this value to "1" to enable content*/
|
||||||
#if 1
|
#if 1
|
||||||
|
|
||||||
/*********************
|
/*********************
|
||||||
|
@ -12,8 +12,7 @@
|
||||||
#include "lv_port_indev_template.h"
|
#include "lv_port_indev_template.h"
|
||||||
#include "../../lvgl.h"
|
#include "../../lvgl.h"
|
||||||
|
|
||||||
static int touch_fd = -1;
|
static int touch_fd = 0;
|
||||||
static TouchDataParam touch_data;
|
|
||||||
/*********************
|
/*********************
|
||||||
* DEFINES
|
* DEFINES
|
||||||
*********************/
|
*********************/
|
||||||
|
@ -23,6 +22,7 @@ static TouchDataParam touch_data;
|
||||||
#define LV_USE_INDEV_ENCODER 0x8u
|
#define LV_USE_INDEV_ENCODER 0x8u
|
||||||
#define LV_USE_INDEV_BUTTUN 0x10u
|
#define LV_USE_INDEV_BUTTUN 0x10u
|
||||||
|
|
||||||
|
#define PRESS_FAILED_LIMIT 15
|
||||||
#define LV_USE_INDEV LV_USE_INDEV_TOUCHPAD ///< modify this DEFINE to enable the indev device. e.g #define LV_USE_INDEV LV_USE_INDEV_TOUCHPAD | LV_USE_INDEV_KEYPAD
|
#define LV_USE_INDEV LV_USE_INDEV_TOUCHPAD ///< modify this DEFINE to enable the indev device. e.g #define LV_USE_INDEV LV_USE_INDEV_TOUCHPAD | LV_USE_INDEV_KEYPAD
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
|
@ -34,33 +34,36 @@ static TouchDataParam touch_data;
|
||||||
**********************/
|
**********************/
|
||||||
#if (LV_USE_INDEV & LV_USE_INDEV_TOUCHPAD) == LV_USE_INDEV_TOUCHPAD
|
#if (LV_USE_INDEV & LV_USE_INDEV_TOUCHPAD) == LV_USE_INDEV_TOUCHPAD
|
||||||
static void touchpad_init(void);
|
static void touchpad_init(void);
|
||||||
static void touchpad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
|
static void touchpad_read(lv_indev_drv_t *indev_drv, lv_indev_data_t *data);
|
||||||
static bool touchpad_is_pressed(void);
|
// static bool touchpad_is_pressed(void);
|
||||||
static void touchpad_get_xy(lv_coord_t * x, lv_coord_t * y);
|
// static void touchpad_get_xy(lv_coord_t * x, lv_coord_t * y);
|
||||||
|
static bool touchpad_is_pressed(struct TouchDataStandard *touch_data_ptr);
|
||||||
|
static void touchpad_get_xy(struct TouchDataStandard *touch_data_ptr,
|
||||||
|
lv_coord_t *x, lv_coord_t *y);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (LV_USE_INDEV & LV_USE_INDEV_MOUSE) == LV_USE_INDEV_MOUSE
|
#if (LV_USE_INDEV & LV_USE_INDEV_MOUSE) == LV_USE_INDEV_MOUSE
|
||||||
static void mouse_init(void);
|
static void mouse_init(void);
|
||||||
static void mouse_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
|
static void mouse_read(lv_indev_drv_t *indev_drv, lv_indev_data_t *data);
|
||||||
static bool mouse_is_pressed(void);
|
static bool mouse_is_pressed(void);
|
||||||
static void mouse_get_xy(lv_coord_t * x, lv_coord_t * y);
|
static void mouse_get_xy(lv_coord_t *x, lv_coord_t *y);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (LV_USE_INDEV & LV_USE_INDEV_KEYPAD) == LV_USE_INDEV_KEYPAD
|
#if (LV_USE_INDEV & LV_USE_INDEV_KEYPAD) == LV_USE_INDEV_KEYPAD
|
||||||
static void keypad_init(void);
|
static void keypad_init(void);
|
||||||
static void keypad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
|
static void keypad_read(lv_indev_drv_t *indev_drv, lv_indev_data_t *data);
|
||||||
static uint32_t keypad_get_key(void);
|
static uint32_t keypad_get_key(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (LV_USE_INDEV & LV_USE_INDEV_ENCODER) == LV_USE_INDEV_ENCODER
|
#if (LV_USE_INDEV & LV_USE_INDEV_ENCODER) == LV_USE_INDEV_ENCODER
|
||||||
static void encoder_init(void);
|
static void encoder_init(void);
|
||||||
static void encoder_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
|
static void encoder_read(lv_indev_drv_t *indev_drv, lv_indev_data_t *data);
|
||||||
static void encoder_handler(void);
|
static void encoder_handler(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (LV_USE_INDEV & LV_USE_INDEV_BUTTUN) == LV_USE_INDEV_BUTTUN
|
#if (LV_USE_INDEV & LV_USE_INDEV_BUTTUN) == LV_USE_INDEV_BUTTUN
|
||||||
static void button_init(void);
|
static void button_init(void);
|
||||||
static void button_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
|
static void button_read(lv_indev_drv_t *indev_drv, lv_indev_data_t *data);
|
||||||
static int8_t button_get_pressed_id(void);
|
static int8_t button_get_pressed_id(void);
|
||||||
static bool button_is_pressed(uint8_t id);
|
static bool button_is_pressed(uint8_t id);
|
||||||
#endif
|
#endif
|
||||||
|
@ -69,23 +72,23 @@ static bool button_is_pressed(uint8_t id);
|
||||||
* STATIC VARIABLES
|
* STATIC VARIABLES
|
||||||
**********************/
|
**********************/
|
||||||
#if (LV_USE_INDEV & LV_USE_INDEV_TOUCHPAD) == LV_USE_INDEV_TOUCHPAD
|
#if (LV_USE_INDEV & LV_USE_INDEV_TOUCHPAD) == LV_USE_INDEV_TOUCHPAD
|
||||||
lv_indev_t * indev_touchpad;
|
lv_indev_t *indev_touchpad;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (LV_USE_INDEV & LV_USE_INDEV_MOUSE) == LV_USE_INDEV_MOUSE
|
#if (LV_USE_INDEV & LV_USE_INDEV_MOUSE) == LV_USE_INDEV_MOUSE
|
||||||
lv_indev_t * indev_mouse;
|
lv_indev_t *indev_mouse;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (LV_USE_INDEV & LV_USE_INDEV_KEYPAD) == LV_USE_INDEV_KEYPAD
|
#if (LV_USE_INDEV & LV_USE_INDEV_KEYPAD) == LV_USE_INDEV_KEYPAD
|
||||||
lv_indev_t * indev_keypad;
|
lv_indev_t *indev_keypad;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (LV_USE_INDEV & LV_USE_INDEV_ENCODER) == LV_USE_INDEV_ENCODER
|
#if (LV_USE_INDEV & LV_USE_INDEV_ENCODER) == LV_USE_INDEV_ENCODER
|
||||||
lv_indev_t * indev_encoder;
|
lv_indev_t *indev_encoder;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (LV_USE_INDEV & LV_USE_INDEV_BUTTUN) == LV_USE_INDEV_BUTTUN
|
#if (LV_USE_INDEV & LV_USE_INDEV_BUTTUN) == LV_USE_INDEV_BUTTUN
|
||||||
lv_indev_t * indev_button;
|
lv_indev_t *indev_button;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int32_t encoder_diff;
|
static int32_t encoder_diff;
|
||||||
|
@ -144,7 +147,7 @@ void lv_port_indev_init(void)
|
||||||
indev_mouse = lv_indev_drv_register(&indev_drv);
|
indev_mouse = lv_indev_drv_register(&indev_drv);
|
||||||
|
|
||||||
/*Set cursor. For simplicity set a HOME symbol now.*/
|
/*Set cursor. For simplicity set a HOME symbol now.*/
|
||||||
lv_obj_t * mouse_cursor = lv_img_create(lv_scr_act());
|
lv_obj_t *mouse_cursor = lv_img_create(lv_scr_act());
|
||||||
lv_img_set_src(mouse_cursor, LV_SYMBOL_HOME);
|
lv_img_set_src(mouse_cursor, LV_SYMBOL_HOME);
|
||||||
lv_indev_set_cursor(indev_mouse, mouse_cursor);
|
lv_indev_set_cursor(indev_mouse, mouse_cursor);
|
||||||
#endif
|
#endif
|
||||||
|
@ -169,8 +172,6 @@ void lv_port_indev_init(void)
|
||||||
*`lv_indev_set_group(indev_keypad, group);`*/
|
*`lv_indev_set_group(indev_keypad, group);`*/
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if (LV_USE_INDEV & LV_USE_INDEV_ENCODER) == LV_USE_INDEV_ENCODER
|
#if (LV_USE_INDEV & LV_USE_INDEV_ENCODER) == LV_USE_INDEV_ENCODER
|
||||||
/*------------------
|
/*------------------
|
||||||
* Encoder
|
* Encoder
|
||||||
|
@ -225,27 +226,37 @@ void lv_port_indev_init(void)
|
||||||
/*Initialize your touchpad*/
|
/*Initialize your touchpad*/
|
||||||
static void touchpad_init(void)
|
static void touchpad_init(void)
|
||||||
{
|
{
|
||||||
touch_fd = PrivOpen(PRIV_TOUCH_DEV,O_RDWR);
|
touch_fd = PrivOpen(PRIV_TOUCH_DEV, O_RDWR);
|
||||||
if(touch_fd >= 0) {
|
if (touch_fd >= 0)
|
||||||
|
{
|
||||||
printf("touch fd = %d\n",touch_fd);
|
printf("touch fd = %d\n",touch_fd);
|
||||||
} else {
|
|
||||||
printf("open %s touch fd = %d failed.\n",PRIV_TOUCH_DEV,touch_fd);
|
|
||||||
touch_fd = -1;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("open %s touch fd = %d failed.\n", PRIV_TOUCH_DEV, touch_fd);
|
||||||
|
}
|
||||||
|
|
||||||
/*Your code comes here*/
|
/*Your code comes here*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// static struct TouchDataStandard touch_data;
|
||||||
|
|
||||||
/*Will be called by the library to read the touchpad*/
|
/*Will be called by the library to read the touchpad*/
|
||||||
static void touchpad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
|
static void touchpad_read(lv_indev_drv_t *indev_drv, lv_indev_data_t *data)
|
||||||
{
|
{
|
||||||
static lv_coord_t last_x = 0;
|
static lv_coord_t last_x = 0;
|
||||||
static lv_coord_t last_y = 0;
|
static lv_coord_t last_y = 0;
|
||||||
|
|
||||||
|
static struct TouchDataStandard touch_data;
|
||||||
|
|
||||||
/*Save the pressed coordinates and the state*/
|
/*Save the pressed coordinates and the state*/
|
||||||
if(touchpad_is_pressed()) {
|
if (touchpad_is_pressed(&touch_data))
|
||||||
touchpad_get_xy(&last_x, &last_y);
|
{
|
||||||
|
touchpad_get_xy(&touch_data, &last_x, &last_y);
|
||||||
data->state = LV_INDEV_STATE_PR;
|
data->state = LV_INDEV_STATE_PR;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
data->state = LV_INDEV_STATE_REL;
|
data->state = LV_INDEV_STATE_REL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -255,34 +266,68 @@ static void touchpad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*Return true is the touchpad is pressed*/
|
/*Return true is the touchpad is pressed*/
|
||||||
static bool touchpad_is_pressed(void)
|
// static bool touchpad_is_pressed(void)
|
||||||
|
// {
|
||||||
|
// int ret;
|
||||||
|
// /*Your code comes here*/
|
||||||
|
// // memset(&touch_data, 0 ,sizeof(TouchDataParam));
|
||||||
|
// memset(&touch_data, 0 ,sizeof(struct TouchDataStandard));
|
||||||
|
// ret = PrivRead(touch_fd, &touch_data, 1);
|
||||||
|
// if (ret && touch_data.x >= 0 && touch_data.x < MY_INDEV_X
|
||||||
|
// && touch_data.y >= 0 && touch_data.y < MY_INDEV_Y)
|
||||||
|
// {
|
||||||
|
// // printf("touch x %d touch y %d\n",touch_data.x,touch_data.y);
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
|
||||||
|
uint32_t press_failed_cnt = 0;
|
||||||
|
static bool touchpad_is_pressed(struct TouchDataStandard *touch_data_ptr)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
/*Your code comes here*/
|
/*Your code comes here*/
|
||||||
memset(&touch_data, 0 ,sizeof(TouchDataParam));
|
memset(touch_data_ptr, 0, sizeof(struct TouchDataStandard));
|
||||||
|
ret = PrivRead(touch_fd, touch_data_ptr, 1);
|
||||||
if (touch_fd < 0) {
|
if (ret)
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = PrivRead(touch_fd, &touch_data, 1);
|
|
||||||
if(ret && touch_data.x >= 0 && touch_data.x < MY_INDEV_X && touch_data.y >= 0 && touch_data.y < MY_INDEV_Y)
|
|
||||||
{
|
{
|
||||||
// printf("touch x %d touch y %d\n",touch_data.x,touch_data.y);
|
if (touch_data_ptr->x > 0 && touch_data_ptr->x < MY_INDEV_X && touch_data_ptr->y > 0 && touch_data_ptr->y < MY_INDEV_Y)
|
||||||
|
{
|
||||||
|
press_failed_cnt = 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
press_failed_cnt++;
|
||||||
|
if (press_failed_cnt >= PRESS_FAILED_LIMIT)
|
||||||
|
{
|
||||||
|
PrivClose(touch_fd);
|
||||||
|
touchpad_init();
|
||||||
|
press_failed_cnt = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*Get the x and y coordinates if the touchpad is pressed*/
|
/*Get the x and y coordinates if the touchpad is pressed*/
|
||||||
static void touchpad_get_xy(lv_coord_t * x, lv_coord_t * y)
|
static void touchpad_get_xy(struct TouchDataStandard *touch_data_ptr,
|
||||||
|
lv_coord_t *x, lv_coord_t *y)
|
||||||
{
|
{
|
||||||
/*Your code comes here*/
|
/*Your code comes here*/
|
||||||
|
|
||||||
(*x) = touch_data.x;
|
(*x) = touch_data_ptr->x;
|
||||||
(*y) = touch_data.y;
|
(*y) = touch_data_ptr->y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// static void touchpad_get_xy(lv_coord_t * x, lv_coord_t * y)
|
||||||
|
// {
|
||||||
|
// /*Your code comes here*/
|
||||||
|
|
||||||
|
// (*x) = touch_data.x;
|
||||||
|
// (*y) = touch_data.y;
|
||||||
|
// }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (LV_USE_INDEV & LV_USE_INDEV_MOUSE) == LV_USE_INDEV_MOUSE
|
#if (LV_USE_INDEV & LV_USE_INDEV_MOUSE) == LV_USE_INDEV_MOUSE
|
||||||
|
@ -297,15 +342,18 @@ static void mouse_init(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*Will be called by the library to read the mouse*/
|
/*Will be called by the library to read the mouse*/
|
||||||
static void mouse_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
|
static void mouse_read(lv_indev_drv_t *indev_drv, lv_indev_data_t *data)
|
||||||
{
|
{
|
||||||
/*Get the current x and y coordinates*/
|
/*Get the current x and y coordinates*/
|
||||||
mouse_get_xy(&data->point.x, &data->point.y);
|
mouse_get_xy(&data->point.x, &data->point.y);
|
||||||
|
|
||||||
/*Get whether the mouse button is pressed or released*/
|
/*Get whether the mouse button is pressed or released*/
|
||||||
if(mouse_is_pressed()) {
|
if (mouse_is_pressed())
|
||||||
|
{
|
||||||
data->state = LV_INDEV_STATE_PR;
|
data->state = LV_INDEV_STATE_PR;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
data->state = LV_INDEV_STATE_REL;
|
data->state = LV_INDEV_STATE_REL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -319,7 +367,7 @@ static bool mouse_is_pressed(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*Get the x and y coordinates if the mouse is pressed*/
|
/*Get the x and y coordinates if the mouse is pressed*/
|
||||||
static void mouse_get_xy(lv_coord_t * x, lv_coord_t * y)
|
static void mouse_get_xy(lv_coord_t *x, lv_coord_t *y)
|
||||||
{
|
{
|
||||||
/*Your code comes here*/
|
/*Your code comes here*/
|
||||||
|
|
||||||
|
@ -328,8 +376,6 @@ static void mouse_get_xy(lv_coord_t * x, lv_coord_t * y)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if (LV_USE_INDEV & LV_USE_INDEV_KEYPAD) == LV_USE_INDEV_KEYPAD
|
#if (LV_USE_INDEV & LV_USE_INDEV_KEYPAD) == LV_USE_INDEV_KEYPAD
|
||||||
/*------------------
|
/*------------------
|
||||||
* Keypad
|
* Keypad
|
||||||
|
@ -342,7 +388,7 @@ static void keypad_init(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*Will be called by the library to read the mouse*/
|
/*Will be called by the library to read the mouse*/
|
||||||
static void keypad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
|
static void keypad_read(lv_indev_drv_t *indev_drv, lv_indev_data_t *data)
|
||||||
{
|
{
|
||||||
static uint32_t last_key = 0;
|
static uint32_t last_key = 0;
|
||||||
|
|
||||||
|
@ -351,11 +397,13 @@ static void keypad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
|
||||||
|
|
||||||
/*Get whether the a key is pressed and save the pressed key*/
|
/*Get whether the a key is pressed and save the pressed key*/
|
||||||
uint32_t act_key = keypad_get_key();
|
uint32_t act_key = keypad_get_key();
|
||||||
if(act_key != 0) {
|
if (act_key != 0)
|
||||||
|
{
|
||||||
data->state = LV_INDEV_STATE_PR;
|
data->state = LV_INDEV_STATE_PR;
|
||||||
|
|
||||||
/*Translate the keys to LVGL control characters according to your key definitions*/
|
/*Translate the keys to LVGL control characters according to your key definitions*/
|
||||||
switch(act_key) {
|
switch (act_key)
|
||||||
|
{
|
||||||
case 1:
|
case 1:
|
||||||
act_key = LV_KEY_NEXT;
|
act_key = LV_KEY_NEXT;
|
||||||
break;
|
break;
|
||||||
|
@ -374,7 +422,9 @@ static void keypad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
|
||||||
}
|
}
|
||||||
|
|
||||||
last_key = act_key;
|
last_key = act_key;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
data->state = LV_INDEV_STATE_REL;
|
data->state = LV_INDEV_STATE_REL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -390,8 +440,6 @@ static uint32_t keypad_get_key(void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if (LV_USE_INDEV & LV_USE_INDEV_ENCODER) == LV_USE_INDEV_ENCODER
|
#if (LV_USE_INDEV & LV_USE_INDEV_ENCODER) == LV_USE_INDEV_ENCODER
|
||||||
/*------------------
|
/*------------------
|
||||||
* Encoder
|
* Encoder
|
||||||
|
@ -404,7 +452,7 @@ static void encoder_init(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*Will be called by the library to read the encoder*/
|
/*Will be called by the library to read the encoder*/
|
||||||
static void encoder_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
|
static void encoder_read(lv_indev_drv_t *indev_drv, lv_indev_data_t *data)
|
||||||
{
|
{
|
||||||
|
|
||||||
data->enc_diff = encoder_diff;
|
data->enc_diff = encoder_diff;
|
||||||
|
@ -433,7 +481,7 @@ static void button_init(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*Will be called by the library to read the button*/
|
/*Will be called by the library to read the button*/
|
||||||
static void button_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
|
static void button_read(lv_indev_drv_t *indev_drv, lv_indev_data_t *data)
|
||||||
{
|
{
|
||||||
|
|
||||||
static uint8_t last_btn = 0;
|
static uint8_t last_btn = 0;
|
||||||
|
@ -441,10 +489,13 @@ static void button_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
|
||||||
/*Get the pressed button's ID*/
|
/*Get the pressed button's ID*/
|
||||||
int8_t btn_act = button_get_pressed_id();
|
int8_t btn_act = button_get_pressed_id();
|
||||||
|
|
||||||
if(btn_act >= 0) {
|
if (btn_act >= 0)
|
||||||
|
{
|
||||||
data->state = LV_INDEV_STATE_PR;
|
data->state = LV_INDEV_STATE_PR;
|
||||||
last_btn = btn_act;
|
last_btn = btn_act;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
data->state = LV_INDEV_STATE_REL;
|
data->state = LV_INDEV_STATE_REL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -458,9 +509,11 @@ static int8_t button_get_pressed_id(void)
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
|
|
||||||
/*Check to buttons see which is being pressed (assume there are 2 buttons)*/
|
/*Check to buttons see which is being pressed (assume there are 2 buttons)*/
|
||||||
for(i = 0; i < 2; i++) {
|
for (i = 0; i < 2; i++)
|
||||||
|
{
|
||||||
/*Return the pressed button's ID*/
|
/*Return the pressed button's ID*/
|
||||||
if(button_is_pressed(i)) {
|
if (button_is_pressed(i))
|
||||||
|
{
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# include $(LVGL_DIR)/$(LVGL_DIR_NAME)/examples/examples.mk
|
include $(LVGL_DIR)/$(LVGL_DIR_NAME)/examples/examples.mk
|
||||||
include $(LVGL_DIR)/$(LVGL_DIR_NAME)/porting/porting.mk
|
|
||||||
include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/extra/extra.mk
|
include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/extra/extra.mk
|
||||||
|
|
||||||
include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/core/lv_core.mk
|
include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/core/lv_core.mk
|
||||||
include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/lv_draw.mk
|
include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/lv_draw.mk
|
||||||
include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/font/lv_font.mk
|
include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/font/lv_font.mk
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
#include "lv_port_indev_template.h"
|
#include "lv_port_indev_template.h"
|
||||||
#include "../lvgl.h"
|
#include "../lvgl.h"
|
||||||
|
|
||||||
#include <dev_touch.h>
|
|
||||||
|
|
||||||
static int touch_fd = 0;
|
static int touch_fd = 0;
|
||||||
/*********************
|
/*********************
|
||||||
|
@ -292,7 +291,7 @@ static bool touchpad_is_pressed(struct TouchDataStandard* touch_data_ptr)
|
||||||
press_failed_cnt = 0;
|
press_failed_cnt = 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
printf("lv_touch:%d,%d\n",touch_data_ptr->x,touch_data_ptr->y);
|
||||||
press_failed_cnt++;
|
press_failed_cnt++;
|
||||||
if (press_failed_cnt >= PRESS_FAILED_LIMIT) {
|
if (press_failed_cnt >= PRESS_FAILED_LIMIT) {
|
||||||
PrivClose(touch_fd);
|
PrivClose(touch_fd);
|
||||||
|
|
|
@ -47,6 +47,7 @@ Modification:
|
||||||
#include "connect_uart.h"
|
#include "connect_uart.h"
|
||||||
#include "connect_w5500.h"
|
#include "connect_w5500.h"
|
||||||
#include "connect_wdt.h"
|
#include "connect_wdt.h"
|
||||||
|
#include "connect_dvp.h"
|
||||||
#include "dmac.h"
|
#include "dmac.h"
|
||||||
#include "encoding.h"
|
#include "encoding.h"
|
||||||
#include "fpioa.h"
|
#include "fpioa.h"
|
||||||
|
@ -217,7 +218,10 @@ struct InitSequenceDesc _board_init[] = {
|
||||||
#ifdef BSP_USING_W5500
|
#ifdef BSP_USING_W5500
|
||||||
{"w5500", HwWiznetInit},
|
{"w5500", HwWiznetInit},
|
||||||
#endif
|
#endif
|
||||||
{" NONE ", NONE},
|
#ifdef BSP_USING_CAMERA
|
||||||
|
{"hw_camera", HwDvpInit },
|
||||||
|
#endif
|
||||||
|
{ " NONE ",NONE },
|
||||||
};
|
};
|
||||||
|
|
||||||
void InitBoardHardware(void) {
|
void InitBoardHardware(void) {
|
||||||
|
|
|
@ -120,3 +120,12 @@ menuconfig BSP_USING_WIZCHIP
|
||||||
if BSP_USING_WIZCHIP
|
if BSP_USING_WIZCHIP
|
||||||
source "$BSP_DIR/third_party_driver/ethernet/Kconfig"
|
source "$BSP_DIR/third_party_driver/ethernet/Kconfig"
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
menuconfig BSP_USING_CAMERA
|
||||||
|
bool "Using camera device"
|
||||||
|
default y
|
||||||
|
select RESOURCES_CAMERA
|
||||||
|
if BSP_USING_CAMERA
|
||||||
|
source "$BSP_DIR/third_party_driver/dvp/Kconfig"
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
|
@ -59,5 +59,9 @@ endif
|
||||||
ifeq ($(CONFIG_BSP_USING_WIZCHIP),y)
|
ifeq ($(CONFIG_BSP_USING_WIZCHIP),y)
|
||||||
SRC_DIR += ethernet
|
SRC_DIR += ethernet
|
||||||
endif
|
endif
|
||||||
|
ifeq ($(CONFIG_BSP_USING_CAMERA),y)
|
||||||
|
SRC_DIR += dvp
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
include $(KERNEL_ROOT)/compiler.mk
|
include $(KERNEL_ROOT)/compiler.mk
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
if BSP_USING_CAMERA
|
||||||
|
config DVP_XCLK_RATE
|
||||||
|
int "Camera interface clk rate"
|
||||||
|
default 24000000
|
||||||
|
config IMAGE_WIDTH
|
||||||
|
int "Camera photo width"
|
||||||
|
default 320
|
||||||
|
config IMAGE_HEIGHT
|
||||||
|
int "Camera photo height"
|
||||||
|
default 240
|
||||||
|
config DVP_BURST_ENABLE
|
||||||
|
bool "brust mode enable"
|
||||||
|
default y
|
||||||
|
config DVP_AUTO_ENABLE
|
||||||
|
bool "auto recv image mode enable"
|
||||||
|
default n
|
||||||
|
config DVP_AI_OUTPUT
|
||||||
|
bool "ai output enable"
|
||||||
|
default n
|
||||||
|
config DVP_INTERRUPT_ENABLE
|
||||||
|
bool "interrupt enable"
|
||||||
|
default y
|
||||||
|
|
||||||
|
config CAMERA_BUS_NAME
|
||||||
|
string "camera bus name"
|
||||||
|
default "camera"
|
||||||
|
config CAMERA_DRV_NAME
|
||||||
|
string "camera driver name"
|
||||||
|
default "camera_drv"
|
||||||
|
config CAMERA_DEVICE_NAME
|
||||||
|
string "camera device name"
|
||||||
|
default "camera_dev"
|
||||||
|
|
||||||
|
choice
|
||||||
|
prompt "set camera framesize and fps"
|
||||||
|
default SVGA_25FPS_MODE
|
||||||
|
|
||||||
|
config UXGA_15FPS_MODE
|
||||||
|
bool "using uxga in 15fps"
|
||||||
|
|
||||||
|
config SVGA_25FPS_MODE
|
||||||
|
bool "using svag in 25fps"
|
||||||
|
endchoice
|
||||||
|
|
||||||
|
|
||||||
|
endif
|
|
@ -0,0 +1,4 @@
|
||||||
|
SRC_FILES := connect_dvp.c dvp.c ov2640.c
|
||||||
|
|
||||||
|
|
||||||
|
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -0,0 +1,243 @@
|
||||||
|
#include <connect_dvp.h>
|
||||||
|
#include <dvp.h>
|
||||||
|
#include <board.h>
|
||||||
|
#include "sysctl.h"
|
||||||
|
#include "bsp.h"
|
||||||
|
#include "plic.h"
|
||||||
|
#include <ov2640.h>
|
||||||
|
|
||||||
|
#define REG_SCCB_READ 0x12U
|
||||||
|
#define REG_SCCB_WRITE 0x13U
|
||||||
|
#define SCCB_REG_LENGTH 0x08U
|
||||||
|
|
||||||
|
// irq interrupt function
|
||||||
|
static int on_irq_dvp(int irq, void *arg)
|
||||||
|
{
|
||||||
|
if (dvp_get_interrupt(DVP_STS_FRAME_FINISH))
|
||||||
|
{
|
||||||
|
dvp_clear_interrupt(DVP_STS_FRAME_FINISH);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dvp_start_convert();
|
||||||
|
dvp_clear_interrupt(DVP_STS_FRAME_START);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct DvpRegConfigureInfo
|
||||||
|
{
|
||||||
|
uint8_t device_addr;
|
||||||
|
uint16_t reg_addr;
|
||||||
|
uint8_t reg_value;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct CameraCfg sensor_config = {
|
||||||
|
.output_h = IMAGE_HEIGHT,//will be resize from window below in ov2640
|
||||||
|
.output_w = IMAGE_WIDTH,
|
||||||
|
.window_h = 600, //register configure in ov2640.h
|
||||||
|
.window_w = 800, //to make window as large as cmos selected size
|
||||||
|
.window_xoffset = 0,
|
||||||
|
.window_yoffset = 0,
|
||||||
|
.gain_manu_enable = 0,
|
||||||
|
.gain = 0x00
|
||||||
|
};
|
||||||
|
|
||||||
|
static uint32 DvpDrvInit(void)
|
||||||
|
{
|
||||||
|
x_err_t ret = EOK;
|
||||||
|
dvp_init(SCCB_REG_LENGTH);
|
||||||
|
dvp_set_xclk_rate(DVP_XCLK_RATE);
|
||||||
|
dvp_set_image_format(DVP_CFG_RGB_FORMAT);
|
||||||
|
dvp_set_image_size(IMAGE_WIDTH, IMAGE_HEIGHT);
|
||||||
|
dvp_set_output_enable(DVP_OUTPUT_DISPLAY, 0);
|
||||||
|
dvp_set_output_enable(DVP_OUTPUT_AI, 0);
|
||||||
|
ov2640_init();
|
||||||
|
SensorConfigure(&sensor_config);
|
||||||
|
|
||||||
|
sysctl_set_spi0_dvp_data(1);
|
||||||
|
#ifdef DVP_BURST_ENABLE
|
||||||
|
dvp_enable_burst();
|
||||||
|
#endif
|
||||||
|
#ifdef DVP_AUTO_ENABLE
|
||||||
|
dvp_disable_auto();
|
||||||
|
#endif
|
||||||
|
#ifdef DVP_AI_OUTPUT
|
||||||
|
dvp_set_output_enable(DVP_OUTPUT_AI, 1);
|
||||||
|
dvp_set_ai_addr((uint32_t)DVP_AI_RED_ADRESS, (uint32_t)DVP_AI_GREEN_ADRESS, (uint32_t)DVP_AI_BLUE_ADRESS);
|
||||||
|
#endif
|
||||||
|
#ifdef DVP_INTERRUPT_ENABLE
|
||||||
|
dvp_config_interrupt(DVP_CFG_START_INT_ENABLE | DVP_CFG_FINISH_INT_ENABLE, 0);
|
||||||
|
isrManager.done->registerIrq(IRQN_DVP_INTERRUPT, (IsrHandlerType)on_irq_dvp, NULL);
|
||||||
|
isrManager.done->enableIrq(IRQN_DVP_INTERRUPT);
|
||||||
|
dvp_clear_interrupt(DVP_STS_FRAME_START | DVP_STS_FRAME_FINISH);
|
||||||
|
dvp_config_interrupt(DVP_CFG_START_INT_ENABLE | DVP_CFG_FINISH_INT_ENABLE, 1);
|
||||||
|
KPrintf("camera interrupt has open!\n");
|
||||||
|
#endif
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32 ReadDvpReg(void *drv, struct DvpRegConfigureInfo *reg_info)
|
||||||
|
{
|
||||||
|
x_err_t ret = EOK;
|
||||||
|
reg_info->reg_value = dvp_sccb_receive_data(reg_info->device_addr, reg_info->reg_addr);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32 WriteDvpReg(void *drv, struct DvpRegConfigureInfo *reg_info)
|
||||||
|
{
|
||||||
|
x_err_t ret = EOK;
|
||||||
|
dvp_sccb_send_data(reg_info->device_addr, reg_info->reg_addr, reg_info->reg_value);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32 DvpOpen(void *dev)
|
||||||
|
{
|
||||||
|
x_err_t ret = EOK;
|
||||||
|
DvpDrvInit();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32 DvpClose(void *dev)
|
||||||
|
{
|
||||||
|
x_err_t ret = EOK;
|
||||||
|
dvp_config_interrupt(DVP_CFG_START_INT_ENABLE | DVP_CFG_FINISH_INT_ENABLE, 0);
|
||||||
|
dvp_set_output_enable(DVP_OUTPUT_AI, 0);
|
||||||
|
dvp_set_output_enable(DVP_OUTPUT_DISPLAY, 0);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32 DvpRead(void *dev, struct BusBlockReadParam *read_param)
|
||||||
|
{
|
||||||
|
x_err_t ret = EOK;
|
||||||
|
|
||||||
|
// change the output buff address by read
|
||||||
|
dvp_set_output_enable(DVP_OUTPUT_DISPLAY, 0);
|
||||||
|
dvp_set_display_addr((uintptr_t)read_param->buffer);
|
||||||
|
dvp_set_output_enable(DVP_OUTPUT_DISPLAY, 1);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32 DvpDrvConfigure(void *drv, struct BusConfigureInfo *args)
|
||||||
|
{
|
||||||
|
x_err_t ret = EOK;
|
||||||
|
|
||||||
|
int cmd_type = args->configure_cmd;
|
||||||
|
struct CameraCfg* tmp_cfg;
|
||||||
|
switch (cmd_type)
|
||||||
|
{
|
||||||
|
case OPE_INT:
|
||||||
|
break;
|
||||||
|
case OPE_CFG:
|
||||||
|
tmp_cfg = (struct CameraCfg *)args->private_data;
|
||||||
|
SensorConfigure(tmp_cfg);
|
||||||
|
dvp_set_image_size(tmp_cfg->output_w, tmp_cfg->output_h);
|
||||||
|
break;
|
||||||
|
case REG_SCCB_READ:
|
||||||
|
ReadDvpReg(drv, (struct DvpRegConfigureInfo *)args->private_data);
|
||||||
|
break;
|
||||||
|
case REG_SCCB_WRITE:
|
||||||
|
//for ov2640,write reg 0x04 to Horizontal mirror or Vertical flip
|
||||||
|
WriteDvpReg(drv, (struct DvpRegConfigureInfo *)args->private_data);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*manage the camera device operations*/
|
||||||
|
static const struct CameraDevDone camera_dev_done =
|
||||||
|
{
|
||||||
|
.dev_open = DvpOpen,
|
||||||
|
.dev_close = DvpClose,
|
||||||
|
.dev_write = NONE,
|
||||||
|
.dev_read = DvpRead,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*Init camera bus*/
|
||||||
|
static int BoardCameraBusInit(struct CameraBus *camera_bus, struct CameraDriver *camera_driver)
|
||||||
|
{
|
||||||
|
x_err_t ret = EOK;
|
||||||
|
|
||||||
|
/*Init the camera bus */
|
||||||
|
camera_bus->private_data = (void *)&camera_dev_done;
|
||||||
|
ret = CameraBusInit(camera_bus, CAMERA_BUS_NAME);
|
||||||
|
if (EOK != ret)
|
||||||
|
{
|
||||||
|
KPrintf("board_camera_init CameraBusInit error %d\n", ret);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Init the camera driver*/
|
||||||
|
camera_driver->private_data = (void *)&camera_dev_done;
|
||||||
|
ret = CameraDriverInit(camera_driver, CAMERA_DRV_NAME);
|
||||||
|
if (EOK != ret)
|
||||||
|
{
|
||||||
|
KPrintf("board_camera_init CameraDriverInit error %d\n", ret);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Attach the camera driver to the camera bus*/
|
||||||
|
ret = CameraDriverAttachToBus(CAMERA_DRV_NAME, CAMERA_BUS_NAME);
|
||||||
|
if (EOK != ret)
|
||||||
|
{
|
||||||
|
KPrintf("board_camera_init CameraDriverAttachToBus error %d\n", ret);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Attach the camera device to the camera bus*/
|
||||||
|
static int BoardCameraDevBend(void)
|
||||||
|
{
|
||||||
|
x_err_t ret = EOK;
|
||||||
|
static struct CameraHardwareDevice camera_device;
|
||||||
|
memset(&camera_device, 0, sizeof(struct CameraHardwareDevice));
|
||||||
|
|
||||||
|
camera_device.camera_dev_done = &camera_dev_done;
|
||||||
|
|
||||||
|
ret = CameraDeviceRegister(&camera_device, NONE, CAMERA_DEVICE_NAME);
|
||||||
|
if (EOK != ret)
|
||||||
|
{
|
||||||
|
KPrintf("board_camera_init CameraDeviceInit device %s error %d\n", CAMERA_DEVICE_NAME, ret);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = CameraDeviceAttachToBus(CAMERA_DEVICE_NAME, CAMERA_BUS_NAME);
|
||||||
|
if (EOK != ret)
|
||||||
|
{
|
||||||
|
KPrintf("board_camera_init CameraDeviceAttachToBus device %s error %d\n", CAMERA_DEVICE_NAME, ret);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int HwDvpInit(void)
|
||||||
|
{
|
||||||
|
x_err_t ret = EOK;
|
||||||
|
static struct CameraBus camera_bus;
|
||||||
|
memset(&camera_bus, 0, sizeof(struct CameraBus));
|
||||||
|
|
||||||
|
static struct CameraDriver camera_driver;
|
||||||
|
memset(&camera_driver, 0, sizeof(struct CameraDriver));
|
||||||
|
|
||||||
|
camera_driver.configure = DvpDrvConfigure;
|
||||||
|
ret = BoardCameraBusInit(&camera_bus, &camera_driver);
|
||||||
|
if (EOK != ret)
|
||||||
|
{
|
||||||
|
KPrintf("board_camera_Init error ret %u\n", ret);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = BoardCameraDevBend();
|
||||||
|
if (EOK != ret)
|
||||||
|
{
|
||||||
|
KPrintf("board_camera_Init error ret %u\n", ret);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
|
@ -0,0 +1,288 @@
|
||||||
|
/* Copyright 2018 Canaan Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "dvp.h"
|
||||||
|
#include "utils.h"
|
||||||
|
#include "fpioa.h"
|
||||||
|
#include "sysctl.h"
|
||||||
|
#include <math.h>
|
||||||
|
#include <sleep.h>
|
||||||
|
|
||||||
|
volatile dvp_t* const dvp = (volatile dvp_t*)DVP_BASE_ADDR;
|
||||||
|
static uint8_t g_sccb_reg_len = 8;
|
||||||
|
|
||||||
|
|
||||||
|
static void dvp_sccb_clk_init(void)
|
||||||
|
{
|
||||||
|
uint32_t tmp;
|
||||||
|
|
||||||
|
tmp = dvp->sccb_cfg & (~(DVP_SCCB_SCL_LCNT_MASK | DVP_SCCB_SCL_HCNT_MASK));
|
||||||
|
tmp |= DVP_SCCB_SCL_LCNT(255) | DVP_SCCB_SCL_HCNT(255);
|
||||||
|
|
||||||
|
dvp->sccb_cfg = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t dvp_sccb_set_clk_rate(uint32_t clk_rate)
|
||||||
|
{
|
||||||
|
uint32_t tmp;
|
||||||
|
uint32_t v_sccb_freq = SysctlClockGetFreq(SYSCTL_CLOCK_APB1);
|
||||||
|
uint16_t v_period_clk_cnt = round(v_sccb_freq / clk_rate / 2.0);
|
||||||
|
if(v_period_clk_cnt > 255)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
tmp = dvp->sccb_cfg & (~(DVP_SCCB_SCL_LCNT_MASK | DVP_SCCB_SCL_HCNT_MASK));
|
||||||
|
tmp |= DVP_SCCB_SCL_LCNT(v_period_clk_cnt) | DVP_SCCB_SCL_HCNT(v_period_clk_cnt);
|
||||||
|
dvp->sccb_cfg = tmp;
|
||||||
|
return SysctlClockGetFreq(SYSCTL_CLOCK_DVP) / (v_period_clk_cnt * 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dvp_sccb_start_transfer(void)
|
||||||
|
{
|
||||||
|
while (dvp->sts & DVP_STS_SCCB_EN)
|
||||||
|
;
|
||||||
|
dvp->sts = DVP_STS_SCCB_EN | DVP_STS_SCCB_EN_WE;
|
||||||
|
while (dvp->sts & DVP_STS_SCCB_EN)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dvp_sccb_send_data(uint8_t dev_addr, uint16_t reg_addr, uint8_t reg_data)
|
||||||
|
{
|
||||||
|
uint32_t tmp;
|
||||||
|
|
||||||
|
tmp = dvp->sccb_cfg & (~DVP_SCCB_BYTE_NUM_MASK);
|
||||||
|
|
||||||
|
(g_sccb_reg_len == 8) ? (tmp |= DVP_SCCB_BYTE_NUM_3) : (tmp |= DVP_SCCB_BYTE_NUM_4);
|
||||||
|
|
||||||
|
dvp->sccb_cfg = tmp;
|
||||||
|
|
||||||
|
if (g_sccb_reg_len == 8)
|
||||||
|
{
|
||||||
|
dvp->sccb_ctl = DVP_SCCB_WRITE_DATA_ENABLE | DVP_SCCB_DEVICE_ADDRESS(dev_addr) | DVP_SCCB_REG_ADDRESS(reg_addr) | DVP_SCCB_WDATA_BYTE0(reg_data);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dvp->sccb_ctl = DVP_SCCB_WRITE_DATA_ENABLE | DVP_SCCB_DEVICE_ADDRESS(dev_addr) | DVP_SCCB_REG_ADDRESS(reg_addr >> 8) | DVP_SCCB_WDATA_BYTE0(reg_addr & 0xff) | DVP_SCCB_WDATA_BYTE1(reg_data);
|
||||||
|
}
|
||||||
|
dvp_sccb_start_transfer();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t dvp_sccb_receive_data(uint8_t dev_addr, uint16_t reg_addr)
|
||||||
|
{
|
||||||
|
uint32_t tmp;
|
||||||
|
|
||||||
|
tmp = dvp->sccb_cfg & (~DVP_SCCB_BYTE_NUM_MASK);
|
||||||
|
|
||||||
|
if (g_sccb_reg_len == 8)
|
||||||
|
tmp |= DVP_SCCB_BYTE_NUM_2;
|
||||||
|
else
|
||||||
|
tmp |= DVP_SCCB_BYTE_NUM_3;
|
||||||
|
|
||||||
|
dvp->sccb_cfg = tmp;
|
||||||
|
|
||||||
|
if (g_sccb_reg_len == 8)
|
||||||
|
{
|
||||||
|
dvp->sccb_ctl = DVP_SCCB_WRITE_DATA_ENABLE | DVP_SCCB_DEVICE_ADDRESS(dev_addr) | DVP_SCCB_REG_ADDRESS(reg_addr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dvp->sccb_ctl = DVP_SCCB_WRITE_DATA_ENABLE | DVP_SCCB_DEVICE_ADDRESS(dev_addr) | DVP_SCCB_REG_ADDRESS(reg_addr >> 8) | DVP_SCCB_WDATA_BYTE0(reg_addr & 0xff);
|
||||||
|
}
|
||||||
|
dvp_sccb_start_transfer();
|
||||||
|
|
||||||
|
dvp->sccb_ctl = DVP_SCCB_DEVICE_ADDRESS(dev_addr);
|
||||||
|
|
||||||
|
dvp_sccb_start_transfer();
|
||||||
|
|
||||||
|
return (uint8_t) DVP_SCCB_RDATA_BYTE(dvp->sccb_cfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dvp_reset(void)
|
||||||
|
{
|
||||||
|
/* First power down */
|
||||||
|
dvp->cmos_cfg |= DVP_CMOS_POWER_DOWN;
|
||||||
|
msleep(200);
|
||||||
|
dvp->cmos_cfg &= ~DVP_CMOS_POWER_DOWN;
|
||||||
|
msleep(200);
|
||||||
|
|
||||||
|
/* Second reset */
|
||||||
|
dvp->cmos_cfg &= ~DVP_CMOS_RESET;
|
||||||
|
msleep(200);
|
||||||
|
dvp->cmos_cfg |= DVP_CMOS_RESET;
|
||||||
|
msleep(200);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dvp_init(uint8_t reg_len)
|
||||||
|
{
|
||||||
|
g_sccb_reg_len = reg_len;
|
||||||
|
sysctl_clock_enable(SYSCTL_CLOCK_DVP);
|
||||||
|
sysctl_reset(SYSCTL_RESET_DVP);
|
||||||
|
dvp->cmos_cfg &= (~DVP_CMOS_CLK_DIV_MASK);
|
||||||
|
dvp->cmos_cfg |= DVP_CMOS_CLK_DIV(3) | DVP_CMOS_CLK_ENABLE;
|
||||||
|
dvp_sccb_clk_init();
|
||||||
|
dvp_reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t dvp_set_xclk_rate(uint32_t xclk_rate)
|
||||||
|
{
|
||||||
|
uint32_t v_apb1_clk = SysctlClockGetFreq(SYSCTL_CLOCK_APB1);
|
||||||
|
uint32_t v_period;
|
||||||
|
if(v_apb1_clk > xclk_rate * 2)
|
||||||
|
v_period = round(v_apb1_clk / (xclk_rate * 2.0)) - 1;
|
||||||
|
else
|
||||||
|
v_period = 0;
|
||||||
|
if(v_period > 255)
|
||||||
|
v_period = 255;
|
||||||
|
dvp->cmos_cfg &= (~DVP_CMOS_CLK_DIV_MASK);
|
||||||
|
dvp->cmos_cfg |= DVP_CMOS_CLK_DIV(v_period) | DVP_CMOS_CLK_ENABLE;
|
||||||
|
dvp_reset();
|
||||||
|
return v_apb1_clk / ((v_period + 1) * 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dvp_set_image_format(uint32_t format)
|
||||||
|
{
|
||||||
|
uint32_t tmp;
|
||||||
|
|
||||||
|
tmp = dvp->dvp_cfg & (~DVP_CFG_FORMAT_MASK);
|
||||||
|
dvp->dvp_cfg = tmp | format;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dvp_enable_burst(void)
|
||||||
|
{
|
||||||
|
dvp->dvp_cfg |= DVP_CFG_BURST_SIZE_4BEATS;
|
||||||
|
|
||||||
|
dvp->axi &= (~DVP_AXI_GM_MLEN_MASK);
|
||||||
|
dvp->axi |= DVP_AXI_GM_MLEN_4BYTE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dvp_disable_burst(void)
|
||||||
|
{
|
||||||
|
dvp->dvp_cfg &= (~DVP_CFG_BURST_SIZE_4BEATS);
|
||||||
|
|
||||||
|
dvp->axi &= (~DVP_AXI_GM_MLEN_MASK);
|
||||||
|
dvp->axi |= DVP_AXI_GM_MLEN_1BYTE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dvp_set_image_size(uint32_t width, uint32_t height)
|
||||||
|
{
|
||||||
|
uint32_t tmp;
|
||||||
|
|
||||||
|
tmp = dvp->dvp_cfg & (~(DVP_CFG_HREF_BURST_NUM_MASK | DVP_CFG_LINE_NUM_MASK));
|
||||||
|
|
||||||
|
tmp |= DVP_CFG_LINE_NUM(height);
|
||||||
|
|
||||||
|
if (dvp->dvp_cfg & DVP_CFG_BURST_SIZE_4BEATS)
|
||||||
|
tmp |= DVP_CFG_HREF_BURST_NUM(width / 8 / 4);
|
||||||
|
else
|
||||||
|
tmp |= DVP_CFG_HREF_BURST_NUM(width / 8 / 1);
|
||||||
|
|
||||||
|
dvp->dvp_cfg = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dvp_set_ai_addr(uint32_t r_addr, uint32_t g_addr, uint32_t b_addr)
|
||||||
|
{
|
||||||
|
dvp->r_addr = r_addr;
|
||||||
|
dvp->g_addr = g_addr;
|
||||||
|
dvp->b_addr = b_addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dvp_set_display_addr(uint32_t addr)
|
||||||
|
{
|
||||||
|
dvp->rgb_addr = addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dvp_start_frame(void)
|
||||||
|
{
|
||||||
|
while (!(dvp->sts & DVP_STS_FRAME_START))
|
||||||
|
;
|
||||||
|
dvp->sts = (DVP_STS_FRAME_START | DVP_STS_FRAME_START_WE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dvp_start_convert(void)
|
||||||
|
{
|
||||||
|
dvp->sts = DVP_STS_DVP_EN | DVP_STS_DVP_EN_WE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dvp_finish_convert(void)
|
||||||
|
{
|
||||||
|
while (!(dvp->sts & DVP_STS_FRAME_FINISH))
|
||||||
|
;
|
||||||
|
dvp->sts = DVP_STS_FRAME_FINISH | DVP_STS_FRAME_FINISH_WE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dvp_get_image(void)
|
||||||
|
{
|
||||||
|
while (!(dvp->sts & DVP_STS_FRAME_START))
|
||||||
|
;
|
||||||
|
dvp->sts = DVP_STS_FRAME_START | DVP_STS_FRAME_START_WE;
|
||||||
|
while (!(dvp->sts & DVP_STS_FRAME_START))
|
||||||
|
;
|
||||||
|
dvp->sts = DVP_STS_FRAME_FINISH | DVP_STS_FRAME_FINISH_WE | DVP_STS_FRAME_START | DVP_STS_FRAME_START_WE | DVP_STS_DVP_EN | DVP_STS_DVP_EN_WE;
|
||||||
|
while (!(dvp->sts & DVP_STS_FRAME_FINISH))
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dvp_config_interrupt(uint32_t interrupt, uint8_t enable)
|
||||||
|
{
|
||||||
|
if (enable)
|
||||||
|
dvp->dvp_cfg |= interrupt;
|
||||||
|
else
|
||||||
|
dvp->dvp_cfg &= (~interrupt);
|
||||||
|
}
|
||||||
|
|
||||||
|
int dvp_get_interrupt(uint32_t interrupt)
|
||||||
|
{
|
||||||
|
if (dvp->sts & interrupt)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dvp_clear_interrupt(uint32_t interrupt)
|
||||||
|
{
|
||||||
|
interrupt |= (interrupt << 1);
|
||||||
|
dvp->sts |= interrupt;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dvp_enable_auto(void)
|
||||||
|
{
|
||||||
|
dvp->dvp_cfg |= DVP_CFG_AUTO_ENABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dvp_disable_auto(void)
|
||||||
|
{
|
||||||
|
dvp->dvp_cfg &= (~DVP_CFG_AUTO_ENABLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dvp_set_output_enable(dvp_output_mode_t index, int enable)
|
||||||
|
{
|
||||||
|
configASSERT(index < 2);
|
||||||
|
|
||||||
|
if (index == 0)
|
||||||
|
{
|
||||||
|
if (enable)
|
||||||
|
dvp->dvp_cfg |= DVP_CFG_AI_OUTPUT_ENABLE;
|
||||||
|
else
|
||||||
|
dvp->dvp_cfg &= ~DVP_CFG_AI_OUTPUT_ENABLE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (enable)
|
||||||
|
dvp->dvp_cfg |= DVP_CFG_DISPLAY_OUTPUT_ENABLE;
|
||||||
|
else
|
||||||
|
dvp->dvp_cfg &= ~DVP_CFG_DISPLAY_OUTPUT_ENABLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,463 @@
|
||||||
|
/* Copyright 2018 Canaan Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "ov2640.h"
|
||||||
|
#include "dvp.h"
|
||||||
|
#include "plic.h"
|
||||||
|
#include "board.h"
|
||||||
|
|
||||||
|
#if defined SVGA_25FPS_MODE
|
||||||
|
const uint8_t ov2640_config[][2]=
|
||||||
|
{
|
||||||
|
{0xff, 0x01},
|
||||||
|
{0x12, 0x80},
|
||||||
|
{0xff, 0x00},
|
||||||
|
{0x2c, 0xff},
|
||||||
|
{0x2e, 0xdf},
|
||||||
|
{0xff, 0x01},
|
||||||
|
{0x3c, 0x32},
|
||||||
|
{0x11, 0x00},
|
||||||
|
{0x09, 0x02},
|
||||||
|
{0x04, 0x28},
|
||||||
|
{0x13, 0xe5},
|
||||||
|
{0x14, 0x48},
|
||||||
|
{0x2c, 0x0c},
|
||||||
|
{0x33, 0x78},
|
||||||
|
{0x3a, 0x33},
|
||||||
|
{0x3b, 0xfb},
|
||||||
|
{0x3e, 0x00},
|
||||||
|
{0x43, 0x11},
|
||||||
|
{0x16, 0x10},
|
||||||
|
{0x39, 0x92},
|
||||||
|
{0x35, 0xda},
|
||||||
|
{0x22, 0x1a},
|
||||||
|
{0x37, 0xc3},
|
||||||
|
{0x23, 0x00},
|
||||||
|
{0x34, 0xc0},
|
||||||
|
{0x36, 0x1a},
|
||||||
|
{0x06, 0x88},
|
||||||
|
{0x07, 0xc0},
|
||||||
|
{0x0d, 0x87},
|
||||||
|
{0x0e, 0x41},
|
||||||
|
{0x4c, 0x00},
|
||||||
|
{0x48, 0x00},
|
||||||
|
{0x5b, 0x00},
|
||||||
|
{0x42, 0x03},
|
||||||
|
{0x4a, 0x81},
|
||||||
|
{0x21, 0x99},
|
||||||
|
{0x24, 0x40},
|
||||||
|
{0x25, 0x38},
|
||||||
|
{0x26, 0x82},
|
||||||
|
{0x5c, 0x00},
|
||||||
|
{0x63, 0x00},
|
||||||
|
{0x46, 0x22},
|
||||||
|
{0x0c, 0x3c},
|
||||||
|
{0x61, 0x70},
|
||||||
|
{0x62, 0x80},
|
||||||
|
{0x7c, 0x05},
|
||||||
|
{0x20, 0x80},
|
||||||
|
{0x28, 0x30},
|
||||||
|
{0x6c, 0x00},
|
||||||
|
{0x6d, 0x80},
|
||||||
|
{0x6e, 0x00},
|
||||||
|
{0x70, 0x02},
|
||||||
|
{0x71, 0x94},
|
||||||
|
{0x73, 0xc1},
|
||||||
|
{0x3d, 0x34},
|
||||||
|
{0x5a, 0x57},
|
||||||
|
{0x12, 0x40},
|
||||||
|
{0x17, 0x11},
|
||||||
|
{0x18, 0x43},
|
||||||
|
{0x19, 0x00},
|
||||||
|
{0x1a, 0x97},
|
||||||
|
{0x32, 0x09},
|
||||||
|
{0x37, 0xc0},
|
||||||
|
{0x4f, 0xca},
|
||||||
|
{0x50, 0xa8},
|
||||||
|
{0x5a, 0x23},
|
||||||
|
{0x6d, 0x00},
|
||||||
|
{0x3d, 0x38},
|
||||||
|
{0xff, 0x00},
|
||||||
|
{0xe5, 0x7f},
|
||||||
|
{0xf9, 0xc0},
|
||||||
|
{0x41, 0x24},
|
||||||
|
{0xe0, 0x14},
|
||||||
|
{0x76, 0xff},
|
||||||
|
{0x33, 0xa0},
|
||||||
|
{0x42, 0x20},
|
||||||
|
{0x43, 0x18},
|
||||||
|
{0x4c, 0x00},
|
||||||
|
{0x87, 0xd5},
|
||||||
|
{0x88, 0x3f},
|
||||||
|
{0xd7, 0x03},
|
||||||
|
{0xd9, 0x10},
|
||||||
|
{0xd3, 0x82},
|
||||||
|
{0xc8, 0x08},
|
||||||
|
{0xc9, 0x80},
|
||||||
|
{0x7c, 0x00},
|
||||||
|
{0x7d, 0x00},
|
||||||
|
{0x7c, 0x03},
|
||||||
|
{0x7d, 0x48},
|
||||||
|
{0x7d, 0x48},
|
||||||
|
{0x7c, 0x08},
|
||||||
|
{0x7d, 0x20},
|
||||||
|
{0x7d, 0x10},
|
||||||
|
{0x7d, 0x0e},
|
||||||
|
{0x90, 0x00},
|
||||||
|
{0x91, 0x0e},
|
||||||
|
{0x91, 0x1a},
|
||||||
|
{0x91, 0x31},
|
||||||
|
{0x91, 0x5a},
|
||||||
|
{0x91, 0x69},
|
||||||
|
{0x91, 0x75},
|
||||||
|
{0x91, 0x7e},
|
||||||
|
{0x91, 0x88},
|
||||||
|
{0x91, 0x8f},
|
||||||
|
{0x91, 0x96},
|
||||||
|
{0x91, 0xa3},
|
||||||
|
{0x91, 0xaf},
|
||||||
|
{0x91, 0xc4},
|
||||||
|
{0x91, 0xd7},
|
||||||
|
{0x91, 0xe8},
|
||||||
|
{0x91, 0x20},
|
||||||
|
{0x92, 0x00},
|
||||||
|
{0x93, 0x06},
|
||||||
|
{0x93, 0xe3},
|
||||||
|
{0x93, 0x05},
|
||||||
|
{0x93, 0x05},
|
||||||
|
{0x93, 0x00},
|
||||||
|
{0x93, 0x04},
|
||||||
|
{0x93, 0x00},
|
||||||
|
{0x93, 0x00},
|
||||||
|
{0x93, 0x00},
|
||||||
|
{0x93, 0x00},
|
||||||
|
{0x93, 0x00},
|
||||||
|
{0x93, 0x00},
|
||||||
|
{0x93, 0x00},
|
||||||
|
{0x96, 0x00},
|
||||||
|
{0x97, 0x08},
|
||||||
|
{0x97, 0x19},
|
||||||
|
{0x97, 0x02},
|
||||||
|
{0x97, 0x0c},
|
||||||
|
{0x97, 0x24},
|
||||||
|
{0x97, 0x30},
|
||||||
|
{0x97, 0x28},
|
||||||
|
{0x97, 0x26},
|
||||||
|
{0x97, 0x02},
|
||||||
|
{0x97, 0x98},
|
||||||
|
{0x97, 0x80},
|
||||||
|
{0x97, 0x00},
|
||||||
|
{0x97, 0x00},
|
||||||
|
{0xc3, 0xed},
|
||||||
|
{0xa4, 0x00},
|
||||||
|
{0xa8, 0x00},
|
||||||
|
{0xc5, 0x11},
|
||||||
|
{0xc6, 0x51},
|
||||||
|
{0xbf, 0x80},
|
||||||
|
{0xc7, 0x10},
|
||||||
|
{0xb6, 0x66},
|
||||||
|
{0xb8, 0xa5},
|
||||||
|
{0xb7, 0x64},
|
||||||
|
{0xb9, 0x7c},
|
||||||
|
{0xb3, 0xaf},
|
||||||
|
{0xb4, 0x97},
|
||||||
|
{0xb5, 0xff},
|
||||||
|
{0xb0, 0xc5},
|
||||||
|
{0xb1, 0x94},
|
||||||
|
{0xb2, 0x0f},
|
||||||
|
{0xc4, 0x5c},
|
||||||
|
{0xc0, 0x64},
|
||||||
|
{0xc1, 0x4b},
|
||||||
|
{0x8c, 0x00},
|
||||||
|
{0x86, 0x3d},
|
||||||
|
{0x50, 0x00},
|
||||||
|
{0x51, 0xc8},
|
||||||
|
{0x52, 0x96},
|
||||||
|
{0x53, 0x00},
|
||||||
|
{0x54, 0x00},
|
||||||
|
{0x55, 0x00},
|
||||||
|
{0x5a, 0xc8},
|
||||||
|
{0x5b, 0x96},
|
||||||
|
{0x5c, 0x00},
|
||||||
|
{0xd3, 0x02},
|
||||||
|
{0xc3, 0xed},
|
||||||
|
{0x7f, 0x00},
|
||||||
|
{0xda, 0x08},
|
||||||
|
{0xe5, 0x1f},
|
||||||
|
{0xe1, 0x67},
|
||||||
|
{0xe0, 0x00},
|
||||||
|
{0xdd, 0x7f},
|
||||||
|
{0x05, 0x00},
|
||||||
|
{0xff, 0x00},
|
||||||
|
{0xe0, 0x04},
|
||||||
|
{0x5a, 0x50},
|
||||||
|
{0x5b, 0x3c},
|
||||||
|
{0x5c, 0x00},
|
||||||
|
{0xe0, 0x00},
|
||||||
|
{0x00, 0x00}
|
||||||
|
};
|
||||||
|
#elif defined UXGA_15FPS_MODE
|
||||||
|
const uint8_t ov2640_config[][2]=
|
||||||
|
{
|
||||||
|
{0xFF, 0x00},
|
||||||
|
{0x2C, 0xFF},
|
||||||
|
{0x2E, 0xDF},
|
||||||
|
{0xFF, 0x01},
|
||||||
|
{0x3C, 0x32},
|
||||||
|
{0x11, 0x00},
|
||||||
|
{0x09, 0x02},
|
||||||
|
{0x04, 0x28},
|
||||||
|
{0x13, 0xE5},
|
||||||
|
{0x14, 0x48},
|
||||||
|
{0x2C, 0x0C},
|
||||||
|
{0x33, 0x78},
|
||||||
|
{0x3A, 0x33},
|
||||||
|
{0x3B, 0xFB},
|
||||||
|
{0x3E, 0x00},
|
||||||
|
{0x43, 0x11},
|
||||||
|
{0x16, 0x10},
|
||||||
|
{0x39, 0x92},
|
||||||
|
{0x35, 0xDA},
|
||||||
|
{0x22, 0x1A},
|
||||||
|
{0x37, 0xC3},
|
||||||
|
{0x23, 0x00},
|
||||||
|
{0x34, 0xC0},
|
||||||
|
{0x36, 0x1A},
|
||||||
|
{0x06, 0x88},
|
||||||
|
{0x07, 0xC0},
|
||||||
|
{0x0D, 0x87},
|
||||||
|
{0x0E, 0x41},
|
||||||
|
{0x4C, 0x00},
|
||||||
|
{0x48, 0x00},
|
||||||
|
{0x5B, 0x00},
|
||||||
|
{0x42, 0x03},
|
||||||
|
{0x4A, 0x81},
|
||||||
|
{0x21, 0x99},
|
||||||
|
{0x24, 0x40},
|
||||||
|
{0x25, 0x38},
|
||||||
|
{0x26, 0x82},
|
||||||
|
{0x5C, 0x00},
|
||||||
|
{0x63, 0x00},
|
||||||
|
{0x46, 0x00},
|
||||||
|
{0x0C, 0x3C},
|
||||||
|
{0x61, 0x70},
|
||||||
|
{0x62, 0x80},
|
||||||
|
{0x7C, 0x05},
|
||||||
|
{0x20, 0x80},
|
||||||
|
{0x28, 0x30},
|
||||||
|
{0x6C, 0x00},
|
||||||
|
{0x6D, 0x80},
|
||||||
|
{0x6E, 0x00},
|
||||||
|
{0x70, 0x02},
|
||||||
|
{0x71, 0x94},
|
||||||
|
{0x73, 0xC1},
|
||||||
|
{0x3D, 0x34},
|
||||||
|
{0x5A, 0x57},
|
||||||
|
{0x12, 0x00},
|
||||||
|
{0x17, 0x11},
|
||||||
|
{0x18, 0x75},
|
||||||
|
{0x19, 0x01},
|
||||||
|
{0x1A, 0x97},
|
||||||
|
{0x32, 0x36},
|
||||||
|
{0x03, 0x0F},
|
||||||
|
{0x37, 0x40},
|
||||||
|
{0x4F, 0xCA},
|
||||||
|
{0x50, 0xA8},
|
||||||
|
{0x5A, 0x23},
|
||||||
|
{0x6D, 0x00},
|
||||||
|
{0x6D, 0x38},
|
||||||
|
{0xFF, 0x00},
|
||||||
|
{0xE5, 0x7F},
|
||||||
|
{0xF9, 0xC0},
|
||||||
|
{0x41, 0x24},
|
||||||
|
{0xE0, 0x14},
|
||||||
|
{0x76, 0xFF},
|
||||||
|
{0x33, 0xA0},
|
||||||
|
{0x42, 0x20},
|
||||||
|
{0x43, 0x18},
|
||||||
|
{0x4C, 0x00},
|
||||||
|
{0x87, 0xD5},
|
||||||
|
{0x88, 0x3F},
|
||||||
|
{0xD7, 0x03},
|
||||||
|
{0xD9, 0x10},
|
||||||
|
{0xD3, 0x82},
|
||||||
|
{0xC8, 0x08},
|
||||||
|
{0xC9, 0x80},
|
||||||
|
{0x7C, 0x00},
|
||||||
|
{0x7D, 0x00},
|
||||||
|
{0x7C, 0x03},
|
||||||
|
{0x7D, 0x48},
|
||||||
|
{0x7D, 0x48},
|
||||||
|
{0x7C, 0x08},
|
||||||
|
{0x7D, 0x20},
|
||||||
|
{0x7D, 0x10},
|
||||||
|
{0x7D, 0x0E},
|
||||||
|
{0x90, 0x00},
|
||||||
|
{0x91, 0x0E},
|
||||||
|
{0x91, 0x1A},
|
||||||
|
{0x91, 0x31},
|
||||||
|
{0x91, 0x5A},
|
||||||
|
{0x91, 0x69},
|
||||||
|
{0x91, 0x75},
|
||||||
|
{0x91, 0x7E},
|
||||||
|
{0x91, 0x88},
|
||||||
|
{0x91, 0x8F},
|
||||||
|
{0x91, 0x96},
|
||||||
|
{0x91, 0xA3},
|
||||||
|
{0x91, 0xAF},
|
||||||
|
{0x91, 0xC4},
|
||||||
|
{0x91, 0xD7},
|
||||||
|
{0x91, 0xE8},
|
||||||
|
{0x91, 0x20},
|
||||||
|
{0x92, 0x00},
|
||||||
|
{0x93, 0x06},
|
||||||
|
{0x93, 0xE3},
|
||||||
|
{0x93, 0x05},
|
||||||
|
{0x93, 0x05},
|
||||||
|
{0x93, 0x00},
|
||||||
|
{0x93, 0x04},
|
||||||
|
{0x93, 0x00},
|
||||||
|
{0x93, 0x00},
|
||||||
|
{0x93, 0x00},
|
||||||
|
{0x93, 0x00},
|
||||||
|
{0x93, 0x00},
|
||||||
|
{0x93, 0x00},
|
||||||
|
{0x93, 0x00},
|
||||||
|
{0x96, 0x00},
|
||||||
|
{0x97, 0x08},
|
||||||
|
{0x97, 0x19},
|
||||||
|
{0x97, 0x02},
|
||||||
|
{0x97, 0x0C},
|
||||||
|
{0x97, 0x24},
|
||||||
|
{0x97, 0x30},
|
||||||
|
{0x97, 0x28},
|
||||||
|
{0x97, 0x26},
|
||||||
|
{0x97, 0x02},
|
||||||
|
{0x97, 0x98},
|
||||||
|
{0x97, 0x80},
|
||||||
|
{0x97, 0x00},
|
||||||
|
{0x97, 0x00},
|
||||||
|
{0xC3, 0xEF},
|
||||||
|
{0xA4, 0x00},
|
||||||
|
{0xA8, 0x00},
|
||||||
|
{0xC5, 0x11},
|
||||||
|
{0xC6, 0x51},
|
||||||
|
{0xBF, 0x80},
|
||||||
|
{0xC7, 0x10},
|
||||||
|
{0xB6, 0x66},
|
||||||
|
{0xB8, 0xA5},
|
||||||
|
{0xB7, 0x64},
|
||||||
|
{0xB9, 0x7C},
|
||||||
|
{0xB3, 0xAF},
|
||||||
|
{0xB4, 0x97},
|
||||||
|
{0xB5, 0xFF},
|
||||||
|
{0xB0, 0xC5},
|
||||||
|
{0xB1, 0x94},
|
||||||
|
{0xB2, 0x0F},
|
||||||
|
{0xC4, 0x5C},
|
||||||
|
{0xC0, 0xC8},
|
||||||
|
{0xC1, 0x96},
|
||||||
|
{0x8C, 0x00},
|
||||||
|
{0x86, 0x3D},
|
||||||
|
{0x50, 0x00},
|
||||||
|
{0x51, 0x90},
|
||||||
|
{0x52, 0x2C},
|
||||||
|
{0x53, 0x00},
|
||||||
|
{0x54, 0x00},
|
||||||
|
{0x55, 0x88},
|
||||||
|
{0x5A, 0x90},
|
||||||
|
{0x5B, 0x2C},
|
||||||
|
{0x5C, 0x05},
|
||||||
|
{0xD3, 0x02},
|
||||||
|
{0xC3, 0xED},
|
||||||
|
{0x7F, 0x00},
|
||||||
|
{0xDA, 0x08},
|
||||||
|
{0xE5, 0x1F},
|
||||||
|
{0xE1, 0x67},
|
||||||
|
{0xE0, 0x00},
|
||||||
|
{0xDD, 0x7F},
|
||||||
|
{0x05, 0x00},
|
||||||
|
{0xe0, 0x04},
|
||||||
|
{0x5a, 0x50},
|
||||||
|
{0x5b, 0x3c},
|
||||||
|
{0x5c, 0x00},
|
||||||
|
{0xe0, 0x00},
|
||||||
|
{0x00, 0x00}
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
const uint8_t ov2640_config[][2]=
|
||||||
|
{
|
||||||
|
{0x00,x00}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int ov2640_init(void)
|
||||||
|
{
|
||||||
|
uint16_t v_manuf_id;
|
||||||
|
uint16_t v_device_id;
|
||||||
|
ov2640_read_id(&v_manuf_id, &v_device_id);
|
||||||
|
printf("manuf_id:0x%04x,device_id:0x%04x\n", v_manuf_id, v_device_id);
|
||||||
|
uint16_t index = 0;
|
||||||
|
for (index = 0; ov2640_config[index][0]; index++)
|
||||||
|
dvp_sccb_send_data(OV2640_ADDR, ov2640_config[index][0], ov2640_config[index][1]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ov2640_read_id(uint16_t *manuf_id, uint16_t *device_id)
|
||||||
|
{
|
||||||
|
dvp_sccb_send_data(OV2640_ADDR, 0xFF, 0x01);
|
||||||
|
*manuf_id = (dvp_sccb_receive_data(OV2640_ADDR, 0x1C) << 8) | dvp_sccb_receive_data(OV2640_ADDR, 0x1D);
|
||||||
|
*device_id = (dvp_sccb_receive_data(OV2640_ADDR, 0x0A) << 8) | dvp_sccb_receive_data(OV2640_ADDR, 0x0B);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SensorConfigure(struct CameraCfg *cfg_info)
|
||||||
|
{
|
||||||
|
uint8_t reg_tmp;
|
||||||
|
|
||||||
|
//set reg mode to sensor
|
||||||
|
dvp_sccb_send_data(OV2640_ADDR, 0xFF, 0x00);
|
||||||
|
|
||||||
|
//configure the window size and position
|
||||||
|
dvp_sccb_send_data(OV2640_ADDR, 0x51, cfg_info->window_w>>2);
|
||||||
|
dvp_sccb_send_data(OV2640_ADDR, 0x52, cfg_info->window_h>>2);
|
||||||
|
dvp_sccb_send_data(OV2640_ADDR, 0x53, (uint8_t)(cfg_info->window_xoffset&0xFF));
|
||||||
|
dvp_sccb_send_data(OV2640_ADDR, 0x54, (uint8_t)(cfg_info->window_yoffset&0xFF));
|
||||||
|
dvp_sccb_send_data(OV2640_ADDR, 0x55, (((cfg_info->window_h/4)&0x100)>>1)+
|
||||||
|
((cfg_info->window_yoffset&0x700)>>4)+
|
||||||
|
(((cfg_info->window_w/4)&0x100)>>5)+
|
||||||
|
((cfg_info->window_xoffset&0x700)>>8));
|
||||||
|
dvp_sccb_send_data(OV2640_ADDR, 0x57, ((cfg_info->window_w/4)&0x200)>>2);
|
||||||
|
dvp_sccb_send_data(OV2640_ADDR, 0x5A, cfg_info->output_w>>2);
|
||||||
|
dvp_sccb_send_data(OV2640_ADDR, 0x5B, cfg_info->output_h>>2);
|
||||||
|
|
||||||
|
//set reg mode to dsp
|
||||||
|
dvp_sccb_send_data(OV2640_ADDR, 0xFF, 0x01);
|
||||||
|
|
||||||
|
//configure dsp gain
|
||||||
|
if(cfg_info->gain_manu_enable){
|
||||||
|
reg_tmp = dvp_sccb_receive_data(OV2640_ADDR, 0x13);
|
||||||
|
dvp_sccb_send_data(OV2640_ADDR, 0x13, reg_tmp&0xFB);
|
||||||
|
dvp_sccb_send_data(OV2640_ADDR, 0x00, cfg_info->gain);
|
||||||
|
}else{
|
||||||
|
reg_tmp = dvp_sccb_receive_data(OV2640_ADDR, 0x13);
|
||||||
|
dvp_sccb_send_data(OV2640_ADDR, 0x13, reg_tmp|0x04);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
|
@ -72,31 +72,15 @@ static struct io_config
|
||||||
IOCONFIG(BSP_UART2_RXD_PIN, FUNC_UART2_RX),
|
IOCONFIG(BSP_UART2_RXD_PIN, FUNC_UART2_RX),
|
||||||
#endif
|
#endif
|
||||||
#ifdef BSP_USING_UART3
|
#ifdef BSP_USING_UART3
|
||||||
IOCONFIG(BSP_UART3_TXD_PIN, FUNC_UART3_RX),
|
IOCONFIG(BSP_UART3_TXD_PIN, FUNC_UART3_TX),
|
||||||
IOCONFIG(BSP_UART3_RXD_PIN, FUNC_UART3_TX),
|
IOCONFIG(BSP_UART3_RXD_PIN, FUNC_UART3_RX),
|
||||||
#endif
|
#endif
|
||||||
#ifdef BSP_USING_I2C
|
#ifdef BSP_USING_I2C
|
||||||
IOCONFIG(BSP_I2C_SDA, FUNC_GPIO3),
|
IOCONFIG(BSP_I2C_SDA, FUNC_GPIO3),
|
||||||
IOCONFIG(BSP_I2C_SCL, FUNC_GPIO4),
|
IOCONFIG(BSP_I2C_SCL, FUNC_GPIO4),
|
||||||
#endif
|
#endif
|
||||||
#ifdef BSP_USING_TOUCH
|
#ifdef BSP_USING_TOUCH
|
||||||
// IOCONFIG(BSP_TOUCH_TP_INT, HS_GPIO(FPIOA_TOUCH_TP_INT)),
|
IOCONFIG(BSP_TOUCH_TP_INT, HS_GPIO(FPIOA_TOUCH_TP_INT)),
|
||||||
IOCONFIG(BSP_TOUCH_TP_INT, HS_GPIO(FUNC_GPIOHS30)),
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef BSP_USING_CH438
|
|
||||||
IOCONFIG(BSP_CH438_ALE_PIN, HS_GPIO(FPIOA_CH438_ALE)),
|
|
||||||
IOCONFIG(BSP_CH438_NWR_PIN, HS_GPIO(FPIOA_CH438_NWR)),
|
|
||||||
IOCONFIG(BSP_CH438_NRD_PIN, HS_GPIO(FPIOA_CH438_NRD)),
|
|
||||||
IOCONFIG(BSP_CH438_INT_PIN, HS_GPIO(FPIOA_CH438_INT)),
|
|
||||||
IOCONFIG(BSP_CH438_D0_PIN, HS_GPIO(FPIOA_CH438_D0)),
|
|
||||||
IOCONFIG(BSP_CH438_D1_PIN, HS_GPIO(FPIOA_CH438_D1)),
|
|
||||||
IOCONFIG(BSP_CH438_D2_PIN, HS_GPIO(FPIOA_CH438_D2)),
|
|
||||||
IOCONFIG(BSP_CH438_D3_PIN, HS_GPIO(FPIOA_CH438_D3)),
|
|
||||||
IOCONFIG(BSP_CH438_D4_PIN, HS_GPIO(FPIOA_CH438_D4)),
|
|
||||||
IOCONFIG(BSP_CH438_D5_PIN, HS_GPIO(FPIOA_CH438_D5)),
|
|
||||||
IOCONFIG(BSP_CH438_D6_PIN, HS_GPIO(FPIOA_CH438_D6)),
|
|
||||||
IOCONFIG(BSP_CH438_D7_PIN, HS_GPIO(FPIOA_CH438_D7)),
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef BSP_USING_SOFT_SPI
|
#ifdef BSP_USING_SOFT_SPI
|
||||||
|
@ -106,6 +90,17 @@ static struct io_config
|
||||||
IOCONFIG(BSP_SOFT_SPI_NCS_PIN, HS_GPIO(FPIOA_SOFT_SPI_NCS)),
|
IOCONFIG(BSP_SOFT_SPI_NCS_PIN, HS_GPIO(FPIOA_SOFT_SPI_NCS)),
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef BSP_USING_CAMERA
|
||||||
|
IOCONFIG(BSP_DVP_RST_PIN,FUNC_CMOS_RST),
|
||||||
|
IOCONFIG(BSP_DVP_PWDN_PIN, FUNC_CMOS_PWDN),
|
||||||
|
IOCONFIG(BSP_DVP_XCLK_PIN,FUNC_CMOS_XCLK),
|
||||||
|
IOCONFIG(BSP_DVP_PCLK_PIN,FUNC_CMOS_PCLK),
|
||||||
|
IOCONFIG(BSP_DVP_HSYNC_PIN,FUNC_CMOS_HREF),
|
||||||
|
IOCONFIG(BSP_DVP_VSYNC_PIN,FUNC_CMOS_VSYNC),
|
||||||
|
IOCONFIG(BSP_DVP_SCL_PIN,FUNC_SCCB_SCLK),
|
||||||
|
IOCONFIG(BSP_DVP_SDA_PIN,FUNC_SCCB_SDA),
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef BSP_USING_LORA
|
#ifdef BSP_USING_LORA
|
||||||
IOCONFIG(BSP_E220_M0_PIN, HS_GPIO(FUNC_GPIOHS10)),
|
IOCONFIG(BSP_E220_M0_PIN, HS_GPIO(FUNC_GPIOHS10)),
|
||||||
IOCONFIG(BSP_E220_M1_PIN, HS_GPIO(FUNC_GPIOHS11)),
|
IOCONFIG(BSP_E220_M1_PIN, HS_GPIO(FUNC_GPIOHS11)),
|
||||||
|
@ -159,6 +154,11 @@ int IoConfigInit(void)
|
||||||
sysctl_set_power_mode(SYSCTL_POWER_BANK3, SYSCTL_POWER_V33);
|
sysctl_set_power_mode(SYSCTL_POWER_BANK3, SYSCTL_POWER_V33);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef BSP_USING_CAMERA
|
||||||
|
sysctl_set_power_mode(SYSCTL_POWER_BANK7,SYSCTL_POWER_V18);
|
||||||
|
// sysctl_set_power_mode(SYSCTL_POWER_BANK7,SYSCTL_POWER_V18);
|
||||||
|
#endif
|
||||||
|
|
||||||
for(i = 0; i < count; i++)
|
for(i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
ret = FpioaSetFunction(io_config[i].io_num, io_config[i].func);
|
ret = FpioaSetFunction(io_config[i].io_num, io_config[i].func);
|
||||||
|
|
|
@ -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_dvp.h
|
||||||
|
* @brief define edu-riscv64-board DVP init function
|
||||||
|
* @version 2.0
|
||||||
|
* @author AIIT XUOS Lab
|
||||||
|
* @date 2022-11-21
|
||||||
|
*/
|
||||||
|
#ifndef CONNECT_DVP_H
|
||||||
|
#define CONNECT_DVP_H
|
||||||
|
#include <device.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int HwDvpInit(void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -64,6 +64,10 @@ typedef enum _touch_event
|
||||||
#define GTP_REG_CONFIG_DATA 0x8047
|
#define GTP_REG_CONFIG_DATA 0x8047
|
||||||
#define GTP_REG_VERSION 0x8140
|
#define GTP_REG_VERSION 0x8140
|
||||||
|
|
||||||
|
#define LCD_SIZE 320
|
||||||
|
#define TOUCH_WIDTH 1000
|
||||||
|
#define TOUCH_HEIGHT 660
|
||||||
|
|
||||||
#define CFG_GROUP_LEN(p_cfg_grp) (sizeof(p_cfg_grp) / sizeof(p_cfg_grp[0]))
|
#define CFG_GROUP_LEN(p_cfg_grp) (sizeof(p_cfg_grp) / sizeof(p_cfg_grp[0]))
|
||||||
|
|
||||||
int HwTouchInit(void);
|
int HwTouchInit(void);
|
||||||
|
|
|
@ -30,7 +30,7 @@ Modification: add edu-riscv64-board io configure define
|
||||||
#ifndef __DRV_IO_CONFIG_H__
|
#ifndef __DRV_IO_CONFIG_H__
|
||||||
#define __DRV_IO_CONFIG_H__
|
#define __DRV_IO_CONFIG_H__
|
||||||
|
|
||||||
<<<<<<< HEAD enum HS_GPIO_CONFIG {
|
enum HS_GPIO_CONFIG {
|
||||||
#ifdef BSP_USING_LCD
|
#ifdef BSP_USING_LCD
|
||||||
LCD_DC_PIN = 0, /* LCD DC PIN */
|
LCD_DC_PIN = 0, /* LCD DC PIN */
|
||||||
#endif
|
#endif
|
||||||
|
@ -53,99 +53,35 @@ Modification: add edu-riscv64-board io configure define
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
#ifdef BSP_USING_CH438
|
#ifdef BSP_USING_SOFT_SPI
|
||||||
#define FPIOA_CH438_ALE 12
|
#define FPIOA_SOFT_SPI_SCK 26
|
||||||
#define FPIOA_CH438_NWR 13
|
#define FPIOA_SOFT_SPI_MIOS 25
|
||||||
#define FPIOA_CH438_NRD 14
|
#define FPIOA_SOFT_SPI_MSOI 27
|
||||||
#define FPIOA_CH438_D0 15
|
#define FPIOA_SOFT_SPI_NCS 28
|
||||||
#define FPIOA_CH438_D1 16
|
|
||||||
#define FPIOA_CH438_D2 17
|
|
||||||
#define FPIOA_CH438_D3 18
|
|
||||||
#define FPIOA_CH438_D4 19
|
|
||||||
#define FPIOA_CH438_D5 20
|
|
||||||
#define FPIOA_CH438_D6 21
|
|
||||||
#define FPIOA_CH438_D7 22
|
|
||||||
#define FPIOA_CH438_INT 23
|
|
||||||
|
|
||||||
#define BSP_CH438_ALE_PIN 24
|
|
||||||
#define BSP_CH438_NWR_PIN 25
|
|
||||||
#define BSP_CH438_NRD_PIN 26
|
|
||||||
#define BSP_CH438_D0_PIN 27
|
|
||||||
#define BSP_CH438_D1_PIN 28
|
|
||||||
#define BSP_CH438_D2_PIN 29
|
|
||||||
#define BSP_CH438_D3_PIN 30
|
|
||||||
#define BSP_CH438_D4_PIN 31
|
|
||||||
#define BSP_CH438_D5_PIN 32
|
|
||||||
#define BSP_CH438_D6_PIN 33
|
|
||||||
#define BSP_CH438_D7_PIN 34
|
|
||||||
#define BSP_CH438_INT_PIN 35
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef BSP_USING_SOFT_SPI
|
#ifdef BSP_USING_SOFT_SPI
|
||||||
#define FPIOA_SOFT_SPI_SCK 26
|
#define FPIOA_SOFT_SPI_SCK 26
|
||||||
#define FPIOA_SOFT_SPI_MIOS 25
|
#define FPIOA_SOFT_SPI_MIOS 25
|
||||||
#define FPIOA_SOFT_SPI_MSOI 27
|
#define FPIOA_SOFT_SPI_MSOI 27
|
||||||
#define FPIOA_SOFT_SPI_NCS 28
|
#define FPIOA_SOFT_SPI_NCS 28
|
||||||
======= enum HS_GPIO_CONFIG {
|
|
||||||
#ifdef BSP_USING_LCD
|
|
||||||
LCD_DC_PIN = 0, /* LCD DC PIN */
|
|
||||||
#endif
|
|
||||||
#ifdef BSP_SPI1_USING_SS0
|
|
||||||
SPI1_CS0_PIN,
|
|
||||||
#endif
|
|
||||||
#ifdef BSP_SPI1_USING_SS1
|
|
||||||
SPI1_CS1_PIN,
|
|
||||||
#endif
|
|
||||||
#ifdef BSP_SPI1_USING_SS2
|
|
||||||
SPI1_CS2_PIN,
|
|
||||||
#endif
|
|
||||||
#ifdef BSP_SPI1_USING_SS3
|
|
||||||
SPI1_CS3_PIN,
|
|
||||||
#endif
|
|
||||||
GPIO_ALLOC_START /* index of gpio driver start */
|
|
||||||
}
|
|
||||||
;
|
|
||||||
|
|
||||||
#ifdef BSP_USING_CH438
|
|
||||||
#define FPIOA_CH438_ALE 12
|
|
||||||
#define FPIOA_CH438_NWR 13
|
|
||||||
#define FPIOA_CH438_NRD 14
|
|
||||||
#define FPIOA_CH438_D0 15
|
|
||||||
#define FPIOA_CH438_D1 16
|
|
||||||
#define FPIOA_CH438_D2 17
|
|
||||||
#define FPIOA_CH438_D3 18
|
|
||||||
#define FPIOA_CH438_D4 19
|
|
||||||
#define FPIOA_CH438_D5 20
|
|
||||||
#define FPIOA_CH438_D6 21
|
|
||||||
#define FPIOA_CH438_D7 22
|
|
||||||
#define FPIOA_CH438_INT 23
|
|
||||||
|
|
||||||
#define BSP_CH438_ALE_PIN 24
|
|
||||||
#define BSP_CH438_NWR_PIN 25
|
|
||||||
#define BSP_CH438_NRD_PIN 26
|
|
||||||
#define BSP_CH438_D0_PIN 27
|
|
||||||
#define BSP_CH438_D1_PIN 28
|
|
||||||
#define BSP_CH438_D2_PIN 29
|
|
||||||
#define BSP_CH438_D3_PIN 30
|
|
||||||
#define BSP_CH438_D4_PIN 31
|
|
||||||
#define BSP_CH438_D5_PIN 32
|
|
||||||
#define BSP_CH438_D6_PIN 33
|
|
||||||
#define BSP_CH438_D7_PIN 34
|
|
||||||
#define BSP_CH438_INT_PIN 35
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef BSP_USING_SOFT_SPI
|
|
||||||
#define FPIOA_SOFT_SPI_SCK 26
|
|
||||||
#define FPIOA_SOFT_SPI_MIOS 25
|
|
||||||
#define FPIOA_SOFT_SPI_MSOI 27
|
|
||||||
#define FPIOA_SOFT_SPI_NCS 28
|
|
||||||
>>>>>>> upstream/prepare_for_master
|
|
||||||
|
|
||||||
#define BSP_SOFT_SPI_SCK_PIN 26
|
#define BSP_SOFT_SPI_SCK_PIN 26
|
||||||
#define BSP_SOFT_SPI_MIOS_PIN 25
|
#define BSP_SOFT_SPI_MIOS_PIN 25
|
||||||
#define BSP_SOFT_SPI_MSOI_PIN 27
|
#define BSP_SOFT_SPI_MSOI_PIN 27
|
||||||
#define BSP_SOFT_SPI_NCS_PIN 28
|
#define BSP_SOFT_SPI_NCS_PIN 28
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef BSP_USING_CAMERA
|
||||||
|
#define BSP_DVP_RST_PIN 40
|
||||||
|
#define BSP_DVP_PWDN_PIN 41
|
||||||
|
#define BSP_DVP_XCLK_PIN 42
|
||||||
|
#define BSP_DVP_PCLK_PIN 43
|
||||||
|
#define BSP_DVP_HSYNC_PIN 44
|
||||||
|
#define BSP_DVP_VSYNC_PIN 45
|
||||||
|
#define BSP_DVP_SCL_PIN 46
|
||||||
|
#define BSP_DVP_SDA_PIN 47
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef BSP_USING_LED
|
#ifdef BSP_USING_LED
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
/* Copyright 2018 Canaan Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
#ifndef _OV2640_H
|
||||||
|
#define _OV2640_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define OV2640_ADDR 0x60
|
||||||
|
|
||||||
|
struct CameraCfg
|
||||||
|
{
|
||||||
|
uint16_t window_w;
|
||||||
|
uint16_t window_h;
|
||||||
|
uint16_t window_xoffset;
|
||||||
|
uint16_t window_yoffset;
|
||||||
|
uint16_t output_w;
|
||||||
|
uint16_t output_h;
|
||||||
|
uint8_t gain;
|
||||||
|
uint8_t gain_manu_enable;
|
||||||
|
};
|
||||||
|
|
||||||
|
int ov2640_init(void);
|
||||||
|
int ov2640_read_id(uint16_t *manuf_id, uint16_t *device_id);
|
||||||
|
int SensorConfigure(struct CameraCfg* cfg_info);
|
||||||
|
|
||||||
|
#endif /* _OV2640_H */
|
|
@ -342,7 +342,7 @@ static void DrvLcdRectUpdate(uint16_t x1, uint16_t y1, uint16_t width, uint16_t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
x_err_t DrvLcdInit(Lcd8080DeviceType dev)
|
static x_err_t DrvLcdInit(Lcd8080DeviceType dev)
|
||||||
{
|
{
|
||||||
x_err_t ret = EOK;
|
x_err_t ret = EOK;
|
||||||
aiit_lcd = (Lcd8080DeviceType)dev;
|
aiit_lcd = (Lcd8080DeviceType)dev;
|
||||||
|
@ -366,6 +366,8 @@ x_err_t DrvLcdInit(Lcd8080DeviceType dev)
|
||||||
data = 0x55;
|
data = 0x55;
|
||||||
DrvLcdDataByte(&data, 1);
|
DrvLcdDataByte(&data, 1);
|
||||||
|
|
||||||
|
DrvLcdCmd(INVERSION_DISPALY_ON);
|
||||||
|
|
||||||
/* set direction */
|
/* set direction */
|
||||||
DrvLcdSetDirection(DIR_YX_RLUD);
|
DrvLcdSetDirection(DIR_YX_RLUD);
|
||||||
|
|
||||||
|
@ -476,7 +478,6 @@ static uint32 LcdWrite(void *dev, struct BusBlockWriteParam *write_param)
|
||||||
}
|
}
|
||||||
else if(1 == show->type) //output dot
|
else if(1 == show->type) //output dot
|
||||||
{
|
{
|
||||||
// DrvLcdSetPixel(show->pixel_info.x_pos, show->pixel_info.y_pos, show->pixel_info.pixel_color);
|
|
||||||
DrvLcdSetPixelDot(show->pixel_info.x_startpos,show->pixel_info.y_startpos, show->pixel_info.x_endpos, show->pixel_info.y_endpos,show->pixel_info.pixel_color);
|
DrvLcdSetPixelDot(show->pixel_info.x_startpos,show->pixel_info.y_startpos, show->pixel_info.x_endpos, show->pixel_info.y_endpos,show->pixel_info.pixel_color);
|
||||||
return EOK;
|
return EOK;
|
||||||
}
|
}
|
||||||
|
@ -549,7 +550,7 @@ static int BoardLcdDevBend(struct LcdHardwareDevice *lcd_device, void *param, co
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
static int flag = 1;
|
||||||
int HwLcdInit(void)
|
int HwLcdInit(void)
|
||||||
{
|
{
|
||||||
x_err_t ret = EOK;
|
x_err_t ret = EOK;
|
||||||
|
@ -613,7 +614,11 @@ int HwLcdInit(void)
|
||||||
|
|
||||||
KPrintf("LCD driver inited ...\r\n");
|
KPrintf("LCD driver inited ...\r\n");
|
||||||
|
|
||||||
|
if(flag){
|
||||||
DrvLcdInit(lcd_dev);
|
DrvLcdInit(lcd_dev);
|
||||||
|
flag = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
#include <dev_spi.h>
|
#include <dev_spi.h>
|
||||||
#include <bus_spi.h>
|
#include <bus_spi.h>
|
||||||
|
|
||||||
static x_err_t softSPIinit(struct SpiDriver *spi_drv, struct BusConfigureInfo *cfg)
|
static x_err_t SoftSPIinit(struct SpiDriver *spi_drv, struct BusConfigureInfo *cfg)
|
||||||
{
|
{
|
||||||
NULL_PARAM_CHECK(spi_drv);
|
NULL_PARAM_CHECK(spi_drv);
|
||||||
NULL_PARAM_CHECK(cfg);
|
NULL_PARAM_CHECK(cfg);
|
||||||
|
@ -29,7 +29,7 @@ static x_err_t softSPIinit(struct SpiDriver *spi_drv, struct BusConfigureInfo *c
|
||||||
return EOK;
|
return EOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32 softSpiDrvConfigure(void *drv, struct BusConfigureInfo *configure_info)
|
static uint32 SoftSpiDrvConfigure(void *drv, struct BusConfigureInfo *configure_info)
|
||||||
{
|
{
|
||||||
NULL_PARAM_CHECK(drv);
|
NULL_PARAM_CHECK(drv);
|
||||||
NULL_PARAM_CHECK(configure_info);
|
NULL_PARAM_CHECK(configure_info);
|
||||||
|
@ -41,7 +41,7 @@ static uint32 softSpiDrvConfigure(void *drv, struct BusConfigureInfo *configure_
|
||||||
switch (configure_info->configure_cmd)
|
switch (configure_info->configure_cmd)
|
||||||
{
|
{
|
||||||
case OPE_INT:
|
case OPE_INT:
|
||||||
softSPIinit(spi_drv, configure_info);
|
SoftSPIinit(spi_drv, configure_info);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OPE_CFG:
|
case OPE_CFG:
|
||||||
|
@ -54,7 +54,7 @@ static uint32 softSpiDrvConfigure(void *drv, struct BusConfigureInfo *configure_
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void soft_spi_writebyte(struct SpiHardwareDevice *spi_dev, uint8_t data)
|
static void SoftSpiWriteByte(struct SpiHardwareDevice *spi_dev, uint8_t data)
|
||||||
{
|
{
|
||||||
int8_t i = 0;
|
int8_t i = 0;
|
||||||
uint8_t temp = 0;
|
uint8_t temp = 0;
|
||||||
|
@ -79,7 +79,7 @@ static void soft_spi_writebyte(struct SpiHardwareDevice *spi_dev, uint8_t data)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 读一个字节 */
|
/* 读一个字节 */
|
||||||
static uint8_t soft_spi_readbyte(struct SpiHardwareDevice *spi_dev)
|
static uint8_t SoftSpiReadbyte(struct SpiHardwareDevice *spi_dev)
|
||||||
{
|
{
|
||||||
uint8_t i = 0;
|
uint8_t i = 0;
|
||||||
uint8_t read_data = 0xFF;
|
uint8_t read_data = 0xFF;
|
||||||
|
@ -100,7 +100,7 @@ static uint8_t soft_spi_readbyte(struct SpiHardwareDevice *spi_dev)
|
||||||
|
|
||||||
/* 读写一个字节 */
|
/* 读写一个字节 */
|
||||||
// this funcition is unverify until now!
|
// this funcition is unverify until now!
|
||||||
static uint8_t soft_spi_readwritebyte(struct SpiHardwareDevice *spi_dev, uint8_t data)
|
static uint8_t SoftSpiReadWriteByte(struct SpiHardwareDevice *spi_dev, uint8_t data)
|
||||||
{
|
{
|
||||||
uint8_t i = 0;
|
uint8_t i = 0;
|
||||||
uint8_t temp = 0;
|
uint8_t temp = 0;
|
||||||
|
@ -129,7 +129,7 @@ static uint8_t soft_spi_readwritebyte(struct SpiHardwareDevice *spi_dev, uint8_t
|
||||||
return read_data;
|
return read_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32 softSpiWriteData(struct SpiHardwareDevice *spi_dev, struct SpiDataStandard *spi_datacfg)
|
static uint32 SoftSpiWriteData(struct SpiHardwareDevice *spi_dev, struct SpiDataStandard *spi_datacfg)
|
||||||
{
|
{
|
||||||
SpiDeviceParam *dev_param = (SpiDeviceParam *)(spi_dev->haldev.private_data);
|
SpiDeviceParam *dev_param = (SpiDeviceParam *)(spi_dev->haldev.private_data);
|
||||||
|
|
||||||
|
@ -148,7 +148,7 @@ static uint32 softSpiWriteData(struct SpiHardwareDevice *spi_dev, struct SpiData
|
||||||
|
|
||||||
for (size_t i = 0; i < data_length; i++)
|
for (size_t i = 0; i < data_length; i++)
|
||||||
{
|
{
|
||||||
soft_spi_writebyte(spi_dev, data_buff[i]);
|
SoftSpiWriteByte(spi_dev, data_buff[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (spi_datacfg->spi_cs_release)
|
if (spi_datacfg->spi_cs_release)
|
||||||
|
@ -160,7 +160,7 @@ static uint32 softSpiWriteData(struct SpiHardwareDevice *spi_dev, struct SpiData
|
||||||
return EOK;
|
return EOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32 softSpiReadData(struct SpiHardwareDevice *spi_dev, struct SpiDataStandard *spi_datacfg)
|
static uint32 SoftSpiReadData(struct SpiHardwareDevice *spi_dev, struct SpiDataStandard *spi_datacfg)
|
||||||
{
|
{
|
||||||
SpiDeviceParam *dev_param = (SpiDeviceParam *)(spi_dev->haldev.private_data);
|
SpiDeviceParam *dev_param = (SpiDeviceParam *)(spi_dev->haldev.private_data);
|
||||||
uint8 cs_gpio_pin = dev_param->spi_slave_param->spi_cs_gpio_pin;
|
uint8 cs_gpio_pin = dev_param->spi_slave_param->spi_cs_gpio_pin;
|
||||||
|
@ -179,7 +179,7 @@ static uint32 softSpiReadData(struct SpiHardwareDevice *spi_dev, struct SpiDataS
|
||||||
|
|
||||||
for (size_t i = 0; i < recv_length; i++)
|
for (size_t i = 0; i < recv_length; i++)
|
||||||
{
|
{
|
||||||
recv_buff[i] = soft_spi_readbyte(spi_dev);
|
recv_buff[i] = SoftSpiReadbyte(spi_dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (spi_datacfg->spi_cs_release)
|
if (spi_datacfg->spi_cs_release)
|
||||||
|
@ -195,8 +195,8 @@ static uint32 softSpiReadData(struct SpiHardwareDevice *spi_dev, struct SpiDataS
|
||||||
const struct SpiDevDone soft_spi_dev_done = {
|
const struct SpiDevDone soft_spi_dev_done = {
|
||||||
.dev_close = NONE,
|
.dev_close = NONE,
|
||||||
.dev_open = NONE,
|
.dev_open = NONE,
|
||||||
.dev_read = softSpiReadData,
|
.dev_read = SoftSpiReadData,
|
||||||
.dev_write = softSpiWriteData};
|
.dev_write = SoftSpiWriteData};
|
||||||
|
|
||||||
static int BoardSoftSpiBusInit(struct SpiBus *spi_bus, struct SpiDriver *spi_driver)
|
static int BoardSoftSpiBusInit(struct SpiBus *spi_bus, struct SpiDriver *spi_driver)
|
||||||
{
|
{
|
||||||
|
@ -275,7 +275,7 @@ int HwSoftSPIInit(void)
|
||||||
static struct SpiDriver spi_driver;
|
static struct SpiDriver spi_driver;
|
||||||
memset(&spi_driver, 0, sizeof(struct SpiDriver));
|
memset(&spi_driver, 0, sizeof(struct SpiDriver));
|
||||||
|
|
||||||
spi_driver.configure = &(softSpiDrvConfigure);
|
spi_driver.configure = &(SoftSpiDrvConfigure);
|
||||||
|
|
||||||
ret = BoardSoftSpiBusInit(&spi_bus, &spi_driver);
|
ret = BoardSoftSpiBusInit(&spi_bus, &spi_driver);
|
||||||
if (EOK != ret)
|
if (EOK != ret)
|
||||||
|
|
|
@ -38,7 +38,7 @@ struct Touch_event {
|
||||||
};
|
};
|
||||||
|
|
||||||
#define DEFAULT_NUM 0x0D
|
#define DEFAULT_NUM 0x0D
|
||||||
#define TOUCH_ADDRESS 0x44
|
#define TOUCH_ADDRESS 0x40
|
||||||
volatile bool SemReleaseFlag = 0;
|
volatile bool SemReleaseFlag = 0;
|
||||||
|
|
||||||
static struct Bus* i2c_bus = NONE;
|
static struct Bus* i2c_bus = NONE;
|
||||||
|
@ -77,7 +77,7 @@ static x_err_t ReadRegs(struct HardwareDev* dev, uint8 len, uint8* buf)
|
||||||
// not used in polling mode
|
// not used in polling mode
|
||||||
static void touch_pin_irqhandler(void* arg)
|
static void touch_pin_irqhandler(void* arg)
|
||||||
{
|
{
|
||||||
// KPrintf("int hdr working.\n");
|
KPrintf("int hdr working.\n");
|
||||||
if (!SemReleaseFlag)
|
if (!SemReleaseFlag)
|
||||||
{
|
{
|
||||||
KSemaphoreAbandon(touch_sem);
|
KSemaphoreAbandon(touch_sem);
|
||||||
|
@ -277,8 +277,8 @@ static uint32 TouchRead(void* dev, struct BusBlockReadParam* read_param)
|
||||||
char status_reg = 0x80;
|
char status_reg = 0x80;
|
||||||
|
|
||||||
struct TouchDataStandard* data = (struct TouchDataStandard*)read_param->buffer;
|
struct TouchDataStandard* data = (struct TouchDataStandard*)read_param->buffer;
|
||||||
read_param->read_length = 0;
|
|
||||||
result = KSemaphoreObtain(touch_sem, 1000);
|
result = KSemaphoreObtain(touch_sem, 100);
|
||||||
// if (EOK == result)
|
// if (EOK == result)
|
||||||
// {
|
// {
|
||||||
memset(TOUCHRECDATA, 0, 24);
|
memset(TOUCHRECDATA, 0, 24);
|
||||||
|
@ -292,13 +292,16 @@ static uint32 TouchRead(void* dev, struct BusBlockReadParam* read_param)
|
||||||
{
|
{
|
||||||
ts_event.fingers[i].x = ((((uint32_t)TOUCHRECDATA[(i * 4) + 5]) << 8) | (uint32_t)TOUCHRECDATA[(i * 4) + 4]) & 0x00000FFF; // 12 bits of X coord
|
ts_event.fingers[i].x = ((((uint32_t)TOUCHRECDATA[(i * 4) + 5]) << 8) | (uint32_t)TOUCHRECDATA[(i * 4) + 4]) & 0x00000FFF; // 12 bits of X coord
|
||||||
ts_event.fingers[i].y = ((((uint32_t)TOUCHRECDATA[(i * 4) + 7]) << 8) | (uint32_t)TOUCHRECDATA[(i * 4) + 6]) & 0x00000FFF;
|
ts_event.fingers[i].y = ((((uint32_t)TOUCHRECDATA[(i * 4) + 7]) << 8) | (uint32_t)TOUCHRECDATA[(i * 4) + 6]) & 0x00000FFF;
|
||||||
|
uint32_t pos_y = 320 > ts_event.fingers[i].x *LCD_SIZE/TOUCH_WIDTH?320 - ts_event.fingers[i].x *LCD_SIZE/TOUCH_WIDTH:0;
|
||||||
|
ts_event.fingers[i].x = ts_event.fingers[i].y *LCD_SIZE/TOUCH_HEIGHT>6?ts_event.fingers[i].y *LCD_SIZE/TOUCH_HEIGHT-6:0;
|
||||||
|
ts_event.fingers[i].y = pos_y;
|
||||||
ts_event.fingers[i].fingerID = (uint32_t)TOUCHRECDATA[(i * 4) + 7] >> 4; // finger that did the touch
|
ts_event.fingers[i].fingerID = (uint32_t)TOUCHRECDATA[(i * 4) + 7] >> 4; // finger that did the touch
|
||||||
printf("fingers[%d] x %d y %d id %d\n",i,ts_event.fingers[i].x,ts_event.fingers[i].y,ts_event.fingers[i].fingerID);
|
// printf("fingers[%d] x %d y %d id %d\n",i,ts_event.fingers[i].x,ts_event.fingers[i].y,ts_event.fingers[i].fingerID);
|
||||||
}
|
}
|
||||||
|
|
||||||
data->x = ts_event.fingers[ts_event.NBfingers - 1].x;
|
data->x = ts_event.fingers[ts_event.NBfingers - 1].x;
|
||||||
data->y = ts_event.fingers[ts_event.NBfingers - 1].y;
|
data->y = ts_event.fingers[ts_event.NBfingers - 1].y;
|
||||||
|
read_param->read_length = ts_event.NBfingers;
|
||||||
SemReleaseFlag = 0;
|
SemReleaseFlag = 0;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
|
|
@ -140,7 +140,7 @@ CONFIG_SHELL_HELP_SHOW_PERMISSION=y
|
||||||
# CONFIG_SHELL_HELP_LIST_VAR is not set
|
# CONFIG_SHELL_HELP_LIST_VAR is not set
|
||||||
# CONFIG_SHELL_HELP_LIST_KEY is not set
|
# CONFIG_SHELL_HELP_LIST_KEY is not set
|
||||||
#CONFIG_KERNEL_QUEUEMANAGE=y
|
#CONFIG_KERNEL_QUEUEMANAGE=y
|
||||||
# CONFIG_KERNEL_WORKQUEUE is not set
|
CONFIG_KERNEL_WORKQUEUE=y
|
||||||
CONFIG_WORKQUEUE_KTASK_STACKSIZE=256
|
CONFIG_WORKQUEUE_KTASK_STACKSIZE=256
|
||||||
CONFIG_WORKQUEUE_KTASK_PRIORITY=2
|
CONFIG_WORKQUEUE_KTASK_PRIORITY=2
|
||||||
CONFIG_QUEUE_MAX=2
|
CONFIG_QUEUE_MAX=2
|
||||||
|
|
|
@ -48,8 +48,7 @@ Modification:
|
||||||
/* Entry Point */
|
/* Entry Point */
|
||||||
ENTRY(Reset_Handler)
|
ENTRY(Reset_Handler)
|
||||||
|
|
||||||
HEAP_SIZE = DEFINED(__heap_size__) ? __heap_size__ : 0x0400;
|
STACK_SIZE = 0x4000;
|
||||||
STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x1000;
|
|
||||||
|
|
||||||
/* Specify the memory areas */
|
/* Specify the memory areas */
|
||||||
MEMORY
|
MEMORY
|
||||||
|
|
|
@ -49,6 +49,7 @@ menuconfig BSP_USING_SDIO
|
||||||
if BSP_USING_SDIO
|
if BSP_USING_SDIO
|
||||||
source "$BSP_DIR/third_party_driver/sdio/Kconfig"
|
source "$BSP_DIR/third_party_driver/sdio/Kconfig"
|
||||||
endif
|
endif
|
||||||
|
|
||||||
menuconfig BSP_USING_LCD
|
menuconfig BSP_USING_LCD
|
||||||
bool "Using LCD device"
|
bool "Using LCD device"
|
||||||
default n
|
default n
|
||||||
|
@ -56,6 +57,7 @@ menuconfig BSP_USING_LCD
|
||||||
if BSP_USING_LCD
|
if BSP_USING_LCD
|
||||||
source "$BSP_DIR/third_party_driver/lcd/Kconfig"
|
source "$BSP_DIR/third_party_driver/lcd/Kconfig"
|
||||||
endif
|
endif
|
||||||
|
|
||||||
menuconfig BSP_USING_TOUCH
|
menuconfig BSP_USING_TOUCH
|
||||||
bool "Using TOUCH device"
|
bool "Using TOUCH device"
|
||||||
default n
|
default n
|
||||||
|
|
|
@ -85,7 +85,7 @@
|
||||||
void enet_delay(void)
|
void enet_delay(void)
|
||||||
{
|
{
|
||||||
volatile uint32_t i = 0;
|
volatile uint32_t i = 0;
|
||||||
for (i = 0; i < 1000000; ++i)
|
for (i = 0; i < 10000000; ++i)
|
||||||
{
|
{
|
||||||
__asm("NOP"); /* delay */
|
__asm("NOP"); /* delay */
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*/
|
*/
|
||||||
#include "board.h"
|
#include "board.h"
|
||||||
|
#include <shell.h>
|
||||||
|
|
||||||
#define EXAMPLE_SEMC_START_ADDRESS (0x80000000U)
|
#define EXAMPLE_SEMC_START_ADDRESS (0x80000000U)
|
||||||
|
|
||||||
|
|
|
@ -359,7 +359,8 @@ static uint32 TouchRead(void *dev, struct BusBlockReadParam *read_param)
|
||||||
result = KSemaphoreObtain(touch_sem, 1000);
|
result = KSemaphoreObtain(touch_sem, 1000);
|
||||||
if (EOK == result)
|
if (EOK == result)
|
||||||
{
|
{
|
||||||
if(GetTouchEvent(&touch_point, &touch_event))
|
ret = GetTouchEvent(&touch_point, &touch_event);
|
||||||
|
if(ret > 0)
|
||||||
{
|
{
|
||||||
data->x = abs(LCD_WIDTH - touch_point.X);
|
data->x = abs(LCD_WIDTH - touch_point.X);
|
||||||
data->y = abs(LCD_HEIGHT - touch_point.Y);
|
data->y = abs(LCD_HEIGHT - touch_point.Y);
|
||||||
|
@ -370,6 +371,11 @@ static uint32 TouchRead(void *dev, struct BusBlockReadParam *read_param)
|
||||||
read_param->read_length = read_param->size;
|
read_param->read_length = read_param->size;
|
||||||
ret = EOK;
|
ret = EOK;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret = -ERROR;
|
||||||
|
read_param->read_length = -ERROR;
|
||||||
|
}
|
||||||
SemReleaseFlag = 0;
|
SemReleaseFlag = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -107,3 +107,19 @@ select RESOURCES_WDT
|
||||||
if BSP_USING_WDT
|
if BSP_USING_WDT
|
||||||
source "$BSP_DIR/third_party_driver/watchdog/Kconfig"
|
source "$BSP_DIR/third_party_driver/watchdog/Kconfig"
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
menuconfig BSP_USING_WDT
|
||||||
|
bool "Using WATCHDOG device"
|
||||||
|
default n
|
||||||
|
select RESOURCES_WDT
|
||||||
|
if BSP_USING_WDT
|
||||||
|
source "$BSP_DIR/third_party_driver/watchdog/Kconfig"
|
||||||
|
endif
|
||||||
|
|
||||||
|
menuconfig BSP_USING_SOFT_SPI
|
||||||
|
bool "Using SOFT_SPI device"
|
||||||
|
default n
|
||||||
|
select RESOURCES_SOFT_SPI
|
||||||
|
if BSP_USING_SOFT_SPI
|
||||||
|
source "$BSP_DIR/third_party_driver/soft_spi/Kconfig"
|
||||||
|
endif
|
||||||
|
|
|
@ -56,4 +56,8 @@ ifeq ($(CONFIG_BSP_USING_WDT),y)
|
||||||
SRC_DIR += watchdog
|
SRC_DIR += watchdog
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_BSP_USING_SOFT_SPI),y)
|
||||||
|
SRC_DIR += soft_spi
|
||||||
|
endif
|
||||||
|
|
||||||
include $(KERNEL_ROOT)/compiler.mk
|
include $(KERNEL_ROOT)/compiler.mk
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
#ifndef CONNECT_TF_H
|
||||||
|
#define CONNECT_TF_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int HwSoftSPIInit(void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,43 @@
|
||||||
|
if BSP_USING_SOFT_SPI
|
||||||
|
config SOFT_SPI_BUS_NAME
|
||||||
|
string "soft spi bus 1 name"
|
||||||
|
default "soft_spi1_bus1"
|
||||||
|
|
||||||
|
config SOFT_SPI_DEVICE_NAME
|
||||||
|
string "soft spi dev 1 name"
|
||||||
|
default "soft_spi1_dev1"
|
||||||
|
|
||||||
|
config SOFT_SPI_DRV_NAME
|
||||||
|
string "soft spi drv 1 name"
|
||||||
|
default "soft_spi1_drv1"
|
||||||
|
|
||||||
|
config SOFT_SPI_SCK
|
||||||
|
int "soft spi sck pin"
|
||||||
|
default 26
|
||||||
|
|
||||||
|
config SOFT_SPI_MOSI
|
||||||
|
int "soft spi mosi pin"
|
||||||
|
default 27
|
||||||
|
|
||||||
|
config SOFT_SPI_MISO
|
||||||
|
int "soft spi miso pin"
|
||||||
|
default 25
|
||||||
|
|
||||||
|
config SOFT_SPI_CS0_PIN
|
||||||
|
int "soft spi cs pin"
|
||||||
|
default 28
|
||||||
|
|
||||||
|
config SOFT_SPI_DEVICE_SLAVE_ID
|
||||||
|
int "soft spi slave id"
|
||||||
|
default 0
|
||||||
|
|
||||||
|
config SOFT_SPI_CHIP_SELECT
|
||||||
|
int "soft spi chip selected"
|
||||||
|
default 0
|
||||||
|
|
||||||
|
config SOFT_SPI_CLK_DELAY
|
||||||
|
int "clk in microsecond"
|
||||||
|
default 0
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
SRC_FILES := connect_soft_spi.c
|
||||||
|
|
||||||
|
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -0,0 +1,295 @@
|
||||||
|
#include <xizi.h>
|
||||||
|
#include <device.h>
|
||||||
|
#include <fpioa.h>
|
||||||
|
#include <gpiohs.h>
|
||||||
|
#include "drv_io_config.h"
|
||||||
|
#include <plic.h>
|
||||||
|
#include <utils.h>
|
||||||
|
#include <connect_soft_spi.h>
|
||||||
|
#include <sleep.h>
|
||||||
|
|
||||||
|
#include <sd_spi.h>
|
||||||
|
#include <dev_spi.h>
|
||||||
|
#include <bus_spi.h>
|
||||||
|
|
||||||
|
static x_err_t SoftSPIinit(struct SpiDriver *spi_drv, struct BusConfigureInfo *cfg)
|
||||||
|
{
|
||||||
|
NULL_PARAM_CHECK(spi_drv);
|
||||||
|
NULL_PARAM_CHECK(cfg);
|
||||||
|
|
||||||
|
// mode CPOL = 0 CPHA = 0
|
||||||
|
gpiohs_set_drive_mode(SOFT_SPI_CS0_PIN, GPIO_DM_OUTPUT);
|
||||||
|
gpiohs_set_pin(SOFT_SPI_CS0_PIN, GPIO_PV_HIGH); // set the cs gpio high
|
||||||
|
gpiohs_set_drive_mode(SOFT_SPI_SCK, GPIO_DM_OUTPUT);
|
||||||
|
gpiohs_set_drive_mode(SOFT_SPI_MOSI, GPIO_DM_OUTPUT);
|
||||||
|
gpiohs_set_drive_mode(SOFT_SPI_MISO, GPIO_DM_INPUT);
|
||||||
|
gpiohs_set_pin(SOFT_SPI_SCK, GPIO_PV_LOW);
|
||||||
|
KPrintf("%s init done\n", SOFT_SPI_BUS_NAME);
|
||||||
|
|
||||||
|
return EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32 SoftSpiDrvConfigure(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:
|
||||||
|
SoftSPIinit(spi_drv, configure_info);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OPE_CFG:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SoftSpiWriteByte(struct SpiHardwareDevice *spi_dev, uint8_t data)
|
||||||
|
{
|
||||||
|
int8_t i = 0;
|
||||||
|
uint8_t temp = 0;
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
|
temp = ((data & 0x80) == 0x80) ? 1 : 0;
|
||||||
|
data = data << 1;
|
||||||
|
gpiohs_set_pin(SOFT_SPI_SCK, GPIO_PV_LOW);
|
||||||
|
usleep(SOFT_SPI_CLK_DELAY);
|
||||||
|
if (0 == temp)
|
||||||
|
{
|
||||||
|
gpiohs_set_pin(SOFT_SPI_MOSI, GPIO_PV_LOW);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gpiohs_set_pin(SOFT_SPI_MOSI, GPIO_PV_HIGH);
|
||||||
|
}
|
||||||
|
gpiohs_set_pin(SOFT_SPI_SCK, GPIO_PV_HIGH);
|
||||||
|
usleep(SOFT_SPI_CLK_DELAY);
|
||||||
|
}
|
||||||
|
gpiohs_set_pin(SOFT_SPI_SCK, GPIO_PV_LOW);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 读一个字节 */
|
||||||
|
static uint8_t SoftSpiReadByte(struct SpiHardwareDevice *spi_dev)
|
||||||
|
{
|
||||||
|
uint8_t i = 0;
|
||||||
|
uint8_t read_data = 0xFF;
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
|
read_data = read_data << 1;
|
||||||
|
gpiohs_set_pin(SOFT_SPI_SCK, GPIO_PV_LOW);
|
||||||
|
usleep(SOFT_SPI_CLK_DELAY);
|
||||||
|
gpiohs_set_pin(SOFT_SPI_SCK, GPIO_PV_HIGH);
|
||||||
|
usleep(SOFT_SPI_CLK_DELAY);
|
||||||
|
if (1 == gpiohs_get_pin(SOFT_SPI_MISO))
|
||||||
|
{
|
||||||
|
read_data = read_data | 0x01;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return read_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 读写一个字节 */
|
||||||
|
// this funcition is unverify until now!
|
||||||
|
static uint8_t SoftSpiReadWriteByte(struct SpiHardwareDevice *spi_dev, uint8_t data)
|
||||||
|
{
|
||||||
|
uint8_t i = 0;
|
||||||
|
uint8_t temp = 0;
|
||||||
|
uint8_t read_data = 0xFF;
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
|
temp = ((data & 0x80) == 0x80) ? 1 : 0;
|
||||||
|
data = data << 1;
|
||||||
|
read_data = read_data << 1;
|
||||||
|
if (temp == 0)
|
||||||
|
{
|
||||||
|
gpiohs_set_pin(SOFT_SPI_MOSI, GPIO_PV_LOW);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gpiohs_set_pin(SOFT_SPI_MOSI, GPIO_PV_HIGH);
|
||||||
|
}
|
||||||
|
usleep(SOFT_SPI_CLK_DELAY);
|
||||||
|
gpiohs_set_pin(SOFT_SPI_SCK, GPIO_PV_HIGH);
|
||||||
|
usleep(SOFT_SPI_CLK_DELAY);
|
||||||
|
if (gpiohs_get_pin(SOFT_SPI_MISO) == 1)
|
||||||
|
{
|
||||||
|
read_data = read_data + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return read_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32 SoftSpiWriteData(struct SpiHardwareDevice *spi_dev, struct SpiDataStandard *spi_datacfg)
|
||||||
|
{
|
||||||
|
SpiDeviceParam *dev_param = (SpiDeviceParam *)(spi_dev->haldev.private_data);
|
||||||
|
|
||||||
|
uint8 cs_gpio_pin = dev_param->spi_slave_param->spi_cs_gpio_pin;
|
||||||
|
const uint8_t *data_buff = spi_datacfg->tx_buff;
|
||||||
|
int data_length = spi_datacfg->length;
|
||||||
|
if (NONE == spi_datacfg->tx_buff)
|
||||||
|
{
|
||||||
|
data_length = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (spi_datacfg->spi_chip_select)
|
||||||
|
{
|
||||||
|
gpiohs_set_pin(cs_gpio_pin, GPIO_PV_LOW);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < data_length; i++)
|
||||||
|
{
|
||||||
|
SoftSpiWriteByte(spi_dev, data_buff[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (spi_datacfg->spi_cs_release)
|
||||||
|
{
|
||||||
|
gpiohs_set_pin(cs_gpio_pin, GPIO_PV_HIGH);
|
||||||
|
}
|
||||||
|
spi_datacfg = spi_datacfg->next;
|
||||||
|
|
||||||
|
return EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32 SoftSpiReadData(struct SpiHardwareDevice *spi_dev, struct SpiDataStandard *spi_datacfg)
|
||||||
|
{
|
||||||
|
SpiDeviceParam *dev_param = (SpiDeviceParam *)(spi_dev->haldev.private_data);
|
||||||
|
uint8 cs_gpio_pin = dev_param->spi_slave_param->spi_cs_gpio_pin;
|
||||||
|
uint8_t *recv_buff = spi_datacfg->rx_buff;
|
||||||
|
int recv_length = spi_datacfg->length;
|
||||||
|
|
||||||
|
if (NONE == spi_datacfg->rx_buff)
|
||||||
|
{
|
||||||
|
recv_length = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (spi_datacfg->spi_chip_select)
|
||||||
|
{
|
||||||
|
gpiohs_set_pin(cs_gpio_pin, GPIO_PV_LOW);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < recv_length; i++)
|
||||||
|
{
|
||||||
|
recv_buff[i] = SoftSpiReadByte(spi_dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (spi_datacfg->spi_cs_release)
|
||||||
|
{
|
||||||
|
gpiohs_set_pin(cs_gpio_pin, GPIO_PV_HIGH);
|
||||||
|
}
|
||||||
|
|
||||||
|
spi_datacfg = spi_datacfg->next;
|
||||||
|
|
||||||
|
return spi_datacfg->length;
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct SpiDevDone soft_spi_dev_done = {
|
||||||
|
.dev_close = NONE,
|
||||||
|
.dev_open = NONE,
|
||||||
|
.dev_read = SoftSpiReadData,
|
||||||
|
.dev_write = SoftSpiWriteData};
|
||||||
|
|
||||||
|
static int BoardSoftSpiBusInit(struct SpiBus *spi_bus, struct SpiDriver *spi_driver)
|
||||||
|
{
|
||||||
|
x_err_t ret = EOK;
|
||||||
|
|
||||||
|
/*Init the spi bus */
|
||||||
|
ret = SpiBusInit(spi_bus, SOFT_SPI_BUS_NAME);
|
||||||
|
if (EOK != ret)
|
||||||
|
{
|
||||||
|
KPrintf("Board_Spi_init SpiBusInit error %d\n", ret);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Init the spi driver*/
|
||||||
|
ret = SpiDriverInit(spi_driver, SOFT_SPI_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(SOFT_SPI_DRV_NAME, SOFT_SPI_BUS_NAME);
|
||||||
|
if (EOK != ret)
|
||||||
|
{
|
||||||
|
KPrintf("Board_Spi_init SpiDriverAttachToBus error %d\n", ret);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int BoardSoftSpiDevBend(void)
|
||||||
|
{
|
||||||
|
x_err_t ret = EOK;
|
||||||
|
|
||||||
|
static struct SpiHardwareDevice spi_device0;
|
||||||
|
memset(&spi_device0, 0, sizeof(struct SpiHardwareDevice));
|
||||||
|
|
||||||
|
static struct SpiSlaveParam spi_slaveparam0;
|
||||||
|
memset(&spi_slaveparam0, 0, sizeof(struct SpiSlaveParam));
|
||||||
|
|
||||||
|
spi_slaveparam0.spi_slave_id = SOFT_SPI_DEVICE_SLAVE_ID;
|
||||||
|
spi_slaveparam0.spi_cs_gpio_pin = SOFT_SPI_CS0_PIN;
|
||||||
|
spi_slaveparam0.spi_cs_select_id = SOFT_SPI_CHIP_SELECT;
|
||||||
|
|
||||||
|
spi_device0.spi_param.spi_dma_param = NONE;
|
||||||
|
spi_device0.spi_param.spi_slave_param = &spi_slaveparam0;
|
||||||
|
|
||||||
|
spi_device0.spi_dev_done = &(soft_spi_dev_done);
|
||||||
|
|
||||||
|
ret = SpiDeviceRegister(&spi_device0, (void *)(&spi_device0.spi_param), SOFT_SPI_DEVICE_NAME);
|
||||||
|
if (EOK != ret)
|
||||||
|
{
|
||||||
|
KPrintf("Board_Spi_init SpiDeviceInit device %s error %d\n", SOFT_SPI_DEVICE_NAME, ret);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = SpiDeviceAttachToBus(SOFT_SPI_DEVICE_NAME, SOFT_SPI_BUS_NAME);
|
||||||
|
if (EOK != ret)
|
||||||
|
{
|
||||||
|
KPrintf("Board_Spi_init SpiDeviceAttachToBus device %s error %d\n", SOFT_SPI_DEVICE_NAME, ret);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int HwSoftSPIInit(void)
|
||||||
|
{
|
||||||
|
x_err_t ret = EOK;
|
||||||
|
|
||||||
|
static struct SpiBus spi_bus;
|
||||||
|
memset(&spi_bus, 0, sizeof(struct SpiBus));
|
||||||
|
|
||||||
|
static struct SpiDriver spi_driver;
|
||||||
|
memset(&spi_driver, 0, sizeof(struct SpiDriver));
|
||||||
|
|
||||||
|
spi_driver.configure = &(SoftSpiDrvConfigure);
|
||||||
|
|
||||||
|
ret = BoardSoftSpiBusInit(&spi_bus, &spi_driver);
|
||||||
|
if (EOK != ret)
|
||||||
|
{
|
||||||
|
KPrintf("Board_Spi_Init error ret %u\n", ret);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = BoardSoftSpiDevBend();
|
||||||
|
if (EOK != ret)
|
||||||
|
{
|
||||||
|
KPrintf("Board_Spi_Init error ret %u\n", ret);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
|
@ -440,6 +440,7 @@ endif
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/Applications/general_functions/circular_area #
|
||||||
KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/Applications/general_functions/list #
|
KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/Applications/general_functions/list #
|
||||||
|
|
||||||
ifeq ($(CONFIG_SUPPORT_SENSOR_FRAMEWORK), y)
|
ifeq ($(CONFIG_SUPPORT_SENSOR_FRAMEWORK), y)
|
||||||
|
@ -472,9 +473,11 @@ 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/shared #
|
KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/Framework/control/shared #
|
||||||
KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/Framework/control/ipc_protocol #
|
KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/Framework/control/ipc_protocol #
|
||||||
|
KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/Framework/control/ipc_protocol/include #
|
||||||
KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/Framework/control/ipc_protocol/modbus_tcp #
|
KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/Framework/control/ipc_protocol/modbus_tcp #
|
||||||
KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/Framework/control/ipc_protocol/modbus_uart #
|
KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/Framework/control/ipc_protocol/modbus_uart #
|
||||||
KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/Framework/control/plc_protocol #
|
KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/Framework/control/plc_protocol #
|
||||||
|
KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/Framework/control/plc_protocol/include #
|
||||||
KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/Framework/control/plc_protocol/fins #
|
KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/Framework/control/plc_protocol/fins #
|
||||||
KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/Framework/control/plc_protocol/melsec #
|
KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/Framework/control/plc_protocol/melsec #
|
||||||
KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/Framework/control/plc_protocol/opcua #
|
KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/Framework/control/plc_protocol/opcua #
|
||||||
|
|
|
@ -163,3 +163,9 @@ if BSP_USING_DAC
|
||||||
bool "Using DAC bus drivers"
|
bool "Using DAC bus drivers"
|
||||||
default n
|
default n
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if BSP_USING_CAMERA
|
||||||
|
config RESOURCES_CAMERA
|
||||||
|
bool "Using Camera bus drivers"
|
||||||
|
default n
|
||||||
|
endif
|
||||||
|
|
|
@ -65,4 +65,8 @@ ifeq ($(CONFIG_RESOURCES_DAC),y)
|
||||||
SRC_DIR += dac
|
SRC_DIR += dac
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_RESOURCES_CAMERA),y)
|
||||||
|
SRC_DIR += camera
|
||||||
|
endif
|
||||||
|
|
||||||
include $(KERNEL_ROOT)/compiler.mk
|
include $(KERNEL_ROOT)/compiler.mk
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
SRC_FILES += dev_camera.c drv_camera.c bus_camera.c
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -0,0 +1,123 @@
|
||||||
|
/*
|
||||||
|
* 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 bus_camera.c
|
||||||
|
* @brief register camera bus function using bus driver framework
|
||||||
|
* @version 1.0
|
||||||
|
* @author AIIT XUOS Lab
|
||||||
|
* @date 2021-04-24
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <bus_camera.h>
|
||||||
|
#include <dev_camera.h>
|
||||||
|
|
||||||
|
/*Register the CAMERA BUS*/
|
||||||
|
int CameraBusInit(struct CameraBus *camera_bus, const char *bus_name)
|
||||||
|
{
|
||||||
|
NULL_PARAM_CHECK(camera_bus);
|
||||||
|
NULL_PARAM_CHECK(bus_name);
|
||||||
|
|
||||||
|
x_err_t ret = EOK;
|
||||||
|
|
||||||
|
if (BUS_INSTALL != camera_bus->bus.bus_state) {
|
||||||
|
strncpy(camera_bus->bus.bus_name, bus_name, NAME_NUM_MAX);
|
||||||
|
|
||||||
|
camera_bus->bus.bus_type = TYPE_CAMERA_BUS;
|
||||||
|
camera_bus->bus.bus_state = BUS_INSTALL;
|
||||||
|
camera_bus->bus.private_data = camera_bus->private_data;
|
||||||
|
|
||||||
|
ret = BusRegister(&camera_bus->bus);
|
||||||
|
if (EOK != ret) {
|
||||||
|
KPrintf("CameraBusInit BusRegister error %u\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
KPrintf("CameraBusInit BusRegister bus has been register state%u\n", camera_bus->bus.bus_state);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Register the CAMERA Driver*/
|
||||||
|
int CameraDriverInit(struct CameraDriver *camera_driver, const char *driver_name)
|
||||||
|
{
|
||||||
|
NULL_PARAM_CHECK(camera_driver);
|
||||||
|
NULL_PARAM_CHECK(driver_name);
|
||||||
|
|
||||||
|
x_err_t ret = EOK;
|
||||||
|
|
||||||
|
if (DRV_INSTALL != camera_driver->driver.driver_state) {
|
||||||
|
camera_driver->driver.driver_type = TYPE_CAMERA_DRV;
|
||||||
|
camera_driver->driver.driver_state = DRV_INSTALL;
|
||||||
|
|
||||||
|
strncpy(camera_driver->driver.drv_name, driver_name, NAME_NUM_MAX);
|
||||||
|
|
||||||
|
camera_driver->driver.private_data = camera_driver->private_data;
|
||||||
|
|
||||||
|
camera_driver->driver.configure = camera_driver->configure;
|
||||||
|
|
||||||
|
ret = CameraDriverRegister(&camera_driver->driver);
|
||||||
|
if (EOK != ret) {
|
||||||
|
KPrintf("CameraDriverInit DriverRegister error %u\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
KPrintf("CameraDriverInit DriverRegister driver has been register state%u\n", camera_driver->driver.driver_state);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Release the CAMERA device*/
|
||||||
|
int CameraReleaseBus(struct CameraBus *camera_bus)
|
||||||
|
{
|
||||||
|
NULL_PARAM_CHECK(camera_bus);
|
||||||
|
|
||||||
|
return BusRelease(&camera_bus->bus);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Register the CAMERA Driver to the CAMERA BUS*/
|
||||||
|
int CameraDriverAttachToBus(const char *drv_name, const char *bus_name)
|
||||||
|
{
|
||||||
|
NULL_PARAM_CHECK(drv_name);
|
||||||
|
NULL_PARAM_CHECK(bus_name);
|
||||||
|
|
||||||
|
x_err_t ret = EOK;
|
||||||
|
|
||||||
|
struct Bus *bus;
|
||||||
|
struct Driver *driver;
|
||||||
|
|
||||||
|
bus = BusFind(bus_name);
|
||||||
|
if (NONE == bus) {
|
||||||
|
KPrintf("CameraDriverAttachToBus find camera bus error!name %s\n", bus_name);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TYPE_CAMERA_BUS == bus->bus_type) {
|
||||||
|
driver = CameraDriverFind(drv_name, TYPE_CAMERA_DRV);
|
||||||
|
if (NONE == driver) {
|
||||||
|
KPrintf("CameraDriverAttachToBus find camera driver error!name %s\n", drv_name);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TYPE_CAMERA_DRV == driver->driver_type) {
|
||||||
|
ret = DriverRegisterToBus(bus, driver);
|
||||||
|
if (EOK != ret) {
|
||||||
|
KPrintf("CameraDriverAttachToBus DriverRegisterToBus error %u\n", ret);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
|
@ -0,0 +1,200 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2006-03-13 bernard first version
|
||||||
|
* 2012-05-15 lgnq modified according bernard's implementation.
|
||||||
|
* 2012-05-28 bernard code cleanup
|
||||||
|
* 2012-11-23 bernard fix compiler warning.
|
||||||
|
* 2013-02-20 bernard use RT_CAMERA_RB_BUFSZ to define
|
||||||
|
* the size of ring buffer.
|
||||||
|
* 2014-07-10 bernard rewrite camera framework
|
||||||
|
* 2014-12-31 bernard use open_flag for poll_tx stream mode.
|
||||||
|
* 2015-05-19 Quintin fix DMA tx mod tx_dma->activated flag !=RT_FALSE BUG
|
||||||
|
* in open function.
|
||||||
|
* 2015-11-10 bernard fix the poll rx issue when there is no data.
|
||||||
|
* 2016-05-10 armink add fifo mode to DMA rx when camera->config.bufsz != 0.
|
||||||
|
* 2017-01-19 aubr.cool prevent change camera rx bufsz when camera is opened.
|
||||||
|
* 2017-11-07 JasonJia fix data bits error issue when using tcsetattr.
|
||||||
|
* 2017-11-15 JasonJia fix poll rx issue when data is full.
|
||||||
|
* add TCFLSH and FIONREAD support.
|
||||||
|
* 2018-12-08 Ernest Chen add DMA choice
|
||||||
|
* 2020-09-14 WillianChan add a line feed to the carriage return character
|
||||||
|
* when using interrupt tx
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file dev_camera.c
|
||||||
|
* @brief register camera dev function using bus driver framework
|
||||||
|
* @version 1.0
|
||||||
|
* @author AIIT XUOS Lab
|
||||||
|
* @date 2021-04-24
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
File name: dev_camera.c
|
||||||
|
Description: support camera dev INT and DMA configure、transfer data
|
||||||
|
Others: take RT-Thread v4.0.2/components/driver/camera/camera.c for references
|
||||||
|
https://github.com/RT-Thread/rt-thread/tree/v4.0.2
|
||||||
|
History:
|
||||||
|
1. Date: 2021-04-24
|
||||||
|
Author: AIIT XUOS Lab
|
||||||
|
Modification:
|
||||||
|
1. support camera dev register, configure, write and read
|
||||||
|
2. add bus driver framework support, include INT and DMA mode
|
||||||
|
*************************************************/
|
||||||
|
|
||||||
|
#include <bus_camera.h>
|
||||||
|
#include <dev_camera.h>
|
||||||
|
|
||||||
|
static DoubleLinklistType cameradev_linklist;
|
||||||
|
|
||||||
|
static uint32 CameraDevOpen(void *dev)
|
||||||
|
{
|
||||||
|
NULL_PARAM_CHECK(dev);
|
||||||
|
|
||||||
|
x_err_t ret = EOK;
|
||||||
|
struct CameraHardwareDevice *camera_dev = (struct CameraHardwareDevice *)dev;
|
||||||
|
|
||||||
|
ret = camera_dev->camera_dev_done->dev_open(dev);
|
||||||
|
|
||||||
|
return EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32 CameraDevClose(void *dev)
|
||||||
|
{
|
||||||
|
NULL_PARAM_CHECK(dev);
|
||||||
|
|
||||||
|
x_err_t ret = EOK;
|
||||||
|
struct CameraHardwareDevice *camera_dev = (struct CameraHardwareDevice *)dev;
|
||||||
|
|
||||||
|
ret = camera_dev->camera_dev_done->dev_close(dev);
|
||||||
|
return EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32 CameraDevWrite(void *dev, struct BusBlockWriteParam *write_param)
|
||||||
|
{
|
||||||
|
NULL_PARAM_CHECK(dev);
|
||||||
|
NULL_PARAM_CHECK(write_param);
|
||||||
|
|
||||||
|
x_err_t ret = EOK;
|
||||||
|
|
||||||
|
struct CameraHardwareDevice *camera_dev = (struct CameraHardwareDevice *)dev;
|
||||||
|
ret = camera_dev->camera_dev_done->dev_write(dev,write_param);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32 CameraDevRead(void *dev, struct BusBlockReadParam *read_param)
|
||||||
|
{
|
||||||
|
NULL_PARAM_CHECK(dev);
|
||||||
|
NULL_PARAM_CHECK(read_param);
|
||||||
|
|
||||||
|
x_err_t ret = EOK;
|
||||||
|
|
||||||
|
struct CameraHardwareDevice *camera_dev = (struct CameraHardwareDevice *)dev;
|
||||||
|
ret = camera_dev->camera_dev_done->dev_read(dev,read_param);
|
||||||
|
|
||||||
|
return EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static const struct HalDevDone dev_done =
|
||||||
|
{
|
||||||
|
.open = CameraDevOpen,
|
||||||
|
.close = CameraDevClose,
|
||||||
|
.write = CameraDevWrite,
|
||||||
|
.read = CameraDevRead,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*Create the camera device linklist*/
|
||||||
|
static void CameraDeviceLinkInit()
|
||||||
|
{
|
||||||
|
InitDoubleLinkList(&cameradev_linklist);
|
||||||
|
}
|
||||||
|
|
||||||
|
HardwareDevType CameraDeviceFind(const char *dev_name, enum DevType dev_type)
|
||||||
|
{
|
||||||
|
NULL_PARAM_CHECK(dev_name);
|
||||||
|
|
||||||
|
struct HardwareDev *device = NONE;
|
||||||
|
|
||||||
|
DoubleLinklistType *node = NONE;
|
||||||
|
DoubleLinklistType *head = &cameradev_linklist;
|
||||||
|
|
||||||
|
for (node = head->node_next; node != head; node = node->node_next) {
|
||||||
|
device = SYS_DOUBLE_LINKLIST_ENTRY(node, struct HardwareDev, dev_link);
|
||||||
|
if ((!strcmp(device->dev_name, dev_name)) && (dev_type == device->dev_type)) {
|
||||||
|
return device;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
KPrintf("CameraDeviceFind cannot find the %s device.return NULL\n", dev_name);
|
||||||
|
return NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CameraDeviceRegister(struct CameraHardwareDevice *camera_device, void *camera_param, const char *device_name)
|
||||||
|
{
|
||||||
|
NULL_PARAM_CHECK(camera_device);
|
||||||
|
NULL_PARAM_CHECK(device_name);
|
||||||
|
|
||||||
|
x_err_t ret = EOK;
|
||||||
|
static x_bool dev_link_flag = RET_FALSE;
|
||||||
|
|
||||||
|
if (!dev_link_flag) {
|
||||||
|
CameraDeviceLinkInit();
|
||||||
|
dev_link_flag = RET_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DEV_INSTALL != camera_device->haldev.dev_state) {
|
||||||
|
strncpy(camera_device->haldev.dev_name, device_name, NAME_NUM_MAX);
|
||||||
|
camera_device->haldev.dev_type = TYPE_CAMERA_DEV;
|
||||||
|
camera_device->haldev.dev_state = DEV_INSTALL;
|
||||||
|
camera_device->haldev.dev_done = (struct HalDevDone *)&dev_done;
|
||||||
|
|
||||||
|
|
||||||
|
DoubleLinkListInsertNodeAfter(&cameradev_linklist, &(camera_device->haldev.dev_link));
|
||||||
|
} else {
|
||||||
|
KPrintf("CameraDeviceRegister device has been register state%u\n", camera_device->haldev.dev_state);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CameraDeviceAttachToBus(const char *dev_name, const char *bus_name)
|
||||||
|
{
|
||||||
|
NULL_PARAM_CHECK(dev_name);
|
||||||
|
NULL_PARAM_CHECK(bus_name);
|
||||||
|
|
||||||
|
x_err_t ret = EOK;
|
||||||
|
|
||||||
|
struct Bus *bus;
|
||||||
|
struct HardwareDev *device;
|
||||||
|
|
||||||
|
bus = BusFind(bus_name);
|
||||||
|
if (NONE == bus) {
|
||||||
|
KPrintf("CameraDeviceAttachToBus find camera bus error!name %s\n", bus_name);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TYPE_CAMERA_BUS == bus->bus_type) {
|
||||||
|
device = CameraDeviceFind(dev_name, TYPE_CAMERA_DEV);
|
||||||
|
if (NONE == device) {
|
||||||
|
KPrintf("CameraDeviceAttachToBus find camera device error!name %s\n", dev_name);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TYPE_CAMERA_DEV == device->dev_type) {
|
||||||
|
ret = DeviceRegisterToBus(bus, device);
|
||||||
|
if (EOK != ret) {
|
||||||
|
KPrintf("CameraDeviceAttachToBus DeviceRegisterToBus error %u\n", ret);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return EOK;
|
||||||
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
/*
|
||||||
|
* 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_camera.c
|
||||||
|
* @brief register camera drv function using bus driver framework
|
||||||
|
* @version 1.0
|
||||||
|
* @author AIIT XUOS Lab
|
||||||
|
* @date 2021-04-24
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <bus_camera.h>
|
||||||
|
#include <dev_camera.h>
|
||||||
|
|
||||||
|
static DoubleLinklistType camera_drv_linklist;
|
||||||
|
|
||||||
|
/*Create the driver linklist*/
|
||||||
|
static void CameraDrvLinkInit()
|
||||||
|
{
|
||||||
|
InitDoubleLinkList(&camera_drv_linklist);
|
||||||
|
}
|
||||||
|
|
||||||
|
DriverType CameraDriverFind(const char *drv_name, enum DriverType_e drv_type)
|
||||||
|
{
|
||||||
|
NULL_PARAM_CHECK(drv_name);
|
||||||
|
|
||||||
|
struct Driver *driver = NONE;
|
||||||
|
|
||||||
|
DoubleLinklistType *node = NONE;
|
||||||
|
DoubleLinklistType *head = &camera_drv_linklist;
|
||||||
|
|
||||||
|
for (node = head->node_next; node != head; node = node->node_next) {
|
||||||
|
driver = SYS_DOUBLE_LINKLIST_ENTRY(node, struct Driver, driver_link);
|
||||||
|
|
||||||
|
if ((!strcmp(driver->drv_name, drv_name)) && (drv_type == driver->driver_type)) {
|
||||||
|
return driver;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
KPrintf("CameraDriverFind cannot find the %s driver.return NULL\n", drv_name);
|
||||||
|
return NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CameraDriverRegister(struct Driver *driver)
|
||||||
|
{
|
||||||
|
NULL_PARAM_CHECK(driver);
|
||||||
|
|
||||||
|
x_err_t ret = EOK;
|
||||||
|
static x_bool driver_link_flag = RET_FALSE;
|
||||||
|
|
||||||
|
if (!driver_link_flag) {
|
||||||
|
CameraDrvLinkInit();
|
||||||
|
driver_link_flag = RET_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
DoubleLinkListInsertNodeAfter(&camera_drv_linklist, &(driver->driver_link));
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
|
@ -269,7 +269,7 @@ typedef unsigned int nfds_t;
|
||||||
#define MEMP_LIB_MALLOC 1
|
#define MEMP_LIB_MALLOC 1
|
||||||
#define MEMP_MEM_MALLOC 1
|
#define MEMP_MEM_MALLOC 1
|
||||||
|
|
||||||
#define lw_print //KPrintf
|
#define lw_print KPrintf
|
||||||
#define lw_error KPrintf
|
#define lw_error KPrintf
|
||||||
#define lw_notice KPrintf
|
#define lw_notice KPrintf
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,7 @@ enum BusType_e
|
||||||
TYPE_SERIAL_BUS,
|
TYPE_SERIAL_BUS,
|
||||||
TYPE_ADC_BUS,
|
TYPE_ADC_BUS,
|
||||||
TYPE_DAC_BUS,
|
TYPE_DAC_BUS,
|
||||||
|
TYPE_CAMERA_BUS,
|
||||||
TYPE_BUS_END,
|
TYPE_BUS_END,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -80,6 +81,7 @@ enum DevType
|
||||||
TYPE_SERIAL_DEV,
|
TYPE_SERIAL_DEV,
|
||||||
TYPE_ADC_DEV,
|
TYPE_ADC_DEV,
|
||||||
TYPE_DAC_DEV,
|
TYPE_DAC_DEV,
|
||||||
|
TYPE_CAMERA_DEV,
|
||||||
TYPE_DEV_END,
|
TYPE_DEV_END,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -106,6 +108,7 @@ enum DriverType_e
|
||||||
TYPE_SERIAL_DRV,
|
TYPE_SERIAL_DRV,
|
||||||
TYPE_ADC_DRV,
|
TYPE_ADC_DRV,
|
||||||
TYPE_DAC_DRV,
|
TYPE_DAC_DRV,
|
||||||
|
TYPE_CAMERA_DRV,
|
||||||
TYPE_DRV_END,
|
TYPE_DRV_END,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
/*
|
||||||
|
* 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 bus_camera.h
|
||||||
|
* @brief define camera bus and drv function using bus driver framework
|
||||||
|
* @version 1.0
|
||||||
|
* @author AIIT XUOS Lab
|
||||||
|
* @date 2022-11-15
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BUS_CAMERA_H
|
||||||
|
#define BUS_CAMERA_H
|
||||||
|
|
||||||
|
#include <bus.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
struct CameraDriver
|
||||||
|
{
|
||||||
|
struct Driver driver;
|
||||||
|
|
||||||
|
uint32 (*configure) (void *drv, struct BusConfigureInfo *configure_info);
|
||||||
|
|
||||||
|
void *private_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CameraBus
|
||||||
|
{
|
||||||
|
struct Bus bus;
|
||||||
|
|
||||||
|
void *private_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*Register the CAMERA bus*/
|
||||||
|
int CameraBusInit(struct CameraBus *camera_bus, const char *bus_name);
|
||||||
|
|
||||||
|
/*Register the CAMERA driver*/
|
||||||
|
int CameraDriverInit(struct CameraDriver *camera_driver, const char *driver_name);
|
||||||
|
|
||||||
|
/*Release the CAMERA device*/
|
||||||
|
int CameraReleaseBus(struct CameraBus *camera_bus);
|
||||||
|
|
||||||
|
/*Register the CAMERA driver to the CAMERA bus*/
|
||||||
|
int CameraDriverAttachToBus(const char *drv_name, const char *bus_name);
|
||||||
|
|
||||||
|
/*Register the driver, manage with the double linklist*/
|
||||||
|
int CameraDriverRegister(struct Driver *driver);
|
||||||
|
|
||||||
|
/*Find the register driver*/
|
||||||
|
DriverType CameraDriverFind(const char *drv_name, enum DriverType_e drv_type);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,69 @@
|
||||||
|
/*
|
||||||
|
* 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 dev_camera.h
|
||||||
|
* @brief define camera dev function using bus driver framework
|
||||||
|
* @version 1.0
|
||||||
|
* @author AIIT XUOS Lab
|
||||||
|
* @date 2022-11-15
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DEV_CAMERA_H
|
||||||
|
#define DEV_CAMERA_H
|
||||||
|
|
||||||
|
#include <bus.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
struct CameraDataStandard
|
||||||
|
{
|
||||||
|
uint16 addr;
|
||||||
|
uint16 flags;
|
||||||
|
uint16 len;
|
||||||
|
uint16 retries;
|
||||||
|
uint8 *buf;
|
||||||
|
|
||||||
|
struct CameraDataStandard *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CameraDevDone
|
||||||
|
{
|
||||||
|
uint32 (*dev_open) (void *camera_device);
|
||||||
|
uint32 (*dev_close) (void *camera_device);
|
||||||
|
uint32 (*dev_write) (void *camera_device, struct BusBlockWriteParam *msg);
|
||||||
|
uint32 (*dev_read) (void *camera_device, struct BusBlockReadParam *msg);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CameraHardwareDevice
|
||||||
|
{
|
||||||
|
struct HardwareDev haldev;
|
||||||
|
const struct CameraDevDone *camera_dev_done;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*Register the CAMERA device*/
|
||||||
|
int CameraDeviceRegister(struct CameraHardwareDevice *camera_device, void *camera_param, const char *device_name);
|
||||||
|
|
||||||
|
/*Register the CAMERA device to the CAMERA bus*/
|
||||||
|
int CameraDeviceAttachToBus(const char *dev_name, const char *bus_name);
|
||||||
|
|
||||||
|
/*Find the register CAMERA device*/
|
||||||
|
HardwareDevType CameraDeviceFind(const char *dev_name, enum DevType dev_type);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -106,4 +106,9 @@ HardwareDevType ObtainConsole(void);
|
||||||
#include <dev_dac.h>
|
#include <dev_dac.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef RESOURCES_CAMERA
|
||||||
|
#include <bus_camera.h>
|
||||||
|
#include <dev_camera.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -384,6 +384,7 @@ static char *const bus_type_str[] =
|
||||||
"SERIAL_BUS",
|
"SERIAL_BUS",
|
||||||
"ADC_BUS",
|
"ADC_BUS",
|
||||||
"DAC_BUS",
|
"DAC_BUS",
|
||||||
|
"CAMERA_BUS",
|
||||||
"Unknown"
|
"Unknown"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue