• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 HPMicro
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 #include "hpm_cam_drv.h"
9 
10 #define CAM_RX_FIFO_THRESHOLD (6U)
11 
cam_get_default_config(CAM_Type * ptr,cam_config_t * config,display_pixel_format_t pixel_format)12 void cam_get_default_config(CAM_Type *ptr, cam_config_t *config, display_pixel_format_t pixel_format)
13 {
14     (void) ptr;
15     config->width = 320;
16     config->height = 240;
17     config->pixclk_sampling_falling = false;
18     config->hsync_active_low = false;
19     config->vsync_active_low = false;
20     config->de_active_low = false;
21     config->color_ext = false;
22     config->data_pack_msb = false;
23     config->enable_buffer2 = false;
24     config->data_store_mode = CAM_DATA_STORE_MODE_NORMAL;
25     config->color_format = pixel_format;
26     config->sensor_bitwidth = CAM_SENSOR_BITWIDTH_10BITS;
27 
28     switch (pixel_format) {
29     case display_pixel_format_yuv422:
30         config->csc_config.enable = true;
31         config->csc_config.ycbcr_mode = false;
32         config->csc_config.yuv2rgb_coef.c0 = 0x100;
33         config->csc_config.yuv2rgb_coef.uv_offset = 0;
34         config->csc_config.yuv2rgb_coef.y_offset = 0;
35         config->csc_config.yuv2rgb_coef.c1 = 0x123;
36         config->csc_config.yuv2rgb_coef.c2 = 0x76B;
37         config->csc_config.yuv2rgb_coef.c3 = 0x79C;
38         config->csc_config.yuv2rgb_coef.c4 = 0x208;
39         break;
40     case display_pixel_format_ycbcr422:
41         config->csc_config.enable = true;
42         config->csc_config.ycbcr_mode = true;
43         config->csc_config.yuv2rgb_coef.c0 = 0x12A;
44         config->csc_config.yuv2rgb_coef.uv_offset = 0x180;
45         config->csc_config.yuv2rgb_coef.y_offset = 0x1F0;
46         config->csc_config.yuv2rgb_coef.c1 = 0x198;
47         config->csc_config.yuv2rgb_coef.c2 = 0x730;
48         config->csc_config.yuv2rgb_coef.c3 = 0x79C;
49         config->csc_config.yuv2rgb_coef.c4 = 0x204;
50         break;
51     default:
52         config->csc_config.enable = false;
53         config->csc_config.ycbcr_mode = false;
54         config->csc_config.yuv2rgb_coef.c0 = 0;
55         config->csc_config.yuv2rgb_coef.uv_offset = 0;
56         config->csc_config.yuv2rgb_coef.y_offset = 0;
57         config->csc_config.yuv2rgb_coef.c1 = 0;
58         config->csc_config.yuv2rgb_coef.c2 = 0;
59         config->csc_config.yuv2rgb_coef.c3 = 0;
60         config->csc_config.yuv2rgb_coef.c4 = 0;
61         break;
62     }
63 }
64 
cam_reset(CAM_Type * ptr)65 void cam_reset(CAM_Type *ptr)
66 {
67     cam_stop(ptr);
68     ptr->CR1 = CAM_CR1_ASYNC_RXFIFO_CLR_MASK;
69     ptr->INT_EN = 0;
70     ptr->CR2 = CAM_CR2_FRMCNT_RST_MASK;
71     ptr->STA = 0xFFFFFFFF;
72     ptr->CR20 = 0;
73 }
74 
cam_init(CAM_Type * ptr,cam_config_t * config)75 hpm_stat_t cam_init(CAM_Type *ptr, cam_config_t *config)
76 {
77     hpm_stat_t stat = status_success;
78     uint32_t pixel_format, width;
79 
80     pixel_format = config->color_format;
81     width = config->width;
82 
83     if (pixel_format == CAM_COLOR_FORMAT_RAW8) {
84         if ((width % 2) != 0) {
85             return status_invalid_argument;
86         }
87         /* use rgb565 format to receive raw8 data and adjust the width to half */
88         pixel_format = CAM_COLOR_FORMAT_RGB565;
89         width /= 2;
90     }
91 
92     cam_reset(ptr);
93 
94     /*
95      * In DVP mode, de_active_low and hsync_active_low are same.
96      */
97     if (config->sensor_bitwidth != CAM_SENSOR_BITWIDTH_24BITS) {
98         config->de_active_low = config->hsync_active_low;
99     }
100 
101     ptr->CR1 = CAM_CR1_INV_PIXCLK_SET(config->pixclk_sampling_falling)
102         | CAM_CR1_INV_HSYNC_SET(config->hsync_active_low)
103         | CAM_CR1_INV_VSYNC_SET(config->vsync_active_low)
104         | CAM_CR1_INV_DEN_SET(config->de_active_low)
105         | CAM_CR1_RESTART_BUSPTR_MASK
106         | CAM_CR1_COLOR_EXT_SET(config->color_ext)
107         | CAM_CR1_PACK_DIR_SET(config->data_pack_msb)
108         | config->data_store_mode
109         | pixel_format
110         | config->sensor_bitwidth;
111 
112     ptr->IDEAL_WN_SIZE = CAM_IDEAL_WN_SIZE_HEIGHT_SET(config->height)
113         | CAM_IDEAL_WN_SIZE_WIDTH_SET(width);
114 
115     ptr->CR2 = CAM_CR2_DMA_REQ_EN_RFF_MASK
116         | CAM_CR2_RXFF_LEVEL_SET(CAM_RX_FIFO_THRESHOLD);
117     ptr->DMASA_FB1 = config->buffer1;
118     if (config->enable_buffer2) {
119         ptr->DMASA_FB2 = config->buffer2;
120     }
121 
122     ptr->CSC_COEF0 = CAM_CSC_COEF0_ENABLE_SET(config->csc_config.enable)
123                     | CAM_CSC_COEF0_YCBCR_MODE_SET(config->csc_config.ycbcr_mode)
124                     | CAM_CSC_COEF0_C0_SET(config->csc_config.yuv2rgb_coef.c0)
125                     | CAM_CSC_COEF0_UV_OFFSET_SET(config->csc_config.yuv2rgb_coef.uv_offset)
126                     | CAM_CSC_COEF0_Y_OFFSET_SET(config->csc_config.yuv2rgb_coef.y_offset);
127     ptr->CSC_COEF1 = CAM_CSC_COEF1_C1_SET(config->csc_config.yuv2rgb_coef.c1)
128                     | CAM_CSC_COEF1_C4_SET(config->csc_config.yuv2rgb_coef.c4);
129     ptr->CSC_COEF2 = CAM_CSC_COEF2_C2_SET(config->csc_config.yuv2rgb_coef.c2)
130                     | CAM_CSC_COEF2_C3_SET(config->csc_config.yuv2rgb_coef.c3);
131 
132     return stat;
133 }
134 
cam_update_buffer(CAM_Type * ptr,uint32_t buffer)135 void cam_update_buffer(CAM_Type *ptr, uint32_t buffer)
136 {
137     ptr->DMASA_FB1 = buffer;
138 }
139 
cam_stop(CAM_Type * ptr)140 void cam_stop(CAM_Type *ptr)
141 {
142     ptr->CR18 &= ~CAM_CR18_CAM_ENABLE_MASK;
143 }
144 
cam_start(CAM_Type * ptr)145 void cam_start(CAM_Type *ptr)
146 {
147     ptr->CR18 |= CAM_CR18_CAM_ENABLE_MASK;
148 }
149 
cam_stop_safely(CAM_Type * ptr)150 void cam_stop_safely(CAM_Type *ptr)
151 {
152     /*
153     * waiting for capture frame to complete
154     */
155     cam_clear_status(ptr, cam_status_end_of_frame);
156     while (cam_check_status(ptr, cam_status_end_of_frame) == false) {
157     }
158     cam_stop(ptr);
159 }
160