mega_ccm.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407
  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 "mega_ccm.h"
  21. #include "mega_ccm_regs.h"
  22. #include "mega_ccm_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 = "mega_ccm";
  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. int ret = SCCB_Read16(slv_addr, reg);
  34. #ifdef REG_DEBUG_ON
  35. if (ret < 0) {
  36. ESP_LOGE(TAG, "READ REG 0x%04x FAILED: %d", reg, ret);
  37. }
  38. #endif
  39. return ret;
  40. }
  41. static int write_reg(uint8_t slv_addr, const uint16_t reg, uint8_t value){
  42. int ret = 0;
  43. ret = SCCB_Write16(slv_addr, reg, value);
  44. return ret;
  45. }
  46. static int reset(sensor_t *sensor)
  47. {
  48. int ret;
  49. ret = write_reg(sensor->slv_addr, CAMERA_RST_REG, 0x00);
  50. ret += write_reg(sensor->slv_addr, CAMERA_RST_REG, 0x01);
  51. vTaskDelay(1000 / portTICK_PERIOD_MS);
  52. return ret;
  53. }
  54. static int set_pixformat(sensor_t *sensor, pixformat_t pixformat)
  55. {
  56. int ret = 0;
  57. switch (pixformat) {
  58. case PIXFORMAT_JPEG:
  59. ret = write_reg(sensor->slv_addr, PIXEL_FMT_REG, 0x01);
  60. break;
  61. case PIXFORMAT_RGB565:
  62. ret = write_reg(sensor->slv_addr, PIXEL_FMT_REG, 0x02);
  63. break;
  64. case PIXFORMAT_YUV422:
  65. ret = write_reg(sensor->slv_addr, PIXEL_FMT_REG, 0x03);
  66. break;
  67. default:
  68. ESP_LOGW(TAG, "unsupport format");
  69. ret = -1;
  70. break;
  71. }
  72. if (ret == 0) {
  73. sensor->pixformat = pixformat;
  74. ESP_LOGD(TAG, "Set pixformat to: %u", pixformat);
  75. }
  76. return ret;
  77. }
  78. static int set_framesize(sensor_t *sensor, framesize_t framesize)
  79. {
  80. ESP_LOGI(TAG, "set_framesize");
  81. int ret = 0;
  82. if (framesize > FRAMESIZE_5MP) {
  83. ESP_LOGW(TAG, "Invalid framesize: %u", framesize);
  84. framesize = FRAMESIZE_5MP;
  85. }
  86. sensor->status.framesize = framesize;
  87. uint16_t w = resolution[framesize].width;
  88. uint16_t h = resolution[framesize].height;
  89. switch (framesize){
  90. case FRAMESIZE_QVGA:
  91. ret = write_reg(sensor->slv_addr, RESOLUTION_REG, 0x01); //320x240
  92. ret += write_reg(sensor->slv_addr, SYSTEM_CLK_DIV_REG, 0x02); // set system clk
  93. ret += write_reg(sensor->slv_addr, SYSTEM_PLL_DIV_REG, 0x01); // set system pll
  94. break;
  95. case FRAMESIZE_VGA:
  96. ret = write_reg(sensor->slv_addr, RESOLUTION_REG, 0x02); //640x480
  97. ret += write_reg(sensor->slv_addr, SYSTEM_CLK_DIV_REG, 0x02); // set system clk
  98. ret += write_reg(sensor->slv_addr, SYSTEM_PLL_DIV_REG, 0x01); // set system pll
  99. break;
  100. case FRAMESIZE_HD:
  101. ret = write_reg(sensor->slv_addr, RESOLUTION_REG, 0x03); //1280x720
  102. ret += write_reg(sensor->slv_addr, SYSTEM_CLK_DIV_REG, 0x02); // set system clk
  103. ret += write_reg(sensor->slv_addr, SYSTEM_PLL_DIV_REG, 0x01); // set system pll
  104. break;
  105. case FRAMESIZE_UXGA:
  106. ret = write_reg(sensor->slv_addr, RESOLUTION_REG, 0x04); //1600x1200
  107. ret += write_reg(sensor->slv_addr, SYSTEM_CLK_DIV_REG, 0x02); // set system clk
  108. ret += write_reg(sensor->slv_addr, SYSTEM_PLL_DIV_REG, 0x01); // set system pll
  109. break;
  110. case FRAMESIZE_FHD:
  111. ret = write_reg(sensor->slv_addr, RESOLUTION_REG, 0x05); //1920x1080
  112. ret += write_reg(sensor->slv_addr, SYSTEM_CLK_DIV_REG, 0x02); // set system clk
  113. ret += write_reg(sensor->slv_addr, SYSTEM_PLL_DIV_REG, 0x01); // set system pll
  114. break;
  115. case FRAMESIZE_5MP:
  116. ret = write_reg(sensor->slv_addr, RESOLUTION_REG, 0x06); //2592x1944
  117. break;
  118. case FRAMESIZE_96X96:
  119. ret = write_reg(sensor->slv_addr, RESOLUTION_REG, 0x07); //96x96
  120. break;
  121. case FRAMESIZE_128X128:
  122. ret = write_reg(sensor->slv_addr, RESOLUTION_REG, 0x08); //128x128
  123. break;
  124. case FRAMESIZE_320X320:
  125. ret = write_reg(sensor->slv_addr, RESOLUTION_REG, 0x09); //320x320
  126. break;
  127. default:
  128. ESP_LOGW(TAG, "unsupport framesize");
  129. ret = -1;
  130. break;
  131. }
  132. if (ret == 0) {
  133. ESP_LOGD(TAG, "Set framesize to: %ux%u", w, h);
  134. }
  135. return ret;
  136. }
  137. static int set_hmirror(sensor_t *sensor, int enable)
  138. {
  139. int ret = 0;
  140. sensor->status.hmirror = enable;
  141. ret = write_reg(sensor->slv_addr, IMAGE_MIRROR_REG, enable);
  142. if (ret == 0) {
  143. ESP_LOGD(TAG, "Set h-mirror to: %d", enable);
  144. }
  145. return ret;
  146. }
  147. static int set_vflip(sensor_t *sensor, int enable)
  148. {
  149. int ret = 0;
  150. sensor->status.vflip = enable;
  151. ret = write_reg(sensor->slv_addr, IMAGE_FLIP_REG, enable);
  152. if (ret == 0) {
  153. ESP_LOGD(TAG, "Set v-flip to: %d", enable);
  154. }
  155. return ret;
  156. }
  157. static int set_quality(sensor_t *sensor, int qs)
  158. {
  159. int ret = 0;
  160. ret = write_reg(sensor->slv_addr, IMAGE_QUALITY_REG, qs);
  161. if (ret == 0) {
  162. sensor->status.quality = qs;
  163. ESP_LOGD(TAG, "Set quality to: %d", qs);
  164. }
  165. return ret;
  166. }
  167. static int set_brightness(sensor_t *sensor, int level)
  168. {
  169. int ret = 0;
  170. if(level < 0) {
  171. level = 0;
  172. } else if(level > 8) {
  173. level = 8;
  174. }
  175. ret = write_reg(sensor->slv_addr, BRIGHTNESS_REG, level);
  176. if (ret == 0) {
  177. ESP_LOGD(TAG, "Set brightness to: %d", level);
  178. sensor->status.brightness = level;
  179. }
  180. return ret;
  181. }
  182. static int set_contrast (sensor_t *sensor, int level)
  183. {
  184. int ret = 0;
  185. if(level < 0) {
  186. level = 0;
  187. } else if(level > 6) {
  188. level = 6;
  189. }
  190. ret = write_reg(sensor->slv_addr, CONTRAST_REG, level);
  191. if (ret == 0) {
  192. ESP_LOGD(TAG, "Set contrast to: %d", level);
  193. sensor->status.contrast = level;
  194. }
  195. return ret;
  196. }
  197. static int set_saturation (sensor_t *sensor, int level)
  198. {
  199. int ret = 0;
  200. if(level < 0) {
  201. level = 0;
  202. } else if(level > 6) {
  203. level = 6;
  204. }
  205. ret = write_reg(sensor->slv_addr, SATURATION_REG, level);
  206. if (ret == 0) {
  207. ESP_LOGD(TAG, "Set saturation to: %d", level);
  208. sensor->status.saturation = level;
  209. }
  210. return ret;
  211. }
  212. static int set_agc_mode (sensor_t *sensor, int enable)
  213. {
  214. int ret = 0;
  215. ret = write_reg(sensor->slv_addr, AGC_MODE_REG, enable);
  216. if (ret == 0) {
  217. ESP_LOGD(TAG, "Set agc mode to: %d", enable);
  218. sensor->status.aec = enable;
  219. }
  220. return ret;
  221. }
  222. static int set_wb_mode (sensor_t *sensor, int mode)
  223. {
  224. int ret = 0;
  225. if(mode < 0) {
  226. mode = 0;
  227. } else if(mode > 5) {
  228. mode = 5;
  229. }
  230. ret = write_reg(sensor->slv_addr, AWB_MODE_REG, mode);
  231. if (ret == 0) {
  232. ESP_LOGD(TAG, "Set wb_mode to: %d", mode);
  233. sensor->status.wb_mode = mode;
  234. }
  235. return ret;
  236. }
  237. static int set_special_effect (sensor_t *sensor, int effect)
  238. {
  239. int ret = 0;
  240. if(effect < 0) {
  241. effect = 0;
  242. } else if(effect > 6) {
  243. effect = 6;
  244. }
  245. ret = write_reg(sensor->slv_addr, SPECIAL_REG, effect);
  246. if (ret == 0) {
  247. ESP_LOGD(TAG, "Set special_effect to: %d", effect);
  248. sensor->status.special_effect = effect;
  249. }
  250. return ret;
  251. }
  252. static int analog_gain (sensor_t *sensor, int val)
  253. {
  254. int ret = 0;
  255. ret = write_reg(sensor->slv_addr, MANUAL_AGC_REG, val);
  256. if (ret == 0) {
  257. ESP_LOGD(TAG, "Set analog gain to: %d", val);
  258. }
  259. return ret;
  260. }
  261. static int exposure_line (sensor_t *sensor, int val)
  262. {
  263. int ret = 0;
  264. ret = write_reg(sensor->slv_addr, MANUAL_EXP_H_REG, val>>8);
  265. ret += write_reg(sensor->slv_addr, MANUAL_EXP_L_REG, val>>8);
  266. if (ret == 0) {
  267. ESP_LOGD(TAG, "Set exposure_line to: %d", val);
  268. }
  269. return ret;
  270. }
  271. static int init_status(sensor_t *sensor)
  272. {
  273. sensor->status.brightness = 0;
  274. sensor->status.contrast = 0;
  275. sensor->status.saturation = 0;
  276. sensor->status.sharpness = 0;
  277. sensor->status.denoise = 0;
  278. sensor->status.ae_level = 0;
  279. sensor->status.gainceiling = 0;
  280. sensor->status.awb = 0;
  281. sensor->status.dcw = 0;
  282. sensor->status.agc = 0;
  283. sensor->status.aec = 0;
  284. sensor->status.hmirror = 0;
  285. sensor->status.vflip = 0;
  286. sensor->status.colorbar = 0;
  287. sensor->status.bpc = 0;
  288. sensor->status.wpc = 0;
  289. sensor->status.raw_gma = 0;
  290. sensor->status.lenc = 0;
  291. sensor->status.quality = 0;
  292. sensor->status.special_effect = 0;
  293. sensor->status.wb_mode = 0;
  294. sensor->status.awb_gain = 0;
  295. sensor->status.agc_gain = 0;
  296. sensor->status.aec_value = 0;
  297. sensor->status.aec2 = 0;
  298. return 0;
  299. }
  300. static int set_dummy(sensor_t *sensor, int val)
  301. {
  302. ESP_LOGW(TAG, "Unsupported");
  303. return -1;
  304. }
  305. static int set_gainceiling_dummy(sensor_t *sensor, gainceiling_t val)
  306. {
  307. ESP_LOGW(TAG, "Unsupported");
  308. return -1;
  309. }
  310. int mega_ccm_detect(int slv_addr, sensor_id_t *id)
  311. {
  312. if (MEGA_CCM_SCCB_ADDR == slv_addr) {
  313. uint8_t h = read_reg(slv_addr, SENSOR_ID_HIGH);
  314. uint8_t l = read_reg(slv_addr, SENSOR_ID_LOW);
  315. uint16_t PID = (h<<8) | l;
  316. if (MEGA_CCM_PID == PID) {
  317. id->PID = PID;
  318. return PID;
  319. } else {
  320. ESP_LOGI(TAG, "Mismatch PID=0x%x", PID);
  321. }
  322. }
  323. return 0;
  324. }
  325. int mega_ccm_init(sensor_t *sensor)
  326. {
  327. sensor->init_status = init_status;
  328. sensor->reset = reset;
  329. sensor->set_pixformat = set_pixformat;
  330. sensor->set_framesize = set_framesize;
  331. sensor->set_contrast = set_contrast;
  332. sensor->set_brightness = set_brightness;
  333. sensor->set_saturation = set_saturation;
  334. sensor->set_sharpness = set_dummy;
  335. sensor->set_denoise = set_dummy;
  336. sensor->set_gainceiling = set_gainceiling_dummy;
  337. sensor->set_quality = set_quality;
  338. sensor->set_colorbar = set_dummy;
  339. sensor->set_whitebal = set_dummy;
  340. sensor->set_gain_ctrl = set_dummy;
  341. sensor->set_exposure_ctrl = set_dummy;
  342. sensor->set_hmirror = set_hmirror;
  343. sensor->set_vflip = set_vflip;
  344. sensor->set_aec2 = set_agc_mode;
  345. sensor->set_awb_gain = set_dummy;
  346. sensor->set_agc_gain = analog_gain;
  347. sensor->set_aec_value = exposure_line;
  348. sensor->set_special_effect = set_special_effect;
  349. sensor->set_wb_mode = set_wb_mode;
  350. sensor->set_ae_level = set_dummy;
  351. sensor->set_dcw = set_dummy;
  352. sensor->set_bpc = set_dummy;
  353. sensor->set_wpc = set_dummy;
  354. sensor->set_raw_gma = set_dummy;
  355. sensor->set_lenc = set_dummy;
  356. sensor->get_reg = NULL;
  357. sensor->set_reg = NULL;
  358. sensor->set_res_raw = NULL;
  359. sensor->set_pll = NULL;
  360. sensor->set_xclk = NULL;
  361. ESP_LOGD(TAG, "MEGA_CCM Attached");
  362. return 0;
  363. }