esp_camera.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include "time.h"
  5. #include "sys/time.h"
  6. #include "freertos/FreeRTOS.h"
  7. #include "freertos/task.h"
  8. #include "driver/gpio.h"
  9. #include "esp_system.h"
  10. #include "nvs_flash.h"
  11. #include "nvs.h"
  12. #include "sensor.h"
  13. #include "sccb.h"
  14. #include "cam_hal.h"
  15. #include "esp_camera.h"
  16. #include "xclk.h"
  17. #if CONFIG_OV2640_SUPPORT
  18. #include "ov2640.h"
  19. #endif
  20. #if CONFIG_OV7725_SUPPORT
  21. #include "ov7725.h"
  22. #endif
  23. #if CONFIG_OV3660_SUPPORT
  24. #include "ov3660.h"
  25. #endif
  26. #if CONFIG_OV5640_SUPPORT
  27. #include "ov5640.h"
  28. #endif
  29. #if CONFIG_NT99141_SUPPORT
  30. #include "nt99141.h"
  31. #endif
  32. #if CONFIG_OV7670_SUPPORT
  33. #include "ov7670.h"
  34. #endif
  35. #if CONFIG_GC2145_SUPPORT
  36. #include "gc2145.h"
  37. #endif
  38. #if CONFIG_GC032A_SUPPORT
  39. #include "gc032a.h"
  40. #endif
  41. #if CONFIG_GC0308_SUPPORT
  42. #include "gc0308.h"
  43. #endif
  44. #if CONFIG_BF3005_SUPPORT
  45. #include "bf3005.h"
  46. #endif
  47. #if CONFIG_BF20A6_SUPPORT
  48. #include "bf20a6.h"
  49. #endif
  50. #if defined(ARDUINO_ARCH_ESP32) && defined(CONFIG_ARDUHAL_ESP_LOG)
  51. #include "esp32-hal-log.h"
  52. #define TAG ""
  53. #else
  54. #include "esp_log.h"
  55. static const char *TAG = "camera";
  56. #endif
  57. typedef struct {
  58. sensor_t sensor;
  59. camera_fb_t fb;
  60. } camera_state_t;
  61. static const char *CAMERA_SENSOR_NVS_KEY = "sensor";
  62. static const char *CAMERA_PIXFORMAT_NVS_KEY = "pixformat";
  63. static camera_state_t *s_state = NULL;
  64. #if CONFIG_IDF_TARGET_ESP32S3 // LCD_CAM module of ESP32-S3 will generate xclk
  65. #define CAMERA_ENABLE_OUT_CLOCK(v)
  66. #define CAMERA_DISABLE_OUT_CLOCK()
  67. #else
  68. #define CAMERA_ENABLE_OUT_CLOCK(v) camera_enable_out_clock((v))
  69. #define CAMERA_DISABLE_OUT_CLOCK() camera_disable_out_clock()
  70. #endif
  71. typedef struct {
  72. int (*detect)(int slv_addr, sensor_id_t *id);
  73. int (*init)(sensor_t *sensor);
  74. } sensor_func_t;
  75. static const sensor_func_t g_sensors[] = {
  76. #if CONFIG_OV7725_SUPPORT
  77. {ov7725_detect, ov7725_init},
  78. #endif
  79. #if CONFIG_OV7670_SUPPORT
  80. {ov7670_detect, ov7670_init},
  81. #endif
  82. #if CONFIG_OV2640_SUPPORT
  83. {ov2640_detect, ov2640_init},
  84. #endif
  85. #if CONFIG_OV3660_SUPPORT
  86. {ov3660_detect, ov3660_init},
  87. #endif
  88. #if CONFIG_OV5640_SUPPORT
  89. {ov5640_detect, ov5640_init},
  90. #endif
  91. #if CONFIG_NT99141_SUPPORT
  92. {nt99141_detect, nt99141_init},
  93. #endif
  94. #if CONFIG_GC2145_SUPPORT
  95. {gc2145_detect, gc2145_init},
  96. #endif
  97. #if CONFIG_GC032A_SUPPORT
  98. {gc032a_detect, gc032a_init},
  99. #endif
  100. #if CONFIG_GC0308_SUPPORT
  101. {gc0308_detect, gc0308_init},
  102. #endif
  103. #if CONFIG_BF3005_SUPPORT
  104. {bf3005_detect, bf3005_init},
  105. #endif
  106. #if CONFIG_BF20A6_SUPPORT
  107. {bf20a6_detect, bf20a6_init},
  108. #endif
  109. };
  110. static esp_err_t camera_probe(const camera_config_t *config, camera_model_t *out_camera_model)
  111. {
  112. *out_camera_model = CAMERA_NONE;
  113. if (s_state != NULL) {
  114. return ESP_ERR_INVALID_STATE;
  115. }
  116. s_state = (camera_state_t *) calloc(sizeof(camera_state_t), 1);
  117. if (!s_state) {
  118. return ESP_ERR_NO_MEM;
  119. }
  120. if (config->pin_xclk >= 0) {
  121. ESP_LOGD(TAG, "Enabling XCLK output");
  122. CAMERA_ENABLE_OUT_CLOCK(config);
  123. }
  124. if (config->pin_sscb_sda != -1) {
  125. ESP_LOGD(TAG, "Initializing SSCB");
  126. SCCB_Init(config->pin_sscb_sda, config->pin_sscb_scl);
  127. }
  128. if (config->pin_pwdn >= 0) {
  129. ESP_LOGD(TAG, "Resetting camera by power down line");
  130. gpio_config_t conf = { 0 };
  131. conf.pin_bit_mask = 1LL << config->pin_pwdn;
  132. conf.mode = GPIO_MODE_OUTPUT;
  133. gpio_config(&conf);
  134. // carefull, logic is inverted compared to reset pin
  135. gpio_set_level(config->pin_pwdn, 1);
  136. vTaskDelay(10 / portTICK_PERIOD_MS);
  137. gpio_set_level(config->pin_pwdn, 0);
  138. vTaskDelay(10 / portTICK_PERIOD_MS);
  139. }
  140. if (config->pin_reset >= 0) {
  141. ESP_LOGD(TAG, "Resetting camera");
  142. gpio_config_t conf = { 0 };
  143. conf.pin_bit_mask = 1LL << config->pin_reset;
  144. conf.mode = GPIO_MODE_OUTPUT;
  145. gpio_config(&conf);
  146. gpio_set_level(config->pin_reset, 0);
  147. vTaskDelay(10 / portTICK_PERIOD_MS);
  148. gpio_set_level(config->pin_reset, 1);
  149. vTaskDelay(10 / portTICK_PERIOD_MS);
  150. }
  151. #if CONFIG_OV2640_SUPPORT
  152. SCCB_Write(0x30, 0xff, 0x01);
  153. #endif
  154. ESP_LOGD(TAG, "Searching for camera address");
  155. vTaskDelay(10 / portTICK_PERIOD_MS);
  156. uint8_t slv_addr = SCCB_Probe();
  157. if (slv_addr == 0) {
  158. CAMERA_DISABLE_OUT_CLOCK();
  159. return ESP_ERR_NOT_FOUND;
  160. }
  161. ESP_LOGI(TAG, "Detected camera at address=0x%02x", slv_addr);
  162. s_state->sensor.slv_addr = slv_addr;
  163. s_state->sensor.xclk_freq_hz = config->xclk_freq_hz;
  164. /**
  165. * Read sensor ID and then initialize sensor
  166. * Attention: Some sensors have the same SCCB address. Therefore, several attempts may be made in the detection process
  167. */
  168. sensor_id_t *id = &s_state->sensor.id;
  169. for (size_t i = 0; i < sizeof(g_sensors) / sizeof(sensor_func_t); i++) {
  170. if (g_sensors[i].detect(slv_addr, id)) {
  171. camera_sensor_info_t *info = esp_camera_sensor_get_info(id);
  172. if (NULL != info) {
  173. *out_camera_model = info->model;
  174. ESP_LOGI(TAG, "Detected %s camera", info->name);
  175. g_sensors[i].init(&s_state->sensor);
  176. break;
  177. }
  178. }
  179. }
  180. if (CAMERA_NONE == *out_camera_model) { //If no supported sensors are detected
  181. CAMERA_DISABLE_OUT_CLOCK();
  182. ESP_LOGE(TAG, "Detected camera not supported.");
  183. return ESP_ERR_NOT_SUPPORTED;
  184. }
  185. ESP_LOGI(TAG, "Camera PID=0x%02x VER=0x%02x MIDL=0x%02x MIDH=0x%02x",
  186. id->PID, id->VER, id->MIDH, id->MIDL);
  187. ESP_LOGD(TAG, "Doing SW reset of sensor");
  188. vTaskDelay(10 / portTICK_PERIOD_MS);
  189. s_state->sensor.reset(&s_state->sensor);
  190. return ESP_OK;
  191. }
  192. esp_err_t esp_camera_init(const camera_config_t *config)
  193. {
  194. esp_err_t err;
  195. err = cam_init(config);
  196. if (err != ESP_OK) {
  197. ESP_LOGE(TAG, "Camera init failed with error 0x%x", err);
  198. return err;
  199. }
  200. camera_model_t camera_model = CAMERA_NONE;
  201. err = camera_probe(config, &camera_model);
  202. if (err != ESP_OK) {
  203. ESP_LOGE(TAG, "Camera probe failed with error 0x%x(%s)", err, esp_err_to_name(err));
  204. goto fail;
  205. }
  206. framesize_t frame_size = (framesize_t) config->frame_size;
  207. pixformat_t pix_format = (pixformat_t) config->pixel_format;
  208. if (PIXFORMAT_JPEG == pix_format && (!camera_sensor[camera_model].support_jpeg)) {
  209. ESP_LOGE(TAG, "JPEG format is not supported on this sensor");
  210. err = ESP_ERR_NOT_SUPPORTED;
  211. goto fail;
  212. }
  213. if (frame_size > camera_sensor[camera_model].max_size) {
  214. ESP_LOGW(TAG, "The frame size exceeds the maximum for this sensor, it will be forced to the maximum possible value");
  215. frame_size = camera_sensor[camera_model].max_size;
  216. }
  217. err = cam_config(config, frame_size, s_state->sensor.id.PID);
  218. if (err != ESP_OK) {
  219. ESP_LOGE(TAG, "Camera config failed with error 0x%x", err);
  220. goto fail;
  221. }
  222. s_state->sensor.status.framesize = frame_size;
  223. s_state->sensor.pixformat = pix_format;
  224. ESP_LOGD(TAG, "Setting frame size to %dx%d", resolution[frame_size].width, resolution[frame_size].height);
  225. if (s_state->sensor.set_framesize(&s_state->sensor, frame_size) != 0) {
  226. ESP_LOGE(TAG, "Failed to set frame size");
  227. err = ESP_ERR_CAMERA_FAILED_TO_SET_FRAME_SIZE;
  228. goto fail;
  229. }
  230. s_state->sensor.set_pixformat(&s_state->sensor, pix_format);
  231. if (s_state->sensor.id.PID == OV2640_PID) {
  232. s_state->sensor.set_gainceiling(&s_state->sensor, GAINCEILING_2X);
  233. s_state->sensor.set_bpc(&s_state->sensor, false);
  234. s_state->sensor.set_wpc(&s_state->sensor, true);
  235. s_state->sensor.set_lenc(&s_state->sensor, true);
  236. }
  237. if (pix_format == PIXFORMAT_JPEG) {
  238. s_state->sensor.set_quality(&s_state->sensor, config->jpeg_quality);
  239. }
  240. s_state->sensor.init_status(&s_state->sensor);
  241. cam_start();
  242. return ESP_OK;
  243. fail:
  244. esp_camera_deinit();
  245. return err;
  246. }
  247. esp_err_t esp_camera_deinit()
  248. {
  249. esp_err_t ret = cam_deinit();
  250. CAMERA_DISABLE_OUT_CLOCK();
  251. if (s_state) {
  252. SCCB_Deinit();
  253. free(s_state);
  254. s_state = NULL;
  255. }
  256. return ret;
  257. }
  258. #define FB_GET_TIMEOUT (4000 / portTICK_PERIOD_MS)
  259. camera_fb_t *esp_camera_fb_get()
  260. {
  261. if (s_state == NULL) {
  262. return NULL;
  263. }
  264. camera_fb_t *fb = cam_take(FB_GET_TIMEOUT);
  265. //set the frame properties
  266. if (fb) {
  267. fb->width = resolution[s_state->sensor.status.framesize].width;
  268. fb->height = resolution[s_state->sensor.status.framesize].height;
  269. fb->format = s_state->sensor.pixformat;
  270. }
  271. return fb;
  272. }
  273. void esp_camera_fb_return(camera_fb_t *fb)
  274. {
  275. if (s_state == NULL) {
  276. return;
  277. }
  278. cam_give(fb);
  279. }
  280. sensor_t *esp_camera_sensor_get()
  281. {
  282. if (s_state == NULL) {
  283. return NULL;
  284. }
  285. return &s_state->sensor;
  286. }
  287. esp_err_t esp_camera_save_to_nvs(const char *key)
  288. {
  289. #if ESP_IDF_VERSION_MAJOR > 3
  290. nvs_handle_t handle;
  291. #else
  292. nvs_handle handle;
  293. #endif
  294. esp_err_t ret = nvs_open(key, NVS_READWRITE, &handle);
  295. if (ret == ESP_OK) {
  296. sensor_t *s = esp_camera_sensor_get();
  297. if (s != NULL) {
  298. ret = nvs_set_blob(handle, CAMERA_SENSOR_NVS_KEY, &s->status, sizeof(camera_status_t));
  299. if (ret == ESP_OK) {
  300. uint8_t pf = s->pixformat;
  301. ret = nvs_set_u8(handle, CAMERA_PIXFORMAT_NVS_KEY, pf);
  302. }
  303. return ret;
  304. } else {
  305. return ESP_ERR_CAMERA_NOT_DETECTED;
  306. }
  307. nvs_close(handle);
  308. return ret;
  309. } else {
  310. return ret;
  311. }
  312. }
  313. esp_err_t esp_camera_load_from_nvs(const char *key)
  314. {
  315. #if ESP_IDF_VERSION_MAJOR > 3
  316. nvs_handle_t handle;
  317. #else
  318. nvs_handle handle;
  319. #endif
  320. uint8_t pf;
  321. esp_err_t ret = nvs_open(key, NVS_READWRITE, &handle);
  322. if (ret == ESP_OK) {
  323. sensor_t *s = esp_camera_sensor_get();
  324. camera_status_t st;
  325. if (s != NULL) {
  326. size_t size = sizeof(camera_status_t);
  327. ret = nvs_get_blob(handle, CAMERA_SENSOR_NVS_KEY, &st, &size);
  328. if (ret == ESP_OK) {
  329. s->set_ae_level(s, st.ae_level);
  330. s->set_aec2(s, st.aec2);
  331. s->set_aec_value(s, st.aec_value);
  332. s->set_agc_gain(s, st.agc_gain);
  333. s->set_awb_gain(s, st.awb_gain);
  334. s->set_bpc(s, st.bpc);
  335. s->set_brightness(s, st.brightness);
  336. s->set_colorbar(s, st.colorbar);
  337. s->set_contrast(s, st.contrast);
  338. s->set_dcw(s, st.dcw);
  339. s->set_denoise(s, st.denoise);
  340. s->set_exposure_ctrl(s, st.aec);
  341. s->set_framesize(s, st.framesize);
  342. s->set_gain_ctrl(s, st.agc);
  343. s->set_gainceiling(s, st.gainceiling);
  344. s->set_hmirror(s, st.hmirror);
  345. s->set_lenc(s, st.lenc);
  346. s->set_quality(s, st.quality);
  347. s->set_raw_gma(s, st.raw_gma);
  348. s->set_saturation(s, st.saturation);
  349. s->set_sharpness(s, st.sharpness);
  350. s->set_special_effect(s, st.special_effect);
  351. s->set_vflip(s, st.vflip);
  352. s->set_wb_mode(s, st.wb_mode);
  353. s->set_whitebal(s, st.awb);
  354. s->set_wpc(s, st.wpc);
  355. }
  356. ret = nvs_get_u8(handle, CAMERA_PIXFORMAT_NVS_KEY, &pf);
  357. if (ret == ESP_OK) {
  358. s->set_pixformat(s, pf);
  359. }
  360. } else {
  361. return ESP_ERR_CAMERA_NOT_DETECTED;
  362. }
  363. nvs_close(handle);
  364. return ret;
  365. } else {
  366. ESP_LOGW(TAG, "Error (%d) opening nvs key \"%s\"", ret, key);
  367. return ret;
  368. }
  369. }