ov3660.c 30 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033
  1. /*
  2. * This file is part of the OpenMV project.
  3. * Copyright (c) 2013/2014 Ibrahim Abdelkader <i.abdalkader@gmail.com>
  4. * This work is licensed under the MIT license, see the file LICENSE for details.
  5. *
  6. * OV3660 driver.
  7. *
  8. */
  9. #include <stdint.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include "sccb.h"
  13. #include "ov3660.h"
  14. #include "ov3660_regs.h"
  15. #include "ov3660_settings.h"
  16. #include "freertos/FreeRTOS.h"
  17. #include "freertos/task.h"
  18. #if defined(ARDUINO_ARCH_ESP32) && defined(CONFIG_ARDUHAL_ESP_LOG)
  19. #include "esp32-hal-log.h"
  20. #else
  21. #include "esp_log.h"
  22. static const char *TAG = "ov3660";
  23. #endif
  24. //#define REG_DEBUG_ON
  25. static int read_reg(uint8_t slv_addr, const uint16_t reg){
  26. int ret = SCCB_Read16(slv_addr, reg);
  27. #ifdef REG_DEBUG_ON
  28. if (ret < 0) {
  29. ESP_LOGE(TAG, "READ REG 0x%04x FAILED: %d", reg, ret);
  30. }
  31. #endif
  32. return ret;
  33. }
  34. static int check_reg_mask(uint8_t slv_addr, uint16_t reg, uint8_t mask){
  35. return (read_reg(slv_addr, reg) & mask) == mask;
  36. }
  37. static int read_reg16(uint8_t slv_addr, const uint16_t reg){
  38. int ret = 0, ret2 = 0;
  39. ret = read_reg(slv_addr, reg);
  40. if (ret >= 0) {
  41. ret = (ret & 0xFF) << 8;
  42. ret2 = read_reg(slv_addr, reg+1);
  43. if (ret2 < 0) {
  44. ret = ret2;
  45. } else {
  46. ret |= ret2 & 0xFF;
  47. }
  48. }
  49. return ret;
  50. }
  51. static int write_reg(uint8_t slv_addr, const uint16_t reg, uint8_t value){
  52. int ret = 0;
  53. #ifndef REG_DEBUG_ON
  54. ret = SCCB_Write16(slv_addr, reg, value);
  55. #else
  56. int old_value = read_reg(slv_addr, reg);
  57. if (old_value < 0) {
  58. return old_value;
  59. }
  60. if ((uint8_t)old_value != value) {
  61. ESP_LOGI(TAG, "NEW REG 0x%04x: 0x%02x to 0x%02x", reg, (uint8_t)old_value, value);
  62. ret = SCCB_Write16(slv_addr, reg, value);
  63. } else {
  64. ESP_LOGD(TAG, "OLD REG 0x%04x: 0x%02x", reg, (uint8_t)old_value);
  65. ret = SCCB_Write16(slv_addr, reg, value);//maybe not?
  66. }
  67. if (ret < 0) {
  68. ESP_LOGE(TAG, "WRITE REG 0x%04x FAILED: %d", reg, ret);
  69. }
  70. #endif
  71. return ret;
  72. }
  73. static int set_reg_bits(uint8_t slv_addr, uint16_t reg, uint8_t offset, uint8_t mask, uint8_t value)
  74. {
  75. int ret = 0;
  76. uint8_t c_value, new_value;
  77. ret = read_reg(slv_addr, reg);
  78. if(ret < 0) {
  79. return ret;
  80. }
  81. c_value = ret;
  82. new_value = (c_value & ~(mask << offset)) | ((value & mask) << offset);
  83. ret = write_reg(slv_addr, reg, new_value);
  84. return ret;
  85. }
  86. static int write_regs(uint8_t slv_addr, const uint16_t (*regs)[2])
  87. {
  88. int i = 0, ret = 0;
  89. while (!ret && regs[i][0] != REGLIST_TAIL) {
  90. if (regs[i][0] == REG_DLY) {
  91. vTaskDelay(regs[i][1] / portTICK_PERIOD_MS);
  92. } else {
  93. ret = write_reg(slv_addr, regs[i][0], regs[i][1]);
  94. }
  95. i++;
  96. }
  97. return ret;
  98. }
  99. static int write_reg16(uint8_t slv_addr, const uint16_t reg, uint16_t value)
  100. {
  101. if (write_reg(slv_addr, reg, value >> 8) || write_reg(slv_addr, reg + 1, value)) {
  102. return -1;
  103. }
  104. return 0;
  105. }
  106. static int write_addr_reg(uint8_t slv_addr, const uint16_t reg, uint16_t x_value, uint16_t y_value)
  107. {
  108. if (write_reg16(slv_addr, reg, x_value) || write_reg16(slv_addr, reg + 2, y_value)) {
  109. return -1;
  110. }
  111. return 0;
  112. }
  113. #define write_reg_bits(slv_addr, reg, mask, enable) set_reg_bits(slv_addr, reg, 0, mask, enable?mask:0)
  114. static int calc_sysclk(int xclk, bool pll_bypass, int pll_multiplier, int pll_sys_div, int pll_pre_div, bool pll_root_2x, int pll_seld5, bool pclk_manual, int pclk_div)
  115. {
  116. const int pll_pre_div2x_map[] = { 2, 3, 4, 6 };//values are multiplied by two to avoid floats
  117. const int pll_seld52x_map[] = { 2, 2, 4, 5 };
  118. if(!pll_sys_div) {
  119. pll_sys_div = 1;
  120. }
  121. int pll_pre_div2x = pll_pre_div2x_map[pll_pre_div];
  122. int pll_root_div = pll_root_2x?2:1;
  123. int pll_seld52x = pll_seld52x_map[pll_seld5];
  124. int VCO = (xclk / 1000) * pll_multiplier * pll_root_div * 2 / pll_pre_div2x;
  125. int PLLCLK = pll_bypass?(xclk):(VCO * 1000 * 2 / pll_sys_div / pll_seld52x);
  126. int PCLK = PLLCLK / 2 / ((pclk_manual && pclk_div)?pclk_div:1);
  127. int SYSCLK = PLLCLK / 4;
  128. ESP_LOGD(TAG, "Calculated VCO: %d Hz, PLLCLK: %d Hz, SYSCLK: %d Hz, PCLK: %d Hz", VCO*1000, PLLCLK, SYSCLK, PCLK);
  129. return SYSCLK;
  130. }
  131. static int set_pll(sensor_t *sensor, bool bypass, uint8_t multiplier, uint8_t sys_div, uint8_t pre_div, bool root_2x, uint8_t seld5, bool pclk_manual, uint8_t pclk_div){
  132. int ret = 0;
  133. if(multiplier > 31 || sys_div > 15 || pre_div > 3 || pclk_div > 31 || seld5 > 3){
  134. ESP_LOGE(TAG, "Invalid arguments");
  135. return -1;
  136. }
  137. calc_sysclk(sensor->xclk_freq_hz, bypass, multiplier, sys_div, pre_div, root_2x, seld5, pclk_manual, pclk_div);
  138. ret = write_reg(sensor->slv_addr, SC_PLLS_CTRL0, bypass?0x80:0x00);
  139. if (ret == 0) {
  140. ret = write_reg(sensor->slv_addr, SC_PLLS_CTRL1, multiplier & 0x1f);
  141. }
  142. if (ret == 0) {
  143. ret = write_reg(sensor->slv_addr, SC_PLLS_CTRL2, 0x10 | (sys_div & 0x0f));
  144. }
  145. if (ret == 0) {
  146. ret = write_reg(sensor->slv_addr, SC_PLLS_CTRL3, (pre_div & 0x3) << 4 | seld5 | (root_2x?0x40:0x00));
  147. }
  148. if (ret == 0) {
  149. ret = write_reg(sensor->slv_addr, PCLK_RATIO, pclk_div & 0x1f);
  150. }
  151. if (ret == 0) {
  152. ret = write_reg(sensor->slv_addr, VFIFO_CTRL0C, pclk_manual?0x22:0x20);
  153. }
  154. if(ret){
  155. ESP_LOGE(TAG, "set_sensor_pll FAILED!");
  156. }
  157. return ret;
  158. }
  159. static int set_ae_level(sensor_t *sensor, int level);
  160. static int reset(sensor_t *sensor)
  161. {
  162. int ret = 0;
  163. // Software Reset: clear all registers and reset them to their default values
  164. ret = write_reg(sensor->slv_addr, SYSTEM_CTROL0, 0x82);
  165. if(ret){
  166. ESP_LOGE(TAG, "Software Reset FAILED!");
  167. return ret;
  168. }
  169. vTaskDelay(100 / portTICK_PERIOD_MS);
  170. ret = write_regs(sensor->slv_addr, sensor_default_regs);
  171. if (ret == 0) {
  172. ESP_LOGD(TAG, "Camera defaults loaded");
  173. ret = set_ae_level(sensor, 0);
  174. vTaskDelay(100 / portTICK_PERIOD_MS);
  175. }
  176. return ret;
  177. }
  178. static int set_pixformat(sensor_t *sensor, pixformat_t pixformat)
  179. {
  180. int ret = 0;
  181. const uint16_t (*regs)[2];
  182. switch (pixformat) {
  183. case PIXFORMAT_YUV422:
  184. regs = sensor_fmt_yuv422;
  185. break;
  186. case PIXFORMAT_GRAYSCALE:
  187. regs = sensor_fmt_grayscale;
  188. break;
  189. case PIXFORMAT_RGB565:
  190. case PIXFORMAT_RGB888:
  191. regs = sensor_fmt_rgb565;
  192. break;
  193. case PIXFORMAT_JPEG:
  194. regs = sensor_fmt_jpeg;
  195. break;
  196. case PIXFORMAT_RAW:
  197. regs = sensor_fmt_raw;
  198. break;
  199. default:
  200. ESP_LOGE(TAG, "Unsupported pixformat: %u", pixformat);
  201. return -1;
  202. }
  203. ret = write_regs(sensor->slv_addr, regs);
  204. if(ret == 0) {
  205. sensor->pixformat = pixformat;
  206. ESP_LOGD(TAG, "Set pixformat to: %u", pixformat);
  207. }
  208. return ret;
  209. }
  210. static int set_image_options(sensor_t *sensor)
  211. {
  212. int ret = 0;
  213. uint8_t reg20 = 0;
  214. uint8_t reg21 = 0;
  215. uint8_t reg4514 = 0;
  216. uint8_t reg4514_test = 0;
  217. // compression
  218. if (sensor->pixformat == PIXFORMAT_JPEG) {
  219. reg21 |= 0x20;
  220. }
  221. // binning
  222. if (sensor->status.binning) {
  223. reg20 |= 0x01;
  224. reg21 |= 0x01;
  225. reg4514_test |= 4;
  226. } else {
  227. reg20 |= 0x40;
  228. }
  229. // V-Flip
  230. if (sensor->status.vflip) {
  231. reg20 |= 0x06;
  232. reg4514_test |= 1;
  233. }
  234. // H-Mirror
  235. if (sensor->status.hmirror) {
  236. reg21 |= 0x06;
  237. reg4514_test |= 2;
  238. }
  239. switch (reg4514_test) {
  240. //no binning
  241. case 0: reg4514 = 0x88; break;//normal
  242. case 1: reg4514 = 0x88; break;//v-flip
  243. case 2: reg4514 = 0xbb; break;//h-mirror
  244. case 3: reg4514 = 0xbb; break;//v-flip+h-mirror
  245. //binning
  246. case 4: reg4514 = 0xaa; break;//normal
  247. case 5: reg4514 = 0xbb; break;//v-flip
  248. case 6: reg4514 = 0xbb; break;//h-mirror
  249. case 7: reg4514 = 0xaa; break;//v-flip+h-mirror
  250. }
  251. if(write_reg(sensor->slv_addr, TIMING_TC_REG20, reg20)
  252. || write_reg(sensor->slv_addr, TIMING_TC_REG21, reg21)
  253. || write_reg(sensor->slv_addr, 0x4514, reg4514)){
  254. ESP_LOGE(TAG, "Setting Image Options Failed");
  255. ret = -1;
  256. }
  257. if (sensor->status.binning) {
  258. ret = write_reg(sensor->slv_addr, 0x4520, 0x0b)
  259. || write_reg(sensor->slv_addr, X_INCREMENT, 0x31)//odd:3, even: 1
  260. || write_reg(sensor->slv_addr, Y_INCREMENT, 0x31);//odd:3, even: 1
  261. } else {
  262. ret = write_reg(sensor->slv_addr, 0x4520, 0xb0)
  263. || write_reg(sensor->slv_addr, X_INCREMENT, 0x11)//odd:1, even: 1
  264. || write_reg(sensor->slv_addr, Y_INCREMENT, 0x11);//odd:1, even: 1
  265. }
  266. ESP_LOGD(TAG, "Set Image Options: Compression: %u, Binning: %u, V-Flip: %u, H-Mirror: %u, Reg-4514: 0x%02x",
  267. sensor->pixformat == PIXFORMAT_JPEG, sensor->status.binning, sensor->status.vflip, sensor->status.hmirror, reg4514);
  268. return ret;
  269. }
  270. static int set_framesize(sensor_t *sensor, framesize_t framesize)
  271. {
  272. int ret = 0;
  273. framesize_t old_framesize = sensor->status.framesize;
  274. sensor->status.framesize = framesize;
  275. if(framesize > FRAMESIZE_QXGA){
  276. ESP_LOGE(TAG, "Invalid framesize: %u", framesize);
  277. return -1;
  278. }
  279. uint16_t w = resolution[framesize].width;
  280. uint16_t h = resolution[framesize].height;
  281. aspect_ratio_t ratio = resolution[sensor->status.framesize].aspect_ratio;
  282. ratio_settings_t settings = ratio_table[ratio];
  283. sensor->status.binning = (w <= (settings.max_width / 2) && h <= (settings.max_height / 2));
  284. sensor->status.scale = !((w == settings.max_width && h == settings.max_height)
  285. || (w == (settings.max_width / 2) && h == (settings.max_height / 2)));
  286. ret = write_addr_reg(sensor->slv_addr, X_ADDR_ST_H, settings.start_x, settings.start_y)
  287. || write_addr_reg(sensor->slv_addr, X_ADDR_END_H, settings.end_x, settings.end_y)
  288. || write_addr_reg(sensor->slv_addr, X_OUTPUT_SIZE_H, w, h);
  289. if (ret) {
  290. goto fail;
  291. }
  292. if (sensor->status.binning) {
  293. ret = write_addr_reg(sensor->slv_addr, X_TOTAL_SIZE_H, settings.total_x, (settings.total_y / 2) + 1)
  294. || write_addr_reg(sensor->slv_addr, X_OFFSET_H, 8, 2);
  295. } else {
  296. ret = write_addr_reg(sensor->slv_addr, X_TOTAL_SIZE_H, settings.total_x, settings.total_y)
  297. || write_addr_reg(sensor->slv_addr, X_OFFSET_H, 16, 6);
  298. }
  299. if (ret == 0) {
  300. ret = write_reg_bits(sensor->slv_addr, ISP_CONTROL_01, 0x20, sensor->status.scale);
  301. }
  302. if (ret == 0) {
  303. ret = set_image_options(sensor);
  304. }
  305. if (ret) {
  306. goto fail;
  307. }
  308. if (sensor->pixformat == PIXFORMAT_JPEG) {
  309. if (framesize == FRAMESIZE_QXGA) {
  310. //40MHz SYSCLK and 10MHz PCLK
  311. ret = set_pll(sensor, false, 24, 1, 3, false, 0, true, 8);
  312. } else {
  313. //50MHz SYSCLK and 10MHz PCLK
  314. ret = set_pll(sensor, false, 30, 1, 3, false, 0, true, 10);
  315. }
  316. } else {
  317. if (framesize > FRAMESIZE_CIF) {
  318. //10MHz SYSCLK and 10MHz PCLK (6.19 FPS)
  319. ret = set_pll(sensor, false, 2, 1, 0, false, 0, true, 2);
  320. } else {
  321. //25MHz SYSCLK and 10MHz PCLK (15.45 FPS)
  322. ret = set_pll(sensor, false, 5, 1, 0, false, 0, true, 5);
  323. }
  324. }
  325. if (ret == 0) {
  326. ESP_LOGD(TAG, "Set framesize to: %ux%u", w, h);
  327. }
  328. return ret;
  329. fail:
  330. sensor->status.framesize = old_framesize;
  331. ESP_LOGE(TAG, "Setting framesize to: %ux%u failed", w, h);
  332. return ret;
  333. }
  334. static int set_hmirror(sensor_t *sensor, int enable)
  335. {
  336. int ret = 0;
  337. sensor->status.hmirror = enable;
  338. ret = set_image_options(sensor);
  339. if (ret == 0) {
  340. ESP_LOGD(TAG, "Set h-mirror to: %d", enable);
  341. }
  342. return ret;
  343. }
  344. static int set_vflip(sensor_t *sensor, int enable)
  345. {
  346. int ret = 0;
  347. sensor->status.vflip = enable;
  348. ret = set_image_options(sensor);
  349. if (ret == 0) {
  350. ESP_LOGD(TAG, "Set v-flip to: %d", enable);
  351. }
  352. return ret;
  353. }
  354. static int set_quality(sensor_t *sensor, int qs)
  355. {
  356. int ret = 0;
  357. ret = write_reg(sensor->slv_addr, COMPRESSION_CTRL07, qs & 0x3f);
  358. if (ret == 0) {
  359. sensor->status.quality = qs;
  360. ESP_LOGD(TAG, "Set quality to: %d", qs);
  361. }
  362. return ret;
  363. }
  364. static int set_colorbar(sensor_t *sensor, int enable)
  365. {
  366. int ret = 0;
  367. ret = write_reg_bits(sensor->slv_addr, PRE_ISP_TEST_SETTING_1, TEST_COLOR_BAR, enable);
  368. if (ret == 0) {
  369. sensor->status.colorbar = enable;
  370. ESP_LOGD(TAG, "Set colorbar to: %d", enable);
  371. }
  372. return ret;
  373. }
  374. static int set_gain_ctrl(sensor_t *sensor, int enable)
  375. {
  376. int ret = 0;
  377. ret = write_reg_bits(sensor->slv_addr, AEC_PK_MANUAL, AEC_PK_MANUAL_AGC_MANUALEN, !enable);
  378. if (ret == 0) {
  379. ESP_LOGD(TAG, "Set gain_ctrl to: %d", enable);
  380. sensor->status.agc = enable;
  381. }
  382. return ret;
  383. }
  384. static int set_exposure_ctrl(sensor_t *sensor, int enable)
  385. {
  386. int ret = 0;
  387. ret = write_reg_bits(sensor->slv_addr, AEC_PK_MANUAL, AEC_PK_MANUAL_AEC_MANUALEN, !enable);
  388. if (ret == 0) {
  389. ESP_LOGD(TAG, "Set exposure_ctrl to: %d", enable);
  390. sensor->status.aec = enable;
  391. }
  392. return ret;
  393. }
  394. static int set_whitebal(sensor_t *sensor, int enable)
  395. {
  396. int ret = 0;
  397. ret = write_reg_bits(sensor->slv_addr, ISP_CONTROL_01, 0x01, enable);
  398. if (ret == 0) {
  399. ESP_LOGD(TAG, "Set awb to: %d", enable);
  400. sensor->status.awb = enable;
  401. }
  402. return ret;
  403. }
  404. //Advanced AWB
  405. static int set_dcw_dsp(sensor_t *sensor, int enable)
  406. {
  407. int ret = 0;
  408. ret = write_reg_bits(sensor->slv_addr, 0x5183, 0x80, !enable);
  409. if (ret == 0) {
  410. ESP_LOGD(TAG, "Set dcw to: %d", enable);
  411. sensor->status.dcw = enable;
  412. }
  413. return ret;
  414. }
  415. //night mode enable
  416. static int set_aec2(sensor_t *sensor, int enable)
  417. {
  418. int ret = 0;
  419. ret = write_reg_bits(sensor->slv_addr, 0x3a00, 0x04, enable);
  420. if (ret == 0) {
  421. ESP_LOGD(TAG, "Set aec2 to: %d", enable);
  422. sensor->status.aec2 = enable;
  423. }
  424. return ret;
  425. }
  426. static int set_bpc_dsp(sensor_t *sensor, int enable)
  427. {
  428. int ret = 0;
  429. ret = write_reg_bits(sensor->slv_addr, 0x5000, 0x04, enable);
  430. if (ret == 0) {
  431. ESP_LOGD(TAG, "Set bpc to: %d", enable);
  432. sensor->status.bpc = enable;
  433. }
  434. return ret;
  435. }
  436. static int set_wpc_dsp(sensor_t *sensor, int enable)
  437. {
  438. int ret = 0;
  439. ret = write_reg_bits(sensor->slv_addr, 0x5000, 0x02, enable);
  440. if (ret == 0) {
  441. ESP_LOGD(TAG, "Set wpc to: %d", enable);
  442. sensor->status.wpc = enable;
  443. }
  444. return ret;
  445. }
  446. //Gamma enable
  447. static int set_raw_gma_dsp(sensor_t *sensor, int enable)
  448. {
  449. int ret = 0;
  450. ret = write_reg_bits(sensor->slv_addr, 0x5000, 0x20, enable);
  451. if (ret == 0) {
  452. ESP_LOGD(TAG, "Set raw_gma to: %d", enable);
  453. sensor->status.raw_gma = enable;
  454. }
  455. return ret;
  456. }
  457. static int set_lenc_dsp(sensor_t *sensor, int enable)
  458. {
  459. int ret = 0;
  460. ret = write_reg_bits(sensor->slv_addr, 0x5000, 0x80, enable);
  461. if (ret == 0) {
  462. ESP_LOGD(TAG, "Set lenc to: %d", enable);
  463. sensor->status.lenc = enable;
  464. }
  465. return ret;
  466. }
  467. static int get_agc_gain(sensor_t *sensor)
  468. {
  469. int ra = read_reg(sensor->slv_addr, 0x350a);
  470. if (ra < 0) {
  471. return 0;
  472. }
  473. int rb = read_reg(sensor->slv_addr, 0x350b);
  474. if (rb < 0) {
  475. return 0;
  476. }
  477. int res = (rb & 0xF0) >> 4 | (ra & 0x03) << 4;
  478. if (rb & 0x0F) {
  479. res += 1;
  480. }
  481. return res;
  482. }
  483. //real gain
  484. static int set_agc_gain(sensor_t *sensor, int gain)
  485. {
  486. int ret = 0;
  487. if(gain < 0) {
  488. gain = 0;
  489. } else if(gain > 64) {
  490. gain = 64;
  491. }
  492. //gain value is 6.4 bits float
  493. //in order to use the max range, we deduct 1/16
  494. int gainv = gain << 4;
  495. if(gainv){
  496. gainv -= 1;
  497. }
  498. ret = write_reg(sensor->slv_addr, 0x350a, gainv >> 8) || write_reg(sensor->slv_addr, 0x350b, gainv & 0xff);
  499. if (ret == 0) {
  500. ESP_LOGD(TAG, "Set agc_gain to: %d", gain);
  501. sensor->status.agc_gain = gain;
  502. }
  503. return ret;
  504. }
  505. static int get_aec_value(sensor_t *sensor)
  506. {
  507. int ra = read_reg(sensor->slv_addr, 0x3500);
  508. if (ra < 0) {
  509. return 0;
  510. }
  511. int rb = read_reg(sensor->slv_addr, 0x3501);
  512. if (rb < 0) {
  513. return 0;
  514. }
  515. int rc = read_reg(sensor->slv_addr, 0x3502);
  516. if (rc < 0) {
  517. return 0;
  518. }
  519. int res = (ra & 0x0F) << 12 | (rb & 0xFF) << 4 | (rc & 0xF0) >> 4;
  520. return res;
  521. }
  522. static int set_aec_value(sensor_t *sensor, int value)
  523. {
  524. int ret = 0, max_val = 0;
  525. max_val = read_reg16(sensor->slv_addr, 0x380e);
  526. if (max_val < 0) {
  527. ESP_LOGE(TAG, "Could not read max aec_value");
  528. return -1;
  529. }
  530. if (value > max_val) {
  531. value =max_val;
  532. }
  533. ret = write_reg(sensor->slv_addr, 0x3500, (value >> 12) & 0x0F)
  534. || write_reg(sensor->slv_addr, 0x3501, (value >> 4) & 0xFF)
  535. || write_reg(sensor->slv_addr, 0x3502, (value << 4) & 0xF0);
  536. if (ret == 0) {
  537. ESP_LOGD(TAG, "Set aec_value to: %d / %d", value, max_val);
  538. sensor->status.aec_value = value;
  539. }
  540. return ret;
  541. }
  542. static int set_ae_level(sensor_t *sensor, int level)
  543. {
  544. int ret = 0;
  545. if (level < -5 || level > 5) {
  546. return -1;
  547. }
  548. //good targets are between 5 and 115
  549. int target_level = ((level + 5) * 10) + 5;
  550. int level_high, level_low;
  551. int fast_high, fast_low;
  552. level_low = target_level * 23 / 25; //0.92 (0.46)
  553. level_high = target_level * 27 / 25; //1.08 (2.08)
  554. fast_low = level_low >> 1;
  555. fast_high = level_high << 1;
  556. if(fast_high>255) {
  557. fast_high = 255;
  558. }
  559. ret = write_reg(sensor->slv_addr, 0x3a0f, level_high)
  560. || write_reg(sensor->slv_addr, 0x3a10, level_low)
  561. || write_reg(sensor->slv_addr, 0x3a1b, level_high)
  562. || write_reg(sensor->slv_addr, 0x3a1e, level_low)
  563. || write_reg(sensor->slv_addr, 0x3a11, fast_high)
  564. || write_reg(sensor->slv_addr, 0x3a1f, fast_low);
  565. if (ret == 0) {
  566. ESP_LOGD(TAG, "Set ae_level to: %d", level);
  567. sensor->status.ae_level = level;
  568. }
  569. return ret;
  570. }
  571. static int set_wb_mode(sensor_t *sensor, int mode)
  572. {
  573. int ret = 0;
  574. if (mode < 0 || mode > 4) {
  575. return -1;
  576. }
  577. ret = write_reg(sensor->slv_addr, 0x3406, (mode != 0));
  578. if (ret) {
  579. return ret;
  580. }
  581. switch (mode) {
  582. case 1://Sunny
  583. ret = write_reg16(sensor->slv_addr, 0x3400, 0x5e0) //AWB R GAIN
  584. || write_reg16(sensor->slv_addr, 0x3402, 0x410) //AWB G GAIN
  585. || write_reg16(sensor->slv_addr, 0x3404, 0x540);//AWB B GAIN
  586. break;
  587. case 2://Cloudy
  588. ret = write_reg16(sensor->slv_addr, 0x3400, 0x650) //AWB R GAIN
  589. || write_reg16(sensor->slv_addr, 0x3402, 0x410) //AWB G GAIN
  590. || write_reg16(sensor->slv_addr, 0x3404, 0x4f0);//AWB B GAIN
  591. break;
  592. case 3://Office
  593. ret = write_reg16(sensor->slv_addr, 0x3400, 0x520) //AWB R GAIN
  594. || write_reg16(sensor->slv_addr, 0x3402, 0x410) //AWB G GAIN
  595. || write_reg16(sensor->slv_addr, 0x3404, 0x660);//AWB B GAIN
  596. break;
  597. case 4://HOME
  598. ret = write_reg16(sensor->slv_addr, 0x3400, 0x420) //AWB R GAIN
  599. || write_reg16(sensor->slv_addr, 0x3402, 0x3f0) //AWB G GAIN
  600. || write_reg16(sensor->slv_addr, 0x3404, 0x710);//AWB B GAIN
  601. break;
  602. default://AUTO
  603. break;
  604. }
  605. if (ret == 0) {
  606. ESP_LOGD(TAG, "Set wb_mode to: %d", mode);
  607. sensor->status.wb_mode = mode;
  608. }
  609. return ret;
  610. }
  611. static int set_awb_gain_dsp(sensor_t *sensor, int enable)
  612. {
  613. int ret = 0;
  614. int old_mode = sensor->status.wb_mode;
  615. int mode = enable?old_mode:0;
  616. ret = set_wb_mode(sensor, mode);
  617. if (ret == 0) {
  618. sensor->status.wb_mode = old_mode;
  619. ESP_LOGD(TAG, "Set awb_gain to: %d", enable);
  620. sensor->status.awb_gain = enable;
  621. }
  622. return ret;
  623. }
  624. static int set_special_effect(sensor_t *sensor, int effect)
  625. {
  626. int ret=0;
  627. if (effect < 0 || effect > 6) {
  628. return -1;
  629. }
  630. uint8_t * regs = (uint8_t *)sensor_special_effects[effect];
  631. ret = write_reg(sensor->slv_addr, 0x5580, regs[0])
  632. || write_reg(sensor->slv_addr, 0x5583, regs[1])
  633. || write_reg(sensor->slv_addr, 0x5584, regs[2])
  634. || write_reg(sensor->slv_addr, 0x5003, regs[3]);
  635. if (ret == 0) {
  636. ESP_LOGD(TAG, "Set special_effect to: %d", effect);
  637. sensor->status.special_effect = effect;
  638. }
  639. return ret;
  640. }
  641. static int set_brightness(sensor_t *sensor, int level)
  642. {
  643. int ret = 0;
  644. uint8_t value = 0;
  645. bool negative = false;
  646. switch (level) {
  647. case 3:
  648. value = 0x30;
  649. break;
  650. case 2:
  651. value = 0x20;
  652. break;
  653. case 1:
  654. value = 0x10;
  655. break;
  656. case -1:
  657. value = 0x10;
  658. negative = true;
  659. break;
  660. case -2:
  661. value = 0x20;
  662. negative = true;
  663. break;
  664. case -3:
  665. value = 0x30;
  666. negative = true;
  667. break;
  668. default: // 0
  669. break;
  670. }
  671. ret = write_reg(sensor->slv_addr, 0x5587, value);
  672. if (ret == 0) {
  673. ret = write_reg_bits(sensor->slv_addr, 0x5588, 0x08, negative);
  674. }
  675. if (ret == 0) {
  676. ESP_LOGD(TAG, "Set brightness to: %d", level);
  677. sensor->status.brightness = level;
  678. }
  679. return ret;
  680. }
  681. static int set_contrast(sensor_t *sensor, int level)
  682. {
  683. int ret = 0;
  684. if(level > 3 || level < -3) {
  685. return -1;
  686. }
  687. ret = write_reg(sensor->slv_addr, 0x5586, (level + 4) << 3);
  688. if (ret == 0) {
  689. ESP_LOGD(TAG, "Set contrast to: %d", level);
  690. sensor->status.contrast = level;
  691. }
  692. return ret;
  693. }
  694. static int set_saturation(sensor_t *sensor, int level)
  695. {
  696. int ret = 0;
  697. if(level > 4 || level < -4) {
  698. return -1;
  699. }
  700. uint8_t * regs = (uint8_t *)sensor_saturation_levels[level+4];
  701. for(int i=0; i<11; i++) {
  702. ret = write_reg(sensor->slv_addr, 0x5381 + i, regs[i]);
  703. if (ret) {
  704. break;
  705. }
  706. }
  707. if (ret == 0) {
  708. ESP_LOGD(TAG, "Set saturation to: %d", level);
  709. sensor->status.saturation = level;
  710. }
  711. return ret;
  712. }
  713. static int set_sharpness(sensor_t *sensor, int level)
  714. {
  715. int ret = 0;
  716. if(level > 3 || level < -3) {
  717. return -1;
  718. }
  719. uint8_t mt_offset_2 = (level + 3) * 8;
  720. uint8_t mt_offset_1 = mt_offset_2 + 1;
  721. ret = write_reg_bits(sensor->slv_addr, 0x5308, 0x40, false)//0x40 means auto
  722. || write_reg(sensor->slv_addr, 0x5300, 0x10)
  723. || write_reg(sensor->slv_addr, 0x5301, 0x10)
  724. || write_reg(sensor->slv_addr, 0x5302, mt_offset_1)
  725. || write_reg(sensor->slv_addr, 0x5303, mt_offset_2)
  726. || write_reg(sensor->slv_addr, 0x5309, 0x10)
  727. || write_reg(sensor->slv_addr, 0x530a, 0x10)
  728. || write_reg(sensor->slv_addr, 0x530b, 0x04)
  729. || write_reg(sensor->slv_addr, 0x530c, 0x06);
  730. if (ret == 0) {
  731. ESP_LOGD(TAG, "Set sharpness to: %d", level);
  732. sensor->status.sharpness = level;
  733. }
  734. return ret;
  735. }
  736. static int set_gainceiling(sensor_t *sensor, gainceiling_t level)
  737. {
  738. int ret = 0, l = (int)level;
  739. ret = write_reg(sensor->slv_addr, 0x3A18, (l >> 8) & 3)
  740. || write_reg(sensor->slv_addr, 0x3A19, l & 0xFF);
  741. if (ret == 0) {
  742. ESP_LOGD(TAG, "Set gainceiling to: %d", l);
  743. sensor->status.gainceiling = l;
  744. }
  745. return ret;
  746. }
  747. static int get_denoise(sensor_t *sensor)
  748. {
  749. if (!check_reg_mask(sensor->slv_addr, 0x5308, 0x10)) {
  750. return 0;
  751. }
  752. return (read_reg(sensor->slv_addr, 0x5306) / 4) + 1;
  753. }
  754. static int set_denoise(sensor_t *sensor, int level)
  755. {
  756. int ret = 0;
  757. if (level < 0 || level > 8) {
  758. return -1;
  759. }
  760. ret = write_reg_bits(sensor->slv_addr, 0x5308, 0x10, level > 0);
  761. if (ret == 0 && level > 0) {
  762. ret = write_reg(sensor->slv_addr, 0x5306, (level - 1) * 4);
  763. }
  764. if (ret == 0) {
  765. ESP_LOGD(TAG, "Set denoise to: %d", level);
  766. sensor->status.denoise = level;
  767. }
  768. return ret;
  769. }
  770. static int get_reg(sensor_t *sensor, int reg, int mask)
  771. {
  772. int ret = 0, ret2 = 0;
  773. if(mask > 0xFF){
  774. ret = read_reg16(sensor->slv_addr, reg);
  775. if(ret >= 0 && mask > 0xFFFF){
  776. ret2 = read_reg(sensor->slv_addr, reg+2);
  777. if(ret2 >= 0){
  778. ret = (ret << 8) | ret2 ;
  779. } else {
  780. ret = ret2;
  781. }
  782. }
  783. } else {
  784. ret = read_reg(sensor->slv_addr, reg);
  785. }
  786. if(ret > 0){
  787. ret &= mask;
  788. }
  789. return ret;
  790. }
  791. static int set_reg(sensor_t *sensor, int reg, int mask, int value)
  792. {
  793. int ret = 0, ret2 = 0;
  794. if(mask > 0xFF){
  795. ret = read_reg16(sensor->slv_addr, reg);
  796. if(ret >= 0 && mask > 0xFFFF){
  797. ret2 = read_reg(sensor->slv_addr, reg+2);
  798. if(ret2 >= 0){
  799. ret = (ret << 8) | ret2 ;
  800. } else {
  801. ret = ret2;
  802. }
  803. }
  804. } else {
  805. ret = read_reg(sensor->slv_addr, reg);
  806. }
  807. if(ret < 0){
  808. return ret;
  809. }
  810. value = (ret & ~mask) | (value & mask);
  811. if(mask > 0xFFFF){
  812. ret = write_reg16(sensor->slv_addr, reg, value >> 8);
  813. if(ret >= 0){
  814. ret = write_reg(sensor->slv_addr, reg+2, value & 0xFF);
  815. }
  816. } else if(mask > 0xFF){
  817. ret = write_reg16(sensor->slv_addr, reg, value);
  818. } else {
  819. ret = write_reg(sensor->slv_addr, reg, value);
  820. }
  821. return ret;
  822. }
  823. static int set_res_raw(sensor_t *sensor, int startX, int startY, int endX, int endY, int offsetX, int offsetY, int totalX, int totalY, int outputX, int outputY, bool scale, bool binning)
  824. {
  825. int ret = 0;
  826. ret = write_addr_reg(sensor->slv_addr, X_ADDR_ST_H, startX, startY)
  827. || write_addr_reg(sensor->slv_addr, X_ADDR_END_H, endX, endY)
  828. || write_addr_reg(sensor->slv_addr, X_OFFSET_H, offsetX, offsetY)
  829. || write_addr_reg(sensor->slv_addr, X_TOTAL_SIZE_H, totalX, totalY)
  830. || write_addr_reg(sensor->slv_addr, X_OUTPUT_SIZE_H, outputX, outputY)
  831. || write_reg_bits(sensor->slv_addr, ISP_CONTROL_01, 0x20, scale);
  832. if(!ret){
  833. sensor->status.scale = scale;
  834. sensor->status.binning = binning;
  835. ret = set_image_options(sensor);
  836. }
  837. return ret;
  838. }
  839. static int _set_pll(sensor_t *sensor, int bypass, int multiplier, int sys_div, int root_2x, int pre_div, int seld5, int pclk_manual, int pclk_div)
  840. {
  841. return set_pll(sensor, bypass > 0, multiplier, sys_div, pre_div, root_2x > 0, seld5, pclk_manual > 0, pclk_div);
  842. }
  843. esp_err_t xclk_timer_conf(int ledc_timer, int xclk_freq_hz);
  844. static int set_xclk(sensor_t *sensor, int timer, int xclk)
  845. {
  846. int ret = 0;
  847. sensor->xclk_freq_hz = xclk * 1000000U;
  848. ret = xclk_timer_conf(timer, sensor->xclk_freq_hz);
  849. return ret;
  850. }
  851. static int init_status(sensor_t *sensor)
  852. {
  853. sensor->status.brightness = 0;
  854. sensor->status.contrast = 0;
  855. sensor->status.saturation = 0;
  856. sensor->status.sharpness = (read_reg(sensor->slv_addr, 0x5303) / 8) - 3;
  857. sensor->status.denoise = get_denoise(sensor);
  858. sensor->status.ae_level = 0;
  859. sensor->status.gainceiling = read_reg16(sensor->slv_addr, 0x3A18) & 0x3FF;
  860. sensor->status.awb = check_reg_mask(sensor->slv_addr, ISP_CONTROL_01, 0x01);
  861. sensor->status.dcw = !check_reg_mask(sensor->slv_addr, 0x5183, 0x80);
  862. sensor->status.agc = !check_reg_mask(sensor->slv_addr, AEC_PK_MANUAL, AEC_PK_MANUAL_AGC_MANUALEN);
  863. sensor->status.aec = !check_reg_mask(sensor->slv_addr, AEC_PK_MANUAL, AEC_PK_MANUAL_AEC_MANUALEN);
  864. sensor->status.hmirror = check_reg_mask(sensor->slv_addr, TIMING_TC_REG21, TIMING_TC_REG21_HMIRROR);
  865. sensor->status.vflip = check_reg_mask(sensor->slv_addr, TIMING_TC_REG20, TIMING_TC_REG20_VFLIP);
  866. sensor->status.colorbar = check_reg_mask(sensor->slv_addr, PRE_ISP_TEST_SETTING_1, TEST_COLOR_BAR);
  867. sensor->status.bpc = check_reg_mask(sensor->slv_addr, 0x5000, 0x04);
  868. sensor->status.wpc = check_reg_mask(sensor->slv_addr, 0x5000, 0x02);
  869. sensor->status.raw_gma = check_reg_mask(sensor->slv_addr, 0x5000, 0x20);
  870. sensor->status.lenc = check_reg_mask(sensor->slv_addr, 0x5000, 0x80);
  871. sensor->status.quality = read_reg(sensor->slv_addr, COMPRESSION_CTRL07) & 0x3f;
  872. sensor->status.special_effect = 0;
  873. sensor->status.wb_mode = 0;
  874. sensor->status.awb_gain = check_reg_mask(sensor->slv_addr, 0x3406, 0x01);
  875. sensor->status.agc_gain = get_agc_gain(sensor);
  876. sensor->status.aec_value = get_aec_value(sensor);
  877. sensor->status.aec2 = check_reg_mask(sensor->slv_addr, 0x3a00, 0x04);
  878. return 0;
  879. }
  880. int ov3660_init(sensor_t *sensor)
  881. {
  882. sensor->reset = reset;
  883. sensor->set_pixformat = set_pixformat;
  884. sensor->set_framesize = set_framesize;
  885. sensor->set_contrast = set_contrast;
  886. sensor->set_brightness = set_brightness;
  887. sensor->set_saturation = set_saturation;
  888. sensor->set_sharpness = set_sharpness;
  889. sensor->set_gainceiling = set_gainceiling;
  890. sensor->set_quality = set_quality;
  891. sensor->set_colorbar = set_colorbar;
  892. sensor->set_gain_ctrl = set_gain_ctrl;
  893. sensor->set_exposure_ctrl = set_exposure_ctrl;
  894. sensor->set_whitebal = set_whitebal;
  895. sensor->set_hmirror = set_hmirror;
  896. sensor->set_vflip = set_vflip;
  897. sensor->init_status = init_status;
  898. sensor->set_aec2 = set_aec2;
  899. sensor->set_aec_value = set_aec_value;
  900. sensor->set_special_effect = set_special_effect;
  901. sensor->set_wb_mode = set_wb_mode;
  902. sensor->set_ae_level = set_ae_level;
  903. sensor->set_dcw = set_dcw_dsp;
  904. sensor->set_bpc = set_bpc_dsp;
  905. sensor->set_wpc = set_wpc_dsp;
  906. sensor->set_awb_gain = set_awb_gain_dsp;
  907. sensor->set_agc_gain = set_agc_gain;
  908. sensor->set_raw_gma = set_raw_gma_dsp;
  909. sensor->set_lenc = set_lenc_dsp;
  910. sensor->set_denoise = set_denoise;
  911. sensor->get_reg = get_reg;
  912. sensor->set_reg = set_reg;
  913. sensor->set_res_raw = set_res_raw;
  914. sensor->set_pll = _set_pll;
  915. sensor->set_xclk = set_xclk;
  916. return 0;
  917. }