gc032a.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391
  1. // Copyright 2015-2021 Espressif Systems (Shanghai) PTE LTD
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. // http://www.apache.org/licenses/LICENSE-2.0
  7. //
  8. // Unless required by applicable law or agreed to in writing, software
  9. // distributed under the License is distributed on an "AS IS" BASIS,
  10. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. // See the License for the specific language governing permissions and
  12. // limitations under the License.
  13. #include <stdint.h>
  14. #include <stdlib.h>
  15. #include <string.h>
  16. #include <stdio.h>
  17. #include "freertos/FreeRTOS.h"
  18. #include "freertos/task.h"
  19. #include "sccb.h"
  20. #include "gc032a.h"
  21. #include "gc032a_regs.h"
  22. #include "gc032a_settings.h"
  23. #if defined(ARDUINO_ARCH_ESP32) && defined(CONFIG_ARDUHAL_ESP_LOG)
  24. #include "esp32-hal-log.h"
  25. #else
  26. #include "esp_log.h"
  27. static const char *TAG = "gc032a";
  28. #endif
  29. #define H8(v) ((v)>>8)
  30. #define L8(v) ((v)&0xff)
  31. //#define REG_DEBUG_ON
  32. static int read_reg(uint8_t slv_addr, const uint16_t reg)
  33. {
  34. int ret = SCCB_Read(slv_addr, reg);
  35. #ifdef REG_DEBUG_ON
  36. if (ret < 0) {
  37. ESP_LOGE(TAG, "READ REG 0x%04x FAILED: %d", reg, ret);
  38. }
  39. #endif
  40. return ret;
  41. }
  42. static int write_reg(uint8_t slv_addr, const uint16_t reg, uint8_t value)
  43. {
  44. int ret = 0;
  45. #ifndef REG_DEBUG_ON
  46. ret = SCCB_Write(slv_addr, reg, value);
  47. #else
  48. int old_value = read_reg(slv_addr, reg);
  49. if (old_value < 0) {
  50. return old_value;
  51. }
  52. if ((uint8_t)old_value != value) {
  53. ESP_LOGI(TAG, "NEW REG 0x%04x: 0x%02x to 0x%02x", reg, (uint8_t)old_value, value);
  54. ret = SCCB_Write(slv_addr, reg, value);
  55. } else {
  56. ESP_LOGD(TAG, "OLD REG 0x%04x: 0x%02x", reg, (uint8_t)old_value);
  57. ret = SCCB_Write(slv_addr, reg, value);//maybe not?
  58. }
  59. if (ret < 0) {
  60. ESP_LOGE(TAG, "WRITE REG 0x%04x FAILED: %d", reg, ret);
  61. }
  62. #endif
  63. return ret;
  64. }
  65. static int check_reg_mask(uint8_t slv_addr, uint16_t reg, uint8_t mask)
  66. {
  67. return (read_reg(slv_addr, reg) & mask) == mask;
  68. }
  69. static void print_regs(uint8_t slv_addr)
  70. {
  71. #ifdef DEBUG_PRINT_REG
  72. vTaskDelay(pdMS_TO_TICKS(100));
  73. ESP_LOGI(TAG, "REG list look ======================");
  74. for (size_t i = 0xf0; i <= 0xfe; i++) {
  75. ESP_LOGI(TAG, "reg[0x%02x] = 0x%02x", i, read_reg(slv_addr, i));
  76. }
  77. ESP_LOGI(TAG, "\npage 0 ===");
  78. write_reg(slv_addr, 0xfe, 0x00); // page 0
  79. for (size_t i = 0x03; i <= 0x24; i++) {
  80. ESP_LOGI(TAG, "p0 reg[0x%02x] = 0x%02x", i, read_reg(slv_addr, i));
  81. }
  82. for (size_t i = 0x40; i <= 0x95; i++) {
  83. ESP_LOGI(TAG, "p0 reg[0x%02x] = 0x%02x", i, read_reg(slv_addr, i));
  84. }
  85. ESP_LOGI(TAG, "\npage 3 ===");
  86. write_reg(slv_addr, 0xfe, 0x03); // page 3
  87. for (size_t i = 0x01; i <= 0x43; i++) {
  88. ESP_LOGI(TAG, "p3 reg[0x%02x] = 0x%02x", i, read_reg(slv_addr, i));
  89. }
  90. #endif
  91. }
  92. static int set_reg_bits(uint8_t slv_addr, uint16_t reg, uint8_t offset, uint8_t mask, uint8_t value)
  93. {
  94. int ret = 0;
  95. uint8_t c_value, new_value;
  96. ret = read_reg(slv_addr, reg);
  97. if (ret < 0) {
  98. return ret;
  99. }
  100. c_value = ret;
  101. new_value = (c_value & ~(mask << offset)) | ((value & mask) << offset);
  102. ret = write_reg(slv_addr, reg, new_value);
  103. return ret;
  104. }
  105. static int write_regs(uint8_t slv_addr, const uint16_t (*regs)[2])
  106. {
  107. int i = 0, ret = 0;
  108. while (!ret && regs[i][0] != REGLIST_TAIL) {
  109. if (regs[i][0] == REG_DLY) {
  110. vTaskDelay(regs[i][1] / portTICK_PERIOD_MS);
  111. } else {
  112. ret = write_reg(slv_addr, regs[i][0], regs[i][1]);
  113. }
  114. i++;
  115. }
  116. return ret;
  117. }
  118. static int reset(sensor_t *sensor)
  119. {
  120. int ret;
  121. // Software Reset: clear all registers and reset them to their default values
  122. ret = write_reg(sensor->slv_addr, RESET_RELATED, 0xf0);
  123. if (ret) {
  124. ESP_LOGE(TAG, "Software Reset FAILED!");
  125. return ret;
  126. }
  127. vTaskDelay(100 / portTICK_PERIOD_MS);
  128. ret = write_regs(sensor->slv_addr, gc032a_default_regs);
  129. if (ret == 0) {
  130. ESP_LOGD(TAG, "Camera defaults loaded");
  131. vTaskDelay(100 / portTICK_PERIOD_MS);
  132. write_reg(sensor->slv_addr, 0xfe, 0x00);
  133. set_reg_bits(sensor->slv_addr, 0xf7, 1, 0x01, 1); // PLL_mode1:div2en
  134. set_reg_bits(sensor->slv_addr, 0xf7, 7, 0x01, 1); // PLL_mode1:dvp mode
  135. set_reg_bits(sensor->slv_addr, 0xf8, 0, 0x3f, 8); //PLL_mode2 :divx4
  136. set_reg_bits(sensor->slv_addr, 0xfa, 4, 0x0f, 2); //vlk div mode :divide_by
  137. }
  138. return ret;
  139. }
  140. static int set_pixformat(sensor_t *sensor, pixformat_t pixformat)
  141. {
  142. int ret = 0;
  143. switch (pixformat) {
  144. case PIXFORMAT_RGB565:
  145. write_reg(sensor->slv_addr, 0xfe, 0x00);
  146. ret = set_reg_bits(sensor->slv_addr, 0x44, 0, 0x1f, 6); //RGB565
  147. break;
  148. case PIXFORMAT_YUV422:
  149. write_reg(sensor->slv_addr, 0xfe, 0x00);
  150. ret = set_reg_bits(sensor->slv_addr, 0x44, 0, 0x1f, 3);
  151. break;
  152. default:
  153. ESP_LOGW(TAG, "unsupport format");
  154. ret = -1;
  155. break;
  156. }
  157. if (ret == 0) {
  158. sensor->pixformat = pixformat;
  159. ESP_LOGD(TAG, "Set pixformat to: %u", pixformat);
  160. }
  161. return ret;
  162. }
  163. static int set_framesize(sensor_t *sensor, framesize_t framesize)
  164. {
  165. ESP_LOGI(TAG, "set_framesize");
  166. int ret = 0;
  167. if (framesize > FRAMESIZE_VGA) {
  168. ESP_LOGW(TAG, "Invalid framesize: %u", framesize);
  169. framesize = FRAMESIZE_VGA;
  170. }
  171. sensor->status.framesize = framesize;
  172. uint16_t w = resolution[framesize].width;
  173. uint16_t h = resolution[framesize].height;
  174. uint16_t row_s = (resolution[FRAMESIZE_VGA].height - h) / 2;
  175. uint16_t col_s = (resolution[FRAMESIZE_VGA].width - w) / 2;
  176. write_reg(sensor->slv_addr, 0xfe, 0x00);
  177. write_reg(sensor->slv_addr, P0_ROW_START_HIGH, H8(row_s)); // Row_start[8]
  178. write_reg(sensor->slv_addr, P0_ROW_START_LOW, L8(row_s)); // Row_start[7:0]
  179. write_reg(sensor->slv_addr, P0_COLUMN_START_HIGH, H8(col_s)); // Column_start[9:8]
  180. write_reg(sensor->slv_addr, P0_COLUMN_START_LOW, L8(col_s)); // Column_start[7:0]
  181. write_reg(sensor->slv_addr, P0_WINDOW_HEIGHT_HIGH, H8(h + 8)); //window_height [8]
  182. write_reg(sensor->slv_addr, P0_WINDOW_HEIGHT_LOW, L8(h + 8)); //window_height [7:0]
  183. write_reg(sensor->slv_addr, P0_WINDOW_WIDTH_HIGH, H8(w + 8)); //window_width [9:8]
  184. write_reg(sensor->slv_addr, P0_WINDOW_WIDTH_LOW, L8(w + 8)); //window_width [7:0]
  185. write_reg(sensor->slv_addr, P0_WIN_MODE, 0x01);
  186. write_reg(sensor->slv_addr, P0_OUT_WIN_HEIGHT_HIGH, H8(h));
  187. write_reg(sensor->slv_addr, P0_OUT_WIN_HEIGHT_LOW, L8(h));
  188. write_reg(sensor->slv_addr, P0_OUT_WIN_WIDTH_HIGH, H8(w));
  189. write_reg(sensor->slv_addr, P0_OUT_WIN_WIDTH_LOW, L8(w));
  190. if (ret == 0) {
  191. ESP_LOGD(TAG, "Set framesize to: %ux%u", w, h);
  192. }
  193. print_regs(sensor->slv_addr);
  194. return ret;
  195. }
  196. static int set_hmirror(sensor_t *sensor, int enable)
  197. {
  198. int ret = 0;
  199. sensor->status.hmirror = enable;
  200. ret = write_reg(sensor->slv_addr, 0xfe, 0x00);
  201. ret |= set_reg_bits(sensor->slv_addr, P0_CISCTL_MODE1, 0, 0x01, enable);
  202. if (ret == 0) {
  203. ESP_LOGD(TAG, "Set h-mirror to: %d", enable);
  204. }
  205. return ret;
  206. }
  207. static int set_vflip(sensor_t *sensor, int enable)
  208. {
  209. int ret = 0;
  210. sensor->status.vflip = enable;
  211. ret = write_reg(sensor->slv_addr, 0xfe, 0x00);
  212. ret |= set_reg_bits(sensor->slv_addr, P0_CISCTL_MODE1, 1, 0x01, enable);
  213. if (ret == 0) {
  214. ESP_LOGD(TAG, "Set v-flip to: %d", enable);
  215. }
  216. return ret;
  217. }
  218. static int set_colorbar(sensor_t *sensor, int enable)
  219. {
  220. int ret = 0;
  221. ret = write_reg(sensor->slv_addr, 0xfe, 0x00);
  222. ret |= set_reg_bits(sensor->slv_addr, P0_DEBUG_MODE2, 3, 0x01, enable);
  223. if (ret == 0) {
  224. sensor->status.colorbar = enable;
  225. ESP_LOGD(TAG, "Set colorbar to: %d", enable);
  226. }
  227. return ret;
  228. }
  229. static int get_reg(sensor_t *sensor, int reg, int mask)
  230. {
  231. int ret = 0;
  232. if (mask > 0xFF) {
  233. ESP_LOGE(TAG, "mask should not more than 0xff");
  234. } else {
  235. ret = read_reg(sensor->slv_addr, reg);
  236. }
  237. if (ret > 0) {
  238. ret &= mask;
  239. }
  240. return ret;
  241. }
  242. static int set_reg(sensor_t *sensor, int reg, int mask, int value)
  243. {
  244. int ret = 0;
  245. if (mask > 0xFF) {
  246. ESP_LOGE(TAG, "mask should not more than 0xff");
  247. } else {
  248. ret = read_reg(sensor->slv_addr, reg);
  249. }
  250. if (ret < 0) {
  251. return ret;
  252. }
  253. value = (ret & ~mask) | (value & mask);
  254. if (mask > 0xFF) {
  255. } else {
  256. ret = write_reg(sensor->slv_addr, reg, value);
  257. }
  258. return ret;
  259. }
  260. static int init_status(sensor_t *sensor)
  261. {
  262. write_reg(sensor->slv_addr, 0xfe, 0x00);
  263. sensor->status.brightness = 0;
  264. sensor->status.contrast = 0;
  265. sensor->status.saturation = 0;
  266. sensor->status.sharpness = 0;
  267. sensor->status.denoise = 0;
  268. sensor->status.ae_level = 0;
  269. sensor->status.gainceiling = 0;
  270. sensor->status.awb = 0;
  271. sensor->status.dcw = 0;
  272. sensor->status.agc = 0;
  273. sensor->status.aec = 0;
  274. sensor->status.hmirror = check_reg_mask(sensor->slv_addr, P0_CISCTL_MODE1, 0x01);
  275. sensor->status.vflip = check_reg_mask(sensor->slv_addr, P0_CISCTL_MODE1, 0x02);
  276. sensor->status.colorbar = 0;
  277. sensor->status.bpc = 0;
  278. sensor->status.wpc = 0;
  279. sensor->status.raw_gma = 0;
  280. sensor->status.lenc = 0;
  281. sensor->status.quality = 0;
  282. sensor->status.special_effect = 0;
  283. sensor->status.wb_mode = 0;
  284. sensor->status.awb_gain = 0;
  285. sensor->status.agc_gain = 0;
  286. sensor->status.aec_value = 0;
  287. sensor->status.aec2 = 0;
  288. return 0;
  289. }
  290. static int set_dummy(sensor_t *sensor, int val)
  291. {
  292. ESP_LOGW(TAG, "Unsupported");
  293. return -1;
  294. }
  295. static int set_gainceiling_dummy(sensor_t *sensor, gainceiling_t val)
  296. {
  297. ESP_LOGW(TAG, "Unsupported");
  298. return -1;
  299. }
  300. int gc032a_detect(int slv_addr, sensor_id_t *id)
  301. {
  302. if (GC032A_SCCB_ADDR == slv_addr) {
  303. uint8_t MIDL = SCCB_Read(slv_addr, SENSOR_ID_LOW);
  304. uint8_t MIDH = SCCB_Read(slv_addr, SENSOR_ID_HIGH);
  305. uint16_t PID = MIDH << 8 | MIDL;
  306. if (GC032A_PID == PID) {
  307. id->PID = PID;
  308. return PID;
  309. } else {
  310. ESP_LOGI(TAG, "Mismatch PID=0x%x", PID);
  311. }
  312. }
  313. return 0;
  314. }
  315. int gc032a_init(sensor_t *sensor)
  316. {
  317. sensor->init_status = init_status;
  318. sensor->reset = reset;
  319. sensor->set_pixformat = set_pixformat;
  320. sensor->set_framesize = set_framesize;
  321. sensor->set_contrast = set_dummy;
  322. sensor->set_brightness = set_dummy;
  323. sensor->set_saturation = set_dummy;
  324. sensor->set_sharpness = set_dummy;
  325. sensor->set_denoise = set_dummy;
  326. sensor->set_gainceiling = set_gainceiling_dummy;
  327. sensor->set_quality = set_dummy;
  328. sensor->set_colorbar = set_colorbar;
  329. sensor->set_whitebal = set_dummy;
  330. sensor->set_gain_ctrl = set_dummy;
  331. sensor->set_exposure_ctrl = set_dummy;
  332. sensor->set_hmirror = set_hmirror;
  333. sensor->set_vflip = set_vflip;
  334. sensor->set_aec2 = set_dummy;
  335. sensor->set_awb_gain = set_dummy;
  336. sensor->set_agc_gain = set_dummy;
  337. sensor->set_aec_value = set_dummy;
  338. sensor->set_special_effect = set_dummy;
  339. sensor->set_wb_mode = set_dummy;
  340. sensor->set_ae_level = set_dummy;
  341. sensor->set_dcw = set_dummy;
  342. sensor->set_bpc = set_dummy;
  343. sensor->set_wpc = set_dummy;
  344. sensor->set_raw_gma = set_dummy;
  345. sensor->set_lenc = set_dummy;
  346. sensor->get_reg = get_reg;
  347. sensor->set_reg = set_reg;
  348. sensor->set_res_raw = NULL;
  349. sensor->set_pll = NULL;
  350. sensor->set_xclk = NULL;
  351. ESP_LOGD(TAG, "GC032A Attached");
  352. return 0;
  353. }