Add camera driver and examples for edu-riscv64 from Wu_zheng

it is OK
This commit is contained in:
xuedongliang 2022-11-25 10:25:38 +08:00
commit e5bf0cee41
51 changed files with 2594 additions and 270 deletions

View File

@ -105,6 +105,8 @@ menu "test app"
menuconfig USER_TEST_HWTIMER
select BSP_USING_HWTIMER
select BSP_USING_GPIO
select RESOURCES_PIN
select BSP_USING_LED
bool "Config test hwtimer"
default n
if USER_TEST_HWTIMER
@ -139,6 +141,21 @@ menu "test app"
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
select BSP_USING_I2C
bool "Config test i2c"
@ -151,6 +168,22 @@ menu "test app"
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
bool "Config test semc sdram"
default n

View File

@ -75,7 +75,15 @@ ifeq ($(CONFIG_ADD_XIZI_FETURES),y)
ifeq ($(CONFIG_USER_TEST_WDT),y)
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
endif

View File

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

View File

@ -6,28 +6,23 @@
#define NULL_PARAMETER 0
static uint16_t pinval=0;
static uint16_t pin_fd=0;
void ledflip(void *parameter)
{
int tmp_fd = *(int*)parameter;
struct PinStat pin_led;
pin_led.pin = BSP_LED_PIN;
pin_led.val = !pinval;
pinval = !pinval;
PrivWrite(tmp_fd,&pin_led,NULL_PARAMETER);
printf("Timer has callback once\n");
PrivWrite(pin_fd,&pin_led,NULL_PARAMETER);
// printf("Timer has callback once:%d\n",pinval);
}
void TestHwTimer(int argc, char *argv[])
void TestHwTimer(void)
{
x_ticks_t period = 100;//uint:10ms
if(argc>1){
period = (x_ticks_t)atoi(argv[1]);
}
int pin_fd = PrivOpen(HWTIMER_PIN_DEV_DRIVER, O_RDWR);
pin_fd = PrivOpen(HWTIMER_PIN_DEV_DRIVER, O_RDWR);
if(pin_fd<0){
printf("open pin fd error:%d\n",pin_fd);
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);
KTimerStartRun(timer_handle);
PrivTaskDelay(10000);
KTimerQuitRun(timer_handle);
KDeleteTimer(timer_handle);
}

View File

@ -41,3 +41,71 @@ void TestTouch(void)
#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);

View File

@ -30,10 +30,10 @@ void HumiHs300x(void)
int32_t humidity;
struct SensorQuantity *humi = SensorQuantityFind(SENSOR_QUANTITY_HS300X_HUMIDITY, SENSOR_QUANTITY_HUMI);
SensorQuantityOpen(humi);
for (i = 0; i < 100; i ++) {
for (i = 0; i < 10; i ++) {
humidity = SensorQuantityReadValue(humi);
printf("Humidity : %d.%d %%RH\n", humidity/10, humidity%10);
PrivTaskDelay(5000);
PrivTaskDelay(500);
}
SensorQuantityClose(humi);
}

View File

