[refactor][cam] refactor camera driver,add standard interfaces for camera

This commit is contained in:
jzlv 2021-10-25 15:14:04 +08:00
parent 9792e36ab4
commit e27aedace2
20 changed files with 404 additions and 259 deletions

View file

@ -77,7 +77,7 @@
#define BSP_DAC_CLOCK_SOURCE ROOT_CLOCK_SOURCE_AUPLL_24000000_HZ #define BSP_DAC_CLOCK_SOURCE ROOT_CLOCK_SOURCE_AUPLL_24000000_HZ
#define BSP_DAC_CLOCK_DIV 1 #define BSP_DAC_CLOCK_DIV 1
#endif #endif
#if defined(BSP_USING_CAM) #if defined(BSP_USING_CAM0)
#define BSP_CAM_CLOCK_SOURCE ROOT_CLOCK_SOURCE_PLL_96M #define BSP_CAM_CLOCK_SOURCE ROOT_CLOCK_SOURCE_PLL_96M
#define BSP_CAM_CLOCK_DIV 3 #define BSP_CAM_CLOCK_DIV 3
#endif #endif

View file

@ -72,7 +72,7 @@
#define BSP_DAC_CLOCK_SOURCE ROOT_CLOCK_SOURCE_AUPLL_24000000_HZ #define BSP_DAC_CLOCK_SOURCE ROOT_CLOCK_SOURCE_AUPLL_24000000_HZ
#define BSP_DAC_CLOCK_DIV 1 #define BSP_DAC_CLOCK_DIV 1
#endif #endif
#if defined(BSP_USING_CAM) #if defined(BSP_USING_CAM0)
#define BSP_CAM_CLOCK_SOURCE ROOT_CLOCK_SOURCE_PLL_96M #define BSP_CAM_CLOCK_SOURCE ROOT_CLOCK_SOURCE_PLL_96M
#define BSP_CAM_CLOCK_DIV 3 #define BSP_CAM_CLOCK_DIV 3
#endif #endif

View file

@ -76,7 +76,7 @@
#define BSP_DAC_CLOCK_SOURCE ROOT_CLOCK_SOURCE_AUPLL_24000000_HZ #define BSP_DAC_CLOCK_SOURCE ROOT_CLOCK_SOURCE_AUPLL_24000000_HZ
#define BSP_DAC_CLOCK_DIV 1 #define BSP_DAC_CLOCK_DIV 1
#endif #endif
#if defined(BSP_USING_CAM) #if defined(BSP_USING_CAM0)
#define BSP_CAM_CLOCK_SOURCE ROOT_CLOCK_SOURCE_PLL_96M #define BSP_CAM_CLOCK_SOURCE ROOT_CLOCK_SOURCE_PLL_96M
#define BSP_CAM_CLOCK_DIV 3 #define BSP_CAM_CLOCK_DIV 3
#endif #endif

View file

@ -44,7 +44,7 @@
#define BSP_USING_QDEC1 #define BSP_USING_QDEC1
#define BSP_USING_QDEC2 #define BSP_USING_QDEC2
#define BSP_USING_USB #define BSP_USING_USB
#define BSP_USING_CAM #define BSP_USING_CAM0
/* ----------------------*/ /* ----------------------*/
/* PERIPHERAL With DMA LIST */ /* PERIPHERAL With DMA LIST */
@ -125,6 +125,8 @@
.clk_phase = SPI_PHASE_1EDGE, \ .clk_phase = SPI_PHASE_1EDGE, \
.datasize = SPI_DATASIZE_8BIT, \ .datasize = SPI_DATASIZE_8BIT, \
.fifo_threshold = 4, \ .fifo_threshold = 4, \
.pin_swap_enable = 1, \
.delitch_cnt = 0, \
} }
#endif #endif
#endif #endif
@ -462,4 +464,24 @@
#endif #endif
#endif #endif
#if defined(BSP_USING_CAM0)
#ifndef CAM0_CONFIG
#define CAM0_CONFIG \
{ \
.id = 0, \
.software_mode = CAM_AUTO_MODE, \
.frame_mode = CAM_FRAME_INTERLEAVE_MODE, \
.yuv_format = CAM_YUV_FORMAT_YUV422, \
.hsp = CAM_HSPOLARITY_LOW, \
.vsp = CAM_VSPOLARITY_LOW, \
.cam_write_ram_addr = 0, \
.cam_write_ram_size = 0, \
.cam_frame_size = 0, \
.cam_write_ram_addr1 = 0, \
.cam_write_ram_size1 = 0, \
.cam_frame_size1 = 0, \
}
#endif
#endif
#endif #endif

View file

@ -72,7 +72,7 @@
#define BSP_DAC_CLOCK_SOURCE ROOT_CLOCK_SOURCE_AUPLL_24000000_HZ #define BSP_DAC_CLOCK_SOURCE ROOT_CLOCK_SOURCE_AUPLL_24000000_HZ
#define BSP_DAC_CLOCK_DIV 1 #define BSP_DAC_CLOCK_DIV 1
#endif #endif
#if defined(BSP_USING_CAM) #if defined(BSP_USING_CAM0)
#define BSP_CAM_CLOCK_SOURCE ROOT_CLOCK_SOURCE_PLL_96M #define BSP_CAM_CLOCK_SOURCE ROOT_CLOCK_SOURCE_PLL_96M
#define BSP_CAM_CLOCK_DIV 3 #define BSP_CAM_CLOCK_DIV 3
#endif #endif

View file

@ -125,6 +125,8 @@
.clk_phase = SPI_PHASE_1EDGE, \ .clk_phase = SPI_PHASE_1EDGE, \
.datasize = SPI_DATASIZE_8BIT, \ .datasize = SPI_DATASIZE_8BIT, \
.fifo_threshold = 1, \ .fifo_threshold = 1, \
.pin_swap_enable = 1, \
.delitch_cnt = 0, \
} }
#endif #endif
#endif #endif

View file

