245 lines
8.1 KiB
C
245 lines
8.1 KiB
C
#include "sys_config.h"
|
|
#include "typesdef.h"
|
|
#include "lib/video/dvp/cmos_sensor/csi.h"
|
|
#include "lib/video/dvp/cmos_sensor/csi_V2.h"
|
|
#include "devid.h"
|
|
#include "hal/gpio.h"
|
|
#include "hal/isp.h"
|
|
#include "hal/i2c.h"
|
|
#include "osal/irq.h"
|
|
#include "osal/string.h"
|
|
#include "dev/vpp/hgvpp.h"
|
|
#include "dev/csi/hgdvp.h"
|
|
#include "lib/lcd/lcd.h"
|
|
#include "hal/jpeg.h"
|
|
#include "hal/gpio.h"
|
|
#include "app/app_iic/app_iic.h"
|
|
#include "lib/video/isp/isp_dev.h"
|
|
#include "lib/video/isp/isp_ircut.h"
|
|
#include "osal/event.h"
|
|
#include "osal/msgqueue.h"
|
|
#include "lib/heap/av_heap.h"
|
|
|
|
#ifndef ISP_HARDWARE_CLK
|
|
#define ISP_HARDWARE_CLK ISP_MODULE_CLK_320M
|
|
#endif
|
|
|
|
extern _Sensor_YGAMMA y_gamma_tbl[];
|
|
// extern uint32 gamma2p4_tbl[];
|
|
extern uint32 gamma_table_addr[3] ;
|
|
extern uint32 luma_ca_addr[];
|
|
extern IRCUT_INFO ircut_info;
|
|
#if ISP_DMA_EN
|
|
#define ISP_IRQ_HANDLE_TYPE ISP_IRQ_FLAG_DMA_DONE
|
|
#else
|
|
#define ISP_IRQ_HANDLE_TYPE ISP_IRQ_FLAG_FRM_END
|
|
#endif
|
|
|
|
volatile struct list_head sensor_info_head;
|
|
const float ev_offset_lut[] = {0.015625, 0.03125, 0.0625, 0.125, 0.25, 0.5, 1, 2, 4, 8, 16, 64};
|
|
const struct isp_awb_mode_param isp_awb_mode_map[] =
|
|
{
|
|
// awb_mode awb_gain_r awb_gain_gr awb_gain_gb awb_gain_b
|
|
{ 0, 0, 256, 256, 0},
|
|
{ 1, 480, 256, 256, 430},
|
|
{ 2, 530, 256, 256, 380},
|
|
{ 3, 551, 256, 256, 360},
|
|
};
|
|
|
|
void sensor_info_init()
|
|
{
|
|
INIT_LIST_HEAD((struct list_head *)&sensor_info_head);
|
|
}
|
|
|
|
void sensor_info_add(enum sensor_type type, enum isp_input_dat_src sensor_src, uint32 sensor_config, uint32 iic_id, uint32 opt_cmd)
|
|
{
|
|
SENSOR_BASIC_INFO *info = os_malloc(sizeof(SENSOR_BASIC_INFO));
|
|
if (info)
|
|
{
|
|
os_memset(info, 0, sizeof(sizeof(SENSOR_BASIC_INFO)));
|
|
info->sensor_src = sensor_src;
|
|
info->sensor_type = type;
|
|
info->sensor_dev_id = iic_id;
|
|
info->sensor_opt_cmd = opt_cmd;
|
|
info->sensor_config = sensor_config;
|
|
INIT_LIST_HEAD(&info->list);
|
|
list_add_tail(&info->list,(struct list_head*)&sensor_info_head);
|
|
}
|
|
}
|
|
|
|
void sensor_info_destory()
|
|
{
|
|
SENSOR_BASIC_INFO *info = NULL;
|
|
struct list_head *nhead = NULL;
|
|
|
|
while(1)
|
|
{
|
|
if (list_empty((void *)&sensor_info_head)) break;
|
|
nhead = sensor_info_head.next;
|
|
info = list_entry(nhead, SENSOR_BASIC_INFO, list);
|
|
list_del(nhead);
|
|
os_free(info);
|
|
}
|
|
}
|
|
|
|
void hgisp_frame_start_handle(uint32 irq, uint32 irq_data, uint32 param1, uint32 param2) {
|
|
// _os_printf("d");
|
|
// os_printf("%s %d\r\n",__func__,__LINE__);
|
|
}
|
|
|
|
void hgisp_frame_done_handle(uint32 irq, uint32 irq_data, uint32 param1, uint32 param2){
|
|
os_printf("%s %d\r\n",__func__,__LINE__);
|
|
}
|
|
|
|
void hgisp_frame_slow_handle(uint32 irq, uint32 irq_data, uint32 param1, uint32 param2){
|
|
os_printf("%s %d\r\n",__func__,__LINE__);
|
|
}
|
|
|
|
void hgisp_frame_fast_handle(uint32 irq, uint32 irq_data, uint32 param1, uint32 param2){
|
|
os_printf("%s %d\r\n",__func__,__LINE__);
|
|
}
|
|
|
|
void hgisp_motion_detect_handle(uint32 irq, uint32 irq_data, uint32 param1, uint32 param2){
|
|
os_printf("%s %d\r\n",__func__,__LINE__);
|
|
}
|
|
|
|
void hgisp_data_overflow_handle(uint32 irq, uint32 irq_data, uint32 param1, uint32 param2){
|
|
os_printf("%s %d\r\n",__func__,__LINE__);
|
|
}
|
|
|
|
void *isp_task_hdl;
|
|
volatile struct os_event isp_event;
|
|
volatile struct os_msgqueue isp_msg;
|
|
int32 isp_task(void *data)
|
|
{
|
|
uint32 flag = 0;
|
|
int32 event_ret = 0;
|
|
int32 msg_ret = 0;
|
|
uint8 msg_cnt = 0;
|
|
|
|
struct isp_device *dev = (struct isp_device *)data;
|
|
struct isp_exposure_opt *cfg = NULL;
|
|
struct isp_sensor_opt *opt = NULL;
|
|
|
|
while (1)
|
|
{
|
|
event_ret = os_event_wait((void *)&isp_event, EVENT_ISP_CALC | EVENT_ISP_FPS_OPT | EVENT_ISP_IMG_OPT, &flag, OS_EVENT_WMODE_OR | OS_EVENT_WMODE_CLEAR, 50);
|
|
if (event_ret)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (flag & EVENT_ISP_CALC)
|
|
{
|
|
if (cfg && iic_devid_finish(cfg->devid_id) == 1)
|
|
{
|
|
cfg->data.size = 0;
|
|
cfg = NULL;
|
|
}
|
|
|
|
isp_calculate(dev, (void *)&cfg);
|
|
|
|
if (cfg)
|
|
{
|
|
wake_up_iic_queue(cfg->devid_id, (void *)&cfg->data, cfg->cmd_len, 2, NULL);
|
|
}
|
|
}
|
|
|
|
if ((flag & EVENT_ISP_IMG_OPT) || (flag & EVENT_ISP_FPS_OPT))
|
|
{
|
|
msg_cnt = os_msgq_cnt((void *)&isp_msg);
|
|
for (int i = 0; i < msg_cnt; i++)
|
|
{
|
|
opt = (struct isp_sensor_opt *)os_msgq_get2((void *)&isp_msg, 100, &msg_ret);
|
|
if (msg_ret == 0)
|
|
{
|
|
while(iic_devid_finish(opt->devid_id) != 1)
|
|
{
|
|
os_sleep_ms(1);
|
|
}
|
|
wake_up_iic_queue(opt->devid_id, (uint8_t*)&opt->data, opt->cmd_len, 2, (uint8_t*)NULL);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
extern const uint16_t isp_param[];
|
|
|
|
void isp_cfg_dev(){
|
|
uint8_t ret;
|
|
struct hgisp_sensor_init *sensor_init = NULL;
|
|
struct isp_device *isp_dev;
|
|
SENSOR_BASIC_INFO *info = NULL;
|
|
isp_dev = (struct isp_device *)dev_get(HG_ISP_DEVID);
|
|
if (isp_dev == NULL)
|
|
{
|
|
os_printf("get isp device err\r\n");
|
|
return;
|
|
}
|
|
os_printf("isp cfg....\r\n");
|
|
sensor_init = (struct hgisp_sensor_init *)isp_sensor_param_load((void *)isp_param);
|
|
if (sensor_init && !list_empty((void *)&sensor_info_head))
|
|
{
|
|
os_event_init((void *)&isp_event);
|
|
os_msgq_init((void *)&isp_msg, 2);
|
|
ret = isp_open(isp_dev, ISP_HARDWARE_CLK, ISP_INPUT_FIFO_FULL);
|
|
if (!ret)
|
|
{
|
|
isp_yuv_range(isp_dev, VIDEO_YUV_RANGE_TYPE);
|
|
isp_sensor_param_config(isp_dev, (uint32)sensor_init);
|
|
isp_y_gamma_init(isp_dev , (uint32)y_gamma_tbl);
|
|
isp_rgb_gamma_init(isp_dev, (uint32)gamma_table_addr[1]);
|
|
isp_awb_mannul_mode_map(isp_dev, (uint32)isp_awb_mode_map);
|
|
isp_ae_ev_offset_lut(isp_dev, (uint32)ev_offset_lut);
|
|
isp_awb_gain_type(isp_dev, AWB_GAIN_TYPE_AWB, SENSOR_TYPE_MASTER);
|
|
isp_awb_gain_type(isp_dev, AWB_GAIN_TYPE_AWB, SENSOR_TYPE_SLAVE0);
|
|
isp_awb_gain_type(isp_dev, AWB_GAIN_TYPE_AWB, SENSOR_TYPE_SLAVE1);
|
|
list_for_each_entry(info, (struct list_head*)&sensor_info_head, list)
|
|
{
|
|
ret = isp_sensor_init(isp_dev, info->sensor_type, info->sensor_src, info->sensor_config);
|
|
if (ret)
|
|
{
|
|
os_printf(KERN_ERR"config sensor param err!\r\n");
|
|
isp_close(isp_dev);
|
|
goto end;
|
|
} else {
|
|
isp_sensor_iic_devid_init(isp_dev, info->sensor_dev_id, info->sensor_type);
|
|
isp_sensor_iic_cmd_init(isp_dev, info->sensor_opt_cmd, info->sensor_type);
|
|
}
|
|
}
|
|
ircut_init();
|
|
isp_request_irq(isp_dev, ISP_IRQ_FLAG_DMA_DONE , hgisp_frame_start_handle , 0);
|
|
// isp_request_irq(isp_dev, ISP_IRQ_FLAG_FRM_END , hgisp_frame_done_handle , (uint32)isp_dev);
|
|
isp_request_irq(isp_dev, ISP_IRQ_FLAG_DAT_OF , hgisp_data_overflow_handle , 0);
|
|
isp_request_irq(isp_dev, ISP_IRQ_FLAG_INTF_SLOW, hgisp_frame_slow_handle , 0);
|
|
isp_request_irq(isp_dev, ISP_IRQ_FLAG_FRM_FAST , hgisp_frame_fast_handle , 0);
|
|
isp_request_irq(isp_dev, ISP_IRQ_FLAG_MD_DONE , hgisp_motion_detect_handle , 0);
|
|
isp_task_hdl = os_task_create("isp", (void *)isp_task, isp_dev, OS_TASK_PRIORITY_HIGH+1, 0, NULL, 1024);
|
|
} else {
|
|
os_printf("isp open err");
|
|
goto end;
|
|
}
|
|
} else {
|
|
os_printf("sensor param init err!\r\n");
|
|
}
|
|
end:
|
|
sensor_info_destory();
|
|
}
|
|
|
|
void isp_dev_close()
|
|
{
|
|
struct isp_device *isp_dev = (struct isp_device *)dev_get(HG_ISP_DEVID);
|
|
if (isp_dev == NULL)
|
|
{
|
|
os_printf("get isp device err\r\n");
|
|
return;
|
|
}
|
|
|
|
isp_close(isp_dev);
|
|
os_task_destroy(isp_task_hdl);
|
|
os_event_del((void *)&isp_event);
|
|
os_msgq_del((void *)&isp_msg);
|
|
}
|
|
|