ov3660.c 30 KB

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