@ -30,14 +30,14 @@ void TempHs300x(void)
int32_t temperature;
struct SensorQuantity *temp = SensorQuantityFind(SENSOR_QUANTITY_HS300X_TEMPERATURE, SENSOR_QUANTITY_TEMP);
SensorQuantityOpen(temp);
for (i = 0; i < 100; i ++) {
for (i = 0; i < 10; i ++) {
temperature = SensorQuantityReadValue(temp);
if (temperature > 0)
printf("Temperature : %d.%d ℃\n", temperature/10, temperature%10);
else
printf("Temperature : %d.%d ℃\n", temperature/10, -temperature%10);
PrivTaskDelay(5000);
PrivTaskDelay(500);
}
SensorQuantityClose(temp);

View File

@ -17,5 +17,9 @@ ifeq ($(CONFIG_ADAPTER_ESP07S_WIFI),y)
SRC_DIR += esp07s_wifi
endif
ifeq ($(CONFIG_ADAPTER_ESP8285_WIFI),y)
SRC_DIR += esp8285_wifi
endif
include $(KERNEL_ROOT)/compiler.mk
endif

View File

@ -8,3 +8,9 @@ if ADD_NUTTX_FETURES
default "/dev/ttyS1"
endif
if ADD_XIZI_FETURES
config ADAPTER_ESP8285_DRIVER
string "ESP8285 device uart driver path"
default "/dev/uart1_dev1"
endif

View File

@ -5,3 +5,8 @@ ifeq ($(CONFIG_ADD_NUTTX_FETURES),y)
include $(APPDIR)/Application.mk
endif
ifeq ($(CONFIG_ADD_XIZI_FETURES),y)
SRC_FILES := esp8285_wifi.c
include $(KERNEL_ROOT)/compiler.mk
endif

View File

@ -205,16 +205,16 @@ static int Esp8285WifiSetUp(struct Adapter *adapter)
PrivTaskDelay(2000);
/* connect the router */
memset(cmd,0,sizeof(cmd));
strncpy(cmd,"AT+CWJAP=",strlen("AT+CWJAP="));
strncat(cmd,"\"",1);
strncat(cmd,param->wifi_ssid,strlen(param->wifi_ssid));
strcat(cmd,"AT+CWJAP=");
strcat(cmd,"\"");
strcat(cmd,param->wifi_ssid);
strncat(cmd,"\"",1);
strncat(cmd,",",1);
strncat(cmd,"\"",1);
strncat(cmd,param->wifi_pwd,strlen(param->wifi_pwd));
strcat(cmd,"\"");
strcat(cmd,",");
strcat(cmd,"\"");
strcat(cmd,param->wifi_pwd);
strncat(cmd,"\"",1);
strcat(cmd,"\"");
strcat(cmd,"\r\n");
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" */
memset(cmd,0,sizeof(cmd));
strncpy(cmd,"AT+CIPAP_DEF=",strlen(" AT+CIPAP_DEF="));
strncat(cmd,"\"",1);
strncat(cmd,ip,strlen(ip));
strncat(cmd,"\"",1);
strncat(cmd,",",1);
strncat(cmd,"\"",1);
strncat(cmd,gateway,strlen(gateway));
strncat(cmd,"\"",1);
strncat(cmd,",",1);
strncat(cmd,"\"",1);
strncat(cmd,netmask,strlen(netmask));
strncat(cmd,"\"",1);
strcat(cmd,"\"");
strcat(cmd,ip);
strcat(cmd,"\"");
strcat(cmd,",");
strcat(cmd,"\"");
strcat(cmd,gateway);
strcat(cmd,"\"");
strcat(cmd,",");
strcat(cmd,"\"");
strcat(cmd,netmask);
strcat(cmd,"\"");
strcat(cmd,"\r\n");
ret = AtCmdConfigAndCheck(adapter->agent, cmd, "OK");
@ -314,9 +314,9 @@ static int Esp8285WifiPing(struct Adapter *adapter, const char *destination)
memset(cmd,0,sizeof(cmd));
strncpy(cmd,"AT+PING=",strlen("AT+PING="));
strncat(cmd,"\"",1);
strncat(cmd,destination,strlen(destination));
strncat(cmd,"\"",1);
strcat(cmd,"\"");
strcat(cmd,destination);
strcat(cmd,"\"");
strcat(cmd,"\r\n");
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
strncpy(cmd,"AT+CIPSTART=",strlen("AT+CIPSTART="));
strncat(cmd,"\"",1);
strncat(cmd,"TCP",strlen("TCP"));
strncat(cmd,"\"",1);
strncat(cmd, ",", 1);
strncat(cmd,"\"",1);
strncat(cmd, ip, strlen(ip));
strncat(cmd, "\"", 1);
strncat(cmd, ",", 1);
strncat(cmd, port, strlen(port));
strcat(cmd,"\"");
strcat(cmd,"TCP");
strcat(cmd,"\"");
strcat(cmd, ",");
strcat(cmd,"\"");
strcat(cmd, ip);
strcat(cmd, "\"");
strcat(cmd, ",");
strcat(cmd, port);
strcat(cmd,"\r\n");
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
strncpy(cmd,"AT+CIPSTART=",strlen("AT+CIPSTART="));
strncat(cmd,"\"",1);
strncat(cmd,"UDP",strlen("UDP"));
strncat(cmd,"\"",1);
strncat(cmd, ",", 1);
strncat(cmd,"\"",1);
strncat(cmd, ip, strlen(ip));
strncat(cmd, "\"", 1);
strncat(cmd, ",", 1);
strncat(cmd, port, strlen(port));
strncat(cmd, ",", 1);
strncat(cmd, "2233", strlen("2233")); ///< local port
strncat(cmd, ",", 1);
strncat(cmd, "0", 1); ///< udp transparent transmission mode must be 0
strcat(cmd,"\"");
strcat(cmd,"UDP");
strcat(cmd,"\"");
strcat(cmd, ",");
strcat(cmd,"\"");
strcat(cmd, ip);
strcat(cmd, "\"");
strcat(cmd, ",");
strcat(cmd, port);
strcat(cmd, ",");
strcat(cmd, "2233"); ///< local port
strcat(cmd, ",");
strcat(cmd, "0"); ///< udp transparent transmission mode must be 0
strcat(cmd,"\r\n");
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);
strncpy(at_cmd, "AT+UART_DEF=", strlen("AT+UART_DEF="));
strncat(at_cmd, baud_str, strlen(baud_str));
strncat(at_cmd, ",", 1);
strncat(at_cmd, "8", 1);
strncat(at_cmd, ",", 1);
strncat(at_cmd, "1", 1);
strncat(at_cmd, ",", 1);
strncat(at_cmd, "0", 1);
strncat(at_cmd, ",", 1);
strncat(at_cmd, "3", 1);
strcat(at_cmd, baud_str);
strcat(at_cmd, ",");
strcat(at_cmd, "8");
strcat(at_cmd, ",");
strcat(at_cmd, "1");
strcat(at_cmd, ",");
strcat(at_cmd, "0");
strcat(at_cmd, ",");
strcat(at_cmd, "3");
strcat(at_cmd,"\r\n");
ret = AtCmdConfigAndCheck(adapter->agent, at_cmd, "OK");

