1 /*
2  * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include "hal/cam_ll.h"
8 #include "hal/cam_hal.h"
9 #include "soc/soc_caps.h"
10 
11 /**
12  * @brief Configure line number to trigger interrupt
13  *
14  * @param hal CAM object data pointer
15  * @param num line number
16  *
17  * @return None
18  */
cam_hal_set_line_int_num(cam_hal_context_t * hal,uint32_t num)19 static void cam_hal_set_line_int_num(cam_hal_context_t *hal, uint32_t num)
20 {
21     if (num > 0) {
22         cam_ll_enable_hs_line_int(hal->hw, 1);
23         cam_ll_set_line_int_num(hal->hw, num);
24     } else {
25         cam_ll_enable_hs_line_int(hal->hw, 0);
26         cam_ll_set_line_int_num(hal->hw, 0);
27     }
28 }
29 
30 /**
31  * @brief Configure V-SYNC filter threshold
32  *
33  * @param hal CAM object data pointer
34  * @param num V-SYNC filter threshold
35  *
36  * @return None
37  */
cam_hal_set_vsync_filter_num(cam_hal_context_t * hal,uint32_t num)38 static void cam_hal_set_vsync_filter_num(cam_hal_context_t *hal, uint32_t num)
39 {
40     if (num > 0) {
41         cam_ll_enable_vsync_filter(hal->hw, 1);
42         cam_ll_set_vsync_filter_thres(hal->hw, num);
43     } else {
44         cam_ll_enable_vsync_filter(hal->hw, 0);
45         cam_ll_set_vsync_filter_thres(hal->hw, 0);
46     }
47 }
48 
49 /**
50  * @brief Initialize CAM hardware
51  *
52  * @param hal    CAM object data pointer
53  * @param config CAM configuration
54  *
55  * @return None
56  */
cam_hal_init(cam_hal_context_t * hal,const cam_hal_config_t * config)57 void cam_hal_init(cam_hal_context_t *hal, const cam_hal_config_t *config)
58 {
59     memset(hal, 0, sizeof(cam_hal_context_t));
60 
61     hal->hw = CAM_LL_GET_HW(0);
62 
63     cam_ll_enable_stop_signal(hal->hw, 0);
64     cam_ll_swap_dma_data_byte_order(hal->hw, config->byte_swap_en);
65     cam_ll_reverse_dma_data_bit_order(hal->hw, 0);
66     cam_ll_enable_vsync_generate_eof(hal->hw, 1);
67 
68     cam_hal_set_line_int_num(hal, 0);
69     cam_hal_set_vsync_filter_num(hal, 0);
70 
71     cam_ll_enable_invert_pclk(hal->hw, 0);
72     cam_ll_set_input_data_width(hal->hw, 8);
73     cam_ll_enable_invert_de(hal->hw, 0);
74     cam_ll_enable_invert_vsync(hal->hw, 0);
75     cam_ll_enable_invert_hsync(hal->hw, 0);
76     cam_ll_set_vh_de_mode(hal->hw, 0); // Disable vh_de mode default
77     cam_ll_enable_rgb_yuv_convert(hal->hw, 0); // bypass conv module default
78 }
79 
80 /**
81  * @brief De-initialize CAM hardware
82  *
83  * @note Stop stream before deinit
84  * @param hal CAM object data pointer
85  *
86  * @return None
87  */
cam_hal_deinit(cam_hal_context_t * hal)88 void cam_hal_deinit(cam_hal_context_t *hal)
89 {
90     cam_ll_stop(hal->hw);
91     cam_ll_reset(hal->hw);
92     cam_ll_fifo_reset(hal->hw);
93 }
94 
95 /**
96  * @brief Start CAM to receive frame data
97  *
98  * @param hal CAM object data pointer
99  *
100  * @return None
101  */
cam_hal_start_streaming(cam_hal_context_t * hal)102 void cam_hal_start_streaming(cam_hal_context_t *hal)
103 {
104     cam_ll_reset(hal->hw);
105     cam_ll_fifo_reset(hal->hw);
106 
107     cam_ll_start(hal->hw);
108 }
109 
110 /**
111  * @brief Stop CAM receiving frame data
112  *
113  * @param hal CAM object data pointer
114  *
115  * @return None
116  */
cam_hal_stop_streaming(cam_hal_context_t * hal)117 void cam_hal_stop_streaming(cam_hal_context_t *hal)
118 {
119     cam_ll_stop(hal->hw);
120 }
121