Ubiquitous/RT_Thread/:update the ov2640 driver

1.can choose the output format:rgb565 or jpeg
2.resolution and window size can be configured directly
3.add the test that the lcd can show rgb565 image in time
This commit is contained in:
chunyexixiaoyu 2022-01-18 15:58:33 +08:00
parent 1c5047f47a
commit 0dee89982a
5 changed files with 130 additions and 50 deletions

View File

@ -46,8 +46,8 @@ void k210_detect(char *json_file_path)
printf("open ov2640 fail !!");
return;
}
_ioctl_set_dvp_reso set_dvp_reso = {detect_params.sensor_output_size[1], detect_params.sensor_output_size[0]};
ioctl(g_fd, IOCTRL_CAMERA_SET_DVP_RESO, &set_dvp_reso);
_ioctl_set_reso set_dvp_reso = {detect_params.sensor_output_size[1], detect_params.sensor_output_size[0]};
ioctl(g_fd, IOCTRL_CAMERA_OUT_SIZE_RESO, &set_dvp_reso);
showbuffer =
(unsigned char *)rt_malloc_align(detect_params.sensor_output_size[0] * detect_params.sensor_output_size[1] * 2, 64);
if (NULL == showbuffer) {

View File

@ -11,14 +11,19 @@
#endif
#endif
#include<drv_ov2640.h>
#ifdef OV2640_JPEG_MODE
#define JPEG_BUF_SIZE (1024*200)
#else
#define JPEG_BUF_SIZE (2*OV2640_X_RESOLUTION_IMAGE_OUTSIZE*OV2640_Y_RESOLUTION_IMAGE_OUTSIZE)
#endif
#define UART_NUMBER2 "uart2"
void lcd_show_ov2640_thread(uint16_t* rgbbuffer);
static int fd = 0;
static _ioctl_shoot_para shoot_para_t = {0};
void ov2640_test(int argc, char **argv)
{
rt_thread_t tid;
rt_err_t ret = 0;
int fd = 0;
fd = open("/dev/ov2640",O_RDONLY);
if(fd < 0)
{
@ -26,7 +31,6 @@ void ov2640_test(int argc, char **argv)
return;
}
rt_uint8_t* JpegBuffer = rt_malloc(JPEG_BUF_SIZE);
_ioctl_shoot_para shoot_para_t = {0};
if (RT_NULL == JpegBuffer)
{
printf("JpegBuffer senddata buf malloc error!\n");
@ -34,27 +38,36 @@ void ov2640_test(int argc, char **argv)
}
printf("ov2640 test by printing the image value in memory \r\n");
shoot_para_t.pdata = (uint32_t)JpegBuffer;
#ifdef OV2640_RGB565_MODE
shoot_para_t.length = JPEG_BUF_SIZE/2;
#elif defined OV2640_JPEG_MODE
shoot_para_t.length = JPEG_BUF_SIZE;
#endif
ret = ioctl(fd,IOCTRL_CAMERA_START_SHOT,&shoot_para_t);
if(RT_ERROR == ret)
{
printf("ov2640 can't wait event flag");
return;
}
printf("print the vaule:\r\n\r\n");
ret = rt_ov2640_calculate_jpeg_len(JpegBuffer,JPEG_BUF_SIZE);
printf("photo leghth is %d :\r\n\r\n",ret);
#ifdef BSP_USING_UART2
void img_output_uart2(rt_uint8_t* jpegbuf,rt_uint16_t len);
img_output_uart2(JpegBuffer,ret);
#ifdef OV2640_JPEG_MODE
printf("print the vaule:\r\n\r\n");
ret = rt_ov2640_calculate_jpeg_len(JpegBuffer,JPEG_BUF_SIZE);
printf("photo leghth is %d :\r\n\r\n",ret);
#ifdef BSP_USING_UART2
void img_output_uart2(rt_uint8_t* jpegbuf,rt_uint16_t len);
img_output_uart2(JpegBuffer,ret);
#endif
for(int i =0;i<ret;i++)
{
printf("%x",*(JpegBuffer+i));
}
printf("\r\n\r\n above :\r\n\r\n");
rt_free(JpegBuffer);
close(fd);
#elif defined OV2640_RGB565_MODE
tid = rt_thread_create("lcdshow", lcd_show_ov2640_thread, JpegBuffer,3000, 9, 20);
rt_thread_startup(tid);
#endif
for(int i =0;i<ret;i++)
{
printf("%x",*(JpegBuffer+i));
}
printf("\r\n\r\n above :\r\n\r\n");
rt_free(JpegBuffer);
close(fd);
return;
}
MSH_CMD_EXPORT(ov2640_test,printing the image value in memory);
@ -90,8 +103,28 @@ void img_output_uart2(rt_uint8_t* jpegbuf,rt_uint16_t len)
}
#endif
#ifdef OV2640_RGB565_MODE
extern void lcd_fill_array(rt_uint16_t x_start, rt_uint16_t y_start, rt_uint16_t x_end, rt_uint16_t y_end, void *pcolor);
void lcd_show_ov2640_thread(uint16_t* rgbbuffer)
{
rt_err_t ret = 0;
while(1)
{
ret = ioctl(fd,IOCTRL_CAMERA_START_SHOT,&shoot_para_t);
if(RT_ERROR == ret)
{
printf("ov2640 can't wait event flag");
rt_free(rgbbuffer);
return;
}
//lcd_show_image(0, 0, 320, 240, rgbbuffer);
lcd_fill_array(0,0,OV2640_X_RESOLUTION_IMAGE_OUTSIZE,OV2640_Y_RESOLUTION_IMAGE_OUTSIZE,rgbbuffer);
rt_thread_mdelay(1);
}
}
#endif
#endif

