bf3005.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541
  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. * BF3005 driver.
  7. *
  8. * Copyright 2015-2021 Espressif Systems (Shanghai) PTE LTD
  9. *
  10. * Licensed under the Apache License, Version 2.0 (the "License");
  11. * you may not use this file except in compliance with the License.
  12. * You may obtain a copy of the License at
  13. * http://www.apache.org/licenses/LICENSE-2.0
  14. *
  15. * Unless required by applicable law or agreed to in writing, software
  16. * distributed under the License is distributed on an "AS IS" BASIS,
  17. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  18. * See the License for the specific language governing permissions and
  19. * limitations under the License.
  20. *
  21. */
  22. #include <stdint.h>
  23. #include <stdlib.h>
  24. #include <string.h>
  25. #include <stdio.h>
  26. #include "sccb.h"
  27. #include "xclk.h"
  28. #include "bf3005.h"
  29. #include "bf3005_regs.h"
  30. #include "freertos/FreeRTOS.h"
  31. #include "freertos/task.h"
  32. #if defined(ARDUINO_ARCH_ESP32) && defined(CONFIG_ARDUHAL_ESP_LOG)
  33. #include "esp32-hal-log.h"
  34. #else
  35. #include "esp_log.h"
  36. static const char* TAG = "bf3005";
  37. #endif
  38. static const uint8_t default_regs[][2] = {
  39. {0x12, 0x40}, //soft reset
  40. {0xff, 0xff}, //delay
  41. {0xff, 0xff}, //delay
  42. {0xff, 0xff}, //delay
  43. {0xff, 0xff}, //delay
  44. {0x13, 0x10},
  45. {0x8c, 0x00},
  46. {0x8d, 0x64},
  47. {0x87, 0x10},
  48. {0x13, 0x17},
  49. {0x00, 0x20},
  50. {0x01, 0x1a},
  51. {0x02, 0x22},
  52. {0x09, 0x03},
  53. {0x0c, 0x80},
  54. {0x0d, 0x24},
  55. {0x0e, 0x21},
  56. {0x0f, 0x28},
  57. {0x11, 0x08},
  58. {0x15, 0x10}, // 0X10
  59. {0x16, 0x03},
  60. {0x1e, 0x30},
  61. {0x20, 0x8a},
  62. {0x21, 0x03},
  63. {0x23, 0x55},
  64. {0x24, 0x68},
  65. {0x25, 0x78},
  66. {0x2a, 0x00},
  67. {0x2b, 0x00},
  68. {0x2d, 0x4f},
  69. {0x2e, 0x98},
  70. {0x2f, 0x04},
  71. {0x30, 0xad},
  72. {0x31, 0x17},
  73. {0x32, 0x6e},
  74. {0x33, 0x20},
  75. {0x35, 0xa6},
  76. {0x3b, 0x00},
  77. {0x3e, 0x00},
  78. {0x3f, 0xA8},
  79. {0x40, 0x38},
  80. {0x41, 0x32},
  81. {0x42, 0x2b},
  82. {0x43, 0x26},
  83. {0x44, 0x1a},
  84. {0x45, 0x16},
  85. {0x46, 0x10},
  86. {0x47, 0x0f},
  87. {0x48, 0x0c},
  88. {0x49, 0x0a},
  89. {0x4b, 0x09},
  90. {0x4c, 0x08},
  91. {0x4d, 0x3c},
  92. {0x4e, 0x06},
  93. {0x4f, 0x05},
  94. {0x50, 0x03},
  95. {0x51, 0x25},
  96. {0x52, 0x88},
  97. {0x53, 0x03},
  98. {0x63, 0x20},
  99. {0x64, 0x02},
  100. {0x65, 0xa6},
  101. {0x66, 0xb6},
  102. {0x69, 0x00},
  103. {0x70, 0xFF},
  104. {0x71, 0xa6},
  105. {0x72, 0x2f},
  106. {0x73, 0x2f},
  107. {0x74, 0x2F},
  108. {0x75, 0x0e},
  109. {0x76, 0x1e},
  110. {0x77, 0x00},
  111. {0x78, 0x1e},
  112. {0x79, 0x8a},
  113. {0x7d, 0xe2},
  114. {0x80, 0x44},
  115. {0x81, 0x00},
  116. {0x82, 0x18},
  117. {0x83, 0x1b},
  118. {0x84, 0x24},
  119. {0x85, 0x2a},
  120. {0x86, 0x4f},
  121. {0x89, 0x82}, //0x82
  122. {0x8b, 0x02},
  123. {0x8e, 0x03},
  124. {0x8f, 0xFC},
  125. {0x9d, 0x4d},
  126. {0x9e, 0x41},
  127. {0xa1, 0x21},
  128. {0xa2, 0x12},
  129. {0xa3, 0x32},
  130. {0xa4, 0x05},
  131. {0xa5, 0x32},
  132. {0xa6, 0x04},
  133. {0xa7, 0x7f},
  134. {0xa8, 0x7f},
  135. {0xa9, 0x21},
  136. {0xaa, 0x21},
  137. {0xab, 0x21},
  138. {0xac, 0x0a},
  139. {0xad, 0xf0},
  140. {0xae, 0xff},
  141. {0xaf, 0x1d},
  142. {0xb0, 0x94},
  143. {0xb1, 0xc0},
  144. {0xb2, 0xc0},
  145. {0xd2, 0x30},
  146. {0xe0, 0x0d},
  147. {0xe1, 0x44},
  148. {0xe7, 0x7c},
  149. {0xe8, 0x89},
  150. {0xe9, 0x01},
  151. {0xea, 0x01},
  152. {0xf0, 0x01},
  153. {0xf3, 0x49},
  154. {0xf4, 0xff},
  155. {0xf5, 0x01},
  156. {0xf6, 0xf2},
  157. {0xf7, 0x6f},
  158. {0x1b, 0x80},
  159. {0x00, 0x00},
  160. };
  161. static int get_reg(sensor_t *sensor, int reg, int mask)
  162. {
  163. int ret = SCCB_Read(sensor->slv_addr, reg & 0xFF);
  164. if(ret > 0){
  165. ret &= mask;
  166. }
  167. return ret;
  168. }
  169. static int set_reg(sensor_t *sensor, int reg, int mask, int value)
  170. {
  171. int ret = 0;
  172. ret = SCCB_Read(sensor->slv_addr, reg & 0xFF);
  173. if(ret < 0){
  174. return ret;
  175. }
  176. value = (ret & ~mask) | (value & mask);
  177. ret = SCCB_Write(sensor->slv_addr, reg & 0xFF, value);
  178. return ret;
  179. }
  180. static int set_reg_bits(sensor_t *sensor, uint8_t reg, uint8_t offset, uint8_t length, uint8_t value)
  181. {
  182. int ret = 0;
  183. ret = SCCB_Read(sensor->slv_addr, reg);
  184. if(ret < 0){
  185. return ret;
  186. }
  187. uint8_t mask = ((1 << length) - 1) << offset;
  188. value = (ret & ~mask) | ((value << offset) & mask);
  189. ret = SCCB_Write(sensor->slv_addr, reg & 0xFF, value);
  190. return ret;
  191. }
  192. static int get_reg_bits(sensor_t *sensor, uint8_t reg, uint8_t offset, uint8_t length)
  193. {
  194. int ret = 0;
  195. ret = SCCB_Read(sensor->slv_addr, reg);
  196. if(ret < 0){
  197. return ret;
  198. }
  199. uint8_t mask = ((1 << length) - 1) << offset;
  200. return (ret & mask) >> offset;
  201. }
  202. static int reset(sensor_t *sensor)
  203. {
  204. int i=0;
  205. const uint8_t (*regs)[2];
  206. // Write default regsiters
  207. for (i=0, regs = default_regs; regs[i][0]; i++) {
  208. SCCB_Write(sensor->slv_addr, regs[i][0], regs[i][1]);
  209. }
  210. // Delay
  211. vTaskDelay(50 / portTICK_PERIOD_MS);
  212. return 0;
  213. }
  214. static int set_pixformat(sensor_t *sensor, pixformat_t pixformat)
  215. {
  216. int ret=0;
  217. sensor->pixformat = pixformat;
  218. switch (pixformat) {
  219. case PIXFORMAT_RGB565:
  220. set_reg_bits(sensor, 0x12, 2, 1, 1);
  221. break;
  222. case PIXFORMAT_RAW:
  223. set_reg_bits(sensor, 0x12, 0, 3, 0x4);
  224. break;
  225. case PIXFORMAT_YUV422:
  226. case PIXFORMAT_GRAYSCALE:
  227. set_reg_bits(sensor, 0x12, 2, 1, 0);
  228. break;
  229. default:
  230. return -1;
  231. }
  232. // Delay
  233. vTaskDelay(30 / portTICK_PERIOD_MS);
  234. return ret;
  235. }
  236. static int set_framesize(sensor_t *sensor, framesize_t framesize)
  237. {
  238. int ret=0;
  239. if (framesize > FRAMESIZE_VGA) {
  240. return -1;
  241. }
  242. uint16_t w = resolution[framesize].width;
  243. uint16_t h = resolution[framesize].height;
  244. // uint8_t reg = SCCB_Read(sensor->slv_addr, COM7);
  245. sensor->status.framesize = framesize;
  246. // Write MSBs
  247. ret |= SCCB_Write(sensor->slv_addr, 0x17, 0);
  248. ret |= SCCB_Write(sensor->slv_addr, 0x18, w>>2);
  249. ret |= SCCB_Write(sensor->slv_addr, 0x19, 0);
  250. ret |= SCCB_Write(sensor->slv_addr, 0x1a, h>>2);
  251. // Write LSBs
  252. ret |= SCCB_Write(sensor->slv_addr, 0x03, 0);
  253. printf("%s %d\r\n", __func__, __LINE__);
  254. if((w<=320)&&(h<=240))
  255. {
  256. printf("%s %d\r\n", __func__, __LINE__);
  257. // Enable auto-scaling/zooming factors
  258. //ret |= SCCB_Write(sensor->slv_addr, 0x12, 0x50);
  259. set_reg_bits(sensor, 0x12, 4, 1, 1);
  260. ret |= SCCB_Write(sensor->slv_addr, 0x17, (80-w/4));
  261. ret |= SCCB_Write(sensor->slv_addr, 0x18, (80+w/4));
  262. ret |= SCCB_Write(sensor->slv_addr, 0x19, (60-h/4));
  263. ret |= SCCB_Write(sensor->slv_addr, 0x1a, (60+h/4));
  264. ret |= SCCB_Write(sensor->slv_addr, 0x03, 0);
  265. } else if((w<=640)&&(h<=480))
  266. {
  267. // Enable auto-scaling/zooming factors
  268. //ret |= SCCB_Write(sensor->slv_addr, 0x12, 0x40);
  269. set_reg_bits(sensor, 0x12, 4, 1, 0);
  270. ret |= SCCB_Write(sensor->slv_addr, 0x17, (80-w/8));
  271. ret |= SCCB_Write(sensor->slv_addr, 0x18, (80+w/8));
  272. ret |= SCCB_Write(sensor->slv_addr, 0x19, (60-h/8));
  273. ret |= SCCB_Write(sensor->slv_addr, 0x1a, (60+h/8));
  274. ret |= SCCB_Write(sensor->slv_addr, 0x03, 0);
  275. }
  276. // Delay
  277. vTaskDelay(30 / portTICK_PERIOD_MS);
  278. return ret;
  279. }
  280. static int set_colorbar(sensor_t *sensor, int value)
  281. {
  282. int ret=0;
  283. sensor->status.colorbar = value;
  284. ret |= SCCB_Write(sensor->slv_addr, 0xb9, value);
  285. return ret;
  286. }
  287. static int set_whitebal(sensor_t *sensor, int enable)
  288. {
  289. if(set_reg_bits(sensor, 0x13, 1, 1, enable) >= 0){
  290. sensor->status.awb = !!enable;
  291. }
  292. return sensor->status.awb;
  293. }
  294. static int set_gain_ctrl(sensor_t *sensor, int enable)
  295. {
  296. if(set_reg_bits(sensor, 0x13, 2, 1, enable) >= 0){
  297. sensor->status.agc = !!enable;
  298. }
  299. return sensor->status.agc;
  300. }
  301. static int set_exposure_ctrl(sensor_t *sensor, int enable)
  302. {
  303. if(set_reg_bits(sensor, 0x13, 0, 1, enable) >= 0){
  304. sensor->status.aec = !!enable;
  305. }
  306. return sensor->status.aec;
  307. }
  308. static int set_hmirror(sensor_t *sensor, int enable)
  309. {
  310. if(set_reg_bits(sensor, 0x1e, 5, 1, enable) >= 0){
  311. sensor->status.hmirror = !!enable;
  312. }
  313. return sensor->status.hmirror;
  314. }
  315. static int set_vflip(sensor_t *sensor, int enable)
  316. {
  317. if(set_reg_bits(sensor, 0x1e, 4, 1, enable) >= 0){
  318. sensor->status.vflip = !!enable;
  319. }
  320. return sensor->status.vflip;
  321. }
  322. static int set_raw_gma_dsp(sensor_t *sensor, int enable)
  323. {
  324. int ret = 0;
  325. ret = set_reg_bits(sensor, 0xf1, 1, 1, !enable);
  326. if (ret == 0) {
  327. ESP_LOGD(TAG, "Set raw_gma to: %d", !enable);
  328. sensor->status.raw_gma = !enable;
  329. }
  330. return ret;
  331. }
  332. static int set_lenc_dsp(sensor_t *sensor, int enable)
  333. {
  334. int ret = 0;
  335. ret = set_reg_bits(sensor, 0xf1, 0, 1, !enable);
  336. if (ret == 0) {
  337. ESP_LOGD(TAG, "Set lenc to: %d", !enable);
  338. sensor->status.lenc = !enable;
  339. }
  340. return ret;
  341. }
  342. static int set_agc_gain(sensor_t *sensor, int option)
  343. {
  344. int ret = 0;
  345. ret = set_reg_bits(sensor, 0x13, 4, 1, !!option);
  346. if (ret == 0) {
  347. ESP_LOGD(TAG, "Set gain to: %d", !!option);
  348. sensor->status.agc_gain = !!option;
  349. }
  350. return ret;
  351. }
  352. static int set_awb_gain_dsp(sensor_t *sensor, int value)
  353. {
  354. int ret = 0;
  355. ret = SCCB_Write(sensor->slv_addr, 0xa6, value);
  356. if (ret == 0) {
  357. ESP_LOGD(TAG, "Set awb gain threthold to: %d", value);
  358. sensor->status.awb_gain = value;
  359. }
  360. return ret;
  361. }
  362. static int set_brightness(sensor_t *sensor, int level)
  363. {
  364. int ret = 0;
  365. ret = SCCB_Write(sensor->slv_addr, 0x55, level);
  366. if (ret == 0) {
  367. ESP_LOGD(TAG, "Set brightness to: %d", level);
  368. sensor->status.brightness = level;
  369. }
  370. return ret;
  371. }
  372. static int set_contrast(sensor_t *sensor, int level)
  373. {
  374. int ret = 0;
  375. ret = SCCB_Write(sensor->slv_addr, 0x56, level);
  376. if (ret == 0) {
  377. ESP_LOGD(TAG, "Set contrast to: %d", level);
  378. sensor->status.contrast = level;
  379. }
  380. return ret;
  381. }
  382. static int set_sharpness(sensor_t *sensor, int level)
  383. {
  384. int ret = 0;
  385. ret = SCCB_Write(sensor->slv_addr, 0x70, level);
  386. if (ret == 0) {
  387. ESP_LOGD(TAG, "Set sharpness to: %d", level);
  388. sensor->status.sharpness = level;
  389. }
  390. return ret;
  391. }
  392. static int init_status(sensor_t *sensor)
  393. {
  394. sensor->status.brightness = SCCB_Read(sensor->slv_addr, 0x55);
  395. sensor->status.contrast = SCCB_Read(sensor->slv_addr, 0x56);
  396. sensor->status.saturation = 0;
  397. sensor->status.ae_level = 0;
  398. sensor->status.gainceiling = SCCB_Read(sensor->slv_addr, 0x87);
  399. sensor->status.awb = get_reg_bits(sensor, 0x13, 1, 1);
  400. sensor->status.awb_gain = SCCB_Read(sensor->slv_addr, 0xa6);
  401. sensor->status.aec = get_reg_bits(sensor, 0x13, 0, 1);
  402. sensor->status.agc = get_reg_bits(sensor, 0x13, 2, 1);
  403. sensor->status.raw_gma = get_reg_bits(sensor, 0xf1, 1, 1);
  404. sensor->status.lenc = get_reg_bits(sensor, 0xf1, 0, 1);
  405. sensor->status.hmirror = get_reg_bits(sensor, 0x1e, 5, 1);
  406. sensor->status.vflip = get_reg_bits(sensor, 0x1e, 4, 1);
  407. sensor->status.colorbar = SCCB_Read(sensor->slv_addr, 0xb9);
  408. sensor->status.sharpness = SCCB_Read(sensor->slv_addr, 0x70);
  409. return 0;
  410. }
  411. static int set_dummy(sensor_t *sensor, int val){ return -1; }
  412. static int set_gainceiling_dummy(sensor_t *sensor, gainceiling_t val){ return -1; }
  413. 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){return -1;}
  414. 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){return -1;}
  415. static int set_xclk(sensor_t *sensor, int timer, int xclk)
  416. {
  417. int ret = 0;
  418. sensor->xclk_freq_hz = xclk * 1000000U;
  419. ret = xclk_timer_conf(timer, sensor->xclk_freq_hz);
  420. return ret;
  421. }
  422. int bf3005_detect(int slv_addr, sensor_id_t *id)
  423. {
  424. if (BF3005_SCCB_ADDR == slv_addr) {
  425. uint16_t PID = SCCB_Read(slv_addr, 0xFC);
  426. if (BF3005_PID == PID) {
  427. id->PID = PID;
  428. id->VER = SCCB_Read(slv_addr, 0xFD);
  429. id->MIDL = SCCB_Read(slv_addr, 0xFC);
  430. id->MIDH = SCCB_Read(slv_addr, 0xFD);
  431. return PID;
  432. } else {
  433. ESP_LOGI(TAG, "Mismatch PID=0x%x", PID);
  434. }
  435. }
  436. return 0;
  437. }
  438. int bf3005_init(sensor_t *sensor)
  439. {
  440. // Set function pointers
  441. sensor->reset = reset;
  442. sensor->init_status = init_status;
  443. sensor->set_pixformat = set_pixformat;
  444. sensor->set_framesize = set_framesize;
  445. sensor->set_brightness = set_brightness;
  446. sensor->set_contrast = set_contrast;
  447. sensor->set_colorbar = set_colorbar;
  448. sensor->set_gain_ctrl = set_gain_ctrl;
  449. sensor->set_exposure_ctrl = set_exposure_ctrl;
  450. sensor->set_hmirror = set_hmirror;
  451. sensor->set_vflip = set_vflip;
  452. sensor->set_whitebal = set_whitebal;
  453. sensor->set_awb_gain = set_awb_gain_dsp;
  454. sensor->set_agc_gain = set_agc_gain;
  455. sensor->set_raw_gma = set_raw_gma_dsp;
  456. sensor->set_lenc = set_lenc_dsp;
  457. sensor->set_sharpness = set_sharpness;
  458. //not supported
  459. sensor->set_saturation= set_dummy;
  460. sensor->set_denoise = set_dummy;
  461. sensor->set_quality = set_dummy;
  462. sensor->set_special_effect = set_dummy;
  463. sensor->set_wb_mode = set_dummy;
  464. sensor->set_ae_level = set_dummy;
  465. sensor->set_gainceiling = set_gainceiling_dummy;
  466. sensor->get_reg = get_reg;
  467. sensor->set_reg = set_reg;
  468. sensor->set_res_raw = set_res_raw;
  469. sensor->set_pll = _set_pll;
  470. sensor->set_xclk = set_xclk;
  471. ESP_LOGD(TAG, "BF3005 Attached");
  472. return 0;
  473. }