@ -60,7 +60,7 @@
#define BSP_DAC_CLOCK_SOURCE ROOT_CLOCK_SOURCE_AUPLL_24000000_HZ #define BSP_DAC_CLOCK_SOURCE ROOT_CLOCK_SOURCE_AUPLL_24000000_HZ
#define BSP_DAC_CLOCK_DIV 1 #define BSP_DAC_CLOCK_DIV 1
#endif #endif
#if defined(BSP_USING_CAM) #if defined(BSP_USING_CAM0)
#define BSP_CAM_CLOCK_SOURCE ROOT_CLOCK_SOURCE_PLL_96M #define BSP_CAM_CLOCK_SOURCE ROOT_CLOCK_SOURCE_PLL_96M
#define BSP_CAM_CLOCK_DIV 3 #define BSP_CAM_CLOCK_DIV 3
#endif #endif

View file

@ -679,24 +679,37 @@ uint8_t image_sensor_init(BL_Fun_Type mjpeg_en, cam_device_t *cam_cfg, mjpeg_dev
return 1; return 1;
} }
cam_stop();
mjpeg_stop(); mjpeg_stop();
if (mjpeg_en) { cam_register(CAM0_INDEX, "camera0");
#if (CAM_MODE == CAM_USING_INT_MODE) struct device *cam0 = device_find("camera0");
cam_init(cam_cfg, DEVICE_OFLAG_INT);
#elif (CAM_MODE == CAM_USING_POLL_MODE) if(!cam0)
cam_init(cam_cfg, DEVICE_OFLAG_POLL); {
#endif MSG("cam do not find\r\n");
mjpeg_init(mjpeg_cfg); return 1;
} else {
#if (CAM_MODE == CAM_USING_INT_MODE)
cam_init(cam_cfg, DEVICE_OFLAG_INT);
#elif (CAM_MODE == CAM_USING_POLL_MODE)
cam_init(cam_cfg, DEVICE_OFLAG_POLL);
#endif
} }
if (mjpeg_en) {
mjpeg_init(mjpeg_cfg);
}
CAM_DEV(cam0)->hsp = CAM_HSPOLARITY_HIGH;
CAM_DEV(cam0)->vsp = CAM_VSPOLARITY_HIGH;
CAM_DEV(cam0)->software_mode = cam_cfg->software_mode;
CAM_DEV(cam0)->frame_mode = cam_cfg->frame_mode;
CAM_DEV(cam0)->yuv_format = cam_cfg->yuv_format;
CAM_DEV(cam0)->cam_write_ram_addr = cam_cfg->cam_write_ram_addr;
CAM_DEV(cam0)->cam_write_ram_size = cam_cfg->cam_write_ram_size;
CAM_DEV(cam0)->cam_frame_size = cam_cfg->cam_frame_size;
CAM_DEV(cam0)->cam_write_ram_addr1 = cam_cfg->cam_write_ram_addr1;
CAM_DEV(cam0)->cam_write_ram_size1 = cam_cfg->cam_write_ram_size1;
CAM_DEV(cam0)->cam_frame_size1 = cam_cfg->cam_frame_size1;
#if (CAM_MODE == CAM_USING_INT_MODE)
device_open(cam0, DEVICE_OFLAG_INT_RX);
#elif (CAM_MODE == CAM_USING_POLL_MODE)
device_open(cam0, DEVICE_OFLAG_STREAM_RX);
#endif
return SUCCESS; return SUCCESS;
} }

View file

