#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); }