• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 HPMicro
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 #ifndef HPM_CAM_DRV_H
9 #define HPM_CAM_DRV_H
10 
11 #include "hpm_common.h"
12 #include "hpm_display_common.h"
13 #include "hpm_cam_regs.h"
14 
15 /**
16  * @brief CAM driver APIs
17  * @defgroup cam_interface CAM driver APIs
18  * @ingroup io_interfaces
19  * @{
20  */
21 
22 /**
23  * @brief CAM data store mode
24  */
25 #define CAM_DATA_STORE_MODE_NORMAL (0U)
26 #define CAM_DATA_STORE_MODE_Y_UV_PLANES (CAM_CR1_STORAGE_MODE_SET(1))
27 #define CAM_DATA_STORE_MODE_Y_ONLY (CAM_CR1_STORAGE_MODE_SET(2))
28 #define CAM_DATA_STORE_MODE_BINARY (CAM_CR1_STORAGE_MODE_SET(3))
29 
30 /**
31  * @brief CAM sensor bitwidth
32  */
33 #define CAM_SENSOR_BITWIDTH_8BITS (CAM_CR1_SENSOR_BIT_WIDTH_SET(0))
34 #define CAM_SENSOR_BITWIDTH_10BITS (CAM_CR1_SENSOR_BIT_WIDTH_SET(1))
35 #define CAM_SENSOR_BITWIDTH_24BITS (CAM_CR1_SENSOR_BIT_WIDTH_SET(3))
36 
37 /**
38  * @brief CAM IRQ mask
39  */
40 typedef enum {
41     cam_irq_unsupported_configuration = CAM_INT_EN_ERR_CL_BWID_CFG_INT_EN_MASK,
42     cam_irq_hist_calculation_done = CAM_INT_EN_HIST_DONE_INT_EN_MASK,
43     cam_irq_hresponse_error = CAM_INT_EN_HRESP_ERR_EN_MASK,
44     cam_irq_end_of_frame = CAM_INT_EN_EOF_INT_EN_MASK,
45     cam_irq_rx_fifo_overrun = CAM_INT_EN_RF_OR_INTEN_MASK,
46     cam_irq_fb2_dma_transfer_done = CAM_INT_EN_FB2_DMA_DONE_INTEN_MASK,
47     cam_irq_fb1_dma_transfer_done = CAM_INT_EN_FB1_DMA_DONE_INTEN_MASK,
48     cam_irq_start_of_frame = CAM_INT_EN_SOF_INT_EN_MASK
49 } cam_irq_mask_t;
50 
51 /**
52  * @brief CAM status mask
53  */
54 typedef enum {
55     cam_status_unsupported_configuration = CAM_STA_ERR_CL_BWID_CFG_MASK,
56     cam_status_hist_calculation_done = CAM_STA_HIST_DONE_MASK,
57     cam_status_rx_fifo_overrun = CAM_STA_RF_OR_INT_MASK,
58     cam_status_fb2_dma_transfer_done = CAM_STA_DMA_TSF_DONE_FB2_MASK,
59     cam_status_fb1_dma_transfer_done = CAM_STA_DMA_TSF_DONE_FB1_MASK,
60     cam_status_end_of_frame = CAM_STA_EOF_INT_MASK,
61     cam_status_start_of_frame = CAM_STA_SOF_INT_MASK,
62     cam_status_hresponse_error = CAM_STA_HRESP_ERR_INT_MASK
63 } cam_status_mask_t;
64 
65 /**
66  * @brief CAM input color format
67  */
68 #define CAM_COLOR_FORMAT_RGB888 (CAM_CR1_COLOR_FORMATS_SET(2))
69 #define CAM_COLOR_FORMAT_RGB565 (CAM_CR1_COLOR_FORMATS_SET(4))
70 #define CAM_COLOR_FORMAT_RGB555 (CAM_CR1_COLOR_FORMATS_SET(6))
71 #define CAM_COLOR_FORMAT_YCBCR422 (CAM_CR1_COLOR_FORMATS_SET(7))
72 #define CAM_COLOR_FORMAT_YUV444 (CAM_CR1_COLOR_FORMATS_SET(8))
73 #define CAM_COLOR_FORMAT_RAW8 (CAM_CR1_COLOR_FORMATS_SET(0xf))
74 #define CAM_COLOR_FORMAT_UNSUPPORTED (1)
75 
76 /**
77  * @brief CAM config
78  */
79 typedef struct {
80     uint32_t width;
81     uint32_t height;
82     bool pixclk_sampling_falling;
83     bool de_active_low; /* de_active_low must is same with hsync_active_low when dvp be used */
84     bool hsync_active_low;
85     bool vsync_active_low;
86     bool color_ext;
87     bool data_pack_msb;
88     bool enable_buffer2;
89     uint16_t data_store_mode;
90     uint8_t color_format;
91     uint8_t sensor_bitwidth;
92     uint32_t buffer1;
93     uint32_t buffer2;
94     display_yuv2rgb_config_t csc_config;
95 } cam_config_t;
96 
97 /**
98  * @brief cam input pixel byte order
99  */
100 typedef enum {
101     cam_input_pixel_yuv444 = 0,    /* Y[23:16] U[15:8] V[7:0] */
102     cam_input_pixel_yvu444 = 1,    /* Y[23:16] V[15:8] U[7:0] */
103     cam_input_pixel_uyv444 = 2,    /* U[23:16] Y[15:8] V[7:0] */
104     cam_input_pixel_vyu444 = 3,    /* V[23:16] Y[15:8] U[7:0] */
105     cam_input_pixel_uvy444 = 4,    /* U[23:16] V[15:8] Y[7:0] */
106     cam_input_pixel_vuy444 = 5,    /* V[23:16] U[15:8] Y[7:0] */
107     cam_input_pixel_yuyv422 = 0,   /* Y0[31:24] U0[23:16] Y1[15:8] V0[7:0] */
108     cam_input_pixel_yvyu422 = 1,   /* Y0[31:24] V0[23:16] Y1[15:8] U0[7:0] */
109     cam_input_pixel_uyvy422 = 2,   /* U0[31:24] Y0[23:16] V0[15:8] Y1[7:0] */
110     cam_input_pixel_vyuy422 = 3,   /* V0[31:24] Y0[23:16] U0[15:8] Y1[7:0] */
111     cam_input_pixel_rgb565 = 0,    /* R[15:11] G[10:8] G[7:5] B[4:0] */
112     cam_input_pixel_bgr565 = 1,    /* B[15:11] G[10:8] G[7:5] R[4:0] */
113     cam_input_pixel_gbr888 = 0,    /* G[23:16] B[15:8] R[7:0] */
114     cam_input_pixel_grb888 = 1,    /* G[23:16] R[15:8] B[7:0] */
115     cam_input_pixel_bgr888 = 2,    /* B[23:16] G[15:8] R[7:0] */
116     cam_input_pixel_rgb888 = 3,    /* R[23:16] G[15:8] B[7:0] */
117     cam_input_pixel_brg888 = 4,    /* B[23:16] R[15:8] G[7:0] */
118     cam_input_pixel_rbg888 = 5,    /* R[23:16] B[15:8] G[7:0] */
119 } cam_input_pixel_byte_order_t;
120 
121 #ifdef __cplusplus
122 extern "C" {
123 #endif
124 
125 /**
126  * @brief cam get pixel format value
127  *
128  * @param format display_pixel_format_t
129  * @return uint32_t cam color format, like CAM_COLOR_FORMAT_RGB565
130  */
cam_get_pixel_format(display_pixel_format_t format)131 static inline uint32_t cam_get_pixel_format(display_pixel_format_t format)
132 {
133     switch (format) {
134     case display_pixel_format_rgb565:
135         return CAM_COLOR_FORMAT_RGB565;
136     case display_pixel_format_ycbcr422:
137         return CAM_COLOR_FORMAT_YCBCR422;
138     case display_pixel_format_raw8:
139         return CAM_COLOR_FORMAT_RAW8;
140     default:
141         return CAM_COLOR_FORMAT_UNSUPPORTED;
142     }
143 }
144 
145 /**
146  * @brief CAM set high and low limits of color key
147  *
148  * @param [in] ptr CAM base address
149  * @param [in] high color key high limits
150  * @param [in] low color key low limits
151  */
cam_set_color_key(CAM_Type * ptr,uint32_t high,uint32_t low)152 static inline void cam_set_color_key(CAM_Type *ptr, uint32_t high, uint32_t low)
153 {
154     ptr->CLRKEY_LOW = CAM_CLRKEY_LOW_LIMIT_SET(low);
155     ptr->CLRKEY_HIGH = CAM_CLRKEY_HIGH_LIMIT_SET(high);
156 }
157 
158 /**
159  * @brief CAM get default config
160  *
161  * @param [in] ptr CAM base address
162  * @param [out] config cam_config_t
163  * @param [in] pixel_format display_pixel_format_t
164  */
165 void cam_get_default_config(CAM_Type *ptr, cam_config_t *config, display_pixel_format_t pixel_format);
166 
167 /**
168  * @brief CAM init
169  *
170  * @param [in] ptr CAM base address
171  * @param [in] config cam_config_t
172  *
173  * @retval hpm_stat_t status_invalid_argument or status_success
174  */
175 hpm_stat_t cam_init(CAM_Type *ptr, cam_config_t *config);
176 
177 /**
178  * @brief CAM start
179  *
180  * @param [in] ptr CAM base address
181  */
182 void cam_start(CAM_Type *ptr);
183 
184 /**
185  * @brief CAM stop
186  *
187  * @note this API will stop CAM immediately no matter there's any frame is being processed or not
188  *
189  * @param [in] ptr CAM base address
190  */
191 void cam_stop(CAM_Type *ptr);
192 
193 void cam_update_buffer(CAM_Type *ptr, uint32_t buffer);
194 
195 /**
196  * @brief CAM enable binary output
197  *
198  * This function is used to enable CAM binary output after
199  * the CAM is initialized by the cam_init.
200  *
201  * @param [in] ptr CAM base address
202  */
cam_enable_binary_output(CAM_Type * ptr)203 static inline void cam_enable_binary_output(CAM_Type *ptr)
204 {
205     ptr->CR20 |= CAM_CR20_BINARY_EN_MASK;
206 }
207 
208 /**
209  * @brief CAM disable binary output
210  *
211  * @param [in] ptr CAM base address
212  */
cam_disable_binary_output(CAM_Type * ptr)213 static inline void cam_disable_binary_output(CAM_Type *ptr)
214 {
215     ptr->CR20 &= ~CAM_CR20_BINARY_EN_MASK;
216 }
217 
218 /**
219  * @brief CAM set binary threshold
220  *
221  * @param [in] ptr CAM base address
222  * @param [in] threshold threshold value of binary output
223  */
cam_set_binary_threshold(CAM_Type * ptr,uint8_t threshold)224 static inline void cam_set_binary_threshold(CAM_Type *ptr, uint8_t threshold)
225 {
226     ptr->CR20 = (ptr->CR20 & (~CAM_CR20_THRESHOLD_MASK)) | CAM_CR20_THRESHOLD_SET(threshold);
227 }
228 
229 /**
230  * @brief CAM enable argb8888 output
231  *
232  * This function is used to enable CAM argb8888 pixel output after the CAM is initialized by
233  * the cam_init and input pixel byte order is configured by the cam_set_input_pixel_byte_order.
234  *
235  * @param [in] ptr CAM base address
236  */
cam_enable_argb8888_output(CAM_Type * ptr)237 static inline void cam_enable_argb8888_output(CAM_Type *ptr)
238 {
239     ptr->CR1 |= CAM_CR1_COLOR_EXT_MASK;
240 }
241 
242 /**
243  * @brief CAM disable argb8888 output
244  *
245  * @param [in] ptr CAM base address
246  */
cam_disable_argb8888_output(CAM_Type * ptr)247 static inline void cam_disable_argb8888_output(CAM_Type *ptr)
248 {
249     ptr->CR1 &= ~CAM_CR1_COLOR_EXT_MASK;
250 }
251 
252 /**
253  * @brief CAM set input pixel byte order
254  *
255  * @param [in] ptr CAM base address
256  * @param [in] order cam_input_pixel_byte_order_t
257  */
cam_set_input_pixel_byte_order(CAM_Type * ptr,cam_input_pixel_byte_order_t order)258 static inline void cam_set_input_pixel_byte_order(CAM_Type *ptr, cam_input_pixel_byte_order_t order)
259 {
260     ptr->CR2 = (ptr->CR2 & (~CAM_CR2_CLRBITFORMAT_MASK)) | CAM_CR2_CLRBITFORMAT_SET(order);
261 }
262 
263 /**
264  * @brief CAM enable irq
265  *
266  * @param [in] ptr CAM base address
267  * @param [in] irq_mask irq mask value
268  */
cam_enable_irq(CAM_Type * ptr,cam_irq_mask_t irq_mask)269 static inline void cam_enable_irq(CAM_Type *ptr, cam_irq_mask_t irq_mask)
270 {
271     ptr->INT_EN |= irq_mask;
272 }
273 
274 
275 /**
276  * @brief CAM disable irq
277  *
278  * @param [in] ptr CAM base address
279  * @param [in] irq_mask irq mask value
280  */
cam_disable_irq(CAM_Type * ptr,cam_irq_mask_t irq_mask)281 static inline void cam_disable_irq(CAM_Type *ptr, cam_irq_mask_t irq_mask)
282 {
283     ptr->INT_EN &= ~irq_mask;
284 }
285 
286 /**
287  * @brief Check CAM status according to the given status mask
288  *
289  * @param [in] ptr CAM base address
290  * @param sta_mask sta_mask refer to cam_status_mask_t
291  * @retval true if any bit in given mask is set
292  * @retval false if none of any bit in given mask is set
293  */
cam_check_status(CAM_Type * ptr,cam_status_mask_t sta_mask)294 static inline bool cam_check_status(CAM_Type *ptr, cam_status_mask_t sta_mask)
295 {
296     return ((ptr->STA & sta_mask) != 0U) ? true : false;
297 }
298 
299 /**
300  * @brief Clear CAM status according to the given status mask
301  *
302  * @param [in] ptr CAM base address
303  * @param sta_mask sta_mask refer to cam_status_mask_t
304  */
cam_clear_status(CAM_Type * ptr,cam_status_mask_t sta_mask)305 static inline void cam_clear_status(CAM_Type *ptr, cam_status_mask_t sta_mask)
306 {
307     ptr->STA = sta_mask;
308 }
309 
310 /**
311  * @brief CAM safety stop
312  *
313  * @note this API will wait for end-of-frame event before stopping CAM
314  *
315  * @param [in] ptr CAM base address
316  */
317 void cam_stop_safely(CAM_Type *ptr);
318 
319 /**
320  * @}
321  *
322  */
323 
324 #ifdef __cplusplus
325 }
326 #endif
327 
328 #endif /* HPM_CAM_DRV_H */
329 
330 
331