@ -25,54 +25,69 @@
#define __HAL_CAM_H__ #define __HAL_CAM_H__
#ifdef __cplusplus #ifdef __cplusplus
extern "C"{ extern "C" {
#endif #endif
#include "hal_common.h" #include "hal_common.h"
#include "drv_device.h" #include "drv_device.h"
#include "bl702_config.h" #include "bl702_config.h"
#include "bl702_cam.h"
#define DEVICE_OFLAG_INT 0x01 #define DEVICE_CTRL_CAM_FRAME_CUT 0x10
#define DEVICE_OFLAG_POLL 0x02 #define DEVICE_CTRL_CAM_FRAME_DROP 0x11
enum camera_event_type { enum cam_index_type {
CAM_EVENT_NORMAL_0, /*!< Interleave mode: normal write interrupt, planar mode:even byte normal write interrupt */ #ifdef BSP_USING_CAM0
CAM_EVENT_NORMAL_1, /*!< Interleave mode: no use, planar mode:odd byte normal write interrupt */ CAM0_INDEX,
CAM_EVENT_MEMORY_OVERWRITE_0, /*!< Interleave mode: memory overwrite interrupt, planar mode:even byte memory overwrite interrupt */ #endif
CAM_EVENT_MEMORY_OVERWRITE_1, /*!< Interleave mode: no use, planar mode:odd byte memory overwrite interrupt */ CAM_MAX_INDEX
CAM_EVENT_FRAME_OVERWRITE_0, /*!< Interleave mode: frame overwrite interrupt, planar mode:even byte frame overwrite interrupt */
CAM_EVENT_FRAME_OVERWRITE_1, /*!< Interleave mode: no use, planar mode:odd byte frame overwrite interrupt */
CAM_EVENT_FIFO_OVERWRITE_0, /*!< Interleave mode: fifo overwrite interrupt, planar mode:even byte fifo overwrite interrupt */
CAM_EVENT_FIFO_OVERWRITE_1, /*!< Interleave mode: no use, planar mode:odd byte fifo overwrite interrupt */
CAM_EVENT_VSYNC_CNT_ERROR, /*!< Vsync valid line count non-match interrupt */
CAM_EVENT_HSYNC_CNT_ERROR, /*!< Hsync valid pixel count non-match interrupt */
CAM_EVENT_ALL, /*!< All of interrupt */
}; };
typedef enum { #define CAM_AUTO_MODE 0
CAM_AUTO_MODE, #define CAM_MANUAL_MODE 1
CAM_MANUAL_MODE,
} cam_software_mode_t;
typedef enum { #define CAM_FRAME_PLANAR_MODE 0
CAM_FRAME_PLANAR_MODE, #define CAM_FRAME_INTERLEAVE_MODE 1
CAM_FRAME_INTERLEAVE_MODE,
} cam_frame_mode_t;
typedef enum { #define CAM_HSPOLARITY_LOW 0
CAM_YUV_FORMAT_YUV422, #define CAM_HSPOLARITY_HIGH 1
CAM_YUV_FORMAT_YUV420_EVEN,
CAM_YUV_FORMAT_YUV420_ODD, #define CAM_VSPOLARITY_LOW 0
CAM_YUV_FORMAT_YUV400_EVEN, #define CAM_VSPOLARITY_HIGH 1
CAM_YUV_FORMAT_YUV400_ODD,
} cam_yuv_format_t; #define CAM_YUV_FORMAT_YUV422 0
#define CAM_YUV_FORMAT_YUV420_EVEN 1
#define CAM_YUV_FORMAT_YUV420_ODD 2
#define CAM_YUV_FORMAT_YUV400_EVEN 3
#define CAM_YUV_FORMAT_YUV400_ODD 4
enum cam_it_type {
CAM_FRAME_IT = 1 << 0,
};
enum cam_event_type {
CAM_EVENT_FRAME = 0,
};
typedef struct {
int16_t x0;
int16_t x1;
int16_t y0;
int16_t y1;
} cam_frame_area_t;
typedef struct {
uint32_t frame_addr;
uint32_t frame_count;
} cam_frame_info_t;
typedef struct cam_device { typedef struct cam_device {
struct device parent; struct device parent;
cam_software_mode_t software_mode; uint8_t id;
cam_frame_mode_t frame_mode; uint8_t software_mode;
cam_yuv_format_t yuv_format; uint8_t frame_mode;
uint8_t yuv_format;
uint8_t hsp;
uint8_t vsp;
uint32_t cam_write_ram_addr; uint32_t cam_write_ram_addr;
uint32_t cam_write_ram_size; uint32_t cam_write_ram_size;
uint32_t cam_frame_size; uint32_t cam_frame_size;
@ -83,19 +98,14 @@ typedef struct cam_device {
uint32_t cam_frame_size1; uint32_t cam_frame_size1;
} cam_device_t; } cam_device_t;
void cam_init(cam_device_t *cam_cfg, uint16_t oflag); #define CAM_DEV(dev) ((cam_device_t *)dev)
void cam_start(void);
void cam_stop(void); int cam_register(enum cam_index_type index, const char *name);
uint8_t cam_get_one_frame_interleave(uint8_t **pic, uint32_t *len);
uint8_t cam_get_one_frame_planar(CAM_YUV_Mode_Type yuv, uint8_t **picYY, uint32_t *lenYY, uint8_t **picUV, uint32_t *lenUV);
void cam_drop_one_frame_interleave(void); void cam_drop_one_frame_interleave(void);
void cam_drop_one_frame_planar(void); uint8_t cam_get_one_frame_interleave(uint8_t **pic, uint32_t *len);
void cam_hsync_crop(uint16_t start, uint16_t end);
void cam_vsync_crop(uint16_t start, uint16_t end);
void cam_hw_mode_wrap(uint8_t enbale);
void CAM_Int_Callback_set(CAM_INT_Type intType, intCallback_Type *cbFun);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif #endif

View file

@ -20,57 +20,250 @@
* under the License. * under the License.
* *
*/ */
#include "hal_cam.h"
#include "bl702_cam.h" #include "bl702_cam.h"
#include "bl702_glb.h" #include "bl702_glb.h"
#include "hal_cam.h"
#ifdef BSP_USING_CAM #ifdef BSP_USING_CAM0
static intCallback_Type *camIntCbfArra[CAM_INT_ALL] = { NULL }; static void CAM0_IRQ(void);
void CAMERA_IRQ(void);
#endif #endif
static cam_device_t camx_device[CAM_MAX_INDEX] = {
#ifdef BSP_USING_CAM0
CAM0_CONFIG,
#endif
};
/** /**
* @brief * @brief
* *
* @param cam_cfg * @param dev
* @param oflag
* @return int
*/ */
void cam_init(cam_device_t *cam_cfg, uint16_t oflag) int cam_open(struct device *dev, uint16_t oflag)
{ {
CAM_CFG_Type camera_cfg = { cam_device_t *cam_device = (cam_device_t *)dev;
.swMode = cam_cfg->software_mode, CAM_CFG_Type camera_cfg = { 0 };
.swIntCnt = 0,
.frameMode = cam_cfg->frame_mode, uint32_t tmpVal;
.yuvMode = cam_cfg->yuv_format, /* Disable camera module */
.waitCount = 0x40, tmpVal = BL_RD_REG(CAM_BASE, CAM_DVP2AXI_CONFIGUE);
.linePol = CAM_LINE_ACTIVE_POLARITY_HIGH, tmpVal = BL_CLR_REG_BIT(tmpVal, CAM_REG_DVP_ENABLE);
.framePol = CAM_FRAME_ACTIVE_POLARITY_HIGH, BL_WR_REG(CAM_BASE, CAM_DVP2AXI_CONFIGUE, tmpVal);
.burstType = CAM_BURST_TYPE_INCR16,
.camSensorMode = CAM_SENSOR_MODE_V_AND_H, camera_cfg.swMode = cam_device->software_mode;
.memStart0 = cam_cfg->cam_write_ram_addr, camera_cfg.frameMode = cam_device->frame_mode;
.memSize0 = cam_cfg->cam_write_ram_size, camera_cfg.yuvMode = cam_device->yuv_format;
.frameSize0 = cam_cfg->cam_frame_size, camera_cfg.waitCount = 0x40;
/* planar mode*/ camera_cfg.linePol = cam_device->hsp;
.memStart1 = cam_cfg->cam_write_ram_addr1, camera_cfg.framePol = cam_device->vsp;
.memSize1 = cam_cfg->cam_write_ram_size1, camera_cfg.burstType = CAM_BURST_TYPE_INCR16;
.frameSize1 = cam_cfg->cam_frame_size1, camera_cfg.camSensorMode = CAM_SENSOR_MODE_V_AND_H;
}; camera_cfg.memStart0 = cam_device->cam_write_ram_addr;
camera_cfg.memSize0 = cam_device->cam_write_ram_size;
camera_cfg.frameSize0 = cam_device->cam_frame_size;
/* planar mode*/
camera_cfg.memStart1 = cam_device->cam_write_ram_addr1;
camera_cfg.memSize1 = cam_device->cam_write_ram_size1;
camera_cfg.frameSize1 = cam_device->cam_frame_size1;
CAM_Init(&camera_cfg); CAM_Init(&camera_cfg);
if (oflag == DEVICE_OFLAG_INT) { if (oflag & DEVICE_OFLAG_INT_RX) {
#ifdef BSP_USING_CAM #ifdef BSP_USING_CAM0
Interrupt_Handler_Register(CAM_IRQn, CAMERA_IRQ); Interrupt_Handler_Register(CAM_IRQn, CAM0_IRQ);
#endif #endif
} }
return 0;
} }
/**
* @brief
*
* @param dev
* @return int
*/
int cam_close(struct device *dev)
{
GLB_AHB_Slave1_Reset(BL_AHB_SLAVE1_CAM);
return 0;
}
/**
* @brief
*
* @param dev
* @param cmd
* @param args
* @return int
*/
int cam_control(struct device *dev, int cmd, void *args)
{
cam_device_t *cam_device = (cam_device_t *)dev;
switch (cmd) {
case DEVICE_CTRL_SET_INT:
if ((uint32_t)args == CAM_FRAME_IT) {
CAM_IntMask(CAM_INT_NORMAL_0, UNMASK);
CPU_Interrupt_Enable(CAM_IRQn);
}
break;
case DEVICE_CTRL_CLR_INT:
if ((uint32_t)args == CAM_FRAME_IT) {
CAM_IntMask(CAM_INT_NORMAL_0, MASK);
CPU_Interrupt_Disable(CAM_IRQn);
}
break;
case DEVICE_CTRL_RESUME: {
uint32_t tmpVal;
/* Enable camera module */
tmpVal = BL_RD_REG(CAM_BASE, CAM_DVP2AXI_CONFIGUE);
tmpVal = BL_SET_REG_BIT(tmpVal, CAM_REG_DVP_ENABLE);
BL_WR_REG(CAM_BASE, CAM_DVP2AXI_CONFIGUE, tmpVal);
} break;
case DEVICE_CTRL_SUSPEND: {
uint32_t tmpVal;
/* Disable camera module */
tmpVal = BL_RD_REG(CAM_BASE, CAM_DVP2AXI_CONFIGUE);
tmpVal = BL_CLR_REG_BIT(tmpVal, CAM_REG_DVP_ENABLE);
BL_WR_REG(CAM_BASE, CAM_DVP2AXI_CONFIGUE, tmpVal);
} break;
case DEVICE_CTRL_CAM_FRAME_CUT: {
cam_frame_area_t *cfg = (cam_frame_area_t *)args;
BL_WR_REG(CAM_BASE, CAM_HSYNC_CONTROL, ((cfg->x0 * 2) << 16) + (cfg->x1 * 2));
BL_WR_REG(CAM_BASE, CAM_VSYNC_CONTROL, ((cfg->y0) << 16) + cfg->y1);
} break;
case DEVICE_CTRL_CAM_FRAME_DROP:
if (cam_device->frame_mode == CAM_FRAME_INTERLEAVE_MODE) {
/* Pop one frame */
BL_WR_REG(CAM_BASE, CAM_DVP_FRAME_FIFO_POP, 1);
} else {
/* Pop one frame */
BL_WR_REG(CAM_BASE, CAM_DVP_FRAME_FIFO_POP, 3);
}
break;
default:
break;
}
return 0;
}
/**
* @brief
*
* @param dev
* @param pos
* @param buffer
* @param size
* @return int
*/
int cam_read(struct device *dev, uint32_t pos, void *buffer, uint32_t size)
{
if (!BL_GET_REG_BITS_VAL(BL_RD_REG(CAM_BASE, CAM_DVP_STATUS_AND_ERROR), CAM_FRAME_VALID_CNT_0)) {
return -1;
}
cam_frame_info_t *frame_info = (cam_frame_info_t *)buffer;
frame_info->frame_addr = BL_RD_REG(CAM_BASE, CAM_FRAME_START_ADDR0_0);
frame_info->frame_count = BL_RD_REG(CAM_BASE, CAM_FRAME_BYTE_CNT0_0);
return 0;
}
/**
* @brief
*
* @param index
* @param name
* @return int
*/
int cam_register(enum cam_index_type index, const char *name)
{
struct device *dev;
if (CAM_MAX_INDEX == 0) {
return -DEVICE_EINVAL;
}
dev = &(camx_device[index].parent);
dev->open = cam_open;
dev->close = cam_close;
dev->control = cam_control;
dev->write = NULL;
dev->read = cam_read;
dev->type = DEVICE_CLASS_CAMERA;
dev->handle = NULL;
return device_register(dev, name);
}
void cam_isr(cam_device_t *handle)
{
uint32_t tmpVal;
if (!handle->parent.callback)
return;
tmpVal = BL_RD_REG(CAM_BASE, CAM_DVP_STATUS_AND_ERROR);
if (BL_IS_REG_BIT_SET(tmpVal, CAM_STS_NORMAL_INT_0)) {
handle->parent.callback(&handle->parent, NULL, 0, CAM_EVENT_FRAME);
CAM_IntClr(CAM_INT_NORMAL_0);
}
if (BL_IS_REG_BIT_SET(tmpVal, CAM_STS_NORMAL_INT_1)) {
CAM_IntClr(CAM_INT_NORMAL_1);
}
if (BL_IS_REG_BIT_SET(tmpVal, CAM_STS_MEM_INT_0)) {
CAM_IntClr(CAM_INT_MEMORY_OVERWRITE_0);
}
if (BL_IS_REG_BIT_SET(tmpVal, CAM_STS_MEM_INT_1)) {
CAM_IntClr(CAM_INT_MEMORY_OVERWRITE_1);
}
if (BL_IS_REG_BIT_SET(tmpVal, CAM_STS_FRAME_INT_0)) {
CAM_IntClr(CAM_INT_FRAME_OVERWRITE_0);
}
if (BL_IS_REG_BIT_SET(tmpVal, CAM_STS_FRAME_INT_1)) {
CAM_IntClr(CAM_INT_FRAME_OVERWRITE_1);
}
if (BL_IS_REG_BIT_SET(tmpVal, CAM_STS_FIFO_INT_0)) {
CAM_IntClr(CAM_INT_FIFO_OVERWRITE_0);
}
if (BL_IS_REG_BIT_SET(tmpVal, CAM_STS_FIFO_INT_1)) {
CAM_IntClr(CAM_INT_FIFO_OVERWRITE_1);
}
if (BL_IS_REG_BIT_SET(tmpVal, CAM_STS_HCNT_INT)) {
CAM_IntClr(CAM_INT_HSYNC_CNT_ERROR);
}
if (BL_IS_REG_BIT_SET(tmpVal, CAM_STS_VCNT_INT)) {
CAM_IntClr(CAM_INT_VSYNC_CNT_ERROR);
}
}
#ifdef BSP_USING_CAM0
void CAM0_IRQ(void)
{
cam_isr(&camx_device[CAM0_INDEX]);
}
#endif
/** /**
* @brief * @brief
* *
*/ */
void cam_start(void) void cam_start(void)
{ {
CAM_Enable(); uint32_t tmpVal;
/* Enable camera module */
tmpVal = BL_RD_REG(CAM_BASE, CAM_DVP2AXI_CONFIGUE);
tmpVal = BL_SET_REG_BIT(tmpVal, CAM_REG_DVP_ENABLE);
BL_WR_REG(CAM_BASE, CAM_DVP2AXI_CONFIGUE, tmpVal);
} }
/** /**
@ -79,7 +272,12 @@ void cam_start(void)
*/ */
void cam_stop(void) void cam_stop(void)
{ {
CAM_Disable(); uint32_t tmpVal;
/* Disable camera module */
tmpVal = BL_RD_REG(CAM_BASE, CAM_DVP2AXI_CONFIGUE);
tmpVal = BL_CLR_REG_BIT(tmpVal, CAM_REG_DVP_ENABLE);
BL_WR_REG(CAM_BASE, CAM_DVP2AXI_CONFIGUE, tmpVal);
} }
/** /**
@ -90,19 +288,13 @@ void cam_stop(void)
*/ */
uint8_t cam_get_one_frame_interleave(uint8_t **pic, uint32_t *len) uint8_t cam_get_one_frame_interleave(uint8_t **pic, uint32_t *len)
{ {
CAM_Interleave_Frame_Info info; if (!BL_GET_REG_BITS_VAL(BL_RD_REG(CAM_BASE, CAM_DVP_STATUS_AND_ERROR), CAM_FRAME_VALID_CNT_0)) {
arch_memset(&info, 0, sizeof(info)); return -1;
CAM_Interleave_Get_Frame_Info(&info);
if (info.validFrames == 0) {
return ERROR;
} }
*pic = (uint8_t *)(info.curFrameAddr); *pic = (uint8_t *)BL_RD_REG(CAM_BASE, CAM_FRAME_START_ADDR0_0);
*len = info.curFrameBytes; *len = BL_RD_REG(CAM_BASE, CAM_FRAME_BYTE_CNT0_0);
return 0;
return SUCCESS;
} }
uint8_t cam_get_one_frame_planar(CAM_YUV_Mode_Type yuv, uint8_t **picYY, uint32_t *lenYY, uint8_t **picUV, uint32_t *lenUV) uint8_t cam_get_one_frame_planar(CAM_YUV_Mode_Type yuv, uint8_t **picYY, uint32_t *lenYY, uint8_t **picUV, uint32_t *lenUV)
@ -132,118 +324,12 @@ uint8_t cam_get_one_frame_planar(CAM_YUV_Mode_Type yuv, uint8_t **picYY, uint32_
void cam_drop_one_frame_interleave(void) void cam_drop_one_frame_interleave(void)
{ {
CAM_Interleave_Pop_Frame(); /* Pop one frame */
BL_WR_REG(CAM_BASE, CAM_DVP_FRAME_FIFO_POP, 1);
} }
void cam_drop_one_frame_planar(void) void cam_drop_one_frame_planar(void)
{ {
CAM_Planar_Pop_Frame(); /* Pop one frame */
BL_WR_REG(CAM_BASE, CAM_DVP_FRAME_FIFO_POP, 3);
} }
void cam_hsync_crop(uint16_t start, uint16_t end)
{
CAM_Hsync_Crop(start, end);
}
void cam_vsync_crop(uint16_t start, uint16_t end)
{
CAM_Vsync_Crop(start, end);
}
void cam_hw_mode_wrap(uint8_t enable)
{
CAM_HW_Mode_Wrap(enable);
}
void cam_isr(cam_device_t *handle)
{
}
#ifdef BSP_USING_CAM
void CAM_Int_Callback_set(CAM_INT_Type intType, intCallback_Type *cbFun)
{
/* Check the parameters */
CHECK_PARAM(IS_CAM_INT_TYPE(intType));
camIntCbfArra[intType] = cbFun;
}
void CAMERA_IRQ(void)
{
uint32_t tmpVal;
tmpVal = BL_RD_REG(CAM_BASE, CAM_DVP_STATUS_AND_ERROR);
if (BL_IS_REG_BIT_SET(tmpVal, CAM_STS_NORMAL_INT_0)) {
CAM_IntClr(CAM_INT_NORMAL_0);
if (camIntCbfArra[CAM_INT_NORMAL_0] != NULL) {
/* call the callback function */
camIntCbfArra[CAM_INT_NORMAL_0]();
}
}
if (BL_IS_REG_BIT_SET(tmpVal, CAM_STS_NORMAL_INT_1)) {
CAM_IntClr(CAM_INT_NORMAL_1);
if (camIntCbfArra[CAM_INT_NORMAL_1] != NULL) {
/* call the callback function */
camIntCbfArra[CAM_INT_NORMAL_1]();
}
}
if (BL_IS_REG_BIT_SET(tmpVal, CAM_STS_MEM_INT_0)) {
CAM_IntClr(CAM_INT_MEMORY_OVERWRITE_0);
if (camIntCbfArra[CAM_INT_MEMORY_OVERWRITE_0] != NULL) {
/* call the callback function */
camIntCbfArra[CAM_INT_MEMORY_OVERWRITE_0]();
}
}
if (BL_IS_REG_BIT_SET(tmpVal, CAM_STS_MEM_INT_1)) {
CAM_IntClr(CAM_INT_MEMORY_OVERWRITE_1);
if (camIntCbfArra[CAM_INT_MEMORY_OVERWRITE_1] != NULL) {
/* call the callback function */
camIntCbfArra[CAM_INT_MEMORY_OVERWRITE_1]();
}
}
if (BL_IS_REG_BIT_SET(tmpVal, CAM_STS_FRAME_INT_0)) {
CAM_IntClr(CAM_INT_FRAME_OVERWRITE_0);
if (camIntCbfArra[CAM_INT_FRAME_OVERWRITE_0] != NULL) {
/* call the callback function */
camIntCbfArra[CAM_INT_FRAME_OVERWRITE_0]();
}
}
if (BL_IS_REG_BIT_SET(tmpVal, CAM_STS_FRAME_INT_1)) {
CAM_IntClr(CAM_INT_FRAME_OVERWRITE_1);
if (camIntCbfArra[CAM_INT_FRAME_OVERWRITE_1] != NULL) {
/* call the callback function */
camIntCbfArra[CAM_INT_FRAME_OVERWRITE_1]();
}
}
if (BL_IS_REG_BIT_SET(tmpVal, CAM_STS_FIFO_INT_0)) {
CAM_IntClr(CAM_INT_FIFO_OVERWRITE_0);
if (camIntCbfArra[CAM_INT_FIFO_OVERWRITE_0] != NULL) {
/* call the callback function */
camIntCbfArra[CAM_INT_FIFO_OVERWRITE_0]();
}
}
if (BL_IS_REG_BIT_SET(tmpVal, CAM_STS_FIFO_INT_1)) {
CAM_IntClr(CAM_INT_FIFO_OVERWRITE_1);
if (camIntCbfArra[CAM_INT_FIFO_OVERWRITE_1] != NULL) {
/* call the callback function */
camIntCbfArra[CAM_INT_FIFO_OVERWRITE_1]();
}
}
if (BL_IS_REG_BIT_SET(tmpVal, CAM_STS_HCNT_INT)) {
CAM_IntClr(CAM_INT_HSYNC_CNT_ERROR);
if (camIntCbfArra[CAM_INT_HSYNC_CNT_ERROR] != NULL) {
/* call the callback function */
camIntCbfArra[CAM_INT_HSYNC_CNT_ERROR]();
}
}
if (BL_IS_REG_BIT_SET(tmpVal, CAM_STS_VCNT_INT)) {
CAM_IntClr(CAM_INT_VSYNC_CNT_ERROR);
if (camIntCbfArra[CAM_INT_VSYNC_CNT_ERROR] != NULL) {
/* call the callback function */
camIntCbfArra[CAM_INT_VSYNC_CNT_ERROR]();
}
}
}
#endif

View file

@ -381,7 +381,7 @@ void peripheral_clock_init(void)
#endif #endif
#endif #endif
#if defined(BSP_USING_CAM) #if defined(BSP_USING_CAM0)
tmpVal |= (1 << BL_AHB_SLAVE1_CAM); tmpVal |= (1 << BL_AHB_SLAVE1_CAM);
#if BSP_CAM_CLOCK_SOURCE == ROOT_CLOCK_SOURCE_PLL_96M #if BSP_CAM_CLOCK_SOURCE == ROOT_CLOCK_SOURCE_PLL_96M
GLB_Set_CAM_CLK(ENABLE, GLB_CAM_CLK_DLL96M, BSP_CAM_CLOCK_DIV); GLB_Set_CAM_CLK(ENABLE, GLB_CAM_CLK_DLL96M, BSP_CAM_CLOCK_DIV);

View file

@ -63,9 +63,6 @@ int main(void)
cam_clk_out(); cam_clk_out();
cam_hsync_crop(0, 2 * CAMERA_RESOLUTION_X);
cam_vsync_crop(0, CAMERA_RESOLUTION_Y);
if (SUCCESS != image_sensor_init(DISABLE, &camera_cfg, &mjpeg_cfg)) { if (SUCCESS != image_sensor_init(DISABLE, &camera_cfg, &mjpeg_cfg)) {
MSG("Init error!\n"); MSG("Init error!\n");
BL_CASE_FAIL; BL_CASE_FAIL;
@ -73,7 +70,15 @@ int main(void)
} }
} }
cam_start(); cam_frame_area_t cfg;
cfg.x0 = 0;
cfg.x1 = CAMERA_RESOLUTION_X;
cfg.y0 = 0;
cfg.y1 = CAMERA_RESOLUTION_Y;
struct device *cam0 = device_find("camera0");
device_control(cam0, DEVICE_CTRL_CAM_FRAME_CUT, &cfg);
device_control(cam0, DEVICE_CTRL_RESUME, NULL);
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
while (SUCCESS != cam_get_one_frame_interleave(&picture, &length)) { while (SUCCESS != cam_get_one_frame_interleave(&picture, &length)) {
@ -82,11 +87,10 @@ int main(void)
MSG("picturestartuyvy"); MSG("picturestartuyvy");
UART_SendData(0, picture, length); UART_SendData(0, picture, length);
MSG("pictureend"); MSG("pictureend");
device_control(cam0, DEVICE_CTRL_CAM_FRAME_DROP, NULL);
cam_drop_one_frame_interleave();
} }
cam_stop(); device_control(cam0, DEVICE_CTRL_SUSPEND, NULL);
BL_CASE_SUCCESS; BL_CASE_SUCCESS;
while (1) { while (1) {

View file

@ -1,4 +1,3 @@
**board/bl706_avb/pinmux_config.h** 中 **PINMUX_SELECT** 选择 **PINMUX_CAMERA_LCD**
**bsp_common/image_sensor/bsp_image_sensor.c** 中**FORMAT_SEL** 选择 **RGB565** **bsp_common/image_sensor/bsp_image_sensor.c** 中**FORMAT_SEL** 选择 **RGB565**
```bash ```bash

View file

@ -99,7 +99,7 @@ void my_memcpy(void *dst, void const *src, uint32_t size)
} }
} }
void ATTR_TCM_SECTION CAM_Interrupt_Normal(void) void ATTR_TCM_SECTION cam_irq_callback(struct device *dev, void *args, uint32_t size, uint32_t state)
{ {
if (flag_normal == 0) { if (flag_normal == 0) {
// memcpy((void *)(uint32_t)(0x42023000 + (8640 * buff_using_num)), (void *)CAMERA_WRITE_ADDR, CAMERA_FRAME_SIZE); // memcpy((void *)(uint32_t)(0x42023000 + (8640 * buff_using_num)), (void *)CAMERA_WRITE_ADDR, CAMERA_FRAME_SIZE);
@ -162,7 +162,6 @@ void ATTR_TCM_SECTION CAM_Interrupt_Normal(void)
return; return;
} }
// MSG("CAM NORMAL\r\n");
return; return;
} }
@ -182,32 +181,34 @@ int ATTR_TCM_SECTION main(void)
} }
// MSG("dma open \r\n"); // MSG("dma open \r\n");
cam_hw_mode_wrap(DISABLE); //CAM_HW_Mode_Wrap(DISABLE);
cam_clk_out(); cam_clk_out();
cam_hsync_crop(0, 2 * CAMERA_RESOLUTION_X);
cam_vsync_crop(0, CAMERA_RESOLUTION_Y);
CAM_IntMask(CAM_INT_ALL, MASK);
CAM_Int_Callback_set(CAM_INT_NORMAL_0, &CAM_Interrupt_Normal);
CAM_IntMask(CAM_INT_NORMAL_0, UNMASK);
CPU_Interrupt_Enable(CAM_IRQn);
if (SUCCESS != image_sensor_init(DISABLE, &camera_cfg, &mjpeg_cfg)) { if (SUCCESS != image_sensor_init(DISABLE, &camera_cfg, &mjpeg_cfg)) {
MSG("Init error!\n"); MSG("Init error!\n");
BL_CASE_FAIL; BL_CASE_FAIL;
while (1) { while (1) {
} }
} }
// MSG("cam init!\n");
cam_start(); cam_frame_area_t cfg;
cfg.x0 = 0;
cfg.x1 = CAMERA_RESOLUTION_X;
cfg.y0 = 0;
cfg.y1 = CAMERA_RESOLUTION_Y;
struct device *cam0 = device_find("camera0");
device_control(cam0, DEVICE_CTRL_CAM_FRAME_CUT, &cfg);
device_set_callback(cam0, cam_irq_callback);
device_control(cam0, DEVICE_CTRL_SET_INT, (void *)CAM_FRAME_IT);
device_control(cam0, DEVICE_CTRL_RESUME, NULL);
while (1) { while (1) {
if (buff_using_num == 18 * 3) { // close cam when 3 pic saved,480x360 = 480x20x18 if (buff_using_num == 18 * 3) { // close cam when 3 pic saved,480x360 = 480x20x18
cam_stop(); device_control(cam0, DEVICE_CTRL_SUSPEND, NULL);
device_write(uart0, 0, (void *)(uint32_t *)PSRAM_START_ADDR, YUV400_FRAME_SIZE * 3); // uart log send 3 pic raw data //device_write(uart0, 0, (void *)(uint32_t *)PSRAM_START_ADDR, YUV400_FRAME_SIZE * 3); // uart log send 3 pic raw data
// MSG("\r\ntim1:%d, tim2:%d, tim3:%d, tim4:%d", tim1, tim2, tim3, tim4); // MSG("\r\ntim1:%d, tim2:%d, tim3:%d, tim4:%d", tim1, tim2, tim3, tim4);
return 0; return 0;

View file

@ -1,4 +1,3 @@
**board/bl706_avb/pinmux_config.h** 中 **PINMUX_SELECT** 选择 **PINMUX_CAMERA_LCD**
**bsp_common/image_sensor/bsp_image_sensor.c** 中**IMAGE_SENSOR_USE** 选择**IMAGE_SENSOR_GC0308** (目前暂时没有 BF2013 sensor 验证) **bsp_common/image_sensor/bsp_image_sensor.c** 中**IMAGE_SENSOR_USE** 选择**IMAGE_SENSOR_GC0308** (目前暂时没有 BF2013 sensor 验证)
**bsp_common/image_sensor/bsp_image_sensor.c** 中**FORMAT_SEL** 选择 **YUYV** **bsp_common/image_sensor/bsp_image_sensor.c** 中**FORMAT_SEL** 选择 **YUYV**
**bsp_common/image_sensor/bsp_image_sensor.c** 中**CAM_MODE** 选择 **CAM_USING_INT_MODE**模式 **bsp_common/image_sensor/bsp_image_sensor.c** 中**CAM_MODE** 选择 **CAM_USING_INT_MODE**模式

View file

@ -70,9 +70,6 @@ int main(void)
cam_clk_out(); cam_clk_out();
cam_hsync_crop(0, 2 * CAMERA_RESOLUTION_X);
cam_vsync_crop(0, CAMERA_RESOLUTION_Y);
if (SUCCESS != image_sensor_init(DISABLE, &camera_cfg, &mjpeg_cfg)) { if (SUCCESS != image_sensor_init(DISABLE, &camera_cfg, &mjpeg_cfg)) {
MSG("Init error!\n"); MSG("Init error!\n");
BL_CASE_FAIL; BL_CASE_FAIL;
@ -80,7 +77,15 @@ int main(void)
} }
} }
cam_start(); cam_frame_area_t cfg;
cfg.x0 = 0;
cfg.x1 = CAMERA_RESOLUTION_X;
cfg.y0 = 0;
cfg.y1 = CAMERA_RESOLUTION_Y;
struct device *cam0 = device_find("camera0");
device_control(cam0, DEVICE_CTRL_CAM_FRAME_CUT, &cfg);
device_control(cam0, DEVICE_CTRL_RESUME, NULL);
for (i = 0; i < 5; i++) { for (i = 0; i < 5; i++) {
while (SUCCESS != cam_get_one_frame_interleave(&picture, &length)) { while (SUCCESS != cam_get_one_frame_interleave(&picture, &length)) {
@ -93,7 +98,7 @@ int main(void)
cam_drop_one_frame_interleave(); cam_drop_one_frame_interleave();
} }
cam_stop(); device_control(cam0, DEVICE_CTRL_SUSPEND, NULL);
BL_CASE_SUCCESS; BL_CASE_SUCCESS;
while (1) { while (1) {

View file

@ -1,4 +1,3 @@
**board/bl706_avb/pinmux_config.h** 中 **PINMUX_SELECT** 选择 **PINMUX_CAMERA_LCD**
**bsp_common/image_sensor/bsp_image_sensor.c** 中**FORMAT_SEL** 选择 **RGB565** **bsp_common/image_sensor/bsp_image_sensor.c** 中**FORMAT_SEL** 选择 **RGB565**
```bash ```bash

View file

@ -246,17 +246,21 @@ int main(void)
cam_clk_out(); cam_clk_out();
cam_hsync_crop(400, (2 * CAMERA_RESOLUTION_X) + 400);
cam_vsync_crop(80, CAMERA_RESOLUTION_Y + 80);
if (SUCCESS != image_sensor_init(DISABLE, &camera_cfg, &mjpeg_cfg)) { if (SUCCESS != image_sensor_init(DISABLE, &camera_cfg, &mjpeg_cfg)) {
MSG("Init error!\n"); MSG("Init error!\n");
BL_CASE_FAIL; BL_CASE_FAIL;
while (1) { while (1) {
} }
} }
cam_frame_area_t cfg;
cfg.x0 = 200;
cfg.x1 = CAMERA_RESOLUTION_X + 200;
cfg.y0 = 80;
cfg.y1 = CAMERA_RESOLUTION_Y + 80;
cam_start(); struct device *cam0 = device_find("camera0");
device_control(cam0, DEVICE_CTRL_CAM_FRAME_CUT, &cfg);
device_control(cam0, DEVICE_CTRL_RESUME, NULL);
LCD_Set_Addr(0, 0, CAMERA_RESOLUTION_X, CAMERA_RESOLUTION_Y); LCD_Set_Addr(0, 0, CAMERA_RESOLUTION_X, CAMERA_RESOLUTION_Y);
@ -268,16 +272,16 @@ int main(void)
while (SUCCESS != cam_get_one_frame_interleave(&picture, &length)) { while (SUCCESS != cam_get_one_frame_interleave(&picture, &length)) {
} }
cam_stop(); device_control(cam0, DEVICE_CTRL_SUSPEND, NULL);
#ifdef USE_YUV422 #ifdef USE_YUV422
yuv422sp_to_rgb24(picture, rgb_pic, CAMERA_RESOLUTION_X, CAMERA_RESOLUTION_Y); yuv422sp_to_rgb24(picture, rgb_pic, CAMERA_RESOLUTION_X, CAMERA_RESOLUTION_Y);
rgb24_to_rgb565(rgb_pic, rgb16_pic); rgb24_to_rgb565(rgb_pic, rgb16_pic);
LCD_DrawPicture_cam(0, 0, CAMERA_RESOLUTION_X, CAMERA_RESOLUTION_Y, picture); LCD_DrawPicture_cam(0, 0, CAMERA_RESOLUTION_X, CAMERA_RESOLUTION_Y, picture);
#else #else
LCD_WR_SPI_DMA(picture, (CAMERA_FRAME_SIZE)); LCD_WR_SPI_DMA((uint16_t *)picture, (CAMERA_FRAME_SIZE));
#endif #endif
cam_drop_one_frame_interleave(); device_control(cam0, DEVICE_CTRL_CAM_FRAME_DROP, NULL);
cam_start(); device_control(cam0, DEVICE_CTRL_RESUME, NULL);
#ifdef TEST_TIM #ifdef TEST_TIM
timer_end = bflb_platform_get_time_ms(); timer_end = bflb_platform_get_time_ms();

View file

@ -1,4 +1,3 @@
**board/bl706_avb/pinmux_config.h** 中 **PINMUX_SELECT** 选择 **PINMUX_CAMERA_LCD**
**bsp_common/image_sensor/bsp_image_sensor.c** 中**FORMAT_SEL** 选择 **RGB565** **bsp_common/image_sensor/bsp_image_sensor.c** 中**FORMAT_SEL** 选择 **RGB565**
```bash ```bash

View file

@ -353,16 +353,18 @@ uint32_t jpeg_count = 0;
void usbd_video_set_interface_callback(uint8_t value) void usbd_video_set_interface_callback(uint8_t value)
{ {
struct device* cam0 = device_find("camera0");
if (value) { if (value) {
play_status = 1; play_status = 1;
MSG("OPEN\r\n"); MSG("OPEN\r\n");
mjpeg_start(); mjpeg_start();
cam_start(); device_control(cam0, DEVICE_CTRL_RESUME, NULL);
} else { } else {
play_status = 0; play_status = 0;
MSG("CLOSE\r\n"); MSG("CLOSE\r\n");
cam_stop(); device_control(cam0, DEVICE_CTRL_SUSPEND, NULL);
mjpeg_stop(); mjpeg_stop();
} }
} }