View File

@ -6,6 +6,12 @@ ifeq ($(CONFIG_ADD_NUTTX_FETURES),y)
endif
ifeq ($(ADD_XIZI_FETURES),y)
include $(APPDIR)/Make.defs
CSRCS += sensor.c
include $(APPDIR)/Application.mk
endif
ifeq ($(CONFIG_ADD_XIZI_FETURES),y)
SRC_FILES := sensor.c

View File

@ -173,6 +173,7 @@ int PrivIoctl(int fd, int cmd, void *args)
case ADC_TYPE:
case DAC_TYPE:
case WDT_TYPE:
case CAMERA_TYPE:
ret = ioctl(fd, cmd, ioctl_cfg->args);
break;
default:

View File

@ -150,9 +150,18 @@ enum IoctlDriverType
DAC_TYPE,
WDT_TYPE,
RTC_TYPE,
CAMERA_TYPE,
DEFAULT_TYPE,
};
struct DvpRegConfigureInfo
{
uint8_t device_addr;
uint16_t reg_addr;
uint8_t reg_value;
} ;
struct PrivIoctlCfg
{
enum IoctlDriverType ioctl_driver_type;
@ -180,6 +189,18 @@ typedef struct
void* pixel_color;
}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
{
char type; // 0:write string;1:write dot
@ -194,6 +215,12 @@ typedef struct
uint16_t press;
}TouchDataParam;
struct TouchDataStandard
{
uint16 x;
uint16 y;
};
struct RtcDrvConfigureParam
{
int rtc_operation_cmd;

View File

@ -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
/*********************
@ -12,18 +12,18 @@
#include "lv_port_indev_template.h"
#include "../../lvgl.h"
static int touch_fd = -1;
static TouchDataParam touch_data;
static int touch_fd = 0;
/*********************
* DEFINES
*********************/
#define LV_USE_INDEV_TOUCHPAD 0x1u
#define LV_USE_INDEV_MOUSE 0x2u
#define LV_USE_INDEV_KEYPAD 0x4u
#define LV_USE_INDEV_ENCODER 0x8u
#define LV_USE_INDEV_BUTTUN 0x10u
#define LV_USE_INDEV_MOUSE 0x2u
#define LV_USE_INDEV_KEYPAD 0x4u
#define LV_USE_INDEV_ENCODER 0x8u
#define LV_USE_INDEV_BUTTUN 0x10u
#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 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
/**********************
* TYPEDEFS
@ -34,33 +34,36 @@ static TouchDataParam touch_data;
**********************/
#if (LV_USE_INDEV & LV_USE_INDEV_TOUCHPAD) == LV_USE_INDEV_TOUCHPAD
static void touchpad_init(void);
static void touchpad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
static bool touchpad_is_pressed(void);
static void touchpad_get_xy(lv_coord_t * x, lv_coord_t * y);
static void touchpad_read(lv_indev_drv_t *indev_drv, lv_indev_data_t *data);
// static bool touchpad_is_pressed(void);
// 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
#if (LV_USE_INDEV & LV_USE_INDEV_MOUSE) == LV_USE_INDEV_MOUSE
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 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
#if (LV_USE_INDEV & LV_USE_INDEV_KEYPAD) == LV_USE_INDEV_KEYPAD
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);
#endif
#if (LV_USE_INDEV & LV_USE_INDEV_ENCODER) == LV_USE_INDEV_ENCODER
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);
#endif
#if (LV_USE_INDEV & LV_USE_INDEV_BUTTUN) == LV_USE_INDEV_BUTTUN
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 bool button_is_pressed(uint8_t id);
#endif
@ -69,23 +72,23 @@ static bool button_is_pressed(uint8_t id);
* STATIC VARIABLES
**********************/
#if (LV_USE_INDEV & LV_USE_INDEV_TOUCHPAD) == LV_USE_INDEV_TOUCHPAD
lv_indev_t * indev_touchpad;
lv_indev_t *indev_touchpad;
#endif
#if (LV_USE_INDEV & LV_USE_INDEV_MOUSE) == LV_USE_INDEV_MOUSE
lv_indev_t * indev_mouse;
lv_indev_t *indev_mouse;
#endif
#if (LV_USE_INDEV & LV_USE_INDEV_KEYPAD) == LV_USE_INDEV_KEYPAD
lv_indev_t * indev_keypad;
lv_indev_t *indev_keypad;
#endif
#if (LV_USE_INDEV & LV_USE_INDEV_ENCODER) == LV_USE_INDEV_ENCODER
lv_indev_t * indev_encoder;
lv_indev_t *indev_encoder;
#endif
#if (LV_USE_INDEV & LV_USE_INDEV_BUTTUN) == LV_USE_INDEV_BUTTUN
lv_indev_t * indev_button;
lv_indev_t *indev_button;
#endif
static int32_t encoder_diff;
@ -144,7 +147,7 @@ void lv_port_indev_init(void)
indev_mouse = lv_indev_drv_register(&indev_drv);
/*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_indev_set_cursor(indev_mouse, mouse_cursor);
#endif
@ -169,8 +172,6 @@ void lv_port_indev_init(void)
*`lv_indev_set_group(indev_keypad, group);`*/
#endif
#if (LV_USE_INDEV & LV_USE_INDEV_ENCODER) == LV_USE_INDEV_ENCODER
/*------------------
* Encoder
@ -207,8 +208,8 @@ void lv_port_indev_init(void)
/*Assign buttons to points on the screen*/
static const lv_point_t btn_points[2] = {
{10, 10}, /*Button 0 -> x:10; y:10*/
{40, 100}, /*Button 1 -> x:40; y:100*/
{10, 10}, /*Button 0 -> x:10; y:10*/
{40, 100}, /*Button 1 -> x:40; y:100*/
};
lv_indev_set_button_points(indev_button, btn_points);
#endif
@ -225,27 +226,37 @@ void lv_port_indev_init(void)
/*Initialize your touchpad*/
static void touchpad_init(void)
{
touch_fd = PrivOpen(PRIV_TOUCH_DEV,O_RDWR);
if(touch_fd >= 0) {
touch_fd = PrivOpen(PRIV_TOUCH_DEV, O_RDWR);
if (touch_fd >= 0)
{
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*/
}
// static struct TouchDataStandard touch_data;
/*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_y = 0;
static struct TouchDataStandard touch_data;
/*Save the pressed coordinates and the state*/
if(touchpad_is_pressed()) {
touchpad_get_xy(&last_x, &last_y);
if (touchpad_is_pressed(&touch_data))
{
touchpad_get_xy(&touch_data, &last_x, &last_y);
data->state = LV_INDEV_STATE_PR;
} else {
}
else
{
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*/
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;
/*Your code comes here*/
memset(&touch_data, 0 ,sizeof(TouchDataParam));
if (touch_fd < 0) {
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)
memset(touch_data_ptr, 0, sizeof(struct TouchDataStandard));
ret = PrivRead(touch_fd, touch_data_ptr, 1);
if (ret)
{
// printf("touch x %d touch y %d\n",touch_data.x,touch_data.y);
return true;
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;
}
else
{
press_failed_cnt++;
if (press_failed_cnt >= PRESS_FAILED_LIMIT)
{
PrivClose(touch_fd);
touchpad_init();
press_failed_cnt = 0;
}
}
}
return false;
}
/*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*/
(*x) = touch_data.x;
(*y) = touch_data.y;
(*x) = touch_data_ptr->x;
(*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
#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*/
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*/
mouse_get_xy(&data->point.x, &data->point.y);
/*Get whether the mouse button is pressed or released*/
if(mouse_is_pressed()) {
if (mouse_is_pressed())
{
data->state = LV_INDEV_STATE_PR;
} else {
}
else
{
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*/
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*/
@ -328,8 +376,6 @@ static void mouse_get_xy(lv_coord_t * x, lv_coord_t * y)
}
#endif
#if (LV_USE_INDEV & LV_USE_INDEV_KEYPAD) == LV_USE_INDEV_KEYPAD
/*------------------
* Keypad
@ -342,7 +388,7 @@ static void keypad_init(void)
}
/*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;
@ -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*/
uint32_t act_key = keypad_get_key();
if(act_key != 0) {
if (act_key != 0)
{
data->state = LV_INDEV_STATE_PR;
/*Translate the keys to LVGL control characters according to your key definitions*/
switch(act_key) {
switch (act_key)
{
case 1:
act_key = LV_KEY_NEXT;
break;
@ -374,7 +422,9 @@ static void keypad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
}
last_key = act_key;
} else {
}
else
{
data->state = LV_INDEV_STATE_REL;
}
@ -390,8 +440,6 @@ static uint32_t keypad_get_key(void)
}
#endif
#if (LV_USE_INDEV & LV_USE_INDEV_ENCODER) == LV_USE_INDEV_ENCODER
/*------------------
* Encoder
@ -404,7 +452,7 @@ static void encoder_init(void)
}
/*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;
@ -433,7 +481,7 @@ static void button_init(void)
}
/*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;
@ -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*/
int8_t btn_act = button_get_pressed_id();
if(btn_act >= 0) {
if (btn_act >= 0)
{
data->state = LV_INDEV_STATE_PR;
last_btn = btn_act;
} else {
}
else
{
data->state = LV_INDEV_STATE_REL;
}
@ -458,9 +509,11 @@ static int8_t button_get_pressed_id(void)
uint8_t i;
/*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*/
if(button_is_pressed(i)) {
if (button_is_pressed(i))
{
return i;
}
}

View File

@ -1,10 +1,10 @@
# include $(LVGL_DIR)/$(LVGL_DIR_NAME)/examples/examples.mk
include $(LVGL_DIR)/$(LVGL_DIR_NAME)/porting/porting.mk
include $(LVGL_DIR)/$(LVGL_DIR_NAME)/examples/examples.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/draw/lv_draw.mk
include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/font/lv_font.mk
include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/gpu/lv_gpu.mk
include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/hal/lv_hal.mk
include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/misc/lv_misc.mk
include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/widgets/lv_widgets.mk
include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/widgets/lv_widgets.mk

View File

@ -12,7 +12,6 @@
#include "lv_port_indev_template.h"
#include "../lvgl.h"
#include <dev_touch.h>
static int touch_fd = 0;
/*********************
@ -292,7 +291,7 @@ static bool touchpad_is_pressed(struct TouchDataStandard* touch_data_ptr)
press_failed_cnt = 0;
return true;
}
printf("lv_touch:%d,%d\n",touch_data_ptr->x,touch_data_ptr->y);
press_failed_cnt++;
if (press_failed_cnt >= PRESS_FAILED_LIMIT) {
PrivClose(touch_fd);

View File

@ -47,6 +47,7 @@ Modification:
#include "connect_uart.h"
#include "connect_w5500.h"
#include "connect_wdt.h"
#include "connect_dvp.h"
#include "dmac.h"
#include "encoding.h"
#include "fpioa.h"
@ -217,7 +218,10 @@ struct InitSequenceDesc _board_init[] = {
#ifdef BSP_USING_W5500
{"w5500", HwWiznetInit},
#endif
{" NONE ", NONE},
#ifdef BSP_USING_CAMERA
{"hw_camera", HwDvpInit },
#endif
{ " NONE ",NONE },
};
void InitBoardHardware(void) {

View File

@ -120,3 +120,12 @@ menuconfig BSP_USING_WIZCHIP
if BSP_USING_WIZCHIP
source "$BSP_DIR/third_party_driver/ethernet/Kconfig"
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

View File

@ -59,5 +59,9 @@ endif
ifeq ($(CONFIG_BSP_USING_WIZCHIP),y)
SRC_DIR += ethernet
endif
ifeq ($(CONFIG_BSP_USING_CAMERA),y)
SRC_DIR += dvp
endif
include $(KERNEL_ROOT)/compiler.mk

View File

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

View File

@ -0,0 +1,4 @@
SRC_FILES := connect_dvp.c dvp.c ov2640.c
include $(KERNEL_ROOT)/compiler.mk

View File

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

View File

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

View File

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

View File

@ -72,31 +72,15 @@ static struct io_config
IOCONFIG(BSP_UART2_RXD_PIN, FUNC_UART2_RX),
#endif
#ifdef BSP_USING_UART3
IOCONFIG(BSP_UART3_TXD_PIN, FUNC_UART3_RX),
IOCONFIG(BSP_UART3_RXD_PIN, FUNC_UART3_TX),
IOCONFIG(BSP_UART3_TXD_PIN, FUNC_UART3_TX),
IOCONFIG(BSP_UART3_RXD_PIN, FUNC_UART3_RX),
#endif
#ifdef BSP_USING_I2C
IOCONFIG(BSP_I2C_SDA, FUNC_GPIO3),
IOCONFIG(BSP_I2C_SCL, FUNC_GPIO4),
#endif
#ifdef BSP_USING_TOUCH
// 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)),
IOCONFIG(BSP_TOUCH_TP_INT, HS_GPIO(FPIOA_TOUCH_TP_INT)),
#endif
#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)),
#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
IOCONFIG(BSP_E220_M0_PIN, HS_GPIO(FUNC_GPIOHS10)),
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);
#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++)
{
ret = FpioaSetFunction(io_config[i].io_num, io_config[i].func);

View File

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

View File

@ -64,6 +64,10 @@ typedef enum _touch_event
#define GTP_REG_CONFIG_DATA 0x8047
#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]))
int HwTouchInit(void);

View File

@ -30,7 +30,7 @@ Modification: add edu-riscv64-board io configure define
#ifndef __DRV_IO_CONFIG_H__
#define __DRV_IO_CONFIG_H__
<<<<<<< HEAD enum HS_GPIO_CONFIG {
enum HS_GPIO_CONFIG {
#ifdef BSP_USING_LCD
LCD_DC_PIN = 0, /* LCD DC PIN */
#endif
@ -53,99 +53,35 @@ Modification: add edu-riscv64-board io configure define
}
;
#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
#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
#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
======= 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_MIOS_PIN 25
#define BSP_SOFT_SPI_MSOI_PIN 27
#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
#ifdef BSP_USING_LED

View File

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

View File

@ -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;
aiit_lcd = (Lcd8080DeviceType)dev;
@ -366,6 +366,8 @@ x_err_t DrvLcdInit(Lcd8080DeviceType dev)
data = 0x55;
DrvLcdDataByte(&data, 1);
DrvLcdCmd(INVERSION_DISPALY_ON);
/* set direction */
DrvLcdSetDirection(DIR_YX_RLUD);
@ -476,7 +478,6 @@ static uint32 LcdWrite(void *dev, struct BusBlockWriteParam *write_param)
}
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);
return EOK;
}
@ -549,7 +550,7 @@ static int BoardLcdDevBend(struct LcdHardwareDevice *lcd_device, void *param, co
return ret;
}
static int flag = 1;
int HwLcdInit(void)
{
x_err_t ret = EOK;
@ -613,7 +614,11 @@ int HwLcdInit(void)
KPrintf("LCD driver inited ...\r\n");
DrvLcdInit(lcd_dev);
if(flag){
DrvLcdInit(lcd_dev);
flag = 0;
}
return ret;
}

View File

@ -12,7 +12,7 @@
#include <dev_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(cfg);
@ -29,7 +29,7 @@ static x_err_t softSPIinit(struct SpiDriver *spi_drv, struct BusConfigureInfo *c
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(configure_info);
@ -41,7 +41,7 @@ static uint32 softSpiDrvConfigure(void *drv, struct BusConfigureInfo *configure_
switch (configure_info->configure_cmd)
{
case OPE_INT:
softSPIinit(spi_drv, configure_info);
SoftSPIinit(spi_drv, configure_info);
break;
case OPE_CFG:
@ -54,7 +54,7 @@ static uint32 softSpiDrvConfigure(void *drv, struct BusConfigureInfo *configure_
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;
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 read_data = 0xFF;
@ -100,7 +100,7 @@ static uint8_t soft_spi_readbyte(struct SpiHardwareDevice *spi_dev)
/* 读写一个字节 */
// 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 temp = 0;
@ -129,7 +129,7 @@ static uint8_t soft_spi_readwritebyte(struct SpiHardwareDevice *spi_dev, uint8_t
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);
@ -148,7 +148,7 @@ static uint32 softSpiWriteData(struct SpiHardwareDevice *spi_dev, struct SpiData
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)
@ -160,7 +160,7 @@ static uint32 softSpiWriteData(struct SpiHardwareDevice *spi_dev, struct SpiData
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);
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++)
{
recv_buff[i] = soft_spi_readbyte(spi_dev);
recv_buff[i] = SoftSpiReadbyte(spi_dev);
}
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 = {
.dev_close = NONE,
.dev_open = NONE,
.dev_read = softSpiReadData,
.dev_write = softSpiWriteData};
.dev_read = SoftSpiReadData,
.dev_write = SoftSpiWriteData};
static int BoardSoftSpiBusInit(struct SpiBus *spi_bus, struct SpiDriver *spi_driver)
{
@ -275,7 +275,7 @@ int HwSoftSPIInit(void)
static struct SpiDriver spi_driver;
memset(&spi_driver, 0, sizeof(struct SpiDriver));
spi_driver.configure = &(softSpiDrvConfigure);
spi_driver.configure = &(SoftSpiDrvConfigure);
ret = BoardSoftSpiBusInit(&spi_bus, &spi_driver);
if (EOK != ret)

View File

@ -38,7 +38,7 @@ struct Touch_event {
};
#define DEFAULT_NUM 0x0D
#define TOUCH_ADDRESS 0x44
#define TOUCH_ADDRESS 0x40
volatile bool SemReleaseFlag = 0;
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
static void touch_pin_irqhandler(void* arg)
{
// KPrintf("int hdr working.\n");
KPrintf("int hdr working.\n");
if (!SemReleaseFlag)
{
KSemaphoreAbandon(touch_sem);
@ -277,8 +277,8 @@ static uint32 TouchRead(void* dev, struct BusBlockReadParam* read_param)
char status_reg = 0x80;
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)
// {
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].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
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->y = ts_event.fingers[ts_event.NBfingers - 1].y;
read_param->read_length = ts_event.NBfingers;
SemReleaseFlag = 0;
// }

View File

@ -359,7 +359,8 @@ static uint32 TouchRead(void *dev, struct BusBlockReadParam *read_param)
result = KSemaphoreObtain(touch_sem, 1000);
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->y = abs(LCD_HEIGHT - touch_point.Y);
@ -369,6 +370,11 @@ static uint32 TouchRead(void *dev, struct BusBlockReadParam *read_param)
read_param->read_length = read_param->size;
ret = EOK;
}
else
{
ret = -ERROR;
read_param->read_length = -ERROR;
}
SemReleaseFlag = 0;
}

View File

@ -107,3 +107,19 @@ select RESOURCES_WDT
if BSP_USING_WDT
source "$BSP_DIR/third_party_driver/watchdog/Kconfig"
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

View File

@ -56,4 +56,8 @@ ifeq ($(CONFIG_BSP_USING_WDT),y)
SRC_DIR += watchdog
endif
ifeq ($(CONFIG_BSP_USING_SOFT_SPI),y)
SRC_DIR += soft_spi
endif
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,14 @@
#ifndef CONNECT_TF_H
#define CONNECT_TF_H
#ifdef __cplusplus
extern "C" {
#endif
int HwSoftSPIInit(void);
#ifdef __cplusplus
}
#endif
#endif

View File

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

View File

@ -0,0 +1,3 @@
SRC_FILES := connect_soft_spi.c
include $(KERNEL_ROOT)/compiler.mk

View File

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

View File

@ -163,3 +163,9 @@ if BSP_USING_DAC
bool "Using DAC bus drivers"
default n
endif
if BSP_USING_CAMERA
config RESOURCES_CAMERA
bool "Using Camera bus drivers"
default n
endif

View File

@ -65,4 +65,8 @@ ifeq ($(CONFIG_RESOURCES_DAC),y)
SRC_DIR += dac
endif
ifeq ($(CONFIG_RESOURCES_CAMERA),y)
SRC_DIR += camera
endif
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,5 @@
SRC_FILES += dev_camera.c drv_camera.c bus_camera.c
include $(KERNEL_ROOT)/compiler.mk

View File

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

View File

@ -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 configuretransfer 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;
}

View File

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

View File

@ -54,6 +54,7 @@ enum BusType_e
TYPE_SERIAL_BUS,
TYPE_ADC_BUS,
TYPE_DAC_BUS,
TYPE_CAMERA_BUS,
TYPE_BUS_END,
};
@ -80,6 +81,7 @@ enum DevType
TYPE_SERIAL_DEV,
TYPE_ADC_DEV,
TYPE_DAC_DEV,
TYPE_CAMERA_DEV,
TYPE_DEV_END,
};
@ -106,6 +108,7 @@ enum DriverType_e
TYPE_SERIAL_DRV,
TYPE_ADC_DRV,
TYPE_DAC_DRV,
TYPE_CAMERA_DRV,
TYPE_DRV_END,
};

View File

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

View File

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

View File

@ -106,4 +106,9 @@ HardwareDevType ObtainConsole(void);
#include <dev_dac.h>
#endif
#ifdef RESOURCES_CAMERA
#include <bus_camera.h>
#include <dev_camera.h>
#endif
#endif

View File

@ -384,6 +384,7 @@ static char *const bus_type_str[] =
"SERIAL_BUS",
"ADC_BUS",
"DAC_BUS",
"CAMERA_BUS",
"Unknown"
};