View File

@ -2,10 +2,46 @@
menuconfig DRV_USING_OV2640
bool "ov2640 driver"
default n
help
note:
The resolution and window size must follow the proportional relationship,
and the resolution value had better choose constant value(eg: 320*240),
otherwise the picture will be problematic
if DRV_USING_OV2640
choice
prompt "Output format"
default OV2640_JPEG_MODE
help
Select the camera output format
config OV2640_JPEG_MODE
bool "jpeg mode"
config OV2640_RGB565_MODE
bool "RGB565 mode"
endchoice
config OV2640_X_RESOLUTION_IMAGE_OUTSIZE
int " X direction resolution of outputimage"
default 240
config OV2640_Y_RESOLUTION_IMAGE_OUTSIZE
int " Y direction resolution of outputimage"
default 240
config OV2640_X_IMAGE_WINDOWS_SIZE
int " X direction WINDOWS SIZE"
default 400
comment "the value must be greater than OV2640_X_RESOLUTION_IMAGE_OUTSIZE"
config OV2640_Y_IMAGE_WINDOWS_SIZE
int " Y direction WINDOWS SIZE"
default 400
comment "the value must be greater than OV2640_Y_RESOLUTION_IMAGE_OUTSIZE"
endif
if SOC_FAMILY_STM32
config DRV_USING_OV2640
select BSP_USING_DCMI
config OV2640_RGB565_MODE
select BSP_USING_MCU_LCD
endif
if BOARD_K210_EVB

View File

