1 /*
2 * Copyright 2021 QuickLogic
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 * SPDX-License-Identifier: Apache-2.0
17 */
18 #include "rtconfig.h"
19 #ifdef PKG_USING_FREERTOS_WRAPPER
20 #include "FreeRTOS.h"
21 #include <camera.h>
22 #include <string.h>
23 #include <stdint.h>
24 #include <stdbool.h>
25 #include "semphr.h"
26 #include "core-v-mcu-config.h"
27 #include "hal_fc_event.h"
28 #include "hal_udma_ctrl_reg_defs.h"
29 #include "hal_udma_cam_reg_defs.h"
30 #include <udma_cam_driver.h>
31 #include <udma_i2cm_driver.h>
32 #include "himax.h"
33 #include "camera.h"
34
35 reg_cfg_t himaxRegInit[] = {
36 {BLC_TGT, 0x08}, // BLC target :8 at 8 bit mode
37 {BLC2_TGT, 0x08}, // BLI target :8 at 8 bit mode
38 {0x3044, 0x0A}, // Increase CDS time for settling
39 {0x3045, 0x00}, // Make symetric for cds_tg and rst_tg
40 {0x3047, 0x0A}, // Increase CDS time for settling
41 {0x3050, 0xC0}, // Make negative offset up to 4x
42 {0x3051, 0x42},
43 {0x3052, 0x50},
44 {0x3053, 0x00},
45 {0x3054, 0x03}, // tuning sf sig clamping as lowest
46 {0x3055, 0xF7}, // tuning dsun
47 {0x3056, 0xF8}, // increase adc nonoverlap clk
48 {0x3057, 0x29}, // increase adc pwr for missing code
49 {0x3058, 0x1F}, // turn on dsun
50 {0x3059, 0x1E},
51 {0x3064, 0x00},
52 {0x3065, 0x04}, // pad pull 0
53
54 {BLC_CFG, 0x43}, // BLC_on, IIR
55
56 {0x1001, 0x43}, // BLC dithering en
57 {0x1002, 0x43}, // blc_darkpixel_thd
58 {0x0350, 0x00}, // Dgain Control
59 {BLI_EN, 0x01}, // BLI enable
60 {0x1003, 0x00}, // BLI Target [Def: 0x20]
61
62 {DPC_CTRL, 0x01}, // DPC option 0: DPC off 1 : mono 3 : bayer1 5 : bayer2
63 {0x1009, 0xA0}, // cluster hot pixel th
64 {0x100A, 0x60}, // cluster cold pixel th
65 {SINGLE_THR_HOT, 0x90}, // single hot pixel th
66 {SINGLE_THR_COLD, 0x40}, // single cold pixel th
67 {0x1012, 0x00}, // Sync. shift disable
68 {0x2000, 0x07},
69 {0x2003, 0x00},
70 {0x2004, 0x1C},
71 {0x2007, 0x00},
72 {0x2008, 0x58},
73 {0x200B, 0x00},
74 {0x200C, 0x7A},
75 {0x200F, 0x00},
76 {0x2010, 0xB8},
77 {0x2013, 0x00},
78 {0x2014, 0x58},
79 {0x2017, 0x00},
80 {0x2018, 0x9B},
81
82 {AE_CTRL, 0x01}, //Automatic Exposure Gain Control
83 {AE_TARGET_MEAN, 0x3C}, //AE target mean [Def: 0x3C]
84 {AE_MIN_MEAN, 0x0A}, //AE min target mean [Def: 0x0A]
85
86 {INTEGRATION_H, 0x00}, //Integration H [Def: 0x01]
87 {INTEGRATION_L, 0x60}, //Integration L [Def: 0x08]
88 {ANALOG_GAIN, 0x00}, //Analog Global Gain
89 {DAMPING_FACTOR, 0x20}, //Damping Factor [Def: 0x20]
90 {DIGITAL_GAIN_H, 0x01}, //Digital Gain High [Def: 0x01]
91 {DIGITAL_GAIN_L, 0x00}, //Digital Gain Low [Def: 0x00]
92
93 {0x2103, 0x03},
94
95 {0x2104, 0x05},
96 {0x2105, 0x01},
97
98 {0x2106, 0x54},
99
100 {0x2108, 0x03},
101 {0x2109, 0x04},
102
103 {0x210B, 0xC0},
104 {0x210E, 0x00}, //Flicker Control
105 {0x210F, 0x00},
106 {0x2110, 0x3C},
107 {0x2111, 0x00},
108 {0x2112, 0x32},
109
110 {0x2150, 0x30},
111 {0x0340, 0x02},
112 {0x0341, 0x16},
113 {0x0342, 0x01},
114 {0x0343, 0x78},
115 {0x3010, 0x01},
116 {0x0383, 0x01},
117 {0x0387, 0x01},
118 {0x0390, 0x00},
119 {0x3011, 0x70},
120 {0x3059, 0x02},
121 {0x3060, 0x01},
122 // {0x3060, 0x25}, //Clock gating and clock divisors
123 {0x3068, 0x20}, //PCLK0 polarity
124 {IMG_ORIENTATION, 0x01}, // change the orientation
125 {0x0104, 0x01},
126 {0x0100, 0x01},
127 //{0x0601, 0x11} //Test pattern walking ones
128 //{0x0601, 0x01} //Test pattern colour bar
129 };
130
131 SemaphoreHandle_t cam_semaphore_rx;
132 static uint8_t cam;
camISR()133 static void camISR() {
134
135 }
cam_open(uint8_t cam_id)136 void cam_open (uint8_t cam_id)
137 {
138 int i = 0;
139 volatile UdmaCtrl_t* pudma_ctrl = (UdmaCtrl_t*)UDMA_CH_ADDR_CTRL;
140
141 /* Enable reset and enable uart clock */
142 pudma_ctrl->reg_rst |= (UDMA_CTRL_CAM0_CLKEN << cam_id);
143 pudma_ctrl->reg_rst &= ~(UDMA_CTRL_CAM0_CLKEN << cam_id);
144 pudma_ctrl->reg_cg |= (UDMA_CTRL_CAM0_CLKEN << cam_id);
145
146 //psdio_regs->clk_div_b.clk_div = 5;
147 //psdio_regs->clk_div_b.valid = 1;
148 hal_setpinmux(21, 0);
149 hal_setpinmux(22, 0);
150 hal_setpinmux(25, 0);
151 for(i=0; i<8; i++ )
152 {
153 //set pin muxes to sdio functionality
154 hal_setpinmux(29+i, 0);
155 }
156
157 /* See if already initialized */
158 if (cam_semaphore_rx != NULL ){
159 return;
160 }
161
162 /* Set semaphore */
163 SemaphoreHandle_t shSemaphoreHandle; // FreeRTOS.h has a define for xSemaphoreHandle, so can't use that
164 shSemaphoreHandle = xSemaphoreCreateBinary();
165 configASSERT(shSemaphoreHandle);
166 xSemaphoreGive(shSemaphoreHandle);
167 cam_semaphore_rx = shSemaphoreHandle;
168
169
170 /* Set handlers. */
171 pi_fc_event_handler_set(SOC_EVENT_UDMA_CAM_RX(cam_id), camISR, cam_semaphore_rx);
172 /* Enable SOC events propagation to FC. */
173 hal_soc_eu_set_fc_mask(SOC_EVENT_UDMA_CAM_RX(cam_id));
174
175 /* configure */
176 cam = 0x48; // Himax address
177 udma_cam_control(kCamReset, NULL);
178
179 return;
180 }
udma_cam_control(udma_cam_control_type_t control_type,void * pparam)181 uint16_t udma_cam_control(udma_cam_control_type_t control_type, void* pparam) {
182 short retval = 0;
183 uint16_t i;
184 SemaphoreHandle_t shSemaphoreHandle;
185 camera_struct_t *camera;
186 //camera = (camera_struct_t *)0x1A102300; // Peripheral 5?
187 camera = (camera_struct_t *)(UDMA_CH_ADDR_CAM + 0 * UDMA_CH_SIZE);
188 shSemaphoreHandle = cam_semaphore_rx;
189
190 switch (control_type) {
191 case kCamReset:
192 _himaxRegWrite(SW_RESET, HIMAX_RESET);
193 break;
194 case kCamID:
195 udma_i2cm_16read8(0, cam, MODEL_ID_H, 2, &retval, 0);
196 retval = (retval >> 8) & 0xff | (retval <<8);
197 break;
198 case kCamInit:
199 for(i=0; i<(sizeof(himaxRegInit)/sizeof(reg_cfg_t)); i++){
200 _himaxRegWrite(himaxRegInit[i].addr, himaxRegInit[i].data);
201 }
202 camera->cfg_ll = 0<<16 | 0;
203 camera->cfg_ur = 323<<16 | 243; // 320 x 240 ?
204 camera->cfg_filter = (1 << 16) | (1 << 8) | 1;
205 camera->cfg_size = 324;
206 camera->vsync_pol = 1;
207 camera->cfg_glob = (0 << 0) | // framedrop disabled
208 (000000 << 1) | // number of frames to drop
209 (0 << 7) | // Frame slice disabled
210 (004 << 8) | // Format binary 100 = ByPass little endian
211 (0000 << 11); // Shift value ignored in bypass
212
213 break;
214 case kCamFrame:
215 configASSERT( xSemaphoreTake( shSemaphoreHandle, 1000000 ) == pdTRUE );
216 camera->rx_saddr = pparam;
217 camera->rx_size = (244*324);
218 camera->rx_cfg = 0x12; // start 16-bit transfers
219 camera->cfg_glob = camera->cfg_glob |
220 (1 << 31) ; // enable 1 == go
221
222 configASSERT( xSemaphoreTake( shSemaphoreHandle, 1000000 ) == pdTRUE );
223 camera->cfg_glob = camera->cfg_glob &
224 (0x7fffffff) ; // enable 1 == go
225 configASSERT( xSemaphoreGive( shSemaphoreHandle ) == pdTRUE );
226 }
227 return retval;
228 }
229
_himaxRegWrite(unsigned int addr,unsigned char value)230 void _himaxRegWrite(unsigned int addr, unsigned char value){
231 uint8_t naddr;
232 uint16_t data;
233 naddr = (addr>>8) & 0xff;
234 data = (value << 8) | (addr & 0xff);
235 udma_i2cm_write (0, cam, naddr, 2, &data, 0);
236 // i2c_16write8(cam,addr,value);
237 }
238 #endif
239