@ -672,7 +672,11 @@ const rt_uint8_t ov2640_jpeg_reg_tbl[][2]=
const rt_uint8_t ov2640_rgb565_reg_tbl[][2]=
{
{0xFF, 0x00},
#ifdef SOC_FAMILY_STM32
{0xDA, 0x09},
#elif defined BOARD_K210_EVB
{0xDA, 0x08},
#endif
{0xD7, 0x03},
{0xDF, 0x02},
{0x33, 0xa0},
@ -1467,7 +1471,7 @@ static rt_err_t rt_ov2640_control(rt_device_t dev, int cmd, void *args)
{
RT_ASSERT(dev != RT_NULL);
rt_err_t ret = RT_EOK;
if(cmd < IOCTRL_CAMERA_SET_DVP_RESO || cmd > IOCTRL_CAMERA_SET_EXPOSURE)
if(cmd < IOCTRL_CAMERA_OUT_SIZE_RESO || cmd > IOCTRL_CAMERA_SET_EXPOSURE)
{
LOG_E("CMD value should be 22 ~29");
return RT_ERROR;
@ -1475,23 +1479,24 @@ static rt_err_t rt_ov2640_control(rt_device_t dev, int cmd, void *args)
int value = 0;
_ioctl_shoot_para shoot_para = {0};
#ifdef BOARD_K210_EVB
_ioctl_set_dvp_reso set_dvp_reso = {0};
#endif
_ioctl_set_reso set_dvp_reso = {0};
if(IOCTRL_CAMERA_START_SHOT == cmd)
{
shoot_para = *((_ioctl_shoot_para*)args);
ret = rt_ov2640_start_shoot(shoot_para.pdata,shoot_para.length);
return ret;
}
#ifdef BOARD_K210_EVB
else if(IOCTRL_CAMERA_SET_DVP_RESO == cmd)
else if(IOCTRL_CAMERA_OUT_SIZE_RESO == cmd)
{
set_dvp_reso =*((_ioctl_set_dvp_reso*)args);
set_dvp_reso =*((_ioctl_set_reso*)args);
#ifdef BOARD_K210_EVB
dvp_set_image_size(set_dvp_reso.width, set_dvp_reso.height);
#elif defined SOC_FAMILY_STM32
ov2640_set_image_size(set_dvp_reso.width, set_dvp_reso.height);
#endif
return RT_EOK;
}
#endif
else
{
value = *((int*)args);
@ -1617,18 +1622,22 @@ static rt_err_t rt_ov2640_init(rt_device_t dev)
sccb_write_reg(i2c_bus, ov2640_svga_init_reg_tbl[i][0], ov2640_svga_init_reg_tbl[i][1]);
}
}
ov2640_rgb565_mode();
ov2640_set_light_mode(0);
ov2640_set_color_saturation(0);
ov2640_set_brightness(2);
ov2640_set_contrast(1);
#ifdef OV2640_RGB565_MODE
ov2640_rgb565_mode();
#elif defined OV2640_JPEG_MODE
ov2640_jpeg_mode();
#endif
#ifdef SOC_FAMILY_STM32
LOG_I("set ov2640 jpeg mode on stm32 board");
ov2640_jpeg_mode();
ov2640_set_image_window_size(0, 0, jpeg_img_size_tbl[g_ov2640_reso_level][0],jpeg_img_size_tbl[g_ov2640_reso_level][1]);
ov2640_set_image_out_size(jpeg_img_size_tbl[g_ov2640_reso_level][0], jpeg_img_size_tbl[g_ov2640_reso_level][1]);
LOG_I("set image resolution is %d * %d ",jpeg_img_size_tbl[g_ov2640_reso_level][0],jpeg_img_size_tbl[g_ov2640_reso_level][1]);
ov2640_set_image_out_size(OV2640_X_RESOLUTION_IMAGE_OUTSIZE,OV2640_Y_RESOLUTION_IMAGE_OUTSIZE);
ov2640_set_image_window_size(0, 0,OV2640_X_IMAGE_WINDOWS_SIZE,OV2640_Y_IMAGE_WINDOWS_SIZE);
LOG_I("set image resolution is %d * %d ",OV2640_X_RESOLUTION_IMAGE_OUTSIZE,OV2640_Y_RESOLUTION_IMAGE_OUTSIZE);
#elif defined BOARD_K210_EVB
ov2640_rgb565_mode();
ov2640_set_image_window_size(0, 0, jpeg_img_size_tbl[5][0],jpeg_img_size_tbl[5][1]);
ov2640_set_image_out_size(jpeg_img_size_tbl[2][0], jpeg_img_size_tbl[2][1]);
LOG_I("set ov2640 rgb565 mode on K210 board and set reselotion QVGA 320,240");

View File

@ -123,28 +123,30 @@ extern "C" {
#define OV2640_SENSOR_HISTO_LOW 0x61
#define OV2640_SENSOR_HISTO_HIGH 0x62
#ifdef BOARD_K210_EVB
#define IOCTRL_CAMERA_SET_DVP_RESO (21) // set dev resolution
#else
#define IOCTRL_CAMERA_SET_DVP_RESO (22) // same as IOCTRL_CAMERA_START_SHOT
#endif
#define IOCTRL_CAMERA_START_SHOT (22) // start shoot
#define IOCTRL_CAMERA_SET_RESO (23) //set resolution
#define IOCTRL_CAMERA_SET_LIGHT (24) //set light mode
#define IOCTRL_CAMERA_SET_COLOR (25) //set color saturation
#define IOCTRL_CAMERA_SET_BRIGHTNESS (26) //set color brightness
#define IOCTRL_CAMERA_SET_CONTRAST (27) //set contrast
#define IOCTRL_CAMERA_SET_EFFECT (28) //set effect
#define IOCTRL_CAMERA_SET_EXPOSURE (29) //set auto exposure
#define IOCTRL_CAMERA_OUT_SIZE_RESO (20) // user set specific resolution outsize
#define IOCTRL_CAMERA_SET_WINDOWS_SIZE (21) // user set specific windows outsize
#define IOCTRL_CAMERA_START_SHOT (22) // start shoot
#define IOCTRL_CAMERA_SET_RESO (23) //set common resolution eg :QQVGA 0 QCIF 1 QVGA 2 WQVGA 3 CIF 4 …………
#define IOCTRL_CAMERA_SET_LIGHT (24) //set light mode
#define IOCTRL_CAMERA_SET_COLOR (25) //set color saturation
#define IOCTRL_CAMERA_SET_BRIGHTNESS (26) //set color brightness
#define IOCTRL_CAMERA_SET_CONTRAST (27) //set contrast
#define IOCTRL_CAMERA_SET_EFFECT (28) //set effect
#define IOCTRL_CAMERA_SET_EXPOSURE (29) //set auto exposure
#ifdef BOARD_K210_EVB
typedef struct
{
uint32_t width; // width The width of image
uint32_t height; // height The height of image
}_ioctl_set_dvp_reso;
#endif
}_ioctl_set_reso;
typedef struct
{
uint32_t width; // width The width of image
uint32_t height; // height The height of image
}_ioctl_ov2640_set_win_size;
struct camera_device