├── esp-idf_components_esp32-camera ├── .gitignore ├── CMakeLists.txt ├── Kconfig ├── LICENSE ├── README.md ├── component.mk ├── conversions │ ├── esp_jpg_decode.c │ ├── include │ │ ├── esp_jpg_decode.h │ │ └── img_converters.h │ ├── jpge.cpp │ ├── private_include │ │ ├── jpge.h │ │ └── yuv.h │ ├── to_bmp.c │ ├── to_jpg.cpp │ └── yuv.c ├── driver │ ├── camera.c │ ├── include │ │ ├── esp_camera.h │ │ └── sensor.h │ ├── private_include │ │ ├── camera_common.h │ │ ├── sccb.h │ │ ├── twi.h │ │ └── xclk.h │ ├── sccb.c │ ├── sensor.c │ ├── twi.c │ └── xclk.c └── sensors │ ├── ov2640.c │ ├── ov3660.c │ ├── ov5640.c │ ├── ov7725.c │ └── private_include │ ├── ov2640.h │ ├── ov2640_regs.h │ ├── ov2640_settings.h │ ├── ov3660.h │ ├── ov3660_regs.h │ ├── ov3660_settings.h │ ├── ov5640.h │ ├── ov5640_regs.h │ ├── ov5640_settings.h │ ├── ov7725.h │ └── ov7725_regs.h ├── micropython_ports └── esp32 │ ├── Makefile │ ├── boards │ ├── basic_cam_8mb_OV2640 │ │ ├── manifest.py │ │ ├── mpconfigboard.h │ │ ├── mpconfigboard.mk │ │ ├── partitions.csv │ │ └── sdkconfig.mod │ ├── sdkconfig.esp32cam_OV2640 │ └── sdkconfig.esp32cam_OV7725 │ ├── modcamera.c │ └── mpconfigport.h └── readme.md /esp-idf_components_esp32-camera/.gitignore: -------------------------------------------------------------------------------- 1 | *.DS_Store 2 | -------------------------------------------------------------------------------- /esp-idf_components_esp32-camera/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(COMPONENT_SRCS 2 | driver/camera.c 3 | driver/sccb.c 4 | driver/sensor.c 5 | driver/twi.c 6 | driver/xclk.c 7 | sensors/ov2640.c 8 | sensors/ov3660.c 9 | sensors/ov5640.c 10 | sensors/ov7725.c 11 | conversions/yuv.c 12 | conversions/to_jpg.cpp 13 | conversions/to_bmp.c 14 | conversions/jpge.cpp 15 | conversions/esp_jpg_decode.c 16 | ) 17 | 18 | set(COMPONENT_ADD_INCLUDEDIRS 19 | driver/include 20 | conversions/include 21 | ) 22 | 23 | set(COMPONENT_PRIV_INCLUDEDIRS 24 | driver/private_include 25 | sensors/private_include 26 | conversions/private_include 27 | ) 28 | 29 | set(COMPONENT_REQUIRES driver) 30 | set(COMPONENT_PRIV_REQUIRES freertos nvs_flash) 31 | 32 | register_component() 33 | -------------------------------------------------------------------------------- /esp-idf_components_esp32-camera/Kconfig: -------------------------------------------------------------------------------- 1 | menu "Camera configuration" 2 | 3 | config OV2640_SUPPORT 4 | bool "OV2640 Support" 5 | default y 6 | help 7 | Enable this option if you want to use the OV2640. 8 | Disable this option to save memory. 9 | 10 | config OV7725_SUPPORT 11 | bool "OV7725 Support" 12 | default n 13 | help 14 | Enable this option if you want to use the OV7725. 15 | Disable this option to save memory. 16 | 17 | config OV3660_SUPPORT 18 | bool "OV3660 Support" 19 | default y 20 | help 21 | Enable this option if you want to use the OV3360. 22 | Disable this option to save memory. 23 | 24 | config OV5640_SUPPORT 25 | bool "OV5640 Support" 26 | default y 27 | help 28 | Enable this option if you want to use the OV5640. 29 | Disable this option to save memory. 30 | 31 | config SCCB_HARDWARE_I2C 32 | bool "Use hardware I2C for SCCB" 33 | default y 34 | help 35 | Enable this option if you want to use hardware I2C to control the camera. 36 | Disable this option to use software I2C. 37 | 38 | choice SCCB_HARDWARE_I2C_PORT 39 | bool "I2C peripheral to use for SCCB" 40 | depends on SCCB_HARDWARE_I2C 41 | default SCCB_HARDWARE_I2C_PORT1 42 | 43 | config SCCB_HARDWARE_I2C_PORT0 44 | bool "I2C0" 45 | config SCCB_HARDWARE_I2C_PORT1 46 | bool "I2C1" 47 | 48 | endchoice 49 | 50 | choice CAMERA_TASK_PINNED_TO_CORE 51 | bool "Camera task pinned to core" 52 | default CAMERA_CORE0 53 | help 54 | Pin the camera handle task to a certain core(0/1). It can also be done automatically choosing NO_AFFINITY. 55 | 56 | config CAMERA_CORE0 57 | bool "CORE0" 58 | config CAMERA_CORE1 59 | bool "CORE1" 60 | config CAMERA_NO_AFFINITY 61 | bool "NO_AFFINITY" 62 | 63 | endchoice 64 | 65 | endmenu 66 | -------------------------------------------------------------------------------- /esp-idf_components_esp32-camera/LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /esp-idf_components_esp32-camera/README.md: -------------------------------------------------------------------------------- 1 | # ESP32 Camera Driver 2 | 3 | ## General Information 4 | 5 | This repository hosts ESP32 compatible driver for OV2640 and OV3660 image sensors. Additionally it provides a few tools, which allow converting the captured frame data to the more common BMP and JPEG formats. 6 | 7 | ## Important to Remember 8 | 9 | - Except when using CIF or lower resolution with JPEG, the driver requires PSRAM to be installed and activated. 10 | - Using YUV or RGB puts a lot of strain on the chip because writing to PSRAM is not particularly fast. The result is that image data might be missing. This is particularly true if WiFi is enabled. If you need RGB data, it is recommended that JPEG is captured and then turned into RGB using `fmt2rgb888` or `fmt2bmp`/`frame2bmp`. 11 | - When 1 frame buffer is used, the driver will wait for the current frame to finish (VSYNC) and start I2S DMA. After the frame is acquired, I2S will be stopped and the frame buffer returned to the application. This approach gives more control over the system, but results in longer time to get the frame. 12 | - When 2 or more frame bufers are used, I2S is running in continuous mode and each frame is pushed to a queue that the application can access. This approach puts more strain on the CPU/Memory, but allows for double the frame rate. Please use only with JPEG. 13 | 14 | ## Installation Instructions 15 | 16 | - Clone or download and extract the repository to the components folder of your ESP-IDF project 17 | - Enable PSRAM in `menuconfig` 18 | - Include `esp_camera.h` in your code 19 | 20 | ## Examples 21 | 22 | ### Initialization 23 | 24 | ```c 25 | #include "esp_camera.h" 26 | 27 | //WROVER-KIT PIN Map 28 | #define CAM_PIN_PWDN -1 //power down is not used 29 | #define CAM_PIN_RESET -1 //software reset will be performed 30 | #define CAM_PIN_XCLK 21 31 | #define CAM_PIN_SIOD 26 32 | #define CAM_PIN_SIOC 27 33 | 34 | #define CAM_PIN_D7 35 35 | #define CAM_PIN_D6 34 36 | #define CAM_PIN_D5 39 37 | #define CAM_PIN_D4 36 38 | #define CAM_PIN_D3 19 39 | #define CAM_PIN_D2 18 40 | #define CAM_PIN_D1 5 41 | #define CAM_PIN_D0 4 42 | #define CAM_PIN_VSYNC 25 43 | #define CAM_PIN_HREF 23 44 | #define CAM_PIN_PCLK 22 45 | 46 | static camera_config_t camera_config = { 47 | .pin_pwdn = CAM_PIN_PWDN, 48 | .pin_reset = CAM_PIN_RESET, 49 | .pin_xclk = CAM_PIN_XCLK, 50 | .pin_sscb_sda = CAM_PIN_SIOD, 51 | .pin_sscb_scl = CAM_PIN_SIOC, 52 | 53 | .pin_d7 = CAM_PIN_D7, 54 | .pin_d6 = CAM_PIN_D6, 55 | .pin_d5 = CAM_PIN_D5, 56 | .pin_d4 = CAM_PIN_D4, 57 | .pin_d3 = CAM_PIN_D3, 58 | .pin_d2 = CAM_PIN_D2, 59 | .pin_d1 = CAM_PIN_D1, 60 | .pin_d0 = CAM_PIN_D0, 61 | .pin_vsync = CAM_PIN_VSYNC, 62 | .pin_href = CAM_PIN_HREF, 63 | .pin_pclk = CAM_PIN_PCLK, 64 | 65 | //XCLK 20MHz or 10MHz for OV2640 double FPS (Experimental) 66 | .xclk_freq_hz = 20000000, 67 | .ledc_timer = LEDC_TIMER_0, 68 | .ledc_channel = LEDC_CHANNEL_0, 69 | 70 | .pixel_format = PIXFORMAT_JPEG,//YUV422,GRAYSCALE,RGB565,JPEG 71 | .frame_size = FRAMESIZE_UXGA,//QQVGA-QXGA Do not use sizes above QVGA when not JPEG 72 | 73 | .jpeg_quality = 12, //0-63 lower number means higher quality 74 | .fb_count = 1 //if more than one, i2s runs in continuous mode. Use only with JPEG 75 | }; 76 | 77 | esp_err_t camera_init(){ 78 | //power up the camera if PWDN pin is defined 79 | if(CAM_PIN_PWDN != -1){ 80 | pinMode(CAM_PIN_PWDN, OUTPUT); 81 | digitalWrite(CAM_PIN_PWDN, LOW); 82 | } 83 | 84 | //initialize the camera 85 | esp_err_t err = esp_camera_init(&camera_config); 86 | if (err != ESP_OK) { 87 | ESP_LOGE(TAG, "Camera Init Failed"); 88 | return err; 89 | } 90 | 91 | return ESP_OK; 92 | } 93 | 94 | esp_err_t camera_capture(){ 95 | //acquire a frame 96 | camera_fb_t * fb = esp_camera_fb_get(); 97 | if (!fb) { 98 | ESP_LOGE(TAG, "Camera Capture Failed"); 99 | return ESP_FAIL; 100 | } 101 | //replace this with your own function 102 | process_image(fb->width, fb->height, fb->format, fb->buf, fb->len); 103 | 104 | //return the frame buffer back to the driver for reuse 105 | esp_camera_fb_return(fb); 106 | return ESP_OK; 107 | } 108 | ``` 109 | 110 | ### JPEG HTTP Capture 111 | 112 | ```c 113 | #include "esp_camera.h" 114 | #include "esp_http_server.h" 115 | #include "esp_timer.h" 116 | 117 | typedef struct { 118 | httpd_req_t *req; 119 | size_t len; 120 | } jpg_chunking_t; 121 | 122 | static size_t jpg_encode_stream(void * arg, size_t index, const void* data, size_t len){ 123 | jpg_chunking_t *j = (jpg_chunking_t *)arg; 124 | if(!index){ 125 | j->len = 0; 126 | } 127 | if(httpd_resp_send_chunk(j->req, (const char *)data, len) != ESP_OK){ 128 | return 0; 129 | } 130 | j->len += len; 131 | return len; 132 | } 133 | 134 | esp_err_t jpg_httpd_handler(httpd_req_t *req){ 135 | camera_fb_t * fb = NULL; 136 | esp_err_t res = ESP_OK; 137 | size_t fb_len = 0; 138 | int64_t fr_start = esp_timer_get_time(); 139 | 140 | fb = esp_camera_fb_get(); 141 | if (!fb) { 142 | ESP_LOGE(TAG, "Camera capture failed"); 143 | httpd_resp_send_500(req); 144 | return ESP_FAIL; 145 | } 146 | res = httpd_resp_set_type(req, "image/jpeg"); 147 | if(res == ESP_OK){ 148 | res = httpd_resp_set_hdr(req, "Content-Disposition", "inline; filename=capture.jpg"); 149 | } 150 | 151 | if(res == ESP_OK){ 152 | if(fb->format == PIXFORMAT_JPEG){ 153 | fb_len = fb->len; 154 | res = httpd_resp_send(req, (const char *)fb->buf, fb->len); 155 | } else { 156 | jpg_chunking_t jchunk = {req, 0}; 157 | res = frame2jpg_cb(fb, 80, jpg_encode_stream, &jchunk)?ESP_OK:ESP_FAIL; 158 | httpd_resp_send_chunk(req, NULL, 0); 159 | fb_len = jchunk.len; 160 | } 161 | } 162 | esp_camera_fb_return(fb); 163 | int64_t fr_end = esp_timer_get_time(); 164 | ESP_LOGI(TAG, "JPG: %uKB %ums", (uint32_t)(fb_len/1024), (uint32_t)((fr_end - fr_start)/1000)); 165 | return res; 166 | } 167 | ``` 168 | 169 | ### JPEG HTTP Stream 170 | 171 | ```c 172 | #include "esp_camera.h" 173 | #include "esp_http_server.h" 174 | #include "esp_timer.h" 175 | 176 | #define PART_BOUNDARY "123456789000000000000987654321" 177 | static const char* _STREAM_CONTENT_TYPE = "multipart/x-mixed-replace;boundary=" PART_BOUNDARY; 178 | static const char* _STREAM_BOUNDARY = "\r\n--" PART_BOUNDARY "\r\n"; 179 | static const char* _STREAM_PART = "Content-Type: image/jpeg\r\nContent-Length: %u\r\n\r\n"; 180 | 181 | esp_err_t jpg_stream_httpd_handler(httpd_req_t *req){ 182 | camera_fb_t * fb = NULL; 183 | esp_err_t res = ESP_OK; 184 | size_t _jpg_buf_len; 185 | uint8_t * _jpg_buf; 186 | char * part_buf[64]; 187 | static int64_t last_frame = 0; 188 | if(!last_frame) { 189 | last_frame = esp_timer_get_time(); 190 | } 191 | 192 | res = httpd_resp_set_type(req, _STREAM_CONTENT_TYPE); 193 | if(res != ESP_OK){ 194 | return res; 195 | } 196 | 197 | while(true){ 198 | fb = esp_camera_fb_get(); 199 | if (!fb) { 200 | ESP_LOGE(TAG, "Camera capture failed"); 201 | res = ESP_FAIL; 202 | break; 203 | } 204 | if(fb->format != PIXFORMAT_JPEG){ 205 | bool jpeg_converted = frame2jpg(fb, 80, &_jpg_buf, &_jpg_buf_len); 206 | if(!jpeg_converted){ 207 | ESP_LOGE(TAG, "JPEG compression failed"); 208 | esp_camera_fb_return(fb); 209 | res = ESP_FAIL; 210 | } 211 | } else { 212 | _jpg_buf_len = fb->len; 213 | _jpg_buf = fb->buf; 214 | } 215 | 216 | if(res == ESP_OK){ 217 | res = httpd_resp_send_chunk(req, _STREAM_BOUNDARY, strlen(_STREAM_BOUNDARY)); 218 | } 219 | if(res == ESP_OK){ 220 | size_t hlen = snprintf((char *)part_buf, 64, _STREAM_PART, _jpg_buf_len); 221 | 222 | res = httpd_resp_send_chunk(req, (const char *)part_buf, hlen); 223 | } 224 | if(res == ESP_OK){ 225 | res = httpd_resp_send_chunk(req, (const char *)_jpg_buf, _jpg_buf_len); 226 | } 227 | if(fb->format != PIXFORMAT_JPEG){ 228 | free(_jpg_buf); 229 | } 230 | esp_camera_fb_return(fb); 231 | if(res != ESP_OK){ 232 | break; 233 | } 234 | int64_t fr_end = esp_timer_get_time(); 235 | int64_t frame_time = fr_end - last_frame; 236 | last_frame = fr_end; 237 | frame_time /= 1000; 238 | ESP_LOGI(TAG, "MJPG: %uKB %ums (%.1ffps)", 239 | (uint32_t)(_jpg_buf_len/1024), 240 | (uint32_t)frame_time, 1000.0 / (uint32_t)frame_time); 241 | } 242 | 243 | last_frame = 0; 244 | return res; 245 | } 246 | ``` 247 | 248 | ### BMP HTTP Capture 249 | 250 | ```c 251 | #include "esp_camera.h" 252 | #include "esp_http_server.h" 253 | #include "esp_timer.h" 254 | 255 | esp_err_t bmp_httpd_handler(httpd_req_t *req){ 256 | camera_fb_t * fb = NULL; 257 | esp_err_t res = ESP_OK; 258 | int64_t fr_start = esp_timer_get_time(); 259 | 260 | fb = esp_camera_fb_get(); 261 | if (!fb) { 262 | ESP_LOGE(TAG, "Camera capture failed"); 263 | httpd_resp_send_500(req); 264 | return ESP_FAIL; 265 | } 266 | 267 | uint8_t * buf = NULL; 268 | size_t buf_len = 0; 269 | bool converted = frame2bmp(fb, &buf, &buf_len); 270 | esp_camera_fb_return(fb); 271 | if(!converted){ 272 | ESP_LOGE(TAG, "BMP conversion failed"); 273 | httpd_resp_send_500(req); 274 | return ESP_FAIL; 275 | } 276 | 277 | res = httpd_resp_set_type(req, "image/x-windows-bmp") 278 | || httpd_resp_set_hdr(req, "Content-Disposition", "inline; filename=capture.bmp") 279 | || httpd_resp_send(req, (const char *)buf, buf_len); 280 | free(buf); 281 | int64_t fr_end = esp_timer_get_time(); 282 | ESP_LOGI(TAG, "BMP: %uKB %ums", (uint32_t)(buf_len/1024), (uint32_t)((fr_end - fr_start)/1000)); 283 | return res; 284 | } 285 | ``` 286 | -------------------------------------------------------------------------------- /esp-idf_components_esp32-camera/component.mk: -------------------------------------------------------------------------------- 1 | COMPONENT_ADD_INCLUDEDIRS := driver/include conversions/include 2 | COMPONENT_PRIV_INCLUDEDIRS := driver/private_include conversions/private_include sensors/private_include 3 | COMPONENT_SRCDIRS := driver conversions sensors 4 | CXXFLAGS += -fno-rtti 5 | -------------------------------------------------------------------------------- /esp-idf_components_esp32-camera/conversions/esp_jpg_decode.c: -------------------------------------------------------------------------------- 1 | // Copyright 2015-2016 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 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | #include "esp_jpg_decode.h" 15 | 16 | #include "esp_system.h" 17 | #if ESP_IDF_VERSION_MAJOR >= 4 // IDF 4+ 18 | #if CONFIG_IDF_TARGET_ESP32 // ESP32/PICO-D4 19 | #include "esp32/rom/tjpgd.h" 20 | #else 21 | #error Target CONFIG_IDF_TARGET is not supported 22 | #endif 23 | #else // ESP32 Before IDF 4.0 24 | #include "rom/tjpgd.h" 25 | #endif 26 | 27 | #if defined(ARDUINO_ARCH_ESP32) && defined(CONFIG_ARDUHAL_ESP_LOG) 28 | #include "esp32-hal-log.h" 29 | #define TAG "" 30 | #else 31 | #include "esp_log.h" 32 | static const char* TAG = "esp_jpg_decode"; 33 | #endif 34 | 35 | typedef struct { 36 | jpg_scale_t scale; 37 | jpg_reader_cb reader; 38 | jpg_writer_cb writer; 39 | void * arg; 40 | size_t len; 41 | size_t index; 42 | } esp_jpg_decoder_t; 43 | 44 | static const char * jd_errors[] = { 45 | "Succeeded", 46 | "Interrupted by output function", 47 | "Device error or wrong termination of input stream", 48 | "Insufficient memory pool for the image", 49 | "Insufficient stream input buffer", 50 | "Parameter error", 51 | "Data format error", 52 | "Right format but not supported", 53 | "Not supported JPEG standard" 54 | }; 55 | 56 | static uint32_t _jpg_write(JDEC *decoder, void *bitmap, JRECT *rect) 57 | { 58 | uint16_t x = rect->left; 59 | uint16_t y = rect->top; 60 | uint16_t w = rect->right + 1 - x; 61 | uint16_t h = rect->bottom + 1 - y; 62 | uint8_t *data = (uint8_t *)bitmap; 63 | 64 | esp_jpg_decoder_t * jpeg = (esp_jpg_decoder_t *)decoder->device; 65 | 66 | if (jpeg->writer) { 67 | return jpeg->writer(jpeg->arg, x, y, w, h, data); 68 | } 69 | return 0; 70 | } 71 | 72 | static uint32_t _jpg_read(JDEC *decoder, uint8_t *buf, uint32_t len) 73 | { 74 | esp_jpg_decoder_t * jpeg = (esp_jpg_decoder_t *)decoder->device; 75 | if (jpeg->len && len > (jpeg->len - jpeg->index)) { 76 | len = jpeg->len - jpeg->index; 77 | } 78 | if (len) { 79 | len = jpeg->reader(jpeg->arg, jpeg->index, buf, len); 80 | if (!len) { 81 | ESP_LOGE(TAG, "Read Fail at %u/%u", jpeg->index, jpeg->len); 82 | } 83 | jpeg->index += len; 84 | } 85 | return len; 86 | } 87 | 88 | esp_err_t esp_jpg_decode(size_t len, jpg_scale_t scale, jpg_reader_cb reader, jpg_writer_cb writer, void * arg) 89 | { 90 | static uint8_t work[3100]; 91 | JDEC decoder; 92 | esp_jpg_decoder_t jpeg; 93 | 94 | jpeg.len = len; 95 | jpeg.reader = reader; 96 | jpeg.writer = writer; 97 | jpeg.arg = arg; 98 | jpeg.scale = scale; 99 | jpeg.index = 0; 100 | 101 | JRESULT jres = jd_prepare(&decoder, _jpg_read, work, 3100, &jpeg); 102 | if(jres != JDR_OK){ 103 | ESP_LOGE(TAG, "JPG Header Parse Failed! %s", jd_errors[jres]); 104 | return ESP_FAIL; 105 | } 106 | 107 | uint16_t output_width = decoder.width / (1 << (uint8_t)(jpeg.scale)); 108 | uint16_t output_height = decoder.height / (1 << (uint8_t)(jpeg.scale)); 109 | 110 | //output start 111 | writer(arg, 0, 0, output_width, output_height, NULL); 112 | //output write 113 | jres = jd_decomp(&decoder, _jpg_write, (uint8_t)jpeg.scale); 114 | //output end 115 | writer(arg, output_width, output_height, output_width, output_height, NULL); 116 | 117 | if (jres != JDR_OK) { 118 | ESP_LOGE(TAG, "JPG Decompression Failed! %s", jd_errors[jres]); 119 | return ESP_FAIL; 120 | } 121 | //check if all data has been consumed. 122 | if (len && jpeg.index < len) { 123 | _jpg_read(&decoder, NULL, len - jpeg.index); 124 | } 125 | 126 | return ESP_OK; 127 | } 128 | 129 | -------------------------------------------------------------------------------- /esp-idf_components_esp32-camera/conversions/include/esp_jpg_decode.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015-2016 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 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | #ifndef _ESP_JPG_DECODE_H_ 15 | #define _ESP_JPG_DECODE_H_ 16 | 17 | #ifdef __cplusplus 18 | extern "C" { 19 | #endif 20 | 21 | #include 22 | #include 23 | #include 24 | #include "esp_err.h" 25 | 26 | typedef enum { 27 | JPG_SCALE_NONE, 28 | JPG_SCALE_2X, 29 | JPG_SCALE_4X, 30 | JPG_SCALE_8X, 31 | JPG_SCALE_MAX = JPG_SCALE_8X 32 | } jpg_scale_t; 33 | 34 | typedef size_t (* jpg_reader_cb)(void * arg, size_t index, uint8_t *buf, size_t len); 35 | typedef bool (* jpg_writer_cb)(void * arg, uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint8_t *data); 36 | 37 | esp_err_t esp_jpg_decode(size_t len, jpg_scale_t scale, jpg_reader_cb reader, jpg_writer_cb writer, void * arg); 38 | 39 | #ifdef __cplusplus 40 | } 41 | #endif 42 | 43 | #endif /* _ESP_JPG_DECODE_H_ */ 44 | -------------------------------------------------------------------------------- /esp-idf_components_esp32-camera/conversions/include/img_converters.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015-2016 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 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | #ifndef _IMG_CONVERTERS_H_ 15 | #define _IMG_CONVERTERS_H_ 16 | 17 | #ifdef __cplusplus 18 | extern "C" { 19 | #endif 20 | 21 | #include 22 | #include 23 | #include 24 | #include "esp_camera.h" 25 | 26 | typedef size_t (* jpg_out_cb)(void * arg, size_t index, const void* data, size_t len); 27 | 28 | /** 29 | * @brief Convert image buffer to JPEG 30 | * 31 | * @param src Source buffer in RGB565, RGB888, YUYV or GRAYSCALE format 32 | * @param src_len Length in bytes of the source buffer 33 | * @param width Width in pixels of the source image 34 | * @param height Height in pixels of the source image 35 | * @param format Format of the source image 36 | * @param quality JPEG quality of the resulting image 37 | * @param cp Callback to be called to write the bytes of the output JPEG 38 | * @param arg Pointer to be passed to the callback 39 | * 40 | * @return true on success 41 | */ 42 | bool fmt2jpg_cb(uint8_t *src, size_t src_len, uint16_t width, uint16_t height, pixformat_t format, uint8_t quality, jpg_out_cb cb, void * arg); 43 | 44 | /** 45 | * @brief Convert camera frame buffer to JPEG 46 | * 47 | * @param fb Source camera frame buffer 48 | * @param quality JPEG quality of the resulting image 49 | * @param cp Callback to be called to write the bytes of the output JPEG 50 | * @param arg Pointer to be passed to the callback 51 | * 52 | * @return true on success 53 | */ 54 | bool frame2jpg_cb(camera_fb_t * fb, uint8_t quality, jpg_out_cb cb, void * arg); 55 | 56 | /** 57 | * @brief Convert image buffer to JPEG buffer 58 | * 59 | * @param src Source buffer in RGB565, RGB888, YUYV or GRAYSCALE format 60 | * @param src_len Length in bytes of the source buffer 61 | * @param width Width in pixels of the source image 62 | * @param height Height in pixels of the source image 63 | * @param format Format of the source image 64 | * @param quality JPEG quality of the resulting image 65 | * @param out Pointer to be populated with the address of the resulting buffer 66 | * @param out_len Pointer to be populated with the length of the output buffer 67 | * 68 | * @return true on success 69 | */ 70 | bool fmt2jpg(uint8_t *src, size_t src_len, uint16_t width, uint16_t height, pixformat_t format, uint8_t quality, uint8_t ** out, size_t * out_len); 71 | 72 | /** 73 | * @brief Convert camera frame buffer to JPEG buffer 74 | * 75 | * @param fb Source camera frame buffer 76 | * @param quality JPEG quality of the resulting image 77 | * @param out Pointer to be populated with the address of the resulting buffer 78 | * @param out_len Pointer to be populated with the length of the output buffer 79 | * 80 | * @return true on success 81 | */ 82 | bool frame2jpg(camera_fb_t * fb, uint8_t quality, uint8_t ** out, size_t * out_len); 83 | 84 | /** 85 | * @brief Convert image buffer to BMP buffer 86 | * 87 | * @param src Source buffer in JPEG, RGB565, RGB888, YUYV or GRAYSCALE format 88 | * @param src_len Length in bytes of the source buffer 89 | * @param width Width in pixels of the source image 90 | * @param height Height in pixels of the source image 91 | * @param format Format of the source image 92 | * @param out Pointer to be populated with the address of the resulting buffer 93 | * @param out_len Pointer to be populated with the length of the output buffer 94 | * 95 | * @return true on success 96 | */ 97 | bool fmt2bmp(uint8_t *src, size_t src_len, uint16_t width, uint16_t height, pixformat_t format, uint8_t ** out, size_t * out_len); 98 | 99 | /** 100 | * @brief Convert camera frame buffer to BMP buffer 101 | * 102 | * @param fb Source camera frame buffer 103 | * @param out Pointer to be populated with the address of the resulting buffer 104 | * @param out_len Pointer to be populated with the length of the output buffer 105 | * 106 | * @return true on success 107 | */ 108 | bool frame2bmp(camera_fb_t * fb, uint8_t ** out, size_t * out_len); 109 | 110 | /** 111 | * @brief Convert image buffer to RGB888 buffer (used for face detection) 112 | * 113 | * @param src Source buffer in JPEG, RGB565, RGB888, YUYV or GRAYSCALE format 114 | * @param src_len Length in bytes of the source buffer 115 | * @param format Format of the source image 116 | * @param rgb_buf Pointer to the output buffer (width * height * 3) 117 | * 118 | * @return true on success 119 | */ 120 | bool fmt2rgb888(const uint8_t *src_buf, size_t src_len, pixformat_t format, uint8_t * rgb_buf); 121 | 122 | #ifdef __cplusplus 123 | } 124 | #endif 125 | 126 | #endif /* _IMG_CONVERTERS_H_ */ 127 | -------------------------------------------------------------------------------- /esp-idf_components_esp32-camera/conversions/private_include/jpge.h: -------------------------------------------------------------------------------- 1 | // jpge.h - C++ class for JPEG compression. 2 | // Public domain, Rich Geldreich 3 | // Alex Evans: Added RGBA support, linear memory allocator. 4 | #ifndef JPEG_ENCODER_H 5 | #define JPEG_ENCODER_H 6 | 7 | namespace jpge 8 | { 9 | typedef unsigned char uint8; 10 | typedef signed short int16; 11 | typedef signed int int32; 12 | typedef unsigned short uint16; 13 | typedef unsigned int uint32; 14 | typedef unsigned int uint; 15 | 16 | // JPEG chroma subsampling factors. Y_ONLY (grayscale images) and H2V2 (color images) are the most common. 17 | enum subsampling_t { Y_ONLY = 0, H1V1 = 1, H2V1 = 2, H2V2 = 3 }; 18 | 19 | // JPEG compression parameters structure. 20 | struct params { 21 | inline params() : m_quality(85), m_subsampling(H2V2) { } 22 | 23 | inline bool check() const { 24 | if ((m_quality < 1) || (m_quality > 100)) { 25 | return false; 26 | } 27 | if ((uint)m_subsampling > (uint)H2V2) { 28 | return false; 29 | } 30 | return true; 31 | } 32 | 33 | // Quality: 1-100, higher is better. Typical values are around 50-95. 34 | int m_quality; 35 | 36 | // m_subsampling: 37 | // 0 = Y (grayscale) only 38 | // 1 = H1V1 subsampling (YCbCr 1x1x1, 3 blocks per MCU) 39 | // 2 = H2V1 subsampling (YCbCr 2x1x1, 4 blocks per MCU) 40 | // 3 = H2V2 subsampling (YCbCr 4x1x1, 6 blocks per MCU-- very common) 41 | subsampling_t m_subsampling; 42 | }; 43 | 44 | // Output stream abstract class - used by the jpeg_encoder class to write to the output stream. 45 | // put_buf() is generally called with len==JPGE_OUT_BUF_SIZE bytes, but for headers it'll be called with smaller amounts. 46 | class output_stream { 47 | public: 48 | virtual ~output_stream() { }; 49 | virtual bool put_buf(const void* Pbuf, int len) = 0; 50 | virtual uint get_size() const = 0; 51 | }; 52 | 53 | // Lower level jpeg_encoder class - useful if more control is needed than the above helper functions. 54 | class jpeg_encoder { 55 | public: 56 | jpeg_encoder(); 57 | ~jpeg_encoder(); 58 | 59 | // Initializes the compressor. 60 | // pStream: The stream object to use for writing compressed data. 61 | // params - Compression parameters structure, defined above. 62 | // width, height - Image dimensions. 63 | // channels - May be 1, or 3. 1 indicates grayscale, 3 indicates RGB source data. 64 | // Returns false on out of memory or if a stream write fails. 65 | bool init(output_stream *pStream, int width, int height, int src_channels, const params &comp_params = params()); 66 | 67 | // Call this method with each source scanline. 68 | // width * src_channels bytes per scanline is expected (RGB or Y format). 69 | // You must call with NULL after all scanlines are processed to finish compression. 70 | // Returns false on out of memory or if a stream write fails. 71 | bool process_scanline(const void* pScanline); 72 | 73 | // Deinitializes the compressor, freeing any allocated memory. May be called at any time. 74 | void deinit(); 75 | 76 | private: 77 | jpeg_encoder(const jpeg_encoder &); 78 | jpeg_encoder &operator =(const jpeg_encoder &); 79 | 80 | typedef int32 sample_array_t; 81 | enum { JPGE_OUT_BUF_SIZE = 512 }; 82 | 83 | output_stream *m_pStream; 84 | params m_params; 85 | uint8 m_num_components; 86 | uint8 m_comp_h_samp[3], m_comp_v_samp[3]; 87 | int m_image_x, m_image_y, m_image_bpp, m_image_bpl; 88 | int m_image_x_mcu, m_image_y_mcu; 89 | int m_image_bpl_xlt, m_image_bpl_mcu; 90 | int m_mcus_per_row; 91 | int m_mcu_x, m_mcu_y; 92 | uint8 *m_mcu_lines[16]; 93 | uint8 m_mcu_y_ofs; 94 | sample_array_t m_sample_array[64]; 95 | int16 m_coefficient_array[64]; 96 | 97 | int m_last_dc_val[3]; 98 | uint8 m_out_buf[JPGE_OUT_BUF_SIZE]; 99 | uint8 *m_pOut_buf; 100 | uint m_out_buf_left; 101 | uint32 m_bit_buffer; 102 | uint m_bits_in; 103 | uint8 m_pass_num; 104 | bool m_all_stream_writes_succeeded; 105 | 106 | bool jpg_open(int p_x_res, int p_y_res, int src_channels); 107 | 108 | void flush_output_buffer(); 109 | void put_bits(uint bits, uint len); 110 | 111 | void emit_byte(uint8 i); 112 | void emit_word(uint i); 113 | void emit_marker(int marker); 114 | 115 | void emit_jfif_app0(); 116 | void emit_dqt(); 117 | void emit_sof(); 118 | void emit_dht(uint8 *bits, uint8 *val, int index, bool ac_flag); 119 | void emit_dhts(); 120 | void emit_sos(); 121 | 122 | void compute_quant_table(int32 *dst, const int16 *src); 123 | void load_quantized_coefficients(int component_num); 124 | 125 | void load_block_8_8_grey(int x); 126 | void load_block_8_8(int x, int y, int c); 127 | void load_block_16_8(int x, int c); 128 | void load_block_16_8_8(int x, int c); 129 | 130 | void code_coefficients_pass_two(int component_num); 131 | void code_block(int component_num); 132 | 133 | void process_mcu_row(); 134 | bool process_end_of_image(); 135 | void load_mcu(const void* src); 136 | void clear(); 137 | void init(); 138 | }; 139 | 140 | } // namespace jpge 141 | 142 | #endif // JPEG_ENCODER 143 | -------------------------------------------------------------------------------- /esp-idf_components_esp32-camera/conversions/private_include/yuv.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015-2016 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 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | #ifndef _CONVERSIONS_YUV_H_ 15 | #define _CONVERSIONS_YUV_H_ 16 | 17 | #ifdef __cplusplus 18 | extern "C" { 19 | #endif 20 | 21 | #include 22 | 23 | void yuv2rgb(uint8_t y, uint8_t u, uint8_t v, uint8_t *r, uint8_t *g, uint8_t *b); 24 | 25 | #ifdef __cplusplus 26 | } 27 | #endif 28 | 29 | #endif /* _CONVERSIONS_YUV_H_ */ 30 | -------------------------------------------------------------------------------- /esp-idf_components_esp32-camera/conversions/to_bmp.c: -------------------------------------------------------------------------------- 1 | // Copyright 2015-2016 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 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | #include 15 | #include 16 | #include "img_converters.h" 17 | #include "esp32/spiram.h" 18 | #include "soc/efuse_reg.h" 19 | #include "esp_heap_caps.h" 20 | #include "yuv.h" 21 | #include "sdkconfig.h" 22 | #include "esp_jpg_decode.h" 23 | 24 | #if defined(ARDUINO_ARCH_ESP32) && defined(CONFIG_ARDUHAL_ESP_LOG) 25 | #include "esp32-hal-log.h" 26 | #define TAG "" 27 | #else 28 | #include "esp_log.h" 29 | static const char* TAG = "to_bmp"; 30 | #endif 31 | 32 | static const int BMP_HEADER_LEN = 54; 33 | 34 | typedef struct { 35 | uint32_t filesize; 36 | uint32_t reserved; 37 | uint32_t fileoffset_to_pixelarray; 38 | uint32_t dibheadersize; 39 | int32_t width; 40 | int32_t height; 41 | uint16_t planes; 42 | uint16_t bitsperpixel; 43 | uint32_t compression; 44 | uint32_t imagesize; 45 | uint32_t ypixelpermeter; 46 | uint32_t xpixelpermeter; 47 | uint32_t numcolorspallette; 48 | uint32_t mostimpcolor; 49 | } bmp_header_t; 50 | 51 | typedef struct { 52 | uint16_t width; 53 | uint16_t height; 54 | uint16_t data_offset; 55 | const uint8_t *input; 56 | uint8_t *output; 57 | } rgb_jpg_decoder; 58 | 59 | static void *_malloc(size_t size) 60 | { 61 | return heap_caps_malloc(size, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); 62 | } 63 | 64 | //output buffer and image width 65 | static bool _rgb_write(void * arg, uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint8_t *data) 66 | { 67 | rgb_jpg_decoder * jpeg = (rgb_jpg_decoder *)arg; 68 | if(!data){ 69 | if(x == 0 && y == 0){ 70 | //write start 71 | jpeg->width = w; 72 | jpeg->height = h; 73 | //if output is null, this is BMP 74 | if(!jpeg->output){ 75 | jpeg->output = (uint8_t *)_malloc((w*h*3)+jpeg->data_offset); 76 | if(!jpeg->output){ 77 | return false; 78 | } 79 | } 80 | } else { 81 | //write end 82 | } 83 | return true; 84 | } 85 | 86 | size_t jw = jpeg->width*3; 87 | size_t t = y * jw; 88 | size_t b = t + (h * jw); 89 | size_t l = x * 3; 90 | uint8_t *out = jpeg->output+jpeg->data_offset; 91 | uint8_t *o = out; 92 | size_t iy, ix; 93 | 94 | w = w * 3; 95 | 96 | for(iy=t; iyinput + index, len); 114 | } 115 | return len; 116 | } 117 | 118 | static bool jpg2rgb888(const uint8_t *src, size_t src_len, uint8_t * out, jpg_scale_t scale) 119 | { 120 | rgb_jpg_decoder jpeg; 121 | jpeg.width = 0; 122 | jpeg.height = 0; 123 | jpeg.input = src; 124 | jpeg.output = out; 125 | jpeg.data_offset = 0; 126 | 127 | if(esp_jpg_decode(src_len, scale, _jpg_read, _rgb_write, (void*)&jpeg) != ESP_OK){ 128 | return false; 129 | } 130 | return true; 131 | } 132 | 133 | bool jpg2bmp(const uint8_t *src, size_t src_len, uint8_t ** out, size_t * out_len) 134 | { 135 | 136 | rgb_jpg_decoder jpeg; 137 | jpeg.width = 0; 138 | jpeg.height = 0; 139 | jpeg.input = src; 140 | jpeg.output = NULL; 141 | jpeg.data_offset = BMP_HEADER_LEN; 142 | 143 | if(esp_jpg_decode(src_len, JPG_SCALE_NONE, _jpg_read, _rgb_write, (void*)&jpeg) != ESP_OK){ 144 | return false; 145 | } 146 | 147 | size_t output_size = jpeg.width*jpeg.height*3; 148 | 149 | jpeg.output[0] = 'B'; 150 | jpeg.output[1] = 'M'; 151 | bmp_header_t * bitmap = (bmp_header_t*)&jpeg.output[2]; 152 | bitmap->reserved = 0; 153 | bitmap->filesize = output_size+BMP_HEADER_LEN; 154 | bitmap->fileoffset_to_pixelarray = BMP_HEADER_LEN; 155 | bitmap->dibheadersize = 40; 156 | bitmap->width = jpeg.width; 157 | bitmap->height = -jpeg.height;//set negative for top to bottom 158 | bitmap->planes = 1; 159 | bitmap->bitsperpixel = 24; 160 | bitmap->compression = 0; 161 | bitmap->imagesize = output_size; 162 | bitmap->ypixelpermeter = 0x0B13 ; //2835 , 72 DPI 163 | bitmap->xpixelpermeter = 0x0B13 ; //2835 , 72 DPI 164 | bitmap->numcolorspallette = 0; 165 | bitmap->mostimpcolor = 0; 166 | 167 | *out = jpeg.output; 168 | *out_len = output_size+BMP_HEADER_LEN; 169 | 170 | return true; 171 | } 172 | 173 | bool fmt2rgb888(const uint8_t *src_buf, size_t src_len, pixformat_t format, uint8_t * rgb_buf) 174 | { 175 | int pix_count = 0; 176 | if(format == PIXFORMAT_JPEG) { 177 | return jpg2rgb888(src_buf, src_len, rgb_buf, JPG_SCALE_NONE); 178 | } else if(format == PIXFORMAT_RGB888) { 179 | memcpy(rgb_buf, src_buf, src_len); 180 | } else if(format == PIXFORMAT_RGB565) { 181 | int i; 182 | uint8_t hb, lb; 183 | pix_count = src_len / 2; 184 | for(i=0; i> 3; 189 | *rgb_buf++ = hb & 0xF8; 190 | } 191 | } else if(format == PIXFORMAT_GRAYSCALE) { 192 | int i; 193 | uint8_t b; 194 | pix_count = src_len; 195 | for(i=0; ireserved = 0; 247 | bitmap->filesize = out_size; 248 | bitmap->fileoffset_to_pixelarray = BMP_HEADER_LEN; 249 | bitmap->dibheadersize = 40; 250 | bitmap->width = width; 251 | bitmap->height = -height;//set negative for top to bottom 252 | bitmap->planes = 1; 253 | bitmap->bitsperpixel = 24; 254 | bitmap->compression = 0; 255 | bitmap->imagesize = pix_count * 3; 256 | bitmap->ypixelpermeter = 0x0B13 ; //2835 , 72 DPI 257 | bitmap->xpixelpermeter = 0x0B13 ; //2835 , 72 DPI 258 | bitmap->numcolorspallette = 0; 259 | bitmap->mostimpcolor = 0; 260 | 261 | uint8_t * rgb_buf = out_buf + BMP_HEADER_LEN; 262 | uint8_t * src_buf = src; 263 | 264 | 265 | //convert data to RGB888 266 | if(format == PIXFORMAT_RGB888) { 267 | memcpy(rgb_buf, src_buf, pix_count*3); 268 | } else if(format == PIXFORMAT_RGB565) { 269 | int i; 270 | uint8_t hb, lb; 271 | for(i=0; i> 3; 276 | *rgb_buf++ = hb & 0xF8; 277 | } 278 | } else if(format == PIXFORMAT_GRAYSCALE) { 279 | int i; 280 | uint8_t b; 281 | for(i=0; ibuf, fb->len, fb->width, fb->height, fb->format, out, out_len); 316 | } 317 | -------------------------------------------------------------------------------- /esp-idf_components_esp32-camera/conversions/to_jpg.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015-2016 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 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | #include 15 | #include 16 | #include "esp_attr.h" 17 | #include "soc/efuse_reg.h" 18 | #include "esp_heap_caps.h" 19 | #include "esp_camera.h" 20 | #include "img_converters.h" 21 | #include "jpge.h" 22 | #include "yuv.h" 23 | 24 | #include "esp_system.h" 25 | #if ESP_IDF_VERSION_MAJOR >= 4 // IDF 4+ 26 | #if CONFIG_IDF_TARGET_ESP32 // ESP32/PICO-D4 27 | #include "esp32/spiram.h" 28 | #else 29 | #error Target CONFIG_IDF_TARGET is not supported 30 | #endif 31 | #else // ESP32 Before IDF 4.0 32 | #include "esp_spiram.h" 33 | #endif 34 | 35 | #if defined(ARDUINO_ARCH_ESP32) && defined(CONFIG_ARDUHAL_ESP_LOG) 36 | #include "esp32-hal-log.h" 37 | #define TAG "" 38 | #else 39 | #include "esp_log.h" 40 | static const char* TAG = "to_jpg"; 41 | #endif 42 | 43 | static void *_malloc(size_t size) 44 | { 45 | void * res = malloc(size); 46 | if(res) { 47 | return res; 48 | } 49 | return heap_caps_malloc(size, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); 50 | } 51 | 52 | static IRAM_ATTR void convert_line_format(uint8_t * src, pixformat_t format, uint8_t * dst, size_t width, size_t in_channels, size_t line) 53 | { 54 | int i=0, o=0, l=0; 55 | if(format == PIXFORMAT_GRAYSCALE) { 56 | memcpy(dst, src + line * width, width); 57 | } else if(format == PIXFORMAT_RGB888) { 58 | l = width * 3; 59 | src += l * line; 60 | for(i=0; i> 3; 71 | dst[o++] = (src[i+1] & 0x1F) << 3; 72 | } 73 | } else if(format == PIXFORMAT_YUV422) { 74 | uint8_t y0, y1, u, v; 75 | uint8_t r, g, b; 76 | l = width * 2; 77 | src += l * line; 78 | for(i=0; i 100) { 110 | quality = 100; 111 | } 112 | 113 | jpge::params comp_params = jpge::params(); 114 | comp_params.m_subsampling = subsampling; 115 | comp_params.m_quality = quality; 116 | 117 | jpge::jpeg_encoder dst_image; 118 | 119 | if (!dst_image.init(dst_stream, width, height, num_channels, comp_params)) { 120 | ESP_LOGE(TAG, "JPG encoder init failed"); 121 | return false; 122 | } 123 | 124 | uint8_t* line = (uint8_t*)_malloc(width * num_channels); 125 | if(!line) { 126 | ESP_LOGE(TAG, "Scan line malloc failed"); 127 | return false; 128 | } 129 | 130 | for (int i = 0; i < height; i++) { 131 | convert_line_format(src, format, line, width, num_channels, i); 132 | if (!dst_image.process_scanline(line)) { 133 | ESP_LOGE(TAG, "JPG process line %u failed", i); 134 | free(line); 135 | return false; 136 | } 137 | } 138 | free(line); 139 | 140 | if (!dst_image.process_scanline(NULL)) { 141 | ESP_LOGE(TAG, "JPG image finish failed"); 142 | return false; 143 | } 144 | dst_image.deinit(); 145 | return true; 146 | } 147 | 148 | class callback_stream : public jpge::output_stream { 149 | protected: 150 | jpg_out_cb ocb; 151 | void * oarg; 152 | size_t index; 153 | 154 | public: 155 | callback_stream(jpg_out_cb cb, void * arg) : ocb(cb), oarg(arg), index(0) { } 156 | virtual ~callback_stream() { } 157 | virtual bool put_buf(const void* data, int len) 158 | { 159 | index += ocb(oarg, index, data, len); 160 | return true; 161 | } 162 | virtual size_t get_size() const 163 | { 164 | return index; 165 | } 166 | }; 167 | 168 | bool fmt2jpg_cb(uint8_t *src, size_t src_len, uint16_t width, uint16_t height, pixformat_t format, uint8_t quality, jpg_out_cb cb, void * arg) 169 | { 170 | callback_stream dst_stream(cb, arg); 171 | return convert_image(src, width, height, format, quality, &dst_stream); 172 | } 173 | 174 | bool frame2jpg_cb(camera_fb_t * fb, uint8_t quality, jpg_out_cb cb, void * arg) 175 | { 176 | return fmt2jpg_cb(fb->buf, fb->len, fb->width, fb->height, fb->format, quality, cb, arg); 177 | } 178 | 179 | 180 | 181 | class memory_stream : public jpge::output_stream { 182 | protected: 183 | uint8_t *out_buf; 184 | size_t max_len, index; 185 | 186 | public: 187 | memory_stream(void *pBuf, uint buf_size) : out_buf(static_cast(pBuf)), max_len(buf_size), index(0) { } 188 | 189 | virtual ~memory_stream() { } 190 | 191 | virtual bool put_buf(const void* pBuf, int len) 192 | { 193 | if (!pBuf) { 194 | //end of image 195 | return true; 196 | } 197 | if ((size_t)len > (max_len - index)) { 198 | ESP_LOGW(TAG, "JPG output overflow: %d bytes", len - (max_len - index)); 199 | len = max_len - index; 200 | } 201 | if (len) { 202 | memcpy(out_buf + index, pBuf, len); 203 | index += len; 204 | } 205 | return true; 206 | } 207 | 208 | virtual size_t get_size() const 209 | { 210 | return index; 211 | } 212 | }; 213 | 214 | bool fmt2jpg(uint8_t *src, size_t src_len, uint16_t width, uint16_t height, pixformat_t format, uint8_t quality, uint8_t ** out, size_t * out_len) 215 | { 216 | //todo: allocate proper buffer for holding JPEG data 217 | //this should be enough for CIF frame size 218 | int jpg_buf_len = 64*1024; 219 | 220 | 221 | uint8_t * jpg_buf = (uint8_t *)_malloc(jpg_buf_len); 222 | if(jpg_buf == NULL) { 223 | ESP_LOGE(TAG, "JPG buffer malloc failed"); 224 | return false; 225 | } 226 | memory_stream dst_stream(jpg_buf, jpg_buf_len); 227 | 228 | if(!convert_image(src, width, height, format, quality, &dst_stream)) { 229 | free(jpg_buf); 230 | return false; 231 | } 232 | 233 | *out = jpg_buf; 234 | *out_len = dst_stream.get_size(); 235 | return true; 236 | } 237 | 238 | bool frame2jpg(camera_fb_t * fb, uint8_t quality, uint8_t ** out, size_t * out_len) 239 | { 240 | return fmt2jpg(fb->buf, fb->len, fb->width, fb->height, fb->format, quality, out, out_len); 241 | } 242 | -------------------------------------------------------------------------------- /esp-idf_components_esp32-camera/conversions/yuv.c: -------------------------------------------------------------------------------- 1 | // Copyright 2015-2016 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 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | #include "yuv.h" 15 | #include "esp_attr.h" 16 | 17 | typedef struct { 18 | int16_t vY; 19 | int16_t vVr; 20 | int16_t vVg; 21 | int16_t vUg; 22 | int16_t vUb; 23 | } yuv_table_row; 24 | 25 | static const yuv_table_row yuv_table[256] = { 26 | // Y Vr Vg Ug Ub // # 27 | { -18, -204, 50, 104, -258 }, // 0 28 | { -17, -202, 49, 103, -256 }, // 1 29 | { -16, -201, 49, 102, -254 }, // 2 30 | { -15, -199, 48, 101, -252 }, // 3 31 | { -13, -197, 48, 100, -250 }, // 4 32 | { -12, -196, 48, 99, -248 }, // 5 33 | { -11, -194, 47, 99, -246 }, // 6 34 | { -10, -193, 47, 98, -244 }, // 7 35 | { -9, -191, 46, 97, -242 }, // 8 36 | { -8, -189, 46, 96, -240 }, // 9 37 | { -6, -188, 46, 95, -238 }, // 10 38 | { -5, -186, 45, 95, -236 }, // 11 39 | { -4, -185, 45, 94, -234 }, // 12 40 | { -3, -183, 44, 93, -232 }, // 13 41 | { -2, -181, 44, 92, -230 }, // 14 42 | { -1, -180, 44, 91, -228 }, // 15 43 | { 0, -178, 43, 91, -226 }, // 16 44 | { 1, -177, 43, 90, -223 }, // 17 45 | { 2, -175, 43, 89, -221 }, // 18 46 | { 3, -173, 42, 88, -219 }, // 19 47 | { 4, -172, 42, 87, -217 }, // 20 48 | { 5, -170, 41, 86, -215 }, // 21 49 | { 6, -169, 41, 86, -213 }, // 22 50 | { 8, -167, 41, 85, -211 }, // 23 51 | { 9, -165, 40, 84, -209 }, // 24 52 | { 10, -164, 40, 83, -207 }, // 25 53 | { 11, -162, 39, 82, -205 }, // 26 54 | { 12, -161, 39, 82, -203 }, // 27 55 | { 13, -159, 39, 81, -201 }, // 28 56 | { 15, -158, 38, 80, -199 }, // 29 57 | { 16, -156, 38, 79, -197 }, // 30 58 | { 17, -154, 37, 78, -195 }, // 31 59 | { 18, -153, 37, 78, -193 }, // 32 60 | { 19, -151, 37, 77, -191 }, // 33 61 | { 20, -150, 36, 76, -189 }, // 34 62 | { 22, -148, 36, 75, -187 }, // 35 63 | { 23, -146, 35, 74, -185 }, // 36 64 | { 24, -145, 35, 73, -183 }, // 37 65 | { 25, -143, 35, 73, -181 }, // 38 66 | { 26, -142, 34, 72, -179 }, // 39 67 | { 27, -140, 34, 71, -177 }, // 40 68 | { 29, -138, 34, 70, -175 }, // 41 69 | { 30, -137, 33, 69, -173 }, // 42 70 | { 31, -135, 33, 69, -171 }, // 43 71 | { 32, -134, 32, 68, -169 }, // 44 72 | { 33, -132, 32, 67, -167 }, // 45 73 | { 34, -130, 32, 66, -165 }, // 46 74 | { 36, -129, 31, 65, -163 }, // 47 75 | { 37, -127, 31, 65, -161 }, // 48 76 | { 38, -126, 30, 64, -159 }, // 49 77 | { 39, -124, 30, 63, -157 }, // 50 78 | { 40, -122, 30, 62, -155 }, // 51 79 | { 41, -121, 29, 61, -153 }, // 52 80 | { 43, -119, 29, 60, -151 }, // 53 81 | { 44, -118, 28, 60, -149 }, // 54 82 | { 45, -116, 28, 59, -147 }, // 55 83 | { 46, -114, 28, 58, -145 }, // 56 84 | { 47, -113, 27, 57, -143 }, // 57 85 | { 48, -111, 27, 56, -141 }, // 58 86 | { 50, -110, 26, 56, -139 }, // 59 87 | { 51, -108, 26, 55, -137 }, // 60 88 | { 52, -106, 26, 54, -135 }, // 61 89 | { 53, -105, 25, 53, -133 }, // 62 90 | { 54, -103, 25, 52, -131 }, // 63 91 | { 55, -102, 25, 52, -129 }, // 64 92 | { 57, -100, 24, 51, -127 }, // 65 93 | { 58, -98, 24, 50, -125 }, // 66 94 | { 59, -97, 23, 49, -123 }, // 67 95 | { 60, -95, 23, 48, -121 }, // 68 96 | { 61, -94, 23, 47, -119 }, // 69 97 | { 62, -92, 22, 47, -117 }, // 70 98 | { 64, -90, 22, 46, -115 }, // 71 99 | { 65, -89, 21, 45, -113 }, // 72 100 | { 66, -87, 21, 44, -110 }, // 73 101 | { 67, -86, 21, 43, -108 }, // 74 102 | { 68, -84, 20, 43, -106 }, // 75 103 | { 69, -82, 20, 42, -104 }, // 76 104 | { 71, -81, 19, 41, -102 }, // 77 105 | { 72, -79, 19, 40, -100 }, // 78 106 | { 73, -78, 19, 39, -98 }, // 79 107 | { 74, -76, 18, 39, -96 }, // 80 108 | { 75, -75, 18, 38, -94 }, // 81 109 | { 76, -73, 17, 37, -92 }, // 82 110 | { 77, -71, 17, 36, -90 }, // 83 111 | { 79, -70, 17, 35, -88 }, // 84 112 | { 80, -68, 16, 34, -86 }, // 85 113 | { 81, -67, 16, 34, -84 }, // 86 114 | { 82, -65, 16, 33, -82 }, // 87 115 | { 83, -63, 15, 32, -80 }, // 88 116 | { 84, -62, 15, 31, -78 }, // 89 117 | { 86, -60, 14, 30, -76 }, // 90 118 | { 87, -59, 14, 30, -74 }, // 91 119 | { 88, -57, 14, 29, -72 }, // 92 120 | { 89, -55, 13, 28, -70 }, // 93 121 | { 90, -54, 13, 27, -68 }, // 94 122 | { 91, -52, 12, 26, -66 }, // 95 123 | { 93, -51, 12, 26, -64 }, // 96 124 | { 94, -49, 12, 25, -62 }, // 97 125 | { 95, -47, 11, 24, -60 }, // 98 126 | { 96, -46, 11, 23, -58 }, // 99 127 | { 97, -44, 10, 22, -56 }, // 100 128 | { 98, -43, 10, 21, -54 }, // 101 129 | { 100, -41, 10, 21, -52 }, // 102 130 | { 101, -39, 9, 20, -50 }, // 103 131 | { 102, -38, 9, 19, -48 }, // 104 132 | { 103, -36, 8, 18, -46 }, // 105 133 | { 104, -35, 8, 17, -44 }, // 106 134 | { 105, -33, 8, 17, -42 }, // 107 135 | { 107, -31, 7, 16, -40 }, // 108 136 | { 108, -30, 7, 15, -38 }, // 109 137 | { 109, -28, 7, 14, -36 }, // 110 138 | { 110, -27, 6, 13, -34 }, // 111 139 | { 111, -25, 6, 13, -32 }, // 112 140 | { 112, -23, 5, 12, -30 }, // 113 141 | { 114, -22, 5, 11, -28 }, // 114 142 | { 115, -20, 5, 10, -26 }, // 115 143 | { 116, -19, 4, 9, -24 }, // 116 144 | { 117, -17, 4, 8, -22 }, // 117 145 | { 118, -15, 3, 8, -20 }, // 118 146 | { 119, -14, 3, 7, -18 }, // 119 147 | { 121, -12, 3, 6, -16 }, // 120 148 | { 122, -11, 2, 5, -14 }, // 121 149 | { 123, -9, 2, 4, -12 }, // 122 150 | { 124, -7, 1, 4, -10 }, // 123 151 | { 125, -6, 1, 3, -8 }, // 124 152 | { 126, -4, 1, 2, -6 }, // 125 153 | { 128, -3, 0, 1, -4 }, // 126 154 | { 129, -1, 0, 0, -2 }, // 127 155 | { 130, 0, 0, 0, 0 }, // 128 156 | { 131, 1, 0, 0, 2 }, // 129 157 | { 132, 3, 0, -1, 4 }, // 130 158 | { 133, 4, -1, -2, 6 }, // 131 159 | { 135, 6, -1, -3, 8 }, // 132 160 | { 136, 7, -1, -4, 10 }, // 133 161 | { 137, 9, -2, -4, 12 }, // 134 162 | { 138, 11, -2, -5, 14 }, // 135 163 | { 139, 12, -3, -6, 16 }, // 136 164 | { 140, 14, -3, -7, 18 }, // 137 165 | { 142, 15, -3, -8, 20 }, // 138 166 | { 143, 17, -4, -8, 22 }, // 139 167 | { 144, 19, -4, -9, 24 }, // 140 168 | { 145, 20, -5, -10, 26 }, // 141 169 | { 146, 22, -5, -11, 28 }, // 142 170 | { 147, 23, -5, -12, 30 }, // 143 171 | { 148, 25, -6, -13, 32 }, // 144 172 | { 150, 27, -6, -13, 34 }, // 145 173 | { 151, 28, -7, -14, 36 }, // 146 174 | { 152, 30, -7, -15, 38 }, // 147 175 | { 153, 31, -7, -16, 40 }, // 148 176 | { 154, 33, -8, -17, 42 }, // 149 177 | { 155, 35, -8, -17, 44 }, // 150 178 | { 157, 36, -8, -18, 46 }, // 151 179 | { 158, 38, -9, -19, 48 }, // 152 180 | { 159, 39, -9, -20, 50 }, // 153 181 | { 160, 41, -10, -21, 52 }, // 154 182 | { 161, 43, -10, -21, 54 }, // 155 183 | { 162, 44, -10, -22, 56 }, // 156 184 | { 164, 46, -11, -23, 58 }, // 157 185 | { 165, 47, -11, -24, 60 }, // 158 186 | { 166, 49, -12, -25, 62 }, // 159 187 | { 167, 51, -12, -26, 64 }, // 160 188 | { 168, 52, -12, -26, 66 }, // 161 189 | { 169, 54, -13, -27, 68 }, // 162 190 | { 171, 55, -13, -28, 70 }, // 163 191 | { 172, 57, -14, -29, 72 }, // 164 192 | { 173, 59, -14, -30, 74 }, // 165 193 | { 174, 60, -14, -30, 76 }, // 166 194 | { 175, 62, -15, -31, 78 }, // 167 195 | { 176, 63, -15, -32, 80 }, // 168 196 | { 178, 65, -16, -33, 82 }, // 169 197 | { 179, 67, -16, -34, 84 }, // 170 198 | { 180, 68, -16, -34, 86 }, // 171 199 | { 181, 70, -17, -35, 88 }, // 172 200 | { 182, 71, -17, -36, 90 }, // 173 201 | { 183, 73, -17, -37, 92 }, // 174 202 | { 185, 75, -18, -38, 94 }, // 175 203 | { 186, 76, -18, -39, 96 }, // 176 204 | { 187, 78, -19, -39, 98 }, // 177 205 | { 188, 79, -19, -40, 100 }, // 178 206 | { 189, 81, -19, -41, 102 }, // 179 207 | { 190, 82, -20, -42, 104 }, // 180 208 | { 192, 84, -20, -43, 106 }, // 181 209 | { 193, 86, -21, -43, 108 }, // 182 210 | { 194, 87, -21, -44, 110 }, // 183 211 | { 195, 89, -21, -45, 113 }, // 184 212 | { 196, 90, -22, -46, 115 }, // 185 213 | { 197, 92, -22, -47, 117 }, // 186 214 | { 199, 94, -23, -47, 119 }, // 187 215 | { 200, 95, -23, -48, 121 }, // 188 216 | { 201, 97, -23, -49, 123 }, // 189 217 | { 202, 98, -24, -50, 125 }, // 190 218 | { 203, 100, -24, -51, 127 }, // 191 219 | { 204, 102, -25, -52, 129 }, // 192 220 | { 206, 103, -25, -52, 131 }, // 193 221 | { 207, 105, -25, -53, 133 }, // 194 222 | { 208, 106, -26, -54, 135 }, // 195 223 | { 209, 108, -26, -55, 137 }, // 196 224 | { 210, 110, -26, -56, 139 }, // 197 225 | { 211, 111, -27, -56, 141 }, // 198 226 | { 213, 113, -27, -57, 143 }, // 199 227 | { 214, 114, -28, -58, 145 }, // 200 228 | { 215, 116, -28, -59, 147 }, // 201 229 | { 216, 118, -28, -60, 149 }, // 202 230 | { 217, 119, -29, -60, 151 }, // 203 231 | { 218, 121, -29, -61, 153 }, // 204 232 | { 219, 122, -30, -62, 155 }, // 205 233 | { 221, 124, -30, -63, 157 }, // 206 234 | { 222, 126, -30, -64, 159 }, // 207 235 | { 223, 127, -31, -65, 161 }, // 208 236 | { 224, 129, -31, -65, 163 }, // 209 237 | { 225, 130, -32, -66, 165 }, // 210 238 | { 226, 132, -32, -67, 167 }, // 211 239 | { 228, 134, -32, -68, 169 }, // 212 240 | { 229, 135, -33, -69, 171 }, // 213 241 | { 230, 137, -33, -69, 173 }, // 214 242 | { 231, 138, -34, -70, 175 }, // 215 243 | { 232, 140, -34, -71, 177 }, // 216 244 | { 233, 142, -34, -72, 179 }, // 217 245 | { 235, 143, -35, -73, 181 }, // 218 246 | { 236, 145, -35, -73, 183 }, // 219 247 | { 237, 146, -35, -74, 185 }, // 220 248 | { 238, 148, -36, -75, 187 }, // 221 249 | { 239, 150, -36, -76, 189 }, // 222 250 | { 240, 151, -37, -77, 191 }, // 223 251 | { 242, 153, -37, -78, 193 }, // 224 252 | { 243, 154, -37, -78, 195 }, // 225 253 | { 244, 156, -38, -79, 197 }, // 226 254 | { 245, 158, -38, -80, 199 }, // 227 255 | { 246, 159, -39, -81, 201 }, // 228 256 | { 247, 161, -39, -82, 203 }, // 229 257 | { 249, 162, -39, -82, 205 }, // 230 258 | { 250, 164, -40, -83, 207 }, // 231 259 | { 251, 165, -40, -84, 209 }, // 232 260 | { 252, 167, -41, -85, 211 }, // 233 261 | { 253, 169, -41, -86, 213 }, // 234 262 | { 254, 170, -41, -86, 215 }, // 235 263 | { 256, 172, -42, -87, 217 }, // 236 264 | { 257, 173, -42, -88, 219 }, // 237 265 | { 258, 175, -43, -89, 221 }, // 238 266 | { 259, 177, -43, -90, 223 }, // 239 267 | { 260, 178, -43, -91, 226 }, // 240 268 | { 261, 180, -44, -91, 228 }, // 241 269 | { 263, 181, -44, -92, 230 }, // 242 270 | { 264, 183, -44, -93, 232 }, // 243 271 | { 265, 185, -45, -94, 234 }, // 244 272 | { 266, 186, -45, -95, 236 }, // 245 273 | { 267, 188, -46, -95, 238 }, // 246 274 | { 268, 189, -46, -96, 240 }, // 247 275 | { 270, 191, -46, -97, 242 }, // 248 276 | { 271, 193, -47, -98, 244 }, // 249 277 | { 272, 194, -47, -99, 246 }, // 250 278 | { 273, 196, -48, -99, 248 }, // 251 279 | { 274, 197, -48, -100, 250 }, // 252 280 | { 275, 199, -48, -101, 252 }, // 253 281 | { 277, 201, -49, -102, 254 }, // 254 282 | { 278, 202, -49, -103, 256 } // 255 283 | }; 284 | 285 | #define YUYV_CONSTRAIN(v) ((v)<0)?0:(((v)>255)?255:(v)) 286 | 287 | void IRAM_ATTR yuv2rgb(uint8_t y, uint8_t u, uint8_t v, uint8_t *r, uint8_t *g, uint8_t *b) 288 | { 289 | int16_t ri, gi, bi; 290 | 291 | ri = yuv_table[y].vY + yuv_table[v].vVr; 292 | gi = yuv_table[y].vY + yuv_table[u].vUg + yuv_table[v].vVg; 293 | bi = yuv_table[y].vY + yuv_table[u].vUb; 294 | 295 | *r = YUYV_CONSTRAIN(ri); 296 | *g = YUYV_CONSTRAIN(gi); 297 | *b = YUYV_CONSTRAIN(bi); 298 | } 299 | -------------------------------------------------------------------------------- /esp-idf_components_esp32-camera/driver/include/esp_camera.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015-2016 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 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | /* 15 | * Example Use 16 | * 17 | static camera_config_t camera_example_config = { 18 | .pin_pwdn = PIN_PWDN, 19 | .pin_reset = PIN_RESET, 20 | .pin_xclk = PIN_XCLK, 21 | .pin_sscb_sda = PIN_SIOD, 22 | .pin_sscb_scl = PIN_SIOC, 23 | .pin_d7 = PIN_D7, 24 | .pin_d6 = PIN_D6, 25 | .pin_d5 = PIN_D5, 26 | .pin_d4 = PIN_D4, 27 | .pin_d3 = PIN_D3, 28 | .pin_d2 = PIN_D2, 29 | .pin_d1 = PIN_D1, 30 | .pin_d0 = PIN_D0, 31 | .pin_vsync = PIN_VSYNC, 32 | .pin_href = PIN_HREF, 33 | .pin_pclk = PIN_PCLK, 34 | 35 | .xclk_freq_hz = 20000000, 36 | .ledc_timer = LEDC_TIMER_0, 37 | .ledc_channel = LEDC_CHANNEL_0, 38 | .pixel_format = PIXFORMAT_JPEG, 39 | .frame_size = FRAMESIZE_SVGA, 40 | .jpeg_quality = 10, 41 | .fb_count = 2 42 | }; 43 | 44 | esp_err_t camera_example_init(){ 45 | return esp_camera_init(&camera_example_config); 46 | } 47 | 48 | esp_err_t camera_example_capture(){ 49 | //capture a frame 50 | camera_fb_t * fb = esp_camera_fb_get(); 51 | if (!fb) { 52 | ESP_LOGE(TAG, "Frame buffer could not be acquired"); 53 | return ESP_FAIL; 54 | } 55 | 56 | //replace this with your own function 57 | display_image(fb->width, fb->height, fb->pixformat, fb->buf, fb->len); 58 | 59 | //return the frame buffer back to be reused 60 | esp_camera_fb_return(fb); 61 | 62 | return ESP_OK; 63 | } 64 | */ 65 | 66 | #pragma once 67 | 68 | #include "esp_err.h" 69 | #include "driver/ledc.h" 70 | #include "sensor.h" 71 | #include "sys/time.h" 72 | 73 | #ifdef __cplusplus 74 | extern "C" { 75 | #endif 76 | 77 | /** 78 | * @brief Configuration structure for camera initialization 79 | */ 80 | typedef struct { 81 | int pin_pwdn; /*!< GPIO pin for camera power down line */ 82 | int pin_reset; /*!< GPIO pin for camera reset line */ 83 | int pin_xclk; /*!< GPIO pin for camera XCLK line */ 84 | int pin_sscb_sda; /*!< GPIO pin for camera SDA line */ 85 | int pin_sscb_scl; /*!< GPIO pin for camera SCL line */ 86 | int pin_d7; /*!< GPIO pin for camera D7 line */ 87 | int pin_d6; /*!< GPIO pin for camera D6 line */ 88 | int pin_d5; /*!< GPIO pin for camera D5 line */ 89 | int pin_d4; /*!< GPIO pin for camera D4 line */ 90 | int pin_d3; /*!< GPIO pin for camera D3 line */ 91 | int pin_d2; /*!< GPIO pin for camera D2 line */ 92 | int pin_d1; /*!< GPIO pin for camera D1 line */ 93 | int pin_d0; /*!< GPIO pin for camera D0 line */ 94 | int pin_vsync; /*!< GPIO pin for camera VSYNC line */ 95 | int pin_href; /*!< GPIO pin for camera HREF line */ 96 | int pin_pclk; /*!< GPIO pin for camera PCLK line */ 97 | 98 | int xclk_freq_hz; /*!< Frequency of XCLK signal, in Hz. Either 20KHz or 10KHz for OV2640 double FPS (Experimental) */ 99 | 100 | ledc_timer_t ledc_timer; /*!< LEDC timer to be used for generating XCLK */ 101 | ledc_channel_t ledc_channel; /*!< LEDC channel to be used for generating XCLK */ 102 | 103 | pixformat_t pixel_format; /*!< Format of the pixel data: PIXFORMAT_ + YUV422|GRAYSCALE|RGB565|JPEG */ 104 | framesize_t frame_size; /*!< Size of the output image: FRAMESIZE_ + QVGA|CIF|VGA|SVGA|XGA|SXGA|UXGA */ 105 | 106 | int jpeg_quality; /*!< Quality of JPEG output. 0-63 lower means higher quality */ 107 | size_t fb_count; /*!< Number of frame buffers to be allocated. If more than one, then each frame will be acquired (double speed) */ 108 | } camera_config_t; 109 | 110 | /** 111 | * @brief Data structure of camera frame buffer 112 | */ 113 | typedef struct { 114 | uint8_t * buf; /*!< Pointer to the pixel data */ 115 | size_t len; /*!< Length of the buffer in bytes */ 116 | size_t width; /*!< Width of the buffer in pixels */ 117 | size_t height; /*!< Height of the buffer in pixels */ 118 | pixformat_t format; /*!< Format of the pixel data */ 119 | struct timeval timestamp; /*!< Timestamp since boot of the first DMA buffer of the frame */ 120 | } camera_fb_t; 121 | 122 | #define ESP_ERR_CAMERA_BASE 0x20000 123 | #define ESP_ERR_CAMERA_NOT_DETECTED (ESP_ERR_CAMERA_BASE + 1) 124 | #define ESP_ERR_CAMERA_FAILED_TO_SET_FRAME_SIZE (ESP_ERR_CAMERA_BASE + 2) 125 | #define ESP_ERR_CAMERA_FAILED_TO_SET_OUT_FORMAT (ESP_ERR_CAMERA_BASE + 3) 126 | #define ESP_ERR_CAMERA_NOT_SUPPORTED (ESP_ERR_CAMERA_BASE + 4) 127 | 128 | /** 129 | * @brief Initialize the camera driver 130 | * 131 | * @note call camera_probe before calling this function 132 | * 133 | * This function detects and configures camera over I2C interface, 134 | * allocates framebuffer and DMA buffers, 135 | * initializes parallel I2S input, and sets up DMA descriptors. 136 | * 137 | * Currently this function can only be called once and there is 138 | * no way to de-initialize this module. 139 | * 140 | * @param config Camera configuration parameters 141 | * 142 | * @return ESP_OK on success 143 | */ 144 | esp_err_t esp_camera_init(const camera_config_t* config); 145 | 146 | /** 147 | * @brief Deinitialize the camera driver 148 | * 149 | * @return 150 | * - ESP_OK on success 151 | * - ESP_ERR_INVALID_STATE if the driver hasn't been initialized yet 152 | */ 153 | esp_err_t esp_camera_deinit(); 154 | 155 | /** 156 | * @brief Obtain pointer to a frame buffer. 157 | * 158 | * @return pointer to the frame buffer 159 | */ 160 | camera_fb_t* esp_camera_fb_get(); 161 | 162 | /** 163 | * @brief Return the frame buffer to be reused again. 164 | * 165 | * @param fb Pointer to the frame buffer 166 | */ 167 | void esp_camera_fb_return(camera_fb_t * fb); 168 | 169 | /** 170 | * @brief Get a pointer to the image sensor control structure 171 | * 172 | * @return pointer to the sensor 173 | */ 174 | sensor_t * esp_camera_sensor_get(); 175 | 176 | /** 177 | * @brief Save camera settings to non-volatile-storage (NVS) 178 | * 179 | * @param key A unique nvs key name for the camera settings 180 | */ 181 | esp_err_t esp_camera_save_to_nvs(const char *key); 182 | 183 | /** 184 | * @brief Load camera settings from non-volatile-storage (NVS) 185 | * 186 | * @param key A unique nvs key name for the camera settings 187 | */ 188 | esp_err_t esp_camera_load_from_nvs(const char *key); 189 | 190 | #ifdef __cplusplus 191 | } 192 | #endif 193 | 194 | #include "img_converters.h" 195 | 196 | -------------------------------------------------------------------------------- /esp-idf_components_esp32-camera/driver/include/sensor.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the OpenMV project. 3 | * Copyright (c) 2013/2014 Ibrahim Abdelkader 4 | * This work is licensed under the MIT license, see the file LICENSE for details. 5 | * 6 | * Sensor abstraction layer. 7 | * 8 | */ 9 | #ifndef __SENSOR_H__ 10 | #define __SENSOR_H__ 11 | #include 12 | #include 13 | 14 | #define OV9650_PID (0x96) 15 | #define OV7725_PID (0x77) 16 | #define OV2640_PID (0x26) 17 | #define OV3660_PID (0x36) 18 | #define OV5640_PID (0x56) 19 | 20 | typedef enum { 21 | PIXFORMAT_RGB565, // 2BPP/RGB565 22 | PIXFORMAT_YUV422, // 2BPP/YUV422 23 | PIXFORMAT_GRAYSCALE, // 1BPP/GRAYSCALE 24 | PIXFORMAT_JPEG, // JPEG/COMPRESSED 25 | PIXFORMAT_RGB888, // 3BPP/RGB888 26 | PIXFORMAT_RAW, // RAW 27 | PIXFORMAT_RGB444, // 3BP2P/RGB444 28 | PIXFORMAT_RGB555, // 3BP2P/RGB555 29 | } pixformat_t; 30 | 31 | typedef enum { 32 | FRAMESIZE_96X96, // 96x96 33 | FRAMESIZE_QQVGA, // 160x120 34 | FRAMESIZE_QCIF, // 176x144 35 | FRAMESIZE_HQVGA, // 240x176 36 | FRAMESIZE_240X240, // 240x240 37 | FRAMESIZE_QVGA, // 320x240 38 | FRAMESIZE_CIF, // 400x296 39 | FRAMESIZE_HVGA, // 480x320 40 | FRAMESIZE_VGA, // 640x480 41 | FRAMESIZE_SVGA, // 800x600 42 | FRAMESIZE_XGA, // 1024x768 43 | FRAMESIZE_HD, // 1280x720 44 | FRAMESIZE_SXGA, // 1280x1024 45 | FRAMESIZE_UXGA, // 1600x1200 46 | // 3MP Sensors 47 | FRAMESIZE_FHD, // 1920x1080 48 | FRAMESIZE_P_HD, // 720x1280 49 | FRAMESIZE_P_3MP, // 864x1536 50 | FRAMESIZE_QXGA, // 2048x1536 51 | // 5MP Sensors 52 | FRAMESIZE_QHD, // 2560x1440 53 | FRAMESIZE_WQXGA, // 2560x1600 54 | FRAMESIZE_P_FHD, // 1080x1920 55 | FRAMESIZE_QSXGA, // 2560x1920 56 | FRAMESIZE_INVALID 57 | } framesize_t; 58 | 59 | typedef enum { 60 | ASPECT_RATIO_4X3, 61 | ASPECT_RATIO_3X2, 62 | ASPECT_RATIO_16X10, 63 | ASPECT_RATIO_5X3, 64 | ASPECT_RATIO_16X9, 65 | ASPECT_RATIO_21X9, 66 | ASPECT_RATIO_5X4, 67 | ASPECT_RATIO_1X1, 68 | ASPECT_RATIO_9X16 69 | } aspect_ratio_t; 70 | 71 | typedef enum { 72 | GAINCEILING_2X, 73 | GAINCEILING_4X, 74 | GAINCEILING_8X, 75 | GAINCEILING_16X, 76 | GAINCEILING_32X, 77 | GAINCEILING_64X, 78 | GAINCEILING_128X, 79 | } gainceiling_t; 80 | 81 | typedef struct { 82 | uint16_t max_width; 83 | uint16_t max_height; 84 | uint16_t start_x; 85 | uint16_t start_y; 86 | uint16_t end_x; 87 | uint16_t end_y; 88 | uint16_t offset_x; 89 | uint16_t offset_y; 90 | uint16_t total_x; 91 | uint16_t total_y; 92 | } ratio_settings_t; 93 | 94 | typedef struct { 95 | const uint16_t width; 96 | const uint16_t height; 97 | const aspect_ratio_t aspect_ratio; 98 | } resolution_info_t; 99 | 100 | // Resolution table (in sensor.c) 101 | extern const resolution_info_t resolution[]; 102 | 103 | typedef struct { 104 | uint8_t MIDH; 105 | uint8_t MIDL; 106 | uint8_t PID; 107 | uint8_t VER; 108 | } sensor_id_t; 109 | 110 | typedef struct { 111 | framesize_t framesize;//0 - 10 112 | bool scale; 113 | bool binning; 114 | uint8_t quality;//0 - 63 115 | int8_t brightness;//-2 - 2 116 | int8_t contrast;//-2 - 2 117 | int8_t saturation;//-2 - 2 118 | int8_t sharpness;//-2 - 2 119 | uint8_t denoise; 120 | uint8_t special_effect;//0 - 6 121 | uint8_t wb_mode;//0 - 4 122 | uint8_t awb; 123 | uint8_t awb_gain; 124 | uint8_t aec; 125 | uint8_t aec2; 126 | int8_t ae_level;//-2 - 2 127 | uint16_t aec_value;//0 - 1200 128 | uint8_t agc; 129 | uint8_t agc_gain;//0 - 30 130 | uint8_t gainceiling;//0 - 6 131 | uint8_t bpc; 132 | uint8_t wpc; 133 | uint8_t raw_gma; 134 | uint8_t lenc; 135 | uint8_t hmirror; 136 | uint8_t vflip; 137 | uint8_t dcw; 138 | uint8_t colorbar; 139 | } camera_status_t; 140 | 141 | typedef struct _sensor sensor_t; 142 | typedef struct _sensor { 143 | sensor_id_t id; // Sensor ID. 144 | uint8_t slv_addr; // Sensor I2C slave address. 145 | pixformat_t pixformat; 146 | camera_status_t status; 147 | int xclk_freq_hz; 148 | 149 | // Sensor function pointers 150 | int (*init_status) (sensor_t *sensor); 151 | int (*reset) (sensor_t *sensor); 152 | int (*set_pixformat) (sensor_t *sensor, pixformat_t pixformat); 153 | int (*set_framesize) (sensor_t *sensor, framesize_t framesize); 154 | int (*set_contrast) (sensor_t *sensor, int level); 155 | int (*set_brightness) (sensor_t *sensor, int level); 156 | int (*set_saturation) (sensor_t *sensor, int level); 157 | int (*set_sharpness) (sensor_t *sensor, int level); 158 | int (*set_denoise) (sensor_t *sensor, int level); 159 | int (*set_gainceiling) (sensor_t *sensor, gainceiling_t gainceiling); 160 | int (*set_quality) (sensor_t *sensor, int quality); 161 | int (*set_colorbar) (sensor_t *sensor, int enable); 162 | int (*set_whitebal) (sensor_t *sensor, int enable); 163 | int (*set_gain_ctrl) (sensor_t *sensor, int enable); 164 | int (*set_exposure_ctrl) (sensor_t *sensor, int enable); 165 | int (*set_hmirror) (sensor_t *sensor, int enable); 166 | int (*set_vflip) (sensor_t *sensor, int enable); 167 | 168 | int (*set_aec2) (sensor_t *sensor, int enable); 169 | int (*set_awb_gain) (sensor_t *sensor, int enable); 170 | int (*set_agc_gain) (sensor_t *sensor, int gain); 171 | int (*set_aec_value) (sensor_t *sensor, int gain); 172 | 173 | int (*set_special_effect) (sensor_t *sensor, int effect); 174 | int (*set_wb_mode) (sensor_t *sensor, int mode); 175 | int (*set_ae_level) (sensor_t *sensor, int level); 176 | 177 | int (*set_dcw) (sensor_t *sensor, int enable); 178 | int (*set_bpc) (sensor_t *sensor, int enable); 179 | int (*set_wpc) (sensor_t *sensor, int enable); 180 | 181 | int (*set_raw_gma) (sensor_t *sensor, int enable); 182 | int (*set_lenc) (sensor_t *sensor, int enable); 183 | 184 | int (*get_reg) (sensor_t *sensor, int reg, int mask); 185 | int (*set_reg) (sensor_t *sensor, int reg, int mask, int value); 186 | 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); 187 | int (*set_pll) (sensor_t *sensor, int bypass, int mul, int sys, int root, int pre, int seld5, int pclken, int pclk); 188 | int (*set_xclk) (sensor_t *sensor, int timer, int xclk); 189 | } sensor_t; 190 | 191 | #endif /* __SENSOR_H__ */ 192 | -------------------------------------------------------------------------------- /esp-idf_components_esp32-camera/driver/private_include/camera_common.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include "esp_err.h" 7 | #include "esp_intr_alloc.h" 8 | #include "freertos/FreeRTOS.h" 9 | #include "freertos/semphr.h" 10 | #include "freertos/task.h" 11 | #include "esp_camera.h" 12 | #include "sensor.h" 13 | 14 | #include "esp_system.h" 15 | #if ESP_IDF_VERSION_MAJOR >= 4 // IDF 4+ 16 | #if CONFIG_IDF_TARGET_ESP32 // ESP32/PICO-D4 17 | #include "esp32/rom/lldesc.h" 18 | #else 19 | #error Target CONFIG_IDF_TARGET is not supported 20 | #endif 21 | #else // ESP32 Before IDF 4.0 22 | #include "rom/lldesc.h" 23 | #endif 24 | 25 | typedef union { 26 | struct { 27 | uint8_t sample2; 28 | uint8_t unused2; 29 | uint8_t sample1; 30 | uint8_t unused1; 31 | }; 32 | uint32_t val; 33 | } dma_elem_t; 34 | 35 | typedef enum { 36 | /* camera sends byte sequence: s1, s2, s3, s4, ... 37 | * fifo receives: 00 s1 00 s2, 00 s2 00 s3, 00 s3 00 s4, ... 38 | */ 39 | SM_0A0B_0B0C = 0, 40 | /* camera sends byte sequence: s1, s2, s3, s4, ... 41 | * fifo receives: 00 s1 00 s2, 00 s3 00 s4, ... 42 | */ 43 | SM_0A0B_0C0D = 1, 44 | /* camera sends byte sequence: s1, s2, s3, s4, ... 45 | * fifo receives: 00 s1 00 00, 00 s2 00 00, 00 s3 00 00, ... 46 | */ 47 | SM_0A00_0B00 = 3, 48 | } i2s_sampling_mode_t; 49 | 50 | -------------------------------------------------------------------------------- /esp-idf_components_esp32-camera/driver/private_include/sccb.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the OpenMV project. 3 | * Copyright (c) 2013/2014 Ibrahim Abdelkader 4 | * This work is licensed under the MIT license, see the file LICENSE for details. 5 | * 6 | * SCCB (I2C like) driver. 7 | * 8 | */ 9 | #ifndef __SCCB_H__ 10 | #define __SCCB_H__ 11 | #include 12 | int SCCB_Init(int pin_sda, int pin_scl); 13 | uint8_t SCCB_Probe(); 14 | uint8_t SCCB_Read(uint8_t slv_addr, uint8_t reg); 15 | uint8_t SCCB_Write(uint8_t slv_addr, uint8_t reg, uint8_t data); 16 | uint8_t SCCB_Read16(uint8_t slv_addr, uint16_t reg); 17 | uint8_t SCCB_Write16(uint8_t slv_addr, uint16_t reg, uint8_t data); 18 | #endif // __SCCB_H__ 19 | -------------------------------------------------------------------------------- /esp-idf_components_esp32-camera/driver/private_include/twi.h: -------------------------------------------------------------------------------- 1 | /* 2 | twi.h - Software I2C library for ESP31B 3 | 4 | Copyright (c) 2015 Hristo Gochkov. All rights reserved. 5 | This file is part of the ESP31B core for Arduino environment. 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Lesser General Public 9 | License as published by the Free Software Foundation; either 10 | version 2.1 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General Public 18 | License along with this library; if not, write to the Free Software 19 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | #ifndef SI2C_h 22 | #define SI2C_h 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | void twi_init(unsigned char sda, unsigned char scl); 29 | void twi_stop(void); 30 | void twi_setClock(unsigned int freq); 31 | uint8_t twi_writeTo(unsigned char address, unsigned char * buf, unsigned int len, unsigned char sendStop); 32 | uint8_t twi_readFrom(unsigned char address, unsigned char * buf, unsigned int len, unsigned char sendStop); 33 | 34 | #ifdef __cplusplus 35 | } 36 | #endif 37 | 38 | #endif -------------------------------------------------------------------------------- /esp-idf_components_esp32-camera/driver/private_include/xclk.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "camera_common.h" 4 | 5 | esp_err_t camera_enable_out_clock(); 6 | 7 | void camera_disable_out_clock(); 8 | -------------------------------------------------------------------------------- /esp-idf_components_esp32-camera/driver/sccb.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the OpenMV project. 3 | * Copyright (c) 2013/2014 Ibrahim Abdelkader 4 | * This work is licensed under the MIT license, see the file LICENSE for details. 5 | * 6 | * SCCB (I2C like) driver. 7 | * 8 | */ 9 | #include 10 | #include 11 | #include 12 | #include "sccb.h" 13 | #include 14 | #include "sdkconfig.h" 15 | #if defined(ARDUINO_ARCH_ESP32) && defined(CONFIG_ARDUHAL_ESP_LOG) 16 | #include "esp32-hal-log.h" 17 | #else 18 | #include "esp_log.h" 19 | static const char* TAG = "sccb"; 20 | #endif 21 | 22 | //#undef CONFIG_SCCB_HARDWARE_I2C 23 | 24 | #define LITTLETOBIG(x) ((x<<8)|(x>>8)) 25 | 26 | #ifdef CONFIG_SCCB_HARDWARE_I2C 27 | #include "driver/i2c.h" 28 | 29 | #define SCCB_FREQ 200000 /*!< I2C master frequency*/ 30 | #define WRITE_BIT I2C_MASTER_WRITE /*!< I2C master write */ 31 | #define READ_BIT I2C_MASTER_READ /*!< I2C master read */ 32 | #define ACK_CHECK_EN 0x1 /*!< I2C master will check ack from slave*/ 33 | #define ACK_CHECK_DIS 0x0 /*!< I2C master will not check ack from slave */ 34 | #define ACK_VAL 0x0 /*!< I2C ack value */ 35 | #define NACK_VAL 0x1 /*!< I2C nack value */ 36 | #if CONFIG_SCCB_HARDWARE_I2C_PORT1 37 | const int SCCB_I2C_PORT = 1; 38 | #else 39 | const int SCCB_I2C_PORT = 0; 40 | #endif 41 | static uint8_t ESP_SLAVE_ADDR = 0x3c; 42 | #else 43 | #include "twi.h" 44 | #endif 45 | 46 | int SCCB_Init(int pin_sda, int pin_scl) 47 | { 48 | ESP_LOGI(TAG, "pin_sda %d pin_scl %d\n", pin_sda, pin_scl); 49 | #ifdef CONFIG_SCCB_HARDWARE_I2C 50 | //log_i("SCCB_Init start"); 51 | i2c_config_t conf; 52 | conf.mode = I2C_MODE_MASTER; 53 | conf.sda_io_num = pin_sda; 54 | conf.sda_pullup_en = GPIO_PULLUP_ENABLE; 55 | conf.scl_io_num = pin_scl; 56 | conf.scl_pullup_en = GPIO_PULLUP_ENABLE; 57 | conf.master.clk_speed = SCCB_FREQ; 58 | 59 | i2c_param_config(SCCB_I2C_PORT, &conf); 60 | i2c_driver_install(SCCB_I2C_PORT, conf.mode, 0, 0, 0); 61 | #else 62 | twi_init(pin_sda, pin_scl); 63 | #endif 64 | return 0; 65 | } 66 | 67 | uint8_t SCCB_Probe() 68 | { 69 | #ifdef CONFIG_SCCB_HARDWARE_I2C 70 | uint8_t slave_addr = 0x0; 71 | while(slave_addr < 0x7f) { 72 | i2c_cmd_handle_t cmd = i2c_cmd_link_create(); 73 | i2c_master_start(cmd); 74 | i2c_master_write_byte(cmd, ( slave_addr << 1 ) | WRITE_BIT, ACK_CHECK_EN); 75 | i2c_master_stop(cmd); 76 | esp_err_t ret = i2c_master_cmd_begin(SCCB_I2C_PORT, cmd, 1000 / portTICK_RATE_MS); 77 | i2c_cmd_link_delete(cmd); 78 | if( ret == ESP_OK) { 79 | ESP_SLAVE_ADDR = slave_addr; 80 | return ESP_SLAVE_ADDR; 81 | } 82 | slave_addr++; 83 | } 84 | return ESP_SLAVE_ADDR; 85 | #else 86 | uint8_t reg = 0x00; 87 | uint8_t slv_addr = 0x00; 88 | 89 | ESP_LOGI(TAG, "SCCB_Probe start"); 90 | for (uint8_t i = 0; i < 127; i++) { 91 | if (twi_writeTo(i, ®, 1, true) == 0) { 92 | slv_addr = i; 93 | break; 94 | } 95 | 96 | if (i!=126) { 97 | vTaskDelay(10 / portTICK_PERIOD_MS); // Necessary for OV7725 camera (not for OV2640). 98 | } 99 | } 100 | return slv_addr; 101 | #endif 102 | } 103 | 104 | uint8_t SCCB_Read(uint8_t slv_addr, uint8_t reg) 105 | { 106 | #ifdef CONFIG_SCCB_HARDWARE_I2C 107 | uint8_t data=0; 108 | esp_err_t ret = ESP_FAIL; 109 | i2c_cmd_handle_t cmd = i2c_cmd_link_create(); 110 | i2c_master_start(cmd); 111 | i2c_master_write_byte(cmd, ( slv_addr << 1 ) | WRITE_BIT, ACK_CHECK_EN); 112 | i2c_master_write_byte(cmd, reg, ACK_CHECK_EN); 113 | i2c_master_stop(cmd); 114 | ret = i2c_master_cmd_begin(SCCB_I2C_PORT, cmd, 1000 / portTICK_RATE_MS); 115 | i2c_cmd_link_delete(cmd); 116 | if(ret != ESP_OK) return -1; 117 | cmd = i2c_cmd_link_create(); 118 | i2c_master_start(cmd); 119 | i2c_master_write_byte(cmd, ( slv_addr << 1 ) | READ_BIT, ACK_CHECK_EN); 120 | i2c_master_read_byte(cmd, &data, NACK_VAL); 121 | i2c_master_stop(cmd); 122 | ret = i2c_master_cmd_begin(SCCB_I2C_PORT, cmd, 1000 / portTICK_RATE_MS); 123 | i2c_cmd_link_delete(cmd); 124 | if(ret != ESP_OK) { 125 | ESP_LOGE(TAG, "SCCB_Read Failed addr:0x%02x, reg:0x%02x, data:0x%02x, ret:%d", slv_addr, reg, data, ret); 126 | } 127 | return data; 128 | #else 129 | uint8_t data=0; 130 | 131 | int rc = twi_writeTo(slv_addr, ®, 1, true); 132 | if (rc != 0) { 133 | data = 0xff; 134 | } else { 135 | rc = twi_readFrom(slv_addr, &data, 1, true); 136 | if (rc != 0) { 137 | data=0xFF; 138 | } 139 | } 140 | if (rc != 0) { 141 | ESP_LOGE(TAG, "SCCB_Read [%02x] failed rc=%d\n", reg, rc); 142 | } 143 | return data; 144 | #endif 145 | } 146 | 147 | uint8_t SCCB_Write(uint8_t slv_addr, uint8_t reg, uint8_t data) 148 | { 149 | #ifdef CONFIG_SCCB_HARDWARE_I2C 150 | esp_err_t ret = ESP_FAIL; 151 | i2c_cmd_handle_t cmd = i2c_cmd_link_create(); 152 | i2c_master_start(cmd); 153 | i2c_master_write_byte(cmd, ( slv_addr << 1 ) | WRITE_BIT, ACK_CHECK_EN); 154 | i2c_master_write_byte(cmd, reg, ACK_CHECK_EN); 155 | i2c_master_write_byte(cmd, data, ACK_CHECK_EN); 156 | i2c_master_stop(cmd); 157 | ret = i2c_master_cmd_begin(SCCB_I2C_PORT, cmd, 1000 / portTICK_RATE_MS); 158 | i2c_cmd_link_delete(cmd); 159 | if(ret != ESP_OK) { 160 | ESP_LOGE(TAG, "SCCB_Write Failed addr:0x%02x, reg:0x%02x, data:0x%02x, ret:%d", slv_addr, reg, data, ret); 161 | } 162 | return ret == ESP_OK ? 0 : -1; 163 | #else 164 | uint8_t ret=0; 165 | uint8_t buf[] = {reg, data}; 166 | 167 | if(twi_writeTo(slv_addr, buf, 2, true) != 0) { 168 | ret=0xFF; 169 | } 170 | if (ret != 0) { 171 | ESP_LOGE(TAG, "SCCB_Write [%02x]=%02x failed\n", reg, data); 172 | } 173 | return ret; 174 | #endif 175 | } 176 | 177 | uint8_t SCCB_Read16(uint8_t slv_addr, uint16_t reg) 178 | { 179 | #ifdef CONFIG_SCCB_HARDWARE_I2C 180 | uint8_t data=0; 181 | esp_err_t ret = ESP_FAIL; 182 | uint16_t reg_htons = LITTLETOBIG(reg); 183 | uint8_t *reg_u8 = (uint8_t *)®_htons; 184 | i2c_cmd_handle_t cmd = i2c_cmd_link_create(); 185 | i2c_master_start(cmd); 186 | i2c_master_write_byte(cmd, ( slv_addr << 1 ) | WRITE_BIT, ACK_CHECK_EN); 187 | i2c_master_write_byte(cmd, reg_u8[0], ACK_CHECK_EN); 188 | i2c_master_write_byte(cmd, reg_u8[1], ACK_CHECK_EN); 189 | i2c_master_stop(cmd); 190 | ret = i2c_master_cmd_begin(SCCB_I2C_PORT, cmd, 1000 / portTICK_RATE_MS); 191 | i2c_cmd_link_delete(cmd); 192 | if(ret != ESP_OK) return -1; 193 | cmd = i2c_cmd_link_create(); 194 | i2c_master_start(cmd); 195 | i2c_master_write_byte(cmd, ( slv_addr << 1 ) | READ_BIT, ACK_CHECK_EN); 196 | i2c_master_read_byte(cmd, &data, NACK_VAL); 197 | i2c_master_stop(cmd); 198 | ret = i2c_master_cmd_begin(SCCB_I2C_PORT, cmd, 1000 / portTICK_RATE_MS); 199 | i2c_cmd_link_delete(cmd); 200 | if(ret != ESP_OK) { 201 | ESP_LOGE(TAG, "W [%04x]=%02x fail\n", reg, data); 202 | } 203 | return data; 204 | #else 205 | uint8_t data=0; 206 | uint16_t reg_htons = LITTLETOBIG(reg); 207 | uint8_t *reg_u8 = (uint8_t *)®_htons; 208 | uint8_t buf[] = {reg_u8[0], reg_u8[1]}; 209 | 210 | int rc = twi_writeTo(slv_addr, buf, 2, true); 211 | if (rc != 0) { 212 | data = 0xff; 213 | } else { 214 | rc = twi_readFrom(slv_addr, &data, 1, true); 215 | if (rc != 0) { 216 | data=0xFF; 217 | } 218 | } 219 | if (rc != 0) { 220 | ESP_LOGE(TAG, "R [%04x] fail rc=%d\n", reg, rc); 221 | } 222 | return data; 223 | #endif 224 | } 225 | 226 | uint8_t SCCB_Write16(uint8_t slv_addr, uint16_t reg, uint8_t data) 227 | { 228 | static uint16_t i = 0; 229 | #ifdef CONFIG_SCCB_HARDWARE_I2C 230 | esp_err_t ret = ESP_FAIL; 231 | uint16_t reg_htons = LITTLETOBIG(reg); 232 | uint8_t *reg_u8 = (uint8_t *)®_htons; 233 | i2c_cmd_handle_t cmd = i2c_cmd_link_create(); 234 | i2c_master_start(cmd); 235 | i2c_master_write_byte(cmd, ( slv_addr << 1 ) | WRITE_BIT, ACK_CHECK_EN); 236 | i2c_master_write_byte(cmd, reg_u8[0], ACK_CHECK_EN); 237 | i2c_master_write_byte(cmd, reg_u8[1], ACK_CHECK_EN); 238 | i2c_master_write_byte(cmd, data, ACK_CHECK_EN); 239 | i2c_master_stop(cmd); 240 | ret = i2c_master_cmd_begin(SCCB_I2C_PORT, cmd, 1000 / portTICK_RATE_MS); 241 | i2c_cmd_link_delete(cmd); 242 | if(ret != ESP_OK) { 243 | ESP_LOGE(TAG, "W [%04x]=%02x %d fail\n", reg, data, i++); 244 | } 245 | return ret == ESP_OK ? 0 : -1; 246 | #else 247 | uint8_t ret=0; 248 | uint16_t reg_htons = LITTLETOBIG(reg); 249 | uint8_t *reg_u8 = (uint8_t *)®_htons; 250 | uint8_t buf[] = {reg_u8[0], reg_u8[1], data}; 251 | 252 | if(twi_writeTo(slv_addr, buf, 3, true) != 0) { 253 | ret = 0xFF; 254 | } 255 | if (ret != 0) { 256 | ESP_LOGE(TAG, "W [%04x]=%02x %d fail\n", reg, data, i++); 257 | } 258 | return ret; 259 | #endif 260 | } 261 | -------------------------------------------------------------------------------- /esp-idf_components_esp32-camera/driver/sensor.c: -------------------------------------------------------------------------------- 1 | #include "sensor.h" 2 | 3 | const resolution_info_t resolution[FRAMESIZE_INVALID] = { 4 | { 96, 96, ASPECT_RATIO_1X1 }, /* 96x96 */ 5 | { 160, 120, ASPECT_RATIO_4X3 }, /* QQVGA */ 6 | { 176, 144, ASPECT_RATIO_5X4 }, /* QCIF */ 7 | { 240, 176, ASPECT_RATIO_4X3 }, /* HQVGA */ 8 | { 240, 240, ASPECT_RATIO_1X1 }, /* 240x240 */ 9 | { 320, 240, ASPECT_RATIO_4X3 }, /* QVGA */ 10 | { 400, 296, ASPECT_RATIO_4X3 }, /* CIF */ 11 | { 480, 320, ASPECT_RATIO_3X2 }, /* HVGA */ 12 | { 640, 480, ASPECT_RATIO_4X3 }, /* VGA */ 13 | { 800, 600, ASPECT_RATIO_4X3 }, /* SVGA */ 14 | { 1024, 768, ASPECT_RATIO_4X3 }, /* XGA */ 15 | { 1280, 720, ASPECT_RATIO_16X9 }, /* HD */ 16 | { 1280, 1024, ASPECT_RATIO_5X4 }, /* SXGA */ 17 | { 1600, 1200, ASPECT_RATIO_4X3 }, /* UXGA */ 18 | // 3MP Sensors 19 | { 1920, 1080, ASPECT_RATIO_16X9 }, /* FHD */ 20 | { 720, 1280, ASPECT_RATIO_9X16 }, /* Portrait HD */ 21 | { 864, 1536, ASPECT_RATIO_9X16 }, /* Portrait 3MP */ 22 | { 2048, 1536, ASPECT_RATIO_4X3 }, /* QXGA */ 23 | // 5MP Sensors 24 | { 2560, 1440, ASPECT_RATIO_16X9 }, /* QHD */ 25 | { 2560, 1600, ASPECT_RATIO_16X10 }, /* WQXGA */ 26 | { 1088, 1920, ASPECT_RATIO_9X16 }, /* Portrait FHD */ 27 | { 2560, 1920, ASPECT_RATIO_4X3 }, /* QSXGA */ 28 | }; 29 | -------------------------------------------------------------------------------- /esp-idf_components_esp32-camera/driver/twi.c: -------------------------------------------------------------------------------- 1 | /* 2 | si2c.c - Software I2C library for ESP31B 3 | 4 | Copyright (c) 2015 Hristo Gochkov. All rights reserved. 5 | This file is part of the ESP31B core for Arduino environment. 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Lesser General Public 9 | License as published by the Free Software Foundation; either 10 | version 2.1 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General Public 18 | License along with this library; if not, write to the Free Software 19 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | #include 22 | #include 23 | #include "twi.h" 24 | #include "soc/gpio_reg.h" 25 | #include "soc/gpio_struct.h" 26 | #include "soc/io_mux_reg.h" 27 | #include "driver/rtc_io.h" 28 | #include 29 | 30 | 31 | #define LOW 0x0 32 | #define HIGH 0x1 33 | 34 | //GPIO FUNCTIONS 35 | #define INPUT 0x01 36 | #define OUTPUT 0x02 37 | #define PULLUP 0x04 38 | #define INPUT_PULLUP 0x05 39 | #define PULLDOWN 0x08 40 | #define INPUT_PULLDOWN 0x09 41 | #define OPEN_DRAIN 0x10 42 | #define OUTPUT_OPEN_DRAIN 0x12 43 | #define SPECIAL 0xF0 44 | #define FUNCTION_1 0x00 45 | #define FUNCTION_2 0x20 46 | #define FUNCTION_3 0x40 47 | #define FUNCTION_4 0x60 48 | #define FUNCTION_5 0x80 49 | #define FUNCTION_6 0xA0 50 | 51 | #define ESP_REG(addr) *((volatile uint32_t *)(addr)) 52 | 53 | const uint8_t pin_to_mux[40] = { 0x44, 0x88, 0x40, 0x84, 0x48, 0x6c, 0x60, 0x64, 0x68, 0x54, 0x58, 0x5c, 0x34, 0x38, 0x30, 0x3c, 0x4c, 0x50, 0x70, 0x74, 0x78, 0x7c, 0x80, 0x8c, 0, 0x24, 0x28, 0x2c, 0, 0, 0, 0, 0x1c, 0x20, 0x14, 0x18, 0x04, 0x08, 0x0c, 0x10}; 54 | 55 | static void pinMode(uint8_t pin, uint8_t mode) 56 | { 57 | if(pin >= 40) { 58 | return; 59 | } 60 | 61 | uint32_t rtc_reg = rtc_gpio_desc[pin].reg; 62 | 63 | //RTC pins PULL settings 64 | if(rtc_reg) { 65 | //lock rtc 66 | ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_gpio_desc[pin].mux); 67 | if(mode & PULLUP) { 68 | ESP_REG(rtc_reg) = (ESP_REG(rtc_reg) | rtc_gpio_desc[pin].pullup) & ~(rtc_gpio_desc[pin].pulldown); 69 | } else if(mode & PULLDOWN) { 70 | ESP_REG(rtc_reg) = (ESP_REG(rtc_reg) | rtc_gpio_desc[pin].pulldown) & ~(rtc_gpio_desc[pin].pullup); 71 | } else { 72 | ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_gpio_desc[pin].pullup | rtc_gpio_desc[pin].pulldown); 73 | } 74 | //unlock rtc 75 | } 76 | 77 | uint32_t pinFunction = 0, pinControl = 0; 78 | 79 | //lock gpio 80 | if(mode & INPUT) { 81 | if(pin < 32) { 82 | GPIO.enable_w1tc = BIT(pin); 83 | } else { 84 | GPIO.enable1_w1tc.val = BIT(pin - 32); 85 | } 86 | } else if(mode & OUTPUT) { 87 | if(pin > 33) { 88 | //unlock gpio 89 | return;//pins above 33 can be only inputs 90 | } else if(pin < 32) { 91 | GPIO.enable_w1ts = BIT(pin); 92 | } else { 93 | GPIO.enable1_w1ts.val = BIT(pin - 32); 94 | } 95 | } 96 | 97 | if(mode & PULLUP) { 98 | pinFunction |= FUN_PU; 99 | } else if(mode & PULLDOWN) { 100 | pinFunction |= FUN_PD; 101 | } 102 | 103 | pinFunction |= ((uint32_t)2 << FUN_DRV_S);//what are the drivers? 104 | pinFunction |= FUN_IE;//input enable but required for output as well? 105 | 106 | if(mode & (INPUT | OUTPUT)) { 107 | pinFunction |= ((uint32_t)2 << MCU_SEL_S); 108 | } else if(mode == SPECIAL) { 109 | pinFunction |= ((uint32_t)(((pin)==1||(pin)==3)?0:1) << MCU_SEL_S); 110 | } else { 111 | pinFunction |= ((uint32_t)(mode >> 5) << MCU_SEL_S); 112 | } 113 | 114 | ESP_REG(DR_REG_IO_MUX_BASE + pin_to_mux[pin]) = pinFunction; 115 | 116 | if(mode & OPEN_DRAIN) { 117 | pinControl = (1 << GPIO_PIN0_PAD_DRIVER_S); 118 | } 119 | 120 | GPIO.pin[pin].val = pinControl; 121 | //unlock gpio 122 | } 123 | 124 | static void digitalWrite(uint8_t pin, uint8_t val) 125 | { 126 | if(val) { 127 | if(pin < 32) { 128 | GPIO.out_w1ts = BIT(pin); 129 | } else if(pin < 34) { 130 | GPIO.out1_w1ts.val = BIT(pin - 32); 131 | } 132 | } else { 133 | if(pin < 32) { 134 | GPIO.out_w1tc = BIT(pin); 135 | } else if(pin < 34) { 136 | GPIO.out1_w1tc.val = BIT(pin - 32); 137 | } 138 | } 139 | } 140 | 141 | 142 | unsigned char twi_dcount = 18; 143 | static unsigned char twi_sda, twi_scl; 144 | 145 | 146 | static inline void SDA_LOW() 147 | { 148 | //Enable SDA (becomes output and since GPO is 0 for the pin, 149 | // it will pull the line low) 150 | if (twi_sda < 32) { 151 | GPIO.enable_w1ts = BIT(twi_sda); 152 | } else { 153 | GPIO.enable1_w1ts.val = BIT(twi_sda - 32); 154 | } 155 | } 156 | 157 | static inline void SDA_HIGH() 158 | { 159 | //Disable SDA (becomes input and since it has pullup it will go high) 160 | if (twi_sda < 32) { 161 | GPIO.enable_w1tc = BIT(twi_sda); 162 | } else { 163 | GPIO.enable1_w1tc.val = BIT(twi_sda - 32); 164 | } 165 | } 166 | 167 | static inline uint32_t SDA_READ() 168 | { 169 | if (twi_sda < 32) { 170 | return (GPIO.in & BIT(twi_sda)) != 0; 171 | } else { 172 | return (GPIO.in1.val & BIT(twi_sda - 32)) != 0; 173 | } 174 | } 175 | 176 | static void SCL_LOW() 177 | { 178 | if (twi_scl < 32) { 179 | GPIO.enable_w1ts = BIT(twi_scl); 180 | } else { 181 | GPIO.enable1_w1ts.val = BIT(twi_scl - 32); 182 | } 183 | } 184 | 185 | static void SCL_HIGH() 186 | { 187 | if (twi_scl < 32) { 188 | GPIO.enable_w1tc = BIT(twi_scl); 189 | } else { 190 | GPIO.enable1_w1tc.val = BIT(twi_scl - 32); 191 | } 192 | } 193 | 194 | static uint32_t SCL_READ() 195 | { 196 | if (twi_scl < 32) { 197 | return (GPIO.in & BIT(twi_scl)) != 0; 198 | } else { 199 | return (GPIO.in1.val & BIT(twi_scl - 32)) != 0; 200 | } 201 | } 202 | 203 | 204 | #ifndef FCPU80 205 | #define FCPU80 80000000L 206 | #endif 207 | 208 | #if F_CPU == FCPU80 209 | #define TWI_CLOCK_STRETCH 800 210 | #else 211 | #define TWI_CLOCK_STRETCH 1600 212 | #endif 213 | 214 | void twi_setClock(unsigned int freq) 215 | { 216 | #if F_CPU == FCPU80 217 | if(freq <= 100000) { 218 | twi_dcount = 19; //about 100KHz 219 | } else if(freq <= 200000) { 220 | twi_dcount = 8; //about 200KHz 221 | } else if(freq <= 300000) { 222 | twi_dcount = 3; //about 300KHz 223 | } else if(freq <= 400000) { 224 | twi_dcount = 1; //about 400KHz 225 | } else { 226 | twi_dcount = 1; //about 400KHz 227 | } 228 | #else 229 | if(freq <= 100000) { 230 | twi_dcount = 32; //about 100KHz 231 | } else if(freq <= 200000) { 232 | twi_dcount = 14; //about 200KHz 233 | } else if(freq <= 300000) { 234 | twi_dcount = 8; //about 300KHz 235 | } else if(freq <= 400000) { 236 | twi_dcount = 5; //about 400KHz 237 | } else if(freq <= 500000) { 238 | twi_dcount = 3; //about 500KHz 239 | } else if(freq <= 600000) { 240 | twi_dcount = 2; //about 600KHz 241 | } else { 242 | twi_dcount = 1; //about 700KHz 243 | } 244 | #endif 245 | } 246 | 247 | void twi_init(unsigned char sda, unsigned char scl) 248 | { 249 | twi_sda = sda; 250 | twi_scl = scl; 251 | pinMode(twi_sda, OUTPUT); 252 | pinMode(twi_scl, OUTPUT); 253 | 254 | digitalWrite(twi_sda, 0); 255 | digitalWrite(twi_scl, 0); 256 | 257 | pinMode(twi_sda, INPUT_PULLUP); 258 | pinMode(twi_scl, INPUT_PULLUP); 259 | twi_setClock(100000); 260 | } 261 | 262 | void twi_stop(void) 263 | { 264 | pinMode(twi_sda, INPUT); 265 | pinMode(twi_scl, INPUT); 266 | } 267 | 268 | static void twi_delay(unsigned char v) 269 | { 270 | unsigned int i; 271 | #pragma GCC diagnostic push 272 | #pragma GCC diagnostic ignored "-Wunused-but-set-variable" 273 | unsigned int reg; 274 | for(i=0; i= 4 22 | timer_conf.clk_cfg = LEDC_AUTO_CLK; 23 | #endif 24 | timer_conf.timer_num = (ledc_timer_t)ledc_timer; 25 | esp_err_t err = ledc_timer_config(&timer_conf); 26 | if (err != ESP_OK) { 27 | ESP_LOGE(TAG, "ledc_timer_config failed for freq %d, rc=%x", xclk_freq_hz, err); 28 | } 29 | return err; 30 | } 31 | 32 | esp_err_t camera_enable_out_clock(camera_config_t* config) 33 | { 34 | periph_module_enable(PERIPH_LEDC_MODULE); 35 | 36 | esp_err_t err = xclk_timer_conf(config->ledc_timer, config->xclk_freq_hz); 37 | if (err != ESP_OK) { 38 | ESP_LOGE(TAG, "ledc_timer_config failed, rc=%x", err); 39 | return err; 40 | } 41 | 42 | ledc_channel_config_t ch_conf; 43 | ch_conf.gpio_num = config->pin_xclk; 44 | ch_conf.speed_mode = LEDC_HIGH_SPEED_MODE; 45 | ch_conf.channel = config->ledc_channel; 46 | ch_conf.intr_type = LEDC_INTR_DISABLE; 47 | ch_conf.timer_sel = config->ledc_timer; 48 | ch_conf.duty = 2; 49 | ch_conf.hpoint = 0; 50 | err = ledc_channel_config(&ch_conf); 51 | if (err != ESP_OK) { 52 | ESP_LOGE(TAG, "ledc_channel_config failed, rc=%x", err); 53 | return err; 54 | } 55 | return ESP_OK; 56 | } 57 | 58 | void camera_disable_out_clock() 59 | { 60 | periph_module_disable(PERIPH_LEDC_MODULE); 61 | } 62 | -------------------------------------------------------------------------------- /esp-idf_components_esp32-camera/sensors/ov7725.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the OpenMV project. 3 | * Copyright (c) 2013/2014 Ibrahim Abdelkader 4 | * This work is licensed under the MIT license, see the file LICENSE for details. 5 | * 6 | * OV7725 driver. 7 | * 8 | */ 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include "sccb.h" 14 | #include "ov7725.h" 15 | #include "ov7725_regs.h" 16 | #include "freertos/FreeRTOS.h" 17 | #include "freertos/task.h" 18 | 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 = "ov7725"; 24 | #endif 25 | 26 | 27 | static const uint8_t default_regs[][2] = { 28 | {COM3, COM3_SWAP_YUV}, 29 | {COM7, COM7_RES_QVGA | COM7_FMT_YUV}, 30 | 31 | {COM4, 0x01 | 0x00}, /* bypass PLL (0x00:off, 0x40:4x, 0x80:6x, 0xC0:8x) */ 32 | {CLKRC, 0x80 | 0x03}, /* Res/Bypass pre-scalar (0x40:bypass, 0x00-0x3F:prescaler PCLK=XCLK/(prescaler + 1)/2 ) */ 33 | 34 | // QVGA Window Size 35 | {HSTART, 0x3F}, 36 | {HSIZE, 0x50}, 37 | {VSTART, 0x03}, 38 | {VSIZE, 0x78}, 39 | {HREF, 0x00}, 40 | 41 | // Scale down to QVGA Resolution 42 | {HOUTSIZE, 0x50}, 43 | {VOUTSIZE, 0x78}, 44 | {EXHCH, 0x00}, 45 | 46 | {COM12, 0x03}, 47 | {TGT_B, 0x7F}, 48 | {FIXGAIN, 0x09}, 49 | {AWB_CTRL0, 0xE0}, 50 | {DSP_CTRL1, 0xFF}, 51 | 52 | {DSP_CTRL2, DSP_CTRL2_VDCW_EN | DSP_CTRL2_HDCW_EN | DSP_CTRL2_HZOOM_EN | DSP_CTRL2_VZOOM_EN}, 53 | 54 | {DSP_CTRL3, 0x00}, 55 | {DSP_CTRL4, 0x00}, 56 | {DSPAUTO, 0xFF}, 57 | 58 | {COM8, 0xF0}, 59 | {COM6, 0xC5}, 60 | {COM9, 0x11}, 61 | {COM10, COM10_VSYNC_NEG | COM10_PCLK_MASK}, //Invert VSYNC and MASK PCLK 62 | {BDBASE, 0x7F}, 63 | {DBSTEP, 0x03}, 64 | {AEW, 0x96}, 65 | {AEB, 0x64}, 66 | {VPT, 0xA1}, 67 | {EXHCL, 0x00}, 68 | {AWB_CTRL3, 0xAA}, 69 | {COM8, 0xFF}, 70 | 71 | //Gamma 72 | {GAM1, 0x0C}, 73 | {GAM2, 0x16}, 74 | {GAM3, 0x2A}, 75 | {GAM4, 0x4E}, 76 | {GAM5, 0x61}, 77 | {GAM6, 0x6F}, 78 | {GAM7, 0x7B}, 79 | {GAM8, 0x86}, 80 | {GAM9, 0x8E}, 81 | {GAM10, 0x97}, 82 | {GAM11, 0xA4}, 83 | {GAM12, 0xAF}, 84 | {GAM13, 0xC5}, 85 | {GAM14, 0xD7}, 86 | {GAM15, 0xE8}, 87 | 88 | {SLOP, 0x20}, 89 | {EDGE1, 0x05}, 90 | {EDGE2, 0x03}, 91 | {EDGE3, 0x00}, 92 | {DNSOFF, 0x01}, 93 | 94 | {MTX1, 0xB0}, 95 | {MTX2, 0x9D}, 96 | {MTX3, 0x13}, 97 | {MTX4, 0x16}, 98 | {MTX5, 0x7B}, 99 | {MTX6, 0x91}, 100 | {MTX_CTRL, 0x1E}, 101 | 102 | {BRIGHTNESS, 0x08}, 103 | {CONTRAST, 0x30}, 104 | {UVADJ0, 0x81}, 105 | {SDE, (SDE_CONT_BRIGHT_EN | SDE_SATURATION_EN)}, 106 | 107 | // For 30 fps/60Hz 108 | {DM_LNL, 0x00}, 109 | {DM_LNH, 0x00}, 110 | {BDBASE, 0x7F}, 111 | {DBSTEP, 0x03}, 112 | 113 | // Lens Correction, should be tuned with real camera module 114 | {LC_RADI, 0x10}, 115 | {LC_COEF, 0x10}, 116 | {LC_COEFB, 0x14}, 117 | {LC_COEFR, 0x17}, 118 | {LC_CTR, 0x05}, 119 | {COM5, 0xF5}, //0x65 120 | 121 | {0x00, 0x00}, 122 | }; 123 | 124 | 125 | static int reset(sensor_t *sensor) 126 | { 127 | int i=0; 128 | const uint8_t (*regs)[2]; 129 | 130 | // Reset all registers 131 | SCCB_Write(sensor->slv_addr, COM7, COM7_RESET); 132 | 133 | // Delay 10 ms 134 | vTaskDelay(10 / portTICK_PERIOD_MS); 135 | 136 | // Write default regsiters 137 | for (i=0, regs = default_regs; regs[i][0]; i++) { 138 | SCCB_Write(sensor->slv_addr, regs[i][0], regs[i][1]); 139 | } 140 | 141 | // Delay 142 | vTaskDelay(30 / portTICK_PERIOD_MS); 143 | 144 | return 0; 145 | } 146 | 147 | 148 | static int set_pixformat(sensor_t *sensor, pixformat_t pixformat) 149 | { 150 | int ret=0; 151 | sensor->pixformat = pixformat; 152 | // Read register COM7 153 | uint8_t reg = SCCB_Read(sensor->slv_addr, COM7); 154 | 155 | switch (pixformat) { 156 | case PIXFORMAT_RGB565: 157 | reg = COM7_SET_RGB(reg, COM7_FMT_RGB565); 158 | break; 159 | case PIXFORMAT_YUV422: 160 | case PIXFORMAT_GRAYSCALE: 161 | reg = COM7_SET_FMT(reg, COM7_FMT_YUV); 162 | break; 163 | default: 164 | return -1; 165 | } 166 | 167 | // Write back register COM7 168 | ret = SCCB_Write(sensor->slv_addr, COM7, reg); 169 | 170 | // Delay 171 | vTaskDelay(30 / portTICK_PERIOD_MS); 172 | 173 | return ret; 174 | } 175 | 176 | static int set_framesize(sensor_t *sensor, framesize_t framesize) 177 | { 178 | int ret=0; 179 | uint16_t w = resolution[framesize].width; 180 | uint16_t h = resolution[framesize].height; 181 | uint8_t reg = SCCB_Read(sensor->slv_addr, COM7); 182 | 183 | sensor->status.framesize = framesize; 184 | 185 | // Write MSBs 186 | ret |= SCCB_Write(sensor->slv_addr, HOUTSIZE, w>>2); 187 | ret |= SCCB_Write(sensor->slv_addr, VOUTSIZE, h>>1); 188 | 189 | ret |= SCCB_Write(sensor->slv_addr, HSIZE, w>>2); 190 | ret |= SCCB_Write(sensor->slv_addr, VSIZE, h>>1); 191 | 192 | // Write LSBs 193 | ret |= SCCB_Write(sensor->slv_addr, HREF, ((w&0x3) | ((h&0x1) << 2))); 194 | 195 | if (framesize < FRAMESIZE_VGA) { 196 | // Enable auto-scaling/zooming factors 197 | ret |= SCCB_Write(sensor->slv_addr, DSPAUTO, 0xFF); 198 | 199 | ret |= SCCB_Write(sensor->slv_addr, HSTART, 0x3F); 200 | ret |= SCCB_Write(sensor->slv_addr, VSTART, 0x03); 201 | 202 | ret |= SCCB_Write(sensor->slv_addr, COM7, reg | COM7_RES_QVGA); 203 | 204 | ret |= SCCB_Write(sensor->slv_addr, CLKRC, 0x80 | 0x01); 205 | 206 | } else { 207 | // Disable auto-scaling/zooming factors 208 | ret |= SCCB_Write(sensor->slv_addr, DSPAUTO, 0xF3); 209 | 210 | // Clear auto-scaling/zooming factors 211 | ret |= SCCB_Write(sensor->slv_addr, SCAL0, 0x00); 212 | ret |= SCCB_Write(sensor->slv_addr, SCAL1, 0x00); 213 | ret |= SCCB_Write(sensor->slv_addr, SCAL2, 0x00); 214 | 215 | ret |= SCCB_Write(sensor->slv_addr, HSTART, 0x23); 216 | ret |= SCCB_Write(sensor->slv_addr, VSTART, 0x07); 217 | 218 | ret |= SCCB_Write(sensor->slv_addr, COM7, reg & ~COM7_RES_QVGA); 219 | 220 | ret |= SCCB_Write(sensor->slv_addr, CLKRC, 0x80 | 0x03); 221 | } 222 | 223 | // Delay 224 | vTaskDelay(30 / portTICK_PERIOD_MS); 225 | 226 | return ret; 227 | } 228 | 229 | static int set_colorbar(sensor_t *sensor, int enable) 230 | { 231 | int ret=0; 232 | uint8_t reg; 233 | sensor->status.colorbar = enable; 234 | 235 | // Read reg COM3 236 | reg = SCCB_Read(sensor->slv_addr, COM3); 237 | // Enable colorbar test pattern output 238 | reg = COM3_SET_CBAR(reg, enable); 239 | // Write back COM3 240 | ret |= SCCB_Write(sensor->slv_addr, COM3, reg); 241 | 242 | // Read reg DSP_CTRL3 243 | reg = SCCB_Read(sensor->slv_addr, DSP_CTRL3); 244 | // Enable DSP colorbar output 245 | reg = DSP_CTRL3_SET_CBAR(reg, enable); 246 | // Write back DSP_CTRL3 247 | ret |= SCCB_Write(sensor->slv_addr, DSP_CTRL3, reg); 248 | 249 | return ret; 250 | } 251 | 252 | static int set_whitebal(sensor_t *sensor, int enable) 253 | { 254 | // Read register COM8 255 | uint8_t reg = SCCB_Read(sensor->slv_addr, COM8); 256 | 257 | sensor->status.awb = enable; 258 | // Set white bal on/off 259 | reg = COM8_SET_AWB(reg, enable); 260 | 261 | // Write back register COM8 262 | return SCCB_Write(sensor->slv_addr, COM8, reg); 263 | } 264 | 265 | static int set_gain_ctrl(sensor_t *sensor, int enable) 266 | { 267 | sensor->status.agc = enable; 268 | // Read register COM8 269 | uint8_t reg = SCCB_Read(sensor->slv_addr, COM8); 270 | 271 | // Set white bal on/off 272 | reg = COM8_SET_AGC(reg, enable); 273 | 274 | // Write back register COM8 275 | return SCCB_Write(sensor->slv_addr, COM8, reg); 276 | } 277 | 278 | static int set_exposure_ctrl(sensor_t *sensor, int enable) 279 | { 280 | sensor->status.aec = enable; 281 | // Read register COM8 282 | uint8_t reg = SCCB_Read(sensor->slv_addr, COM8); 283 | 284 | // Set white bal on/off 285 | reg = COM8_SET_AEC(reg, enable); 286 | 287 | // Write back register COM8 288 | return SCCB_Write(sensor->slv_addr, COM8, reg); 289 | } 290 | 291 | static int set_hmirror(sensor_t *sensor, int enable) 292 | { 293 | sensor->status.hmirror = enable; 294 | // Read register COM3 295 | uint8_t reg = SCCB_Read(sensor->slv_addr, COM3); 296 | 297 | // Set mirror on/off 298 | reg = COM3_SET_MIRROR(reg, enable); 299 | 300 | // Write back register COM3 301 | return SCCB_Write(sensor->slv_addr, COM3, reg); 302 | } 303 | 304 | static int set_vflip(sensor_t *sensor, int enable) 305 | { 306 | sensor->status.vflip = enable; 307 | // Read register COM3 308 | uint8_t reg = SCCB_Read(sensor->slv_addr, COM3); 309 | 310 | // Set mirror on/off 311 | reg = COM3_SET_FLIP(reg, enable); 312 | 313 | // Write back register COM3 314 | return SCCB_Write(sensor->slv_addr, COM3, reg); 315 | } 316 | 317 | static int init_status(sensor_t *sensor) 318 | { 319 | sensor->status.awb = 0;//get_reg_bits(sensor, BANK_DSP, CTRL1, 3, 1); 320 | sensor->status.aec = 0; 321 | sensor->status.agc = 0; 322 | sensor->status.hmirror = 0; 323 | sensor->status.vflip = 0; 324 | sensor->status.colorbar = 0; 325 | return 0; 326 | } 327 | 328 | static int set_dummy(sensor_t *sensor, int val){ return -1; } 329 | static int set_gainceiling_dummy(sensor_t *sensor, gainceiling_t val){ return -1; } 330 | 331 | int ov7725_init(sensor_t *sensor) 332 | { 333 | // Set function pointers 334 | sensor->reset = reset; 335 | sensor->init_status = init_status; 336 | sensor->set_pixformat = set_pixformat; 337 | sensor->set_framesize = set_framesize; 338 | sensor->set_colorbar = set_colorbar; 339 | sensor->set_whitebal = set_whitebal; 340 | sensor->set_gain_ctrl = set_gain_ctrl; 341 | sensor->set_exposure_ctrl = set_exposure_ctrl; 342 | sensor->set_hmirror = set_hmirror; 343 | sensor->set_vflip = set_vflip; 344 | 345 | //not supported 346 | sensor->set_brightness= set_dummy; 347 | sensor->set_saturation= set_dummy; 348 | sensor->set_quality = set_dummy; 349 | sensor->set_gainceiling = set_gainceiling_dummy; 350 | sensor->set_gain_ctrl = set_dummy; 351 | sensor->set_exposure_ctrl = set_dummy; 352 | sensor->set_hmirror = set_dummy; 353 | sensor->set_vflip = set_dummy; 354 | sensor->set_whitebal = set_dummy; 355 | sensor->set_aec2 = set_dummy; 356 | sensor->set_aec_value = set_dummy; 357 | sensor->set_special_effect = set_dummy; 358 | sensor->set_wb_mode = set_dummy; 359 | sensor->set_ae_level = set_dummy; 360 | sensor->set_dcw = set_dummy; 361 | sensor->set_bpc = set_dummy; 362 | sensor->set_wpc = set_dummy; 363 | sensor->set_awb_gain = set_dummy; 364 | sensor->set_agc_gain = set_dummy; 365 | sensor->set_raw_gma = set_dummy; 366 | sensor->set_lenc = set_dummy; 367 | sensor->set_sharpness = set_dummy; 368 | sensor->set_denoise = set_dummy; 369 | 370 | 371 | 372 | 373 | // Retrieve sensor's signature 374 | sensor->id.MIDH = SCCB_Read(sensor->slv_addr, REG_MIDH); 375 | sensor->id.MIDL = SCCB_Read(sensor->slv_addr, REG_MIDL); 376 | sensor->id.PID = SCCB_Read(sensor->slv_addr, REG_PID); 377 | sensor->id.VER = SCCB_Read(sensor->slv_addr, REG_VER); 378 | 379 | ESP_LOGD(TAG, "OV7725 Attached"); 380 | 381 | return 0; 382 | } 383 | -------------------------------------------------------------------------------- /esp-idf_components_esp32-camera/sensors/private_include/ov2640.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the OpenMV project. 3 | * Copyright (c) 2013/2014 Ibrahim Abdelkader 4 | * This work is licensed under the MIT license, see the file LICENSE for details. 5 | * 6 | * OV2640 driver. 7 | * 8 | */ 9 | #ifndef __OV2640_H__ 10 | #define __OV2640_H__ 11 | #include "sensor.h" 12 | int ov2640_init(sensor_t *sensor); 13 | #endif // __OV2640_H__ 14 | -------------------------------------------------------------------------------- /esp-idf_components_esp32-camera/sensors/private_include/ov2640_regs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the OpenMV project. 3 | * Copyright (c) 2013/2014 Ibrahim Abdelkader 4 | * This work is licensed under the MIT license, see the file LICENSE for details. 5 | * 6 | * OV2640 register definitions. 7 | */ 8 | #ifndef __REG_REGS_H__ 9 | #define __REG_REGS_H__ 10 | /* DSP register bank FF=0x00*/ 11 | #define R_BYPASS 0x05 12 | #define QS 0x44 13 | #define CTRLI 0x50 14 | #define HSIZE 0x51 15 | #define VSIZE 0x52 16 | #define XOFFL 0x53 17 | #define YOFFL 0x54 18 | #define VHYX 0x55 19 | #define DPRP 0x56 20 | #define TEST 0x57 21 | #define ZMOW 0x5A 22 | #define ZMOH 0x5B 23 | #define ZMHH 0x5C 24 | #define BPADDR 0x7C 25 | #define BPDATA 0x7D 26 | #define CTRL2 0x86 27 | #define CTRL3 0x87 28 | #define SIZEL 0x8C 29 | #define HSIZE8 0xC0 30 | #define VSIZE8 0xC1 31 | #define CTRL0 0xC2 32 | #define CTRL1 0xC3 33 | #define R_DVP_SP 0xD3 34 | #define IMAGE_MODE 0xDA 35 | #define RESET 0xE0 36 | #define MS_SP 0xF0 37 | #define SS_ID 0xF7 38 | #define SS_CTRL 0xF7 39 | #define MC_BIST 0xF9 40 | #define MC_AL 0xFA 41 | #define MC_AH 0xFB 42 | #define MC_D 0xFC 43 | #define P_CMD 0xFD 44 | #define P_STATUS 0xFE 45 | #define BANK_SEL 0xFF 46 | 47 | #define CTRLI_LP_DP 0x80 48 | #define CTRLI_ROUND 0x40 49 | 50 | #define CTRL0_AEC_EN 0x80 51 | #define CTRL0_AEC_SEL 0x40 52 | #define CTRL0_STAT_SEL 0x20 53 | #define CTRL0_VFIRST 0x10 54 | #define CTRL0_YUV422 0x08 55 | #define CTRL0_YUV_EN 0x04 56 | #define CTRL0_RGB_EN 0x02 57 | #define CTRL0_RAW_EN 0x01 58 | 59 | #define CTRL2_DCW_EN 0x20 60 | #define CTRL2_SDE_EN 0x10 61 | #define CTRL2_UV_ADJ_EN 0x08 62 | #define CTRL2_UV_AVG_EN 0x04 63 | #define CTRL2_CMX_EN 0x01 64 | 65 | #define CTRL3_BPC_EN 0x80 66 | #define CTRL3_WPC_EN 0x40 67 | 68 | #define R_DVP_SP_AUTO_MODE 0x80 69 | 70 | #define R_BYPASS_DSP_EN 0x00 71 | #define R_BYPASS_DSP_BYPAS 0x01 72 | 73 | #define IMAGE_MODE_Y8_DVP_EN 0x40 74 | #define IMAGE_MODE_JPEG_EN 0x10 75 | #define IMAGE_MODE_YUV422 0x00 76 | #define IMAGE_MODE_RAW10 0x04 77 | #define IMAGE_MODE_RGB565 0x08 78 | #define IMAGE_MODE_HREF_VSYNC 0x02 79 | #define IMAGE_MODE_LBYTE_FIRST 0x01 80 | 81 | #define RESET_MICROC 0x40 82 | #define RESET_SCCB 0x20 83 | #define RESET_JPEG 0x10 84 | #define RESET_DVP 0x04 85 | #define RESET_IPU 0x02 86 | #define RESET_CIF 0x01 87 | 88 | #define MC_BIST_RESET 0x80 89 | #define MC_BIST_BOOT_ROM_SEL 0x40 90 | #define MC_BIST_12KB_SEL 0x20 91 | #define MC_BIST_12KB_MASK 0x30 92 | #define MC_BIST_512KB_SEL 0x08 93 | #define MC_BIST_512KB_MASK 0x0C 94 | #define MC_BIST_BUSY_BIT_R 0x02 95 | #define MC_BIST_MC_RES_ONE_SH_W 0x02 96 | #define MC_BIST_LAUNCH 0x01 97 | 98 | 99 | typedef enum { 100 | BANK_DSP, BANK_SENSOR, BANK_MAX 101 | } ov2640_bank_t; 102 | 103 | /* Sensor register bank FF=0x01*/ 104 | #define GAIN 0x00 105 | #define COM1 0x03 106 | #define REG04 0x04 107 | #define REG08 0x08 108 | #define COM2 0x09 109 | #define REG_PID 0x0A 110 | #define REG_VER 0x0B 111 | #define COM3 0x0C 112 | #define COM4 0x0D 113 | #define AEC 0x10 114 | #define CLKRC 0x11 115 | #define COM7 0x12 116 | #define COM8 0x13 117 | #define COM9 0x14 /* AGC gain ceiling */ 118 | #define COM10 0x15 119 | #define HSTART 0x17 120 | #define HSTOP 0x18 121 | #define VSTART 0x19 122 | #define VSTOP 0x1A 123 | #define MIDH 0x1C 124 | #define MIDL 0x1D 125 | #define AEW 0x24 126 | #define AEB 0x25 127 | #define VV 0x26 128 | #define REG2A 0x2A 129 | #define FRARL 0x2B 130 | #define ADDVSL 0x2D 131 | #define ADDVSH 0x2E 132 | #define YAVG 0x2F 133 | #define HSDY 0x30 134 | #define HEDY 0x31 135 | #define REG32 0x32 136 | #define ARCOM2 0x34 137 | #define REG45 0x45 138 | #define FLL 0x46 139 | #define FLH 0x47 140 | #define COM19 0x48 141 | #define ZOOMS 0x49 142 | #define COM22 0x4B 143 | #define COM25 0x4E 144 | #define BD50 0x4F 145 | #define BD60 0x50 146 | #define REG5D 0x5D 147 | #define REG5E 0x5E 148 | #define REG5F 0x5F 149 | #define REG60 0x60 150 | #define HISTO_LOW 0x61 151 | #define HISTO_HIGH 0x62 152 | 153 | #define REG04_DEFAULT 0x28 154 | #define REG04_HFLIP_IMG 0x80 155 | #define REG04_VFLIP_IMG 0x40 156 | #define REG04_VREF_EN 0x10 157 | #define REG04_HREF_EN 0x08 158 | #define REG04_SET(x) (REG04_DEFAULT|x) 159 | 160 | #define COM2_STDBY 0x10 161 | #define COM2_OUT_DRIVE_1x 0x00 162 | #define COM2_OUT_DRIVE_2x 0x01 163 | #define COM2_OUT_DRIVE_3x 0x02 164 | #define COM2_OUT_DRIVE_4x 0x03 165 | 166 | #define COM3_DEFAULT 0x38 167 | #define COM3_BAND_50Hz 0x04 168 | #define COM3_BAND_60Hz 0x00 169 | #define COM3_BAND_AUTO 0x02 170 | #define COM3_BAND_SET(x) (COM3_DEFAULT|x) 171 | 172 | #define COM7_SRST 0x80 173 | #define COM7_RES_UXGA 0x00 /* UXGA */ 174 | #define COM7_RES_SVGA 0x40 /* SVGA */ 175 | #define COM7_RES_CIF 0x20 /* CIF */ 176 | #define COM7_ZOOM_EN 0x04 /* Enable Zoom */ 177 | #define COM7_COLOR_BAR 0x02 /* Enable Color Bar Test */ 178 | 179 | #define COM8_DEFAULT 0xC0 180 | #define COM8_BNDF_EN 0x20 /* Enable Banding filter */ 181 | #define COM8_AGC_EN 0x04 /* AGC Auto/Manual control selection */ 182 | #define COM8_AEC_EN 0x01 /* Auto/Manual Exposure control */ 183 | #define COM8_SET(x) (COM8_DEFAULT|x) 184 | 185 | #define COM9_DEFAULT 0x08 186 | #define COM9_AGC_GAIN_2x 0x00 /* AGC: 2x */ 187 | #define COM9_AGC_GAIN_4x 0x01 /* AGC: 4x */ 188 | #define COM9_AGC_GAIN_8x 0x02 /* AGC: 8x */ 189 | #define COM9_AGC_GAIN_16x 0x03 /* AGC: 16x */ 190 | #define COM9_AGC_GAIN_32x 0x04 /* AGC: 32x */ 191 | #define COM9_AGC_GAIN_64x 0x05 /* AGC: 64x */ 192 | #define COM9_AGC_GAIN_128x 0x06 /* AGC: 128x */ 193 | #define COM9_AGC_SET(x) (COM9_DEFAULT|(x<<5)) 194 | 195 | #define COM10_HREF_EN 0x80 /* HSYNC changes to HREF */ 196 | #define COM10_HSYNC_EN 0x40 /* HREF changes to HSYNC */ 197 | #define COM10_PCLK_FREE 0x20 /* PCLK output option: free running PCLK */ 198 | #define COM10_PCLK_EDGE 0x10 /* Data is updated at the rising edge of PCLK */ 199 | #define COM10_HREF_NEG 0x08 /* HREF negative */ 200 | #define COM10_VSYNC_NEG 0x02 /* VSYNC negative */ 201 | #define COM10_HSYNC_NEG 0x01 /* HSYNC negative */ 202 | 203 | #define CTRL1_AWB 0x08 /* Enable AWB */ 204 | 205 | #define VV_AGC_TH_SET(h,l) ((h<<4)|(l&0x0F)) 206 | 207 | #define REG32_UXGA 0x36 208 | #define REG32_SVGA 0x09 209 | #define REG32_CIF 0x89 210 | 211 | #define CLKRC_2X 0x80 212 | #define CLKRC_2X_UXGA (0x01 | CLKRC_2X) 213 | #define CLKRC_2X_SVGA CLKRC_2X 214 | #define CLKRC_2X_CIF CLKRC_2X 215 | 216 | #endif //__REG_REGS_H__ 217 | -------------------------------------------------------------------------------- /esp-idf_components_esp32-camera/sensors/private_include/ov2640_settings.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015-2016 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 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | #ifndef _OV2640_SETTINGS_H_ 15 | #define _OV2640_SETTINGS_H_ 16 | 17 | #include 18 | #include 19 | #include "esp_attr.h" 20 | #include "ov2640_regs.h" 21 | 22 | typedef enum { 23 | OV2640_MODE_UXGA, OV2640_MODE_SVGA, OV2640_MODE_CIF, OV2640_MODE_MAX 24 | } ov2640_sensor_mode_t; 25 | 26 | typedef struct { 27 | union { 28 | struct { 29 | uint8_t pclk_div:7; 30 | uint8_t pclk_auto:1; 31 | }; 32 | uint8_t pclk; 33 | }; 34 | union { 35 | struct { 36 | uint8_t clk_div:6; 37 | uint8_t reserved:1; 38 | uint8_t clk_2x:1; 39 | }; 40 | uint8_t clk; 41 | }; 42 | } ov2640_clk_t; 43 | 44 | typedef struct { 45 | uint16_t offset_x; 46 | uint16_t offset_y; 47 | uint16_t max_x; 48 | uint16_t max_y; 49 | } ov2640_ratio_settings_t; 50 | 51 | static const DRAM_ATTR ov2640_ratio_settings_t ratio_table[] = { 52 | // ox, oy, mx, my 53 | { 0, 0, 1600, 1200 }, //4x3 54 | { 8, 72, 1584, 1056 }, //3x2 55 | { 0, 100, 1600, 1000 }, //16x10 56 | { 0, 120, 1600, 960 }, //5x3 57 | { 0, 150, 1600, 900 }, //16x9 58 | { 2, 258, 1596, 684 }, //21x9 59 | { 50, 0, 1500, 1200 }, //5x4 60 | { 200, 0, 1200, 1200 }, //1x1 61 | { 462, 0, 676, 1200 } //9x16 62 | }; 63 | 64 | // 30fps@24MHz 65 | const DRAM_ATTR uint8_t ov2640_settings_cif[][2] = { 66 | {BANK_SEL, BANK_DSP}, 67 | {0x2c, 0xff}, 68 | {0x2e, 0xdf}, 69 | {BANK_SEL, BANK_SENSOR}, 70 | {0x3c, 0x32}, 71 | {CLKRC, 0x01}, 72 | {COM2, COM2_OUT_DRIVE_3x}, 73 | {REG04, REG04_DEFAULT}, 74 | {COM8, COM8_DEFAULT | COM8_BNDF_EN | COM8_AGC_EN | COM8_AEC_EN}, 75 | {COM9, COM9_AGC_SET(COM9_AGC_GAIN_8x)}, 76 | {0x2c, 0x0c}, 77 | {0x33, 0x78}, 78 | {0x3a, 0x33}, 79 | {0x3b, 0xfB}, 80 | {0x3e, 0x00}, 81 | {0x43, 0x11}, 82 | {0x16, 0x10}, 83 | {0x39, 0x92}, 84 | {0x35, 0xda}, 85 | {0x22, 0x1a}, 86 | {0x37, 0xc3}, 87 | {0x23, 0x00}, 88 | {ARCOM2, 0xc0}, 89 | {0x06, 0x88}, 90 | {0x07, 0xc0}, 91 | {COM4, 0x87}, 92 | {0x0e, 0x41}, 93 | {0x4c, 0x00}, 94 | {0x4a, 0x81}, 95 | {0x21, 0x99}, 96 | {AEW, 0x40}, 97 | {AEB, 0x38}, 98 | {VV, VV_AGC_TH_SET(8,2)}, 99 | {0x5c, 0x00}, 100 | {0x63, 0x00}, 101 | {HISTO_LOW, 0x70}, 102 | {HISTO_HIGH, 0x80}, 103 | {0x7c, 0x05}, 104 | {0x20, 0x80}, 105 | {0x28, 0x30}, 106 | {0x6c, 0x00}, 107 | {0x6d, 0x80}, 108 | {0x6e, 0x00}, 109 | {0x70, 0x02}, 110 | {0x71, 0x94}, 111 | {0x73, 0xc1}, 112 | {0x3d, 0x34}, 113 | {0x5a, 0x57}, 114 | {BD50, 0xbb}, 115 | {BD60, 0x9c}, 116 | {COM7, COM7_RES_CIF}, 117 | {HSTART, 0x11}, 118 | {HSTOP, 0x43}, 119 | {VSTART, 0x00}, 120 | {VSTOP, 0x25}, 121 | {REG32, 0x89}, 122 | {0x37, 0xc0}, 123 | {BD50, 0xca}, 124 | {BD60, 0xa8}, 125 | {0x6d, 0x00}, 126 | {0x3d, 0x38}, 127 | {BANK_SEL, BANK_DSP}, 128 | {0xe5, 0x7f}, 129 | {MC_BIST, MC_BIST_RESET | MC_BIST_BOOT_ROM_SEL}, 130 | {0x41, 0x24}, 131 | {RESET, RESET_JPEG | RESET_DVP}, 132 | {0x76, 0xff}, 133 | {0x33, 0xa0}, 134 | {0x42, 0x20}, 135 | {0x43, 0x18}, 136 | {0x4c, 0x00}, 137 | {CTRL3, CTRL3_WPC_EN | 0x10 }, 138 | {0x88, 0x3f}, 139 | {0xd7, 0x03}, 140 | {0xd9, 0x10}, 141 | {R_DVP_SP, R_DVP_SP_AUTO_MODE | 0x02}, 142 | {0xc8, 0x08}, 143 | {0xc9, 0x80}, 144 | {BPADDR, 0x00}, 145 | {BPDATA, 0x00}, 146 | {BPADDR, 0x03}, 147 | {BPDATA, 0x48}, 148 | {BPDATA, 0x48}, 149 | {BPADDR, 0x08}, 150 | {BPDATA, 0x20}, 151 | {BPDATA, 0x10}, 152 | {BPDATA, 0x0e}, 153 | {0x90, 0x00}, 154 | {0x91, 0x0e}, 155 | {0x91, 0x1a}, 156 | {0x91, 0x31}, 157 | {0x91, 0x5a}, 158 | {0x91, 0x69}, 159 | {0x91, 0x75}, 160 | {0x91, 0x7e}, 161 | {0x91, 0x88}, 162 | {0x91, 0x8f}, 163 | {0x91, 0x96}, 164 | {0x91, 0xa3}, 165 | {0x91, 0xaf}, 166 | {0x91, 0xc4}, 167 | {0x91, 0xd7}, 168 | {0x91, 0xe8}, 169 | {0x91, 0x20}, 170 | {0x92, 0x00}, 171 | {0x93, 0x06}, 172 | {0x93, 0xe3}, 173 | {0x93, 0x05}, 174 | {0x93, 0x05}, 175 | {0x93, 0x00}, 176 | {0x93, 0x04}, 177 | {0x93, 0x00}, 178 | {0x93, 0x00}, 179 | {0x93, 0x00}, 180 | {0x93, 0x00}, 181 | {0x93, 0x00}, 182 | {0x93, 0x00}, 183 | {0x93, 0x00}, 184 | {0x96, 0x00}, 185 | {0x97, 0x08}, 186 | {0x97, 0x19}, 187 | {0x97, 0x02}, 188 | {0x97, 0x0c}, 189 | {0x97, 0x24}, 190 | {0x97, 0x30}, 191 | {0x97, 0x28}, 192 | {0x97, 0x26}, 193 | {0x97, 0x02}, 194 | {0x97, 0x98}, 195 | {0x97, 0x80}, 196 | {0x97, 0x00}, 197 | {0x97, 0x00}, 198 | {0xa4, 0x00}, 199 | {0xa8, 0x00}, 200 | {0xc5, 0x11}, 201 | {0xc6, 0x51}, 202 | {0xbf, 0x80}, 203 | {0xc7, 0x10}, 204 | {0xb6, 0x66}, 205 | {0xb8, 0xA5}, 206 | {0xb7, 0x64}, 207 | {0xb9, 0x7C}, 208 | {0xb3, 0xaf}, 209 | {0xb4, 0x97}, 210 | {0xb5, 0xFF}, 211 | {0xb0, 0xC5}, 212 | {0xb1, 0x94}, 213 | {0xb2, 0x0f}, 214 | {0xc4, 0x5c}, 215 | {CTRL1, 0xfd}, 216 | {0x7f, 0x00}, 217 | {0xe5, 0x1f}, 218 | {0xe1, 0x67}, 219 | {0xdd, 0x7f}, 220 | {IMAGE_MODE, 0x00}, 221 | {RESET, 0x00}, 222 | {R_BYPASS, R_BYPASS_DSP_EN}, 223 | {0, 0} 224 | }; 225 | 226 | const DRAM_ATTR uint8_t ov2640_settings_to_cif[][2] = { 227 | {BANK_SEL, BANK_SENSOR}, 228 | {COM7, COM7_RES_CIF}, 229 | 230 | //Set the sensor output window 231 | {COM1, 0x0A}, 232 | {REG32, REG32_CIF}, 233 | {HSTART, 0x11}, 234 | {HSTOP, 0x43}, 235 | {VSTART, 0x00}, 236 | {VSTOP, 0x25}, 237 | 238 | //{CLKRC, 0x00}, 239 | {BD50, 0xca}, 240 | {BD60, 0xa8}, 241 | {0x5a, 0x23}, 242 | {0x6d, 0x00}, 243 | {0x3d, 0x38}, 244 | {0x39, 0x92}, 245 | {0x35, 0xda}, 246 | {0x22, 0x1a}, 247 | {0x37, 0xc3}, 248 | {0x23, 0x00}, 249 | {ARCOM2, 0xc0}, 250 | {0x06, 0x88}, 251 | {0x07, 0xc0}, 252 | {COM4, 0x87}, 253 | {0x0e, 0x41}, 254 | {0x4c, 0x00}, 255 | {BANK_SEL, BANK_DSP}, 256 | {RESET, RESET_DVP}, 257 | 258 | //Set the sensor resolution (UXGA, SVGA, CIF) 259 | {HSIZE8, 0x32}, 260 | {VSIZE8, 0x25}, 261 | {SIZEL, 0x00}, 262 | 263 | //Set the image window size >= output size 264 | {HSIZE, 0x64}, 265 | {VSIZE, 0x4a}, 266 | {XOFFL, 0x00}, 267 | {YOFFL, 0x00}, 268 | {VHYX, 0x00}, 269 | {TEST, 0x00}, 270 | 271 | {CTRL2, CTRL2_DCW_EN | 0x1D}, 272 | {CTRLI, CTRLI_LP_DP | 0x00}, 273 | //{R_DVP_SP, 0x08}, 274 | {0, 0} 275 | }; 276 | 277 | const DRAM_ATTR uint8_t ov2640_settings_to_svga[][2] = { 278 | {BANK_SEL, BANK_SENSOR}, 279 | {COM7, COM7_RES_SVGA}, 280 | 281 | //Set the sensor output window 282 | {COM1, 0x0A}, 283 | {REG32, REG32_SVGA}, 284 | {HSTART, 0x11}, 285 | {HSTOP, 0x43}, 286 | {VSTART, 0x00}, 287 | {VSTOP, 0x4b}, 288 | 289 | //{CLKRC, 0x00}, 290 | {0x37, 0xc0}, 291 | {BD50, 0xca}, 292 | {BD60, 0xa8}, 293 | {0x5a, 0x23}, 294 | {0x6d, 0x00}, 295 | {0x3d, 0x38}, 296 | {0x39, 0x92}, 297 | {0x35, 0xda}, 298 | {0x22, 0x1a}, 299 | {0x37, 0xc3}, 300 | {0x23, 0x00}, 301 | {ARCOM2, 0xc0}, 302 | {0x06, 0x88}, 303 | {0x07, 0xc0}, 304 | {COM4, 0x87}, 305 | {0x0e, 0x41}, 306 | {0x42, 0x03}, 307 | {0x4c, 0x00}, 308 | {BANK_SEL, BANK_DSP}, 309 | {RESET, RESET_DVP}, 310 | 311 | //Set the sensor resolution (UXGA, SVGA, CIF) 312 | {HSIZE8, 0x64}, 313 | {VSIZE8, 0x4B}, 314 | {SIZEL, 0x00}, 315 | 316 | //Set the image window size >= output size 317 | {HSIZE, 0xC8}, 318 | {VSIZE, 0x96}, 319 | {XOFFL, 0x00}, 320 | {YOFFL, 0x00}, 321 | {VHYX, 0x00}, 322 | {TEST, 0x00}, 323 | 324 | {CTRL2, CTRL2_DCW_EN | 0x1D}, 325 | {CTRLI, CTRLI_LP_DP | 0x00}, 326 | //{R_DVP_SP, 0x08}, 327 | {0, 0} 328 | }; 329 | 330 | const DRAM_ATTR uint8_t ov2640_settings_to_uxga[][2] = { 331 | {BANK_SEL, BANK_SENSOR}, 332 | {COM7, COM7_RES_UXGA}, 333 | 334 | //Set the sensor output window 335 | {COM1, 0x0F}, 336 | {REG32, REG32_UXGA}, 337 | {HSTART, 0x11}, 338 | {HSTOP, 0x75}, 339 | {VSTART, 0x01}, 340 | {VSTOP, 0x97}, 341 | 342 | //{CLKRC, 0x00}, 343 | {0x3d, 0x34}, 344 | {BD50, 0xbb}, 345 | {BD60, 0x9c}, 346 | {0x5a, 0x57}, 347 | {0x6d, 0x80}, 348 | {0x39, 0x82}, 349 | {0x23, 0x00}, 350 | {0x07, 0xc0}, 351 | {0x4c, 0x00}, 352 | {0x35, 0x88}, 353 | {0x22, 0x0a}, 354 | {0x37, 0x40}, 355 | {ARCOM2, 0xa0}, 356 | {0x06, 0x02}, 357 | {COM4, 0xb7}, 358 | {0x0e, 0x01}, 359 | {0x42, 0x83}, 360 | {BANK_SEL, BANK_DSP}, 361 | {RESET, RESET_DVP}, 362 | 363 | //Set the sensor resolution (UXGA, SVGA, CIF) 364 | {HSIZE8, 0xc8}, 365 | {VSIZE8, 0x96}, 366 | {SIZEL, 0x00}, 367 | 368 | //Set the image window size >= output size 369 | {HSIZE, 0x90}, 370 | {VSIZE, 0x2c}, 371 | {XOFFL, 0x00}, 372 | {YOFFL, 0x00}, 373 | {VHYX, 0x88}, 374 | {TEST, 0x00}, 375 | 376 | {CTRL2, CTRL2_DCW_EN | 0x1d}, 377 | {CTRLI, 0x00}, 378 | //{R_DVP_SP, 0x06}, 379 | {0, 0} 380 | }; 381 | 382 | const DRAM_ATTR uint8_t ov2640_settings_jpeg3[][2] = { 383 | {BANK_SEL, BANK_DSP}, 384 | {RESET, RESET_JPEG | RESET_DVP}, 385 | {IMAGE_MODE, IMAGE_MODE_JPEG_EN | IMAGE_MODE_HREF_VSYNC}, 386 | {0xD7, 0x03}, 387 | {0xE1, 0x77}, 388 | {0xE5, 0x1F}, 389 | {0xD9, 0x10}, 390 | {0xDF, 0x80}, 391 | {0x33, 0x80}, 392 | {0x3C, 0x10}, 393 | {0xEB, 0x30}, 394 | {0xDD, 0x7F}, 395 | {RESET, 0x00}, 396 | {0, 0} 397 | }; 398 | 399 | static const uint8_t ov2640_settings_yuv422[][2] = { 400 | {BANK_SEL, BANK_DSP}, 401 | {RESET, RESET_DVP}, 402 | {IMAGE_MODE, IMAGE_MODE_YUV422}, 403 | {0xD7, 0x01}, 404 | {0xE1, 0x67}, 405 | {RESET, 0x00}, 406 | {0, 0}, 407 | }; 408 | 409 | static const uint8_t ov2640_settings_rgb565[][2] = { 410 | {BANK_SEL, BANK_DSP}, 411 | {RESET, RESET_DVP}, 412 | {IMAGE_MODE, IMAGE_MODE_RGB565}, 413 | {0xD7, 0x03}, 414 | {0xE1, 0x77}, 415 | {RESET, 0x00}, 416 | {0, 0}, 417 | }; 418 | 419 | #define NUM_BRIGHTNESS_LEVELS (5) 420 | static const uint8_t brightness_regs[NUM_BRIGHTNESS_LEVELS + 1][5] = { 421 | {BPADDR, BPDATA, BPADDR, BPDATA, BPDATA }, 422 | {0x00, 0x04, 0x09, 0x00, 0x00 }, /* -2 */ 423 | {0x00, 0x04, 0x09, 0x10, 0x00 }, /* -1 */ 424 | {0x00, 0x04, 0x09, 0x20, 0x00 }, /* 0 */ 425 | {0x00, 0x04, 0x09, 0x30, 0x00 }, /* +1 */ 426 | {0x00, 0x04, 0x09, 0x40, 0x00 }, /* +2 */ 427 | }; 428 | 429 | #define NUM_CONTRAST_LEVELS (5) 430 | static const uint8_t contrast_regs[NUM_CONTRAST_LEVELS + 1][7] = { 431 | {BPADDR, BPDATA, BPADDR, BPDATA, BPDATA, BPDATA, BPDATA }, 432 | {0x00, 0x04, 0x07, 0x20, 0x18, 0x34, 0x06 }, /* -2 */ 433 | {0x00, 0x04, 0x07, 0x20, 0x1c, 0x2a, 0x06 }, /* -1 */ 434 | {0x00, 0x04, 0x07, 0x20, 0x20, 0x20, 0x06 }, /* 0 */ 435 | {0x00, 0x04, 0x07, 0x20, 0x24, 0x16, 0x06 }, /* +1 */ 436 | {0x00, 0x04, 0x07, 0x20, 0x28, 0x0c, 0x06 }, /* +2 */ 437 | }; 438 | 439 | #define NUM_SATURATION_LEVELS (5) 440 | static const uint8_t saturation_regs[NUM_SATURATION_LEVELS + 1][5] = { 441 | {BPADDR, BPDATA, BPADDR, BPDATA, BPDATA }, 442 | {0x00, 0x02, 0x03, 0x28, 0x28 }, /* -2 */ 443 | {0x00, 0x02, 0x03, 0x38, 0x38 }, /* -1 */ 444 | {0x00, 0x02, 0x03, 0x48, 0x48 }, /* 0 */ 445 | {0x00, 0x02, 0x03, 0x58, 0x58 }, /* +1 */ 446 | {0x00, 0x02, 0x03, 0x68, 0x68 }, /* +2 */ 447 | }; 448 | 449 | #define NUM_SPECIAL_EFFECTS (7) 450 | static const uint8_t special_effects_regs[NUM_SPECIAL_EFFECTS + 1][5] = { 451 | {BPADDR, BPDATA, BPADDR, BPDATA, BPDATA }, 452 | {0x00, 0X00, 0x05, 0X80, 0X80 }, /* no effect */ 453 | {0x00, 0X40, 0x05, 0X80, 0X80 }, /* negative */ 454 | {0x00, 0X18, 0x05, 0X80, 0X80 }, /* black and white */ 455 | {0x00, 0X18, 0x05, 0X40, 0XC0 }, /* reddish */ 456 | {0x00, 0X18, 0x05, 0X40, 0X40 }, /* greenish */ 457 | {0x00, 0X18, 0x05, 0XA0, 0X40 }, /* blue */ 458 | {0x00, 0X18, 0x05, 0X40, 0XA6 }, /* retro */ 459 | }; 460 | 461 | #define NUM_WB_MODES (4) 462 | static const uint8_t wb_modes_regs[NUM_WB_MODES + 1][3] = { 463 | {0XCC, 0XCD, 0XCE }, 464 | {0x5E, 0X41, 0x54 }, /* sunny */ 465 | {0x65, 0X41, 0x4F }, /* cloudy */ 466 | {0x52, 0X41, 0x66 }, /* office */ 467 | {0x42, 0X3F, 0x71 }, /* home */ 468 | }; 469 | 470 | #define NUM_AE_LEVELS (5) 471 | static const uint8_t ae_levels_regs[NUM_AE_LEVELS + 1][3] = { 472 | { AEW, AEB, VV }, 473 | {0x20, 0X18, 0x60 }, 474 | {0x34, 0X1C, 0x00 }, 475 | {0x3E, 0X38, 0x81 }, 476 | {0x48, 0X40, 0x81 }, 477 | {0x58, 0X50, 0x92 }, 478 | }; 479 | 480 | const uint8_t agc_gain_tbl[31] = { 481 | 0x00, 0x10, 0x18, 0x30, 0x34, 0x38, 0x3C, 0x70, 0x72, 0x74, 0x76, 0x78, 0x7A, 0x7C, 0x7E, 0xF0, 482 | 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF 483 | }; 484 | 485 | #endif /* _OV2640_SETTINGS_H_ */ 486 | -------------------------------------------------------------------------------- /esp-idf_components_esp32-camera/sensors/private_include/ov3660.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the OpenMV project. 3 | * Copyright (c) 2013/2014 Ibrahim Abdelkader 4 | * This work is licensed under the MIT license, see the file LICENSE for details. 5 | * 6 | * OV3660 driver. 7 | * 8 | */ 9 | #ifndef __OV3660_H__ 10 | #define __OV3660_H__ 11 | 12 | #include "sensor.h" 13 | 14 | int ov3660_init(sensor_t *sensor); 15 | 16 | #endif // __OV3660_H__ 17 | -------------------------------------------------------------------------------- /esp-idf_components_esp32-camera/sensors/private_include/ov3660_regs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * OV3660 register definitions. 3 | */ 4 | #ifndef __OV3660_REG_REGS_H__ 5 | #define __OV3660_REG_REGS_H__ 6 | 7 | /* system control registers */ 8 | #define SYSTEM_CTROL0 0x3008 // Bit[7]: Software reset 9 | // Bit[6]: Software power down 10 | // Bit[5]: Reserved 11 | // Bit[4]: SRB clock SYNC enable 12 | // Bit[3]: Isolation suspend select 13 | // Bit[2:0]: Not used 14 | 15 | /* output format control registers */ 16 | #define FORMAT_CTRL 0x501F // Format select 17 | // Bit[2:0]: 18 | // 000: YUV422 19 | // 001: RGB 20 | // 010: Dither 21 | // 011: RAW after DPC 22 | // 101: RAW after CIP 23 | 24 | /* format control registers */ 25 | #define FORMAT_CTRL00 0x4300 26 | 27 | /* frame control registers */ 28 | #define FRAME_CTRL01 0x4201 // Control Passed Frame Number When both ON and OFF number set to 0x00,frame control is in bypass mode 29 | // Bit[7:4]: Not used 30 | // Bit[3:0]: Frame ON number 31 | #define FRAME_CTRL02 0x4202 // Control Masked Frame Number When both ON and OFF number set to 0x00,frame control is in bypass mode 32 | // Bit[7:4]: Not used 33 | // BIT[3:0]: Frame OFF number 34 | 35 | /* ISP top control registers */ 36 | #define PRE_ISP_TEST_SETTING_1 0x503D // Bit[7]: Test enable 37 | // 0: Test disable 38 | // 1: Color bar enable 39 | // Bit[6]: Rolling 40 | // Bit[5]: Transparent 41 | // Bit[4]: Square black and white 42 | // Bit[3:2]: Color bar style 43 | // 00: Standard 8 color bar 44 | // 01: Gradual change at vertical mode 1 45 | // 10: Gradual change at horizontal 46 | // 11: Gradual change at vertical mode 2 47 | // Bit[1:0]: Test select 48 | // 00: Color bar 49 | // 01: Random data 50 | // 10: Square data 51 | // 11: Black image 52 | 53 | //exposure = {0x3500[3:0], 0x3501[7:0], 0x3502[7:0]} / 16 × tROW 54 | 55 | /* AEC/AGC control functions */ 56 | #define AEC_PK_MANUAL 0x3503 // AEC Manual Mode Control 57 | // Bit[7:6]: Reserved 58 | // Bit[5]: Gain delay option 59 | // Valid when 0x3503[4]=1’b0 60 | // 0: Delay one frame latch 61 | // 1: One frame latch 62 | // Bit[4:2]: Reserved 63 | // Bit[1]: AGC manual 64 | // 0: Auto enable 65 | // 1: Manual enable 66 | // Bit[0]: AEC manual 67 | // 0: Auto enable 68 | // 1: Manual enable 69 | 70 | //gain = {0x350A[1:0], 0x350B[7:0]} / 16 71 | 72 | /* mirror and flip registers */ 73 | #define TIMING_TC_REG20 0x3820 // Timing Control Register 74 | // Bit[2:1]: Vertical flip enable 75 | // 00: Normal 76 | // 11: Vertical flip 77 | // Bit[0]: Vertical binning enable 78 | #define TIMING_TC_REG21 0x3821 // Timing Control Register 79 | // Bit[5]: Compression Enable 80 | // Bit[2:1]: Horizontal mirror enable 81 | // 00: Normal 82 | // 11: Horizontal mirror 83 | // Bit[0]: Horizontal binning enable 84 | 85 | #define CLOCK_POL_CONTROL 0x4740// Bit[5]: PCLK polarity 0: active low 86 | // 1: active high 87 | // Bit[3]: Gate PCLK under VSYNC 88 | // Bit[2]: Gate PCLK under HREF 89 | // Bit[1]: HREF polarity 90 | // 0: active low 91 | // 1: active high 92 | // Bit[0] VSYNC polarity 93 | // 0: active low 94 | // 1: active high 95 | #define DRIVE_CAPABILITY 0x302c // Bit[7:6]: 96 | // 00: 1x 97 | // 01: 2x 98 | // 10: 3x 99 | // 11: 4x 100 | 101 | 102 | #define X_ADDR_ST_H 0x3800 //Bit[3:0]: X address start[11:8] 103 | #define X_ADDR_ST_L 0x3801 //Bit[7:0]: X address start[7:0] 104 | #define Y_ADDR_ST_H 0x3802 //Bit[2:0]: Y address start[10:8] 105 | #define Y_ADDR_ST_L 0x3803 //Bit[7:0]: Y address start[7:0] 106 | #define X_ADDR_END_H 0x3804 //Bit[3:0]: X address end[11:8] 107 | #define X_ADDR_END_L 0x3805 //Bit[7:0]: 108 | #define Y_ADDR_END_H 0x3806 //Bit[2:0]: Y address end[10:8] 109 | #define Y_ADDR_END_L 0x3807 //Bit[7:0]: 110 | // Size after scaling 111 | #define X_OUTPUT_SIZE_H 0x3808 //Bit[3:0]: DVP output horizontal width[11:8] 112 | #define X_OUTPUT_SIZE_L 0x3809 //Bit[7:0]: 113 | #define Y_OUTPUT_SIZE_H 0x380a //Bit[2:0]: DVP output vertical height[10:8] 114 | #define Y_OUTPUT_SIZE_L 0x380b //Bit[7:0]: 115 | #define X_TOTAL_SIZE_H 0x380c //Bit[3:0]: Total horizontal size[11:8] 116 | #define X_TOTAL_SIZE_L 0x380d //Bit[7:0]: 117 | #define Y_TOTAL_SIZE_H 0x380e //Bit[7:0]: Total vertical size[15:8] 118 | #define Y_TOTAL_SIZE_L 0x380f //Bit[7:0]: 119 | #define X_OFFSET_H 0x3810 //Bit[3:0]: ISP horizontal offset[11:8] 120 | #define X_OFFSET_L 0x3811 //Bit[7:0]: 121 | #define Y_OFFSET_H 0x3812 //Bit[2:0]: ISP vertical offset[10:8] 122 | #define Y_OFFSET_L 0x3813 //Bit[7:0]: 123 | #define X_INCREMENT 0x3814 //Bit[7:4]: Horizontal odd subsample increment 124 | //Bit[3:0]: Horizontal even subsample increment 125 | #define Y_INCREMENT 0x3815 //Bit[7:4]: Vertical odd subsample increment 126 | //Bit[3:0]: Vertical even subsample increment 127 | // Size before scaling 128 | //#define X_INPUT_SIZE (X_ADDR_END - X_ADDR_ST + 1 - (2 * X_OFFSET)) 129 | //#define Y_INPUT_SIZE (Y_ADDR_END - Y_ADDR_ST + 1 - (2 * Y_OFFSET)) 130 | 131 | #define ISP_CONTROL_01 0x5001 // Bit[5]: Scale enable 132 | // 0: Disable 133 | // 1: Enable 134 | 135 | #define SCALE_CTRL_1 0x5601 // Bit[6:4]: HDIV RW 136 | // DCW scale times 137 | // 000: DCW 1 time 138 | // 001: DCW 2 times 139 | // 010: DCW 4 times 140 | // 100: DCW 8 times 141 | // 101: DCW 16 times 142 | // Others: DCW 16 times 143 | // Bit[2:0]: VDIV RW 144 | // DCW scale times 145 | // 000: DCW 1 time 146 | // 001: DCW 2 times 147 | // 010: DCW 4 times 148 | // 100: DCW 8 times 149 | // 101: DCW 16 times 150 | // Others: DCW 16 times 151 | 152 | #define SCALE_CTRL_2 0x5602 // X_SCALE High Bits 153 | #define SCALE_CTRL_3 0x5603 // X_SCALE Low Bits 154 | #define SCALE_CTRL_4 0x5604 // Y_SCALE High Bits 155 | #define SCALE_CTRL_5 0x5605 // Y_SCALE Low Bits 156 | #define SCALE_CTRL_6 0x5606 // Bit[3:0]: V Offset 157 | 158 | #define PCLK_RATIO 0x3824 // Bit[4:0]: PCLK ratio manual 159 | #define VFIFO_CTRL0C 0x460C // Bit[1]: PCLK manual enable 160 | // 0: Auto 161 | // 1: Manual by PCLK_RATIO 162 | 163 | #define VFIFO_X_SIZE_H 0x4602 164 | #define VFIFO_X_SIZE_L 0x4603 165 | #define VFIFO_Y_SIZE_H 0x4604 166 | #define VFIFO_Y_SIZE_L 0x4605 167 | 168 | #define SC_PLLS_CTRL0 0x303a // Bit[7]: PLLS bypass 169 | #define SC_PLLS_CTRL1 0x303b // Bit[4:0]: PLLS multiplier 170 | #define SC_PLLS_CTRL2 0x303c // Bit[6:4]: PLLS charge pump control 171 | // Bit[3:0]: PLLS system divider 172 | #define SC_PLLS_CTRL3 0x303d // Bit[5:4]: PLLS pre-divider 173 | // 00: 1 174 | // 01: 1.5 175 | // 10: 2 176 | // 11: 3 177 | // Bit[2]: PLLS root-divider - 1 178 | // Bit[1:0]: PLLS seld5 179 | // 00: 1 180 | // 01: 1 181 | // 10: 2 182 | // 11: 2.5 183 | 184 | #define COMPRESSION_CTRL00 0x4400 // 185 | #define COMPRESSION_CTRL01 0x4401 // 186 | #define COMPRESSION_CTRL02 0x4402 // 187 | #define COMPRESSION_CTRL03 0x4403 // 188 | #define COMPRESSION_CTRL04 0x4404 // 189 | #define COMPRESSION_CTRL05 0x4405 // 190 | #define COMPRESSION_CTRL06 0x4406 // 191 | #define COMPRESSION_CTRL07 0x4407 // Bit[5:0]: QS 192 | #define COMPRESSION_ISI_CTRL 0x4408 // 193 | #define COMPRESSION_CTRL09 0x4409 // 194 | #define COMPRESSION_CTRL0a 0x440a // 195 | #define COMPRESSION_CTRL0b 0x440b // 196 | #define COMPRESSION_CTRL0c 0x440c // 197 | #define COMPRESSION_CTRL0d 0x440d // 198 | #define COMPRESSION_CTRL0E 0x440e // 199 | 200 | /** 201 | * @brief register value 202 | */ 203 | #define TEST_COLOR_BAR 0xC0 /* Enable Color Bar roling Test */ 204 | 205 | #define AEC_PK_MANUAL_AGC_MANUALEN 0x02 /* Enable AGC Manual enable */ 206 | #define AEC_PK_MANUAL_AEC_MANUALEN 0x01 /* Enable AEC Manual enable */ 207 | 208 | #define TIMING_TC_REG20_VFLIP 0x06 /* Vertical flip enable */ 209 | #define TIMING_TC_REG21_HMIRROR 0x06 /* Horizontal mirror enable */ 210 | 211 | #endif // __OV3660_REG_REGS_H__ 212 | -------------------------------------------------------------------------------- /esp-idf_components_esp32-camera/sensors/private_include/ov3660_settings.h: -------------------------------------------------------------------------------- 1 | #ifndef _OV3660_SETTINGS_H_ 2 | #define _OV3660_SETTINGS_H_ 3 | 4 | #include 5 | #include 6 | #include "esp_attr.h" 7 | #include "ov3660_regs.h" 8 | 9 | static const ratio_settings_t ratio_table[] = { 10 | // mw, mh, sx, sy, ex, ey, ox, oy, tx, ty 11 | { 2048, 1536, 0, 0, 2079, 1547, 16, 6, 2300, 1564 }, //4x3 12 | { 1920, 1280, 64, 128, 2015, 1419, 16, 6, 2172, 1436 }, //3x2 13 | { 2048, 1280, 0, 128, 2079, 1419, 16, 6, 2300, 1436 }, //16x10 14 | { 1920, 1152, 64, 192, 2015, 1355, 16, 6, 2172, 1372 }, //5x3 15 | { 1920, 1080, 64, 242, 2015, 1333, 16, 6, 2172, 1322 }, //16x9 16 | { 2048, 880, 0, 328, 2079, 1219, 16, 6, 2300, 1236 }, //21x9 17 | { 1920, 1536, 64, 0, 2015, 1547, 16, 6, 2172, 1564 }, //5x4 18 | { 1536, 1536, 256, 0, 1823, 1547, 16, 6, 2044, 1564 }, //1x1 19 | { 864, 1536, 592, 0, 1487, 1547, 16, 6, 2044, 1564 } //9x16 20 | }; 21 | 22 | #define REG_DLY 0xffff 23 | #define REGLIST_TAIL 0x0000 24 | 25 | static const DRAM_ATTR uint16_t sensor_default_regs[][2] = { 26 | {SYSTEM_CTROL0, 0x82}, // software reset 27 | {REG_DLY, 10}, // delay 10ms 28 | 29 | {0x3103, 0x13}, 30 | {SYSTEM_CTROL0, 0x42}, 31 | {0x3017, 0xff}, 32 | {0x3018, 0xff}, 33 | {DRIVE_CAPABILITY, 0xc3}, 34 | {CLOCK_POL_CONTROL, 0x21}, 35 | 36 | {0x3611, 0x01}, 37 | {0x3612, 0x2d}, 38 | 39 | {0x3032, 0x00}, 40 | {0x3614, 0x80}, 41 | {0x3618, 0x00}, 42 | {0x3619, 0x75}, 43 | {0x3622, 0x80}, 44 | {0x3623, 0x00}, 45 | {0x3624, 0x03}, 46 | {0x3630, 0x52}, 47 | {0x3632, 0x07}, 48 | {0x3633, 0xd2}, 49 | {0x3704, 0x80}, 50 | {0x3708, 0x66}, 51 | {0x3709, 0x12}, 52 | {0x370b, 0x12}, 53 | {0x3717, 0x00}, 54 | {0x371b, 0x60}, 55 | {0x371c, 0x00}, 56 | {0x3901, 0x13}, 57 | 58 | {0x3600, 0x08}, 59 | {0x3620, 0x43}, 60 | {0x3702, 0x20}, 61 | {0x3739, 0x48}, 62 | {0x3730, 0x20}, 63 | {0x370c, 0x0c}, 64 | 65 | {0x3a18, 0x00}, 66 | {0x3a19, 0xf8}, 67 | 68 | {0x3000, 0x10}, 69 | {0x3004, 0xef}, 70 | 71 | {0x6700, 0x05}, 72 | {0x6701, 0x19}, 73 | {0x6702, 0xfd}, 74 | {0x6703, 0xd1}, 75 | {0x6704, 0xff}, 76 | {0x6705, 0xff}, 77 | 78 | {0x3c01, 0x80}, 79 | {0x3c00, 0x04}, 80 | {0x3a08, 0x00}, {0x3a09, 0x62}, //50Hz Band Width Step (10bit) 81 | {0x3a0e, 0x08}, //50Hz Max Bands in One Frame (6 bit) 82 | {0x3a0a, 0x00}, {0x3a0b, 0x52}, //60Hz Band Width Step (10bit) 83 | {0x3a0d, 0x09}, //60Hz Max Bands in One Frame (6 bit) 84 | 85 | {0x3a00, 0x3a},//night mode off 86 | {0x3a14, 0x09}, 87 | {0x3a15, 0x30}, 88 | {0x3a02, 0x09}, 89 | {0x3a03, 0x30}, 90 | 91 | {COMPRESSION_CTRL0E, 0x08}, 92 | {0x4520, 0x0b}, 93 | {0x460b, 0x37}, 94 | {0x4713, 0x02}, 95 | {0x471c, 0xd0}, 96 | {0x5086, 0x00}, 97 | 98 | {0x5002, 0x00}, 99 | {0x501f, 0x00}, 100 | 101 | {SYSTEM_CTROL0, 0x02}, 102 | 103 | {0x5180, 0xff}, 104 | {0x5181, 0xf2}, 105 | {0x5182, 0x00}, 106 | {0x5183, 0x14}, 107 | {0x5184, 0x25}, 108 | {0x5185, 0x24}, 109 | {0x5186, 0x16}, 110 | {0x5187, 0x16}, 111 | {0x5188, 0x16}, 112 | {0x5189, 0x68}, 113 | {0x518a, 0x60}, 114 | {0x518b, 0xe0}, 115 | {0x518c, 0xb2}, 116 | {0x518d, 0x42}, 117 | {0x518e, 0x35}, 118 | {0x518f, 0x56}, 119 | {0x5190, 0x56}, 120 | {0x5191, 0xf8}, 121 | {0x5192, 0x04}, 122 | {0x5193, 0x70}, 123 | {0x5194, 0xf0}, 124 | {0x5195, 0xf0}, 125 | {0x5196, 0x03}, 126 | {0x5197, 0x01}, 127 | {0x5198, 0x04}, 128 | {0x5199, 0x12}, 129 | {0x519a, 0x04}, 130 | {0x519b, 0x00}, 131 | {0x519c, 0x06}, 132 | {0x519d, 0x82}, 133 | {0x519e, 0x38}, 134 | 135 | {0x5381, 0x1d}, 136 | {0x5382, 0x60}, 137 | {0x5383, 0x03}, 138 | {0x5384, 0x0c}, 139 | {0x5385, 0x78}, 140 | {0x5386, 0x84}, 141 | {0x5387, 0x7d}, 142 | {0x5388, 0x6b}, 143 | {0x5389, 0x12}, 144 | {0x538a, 0x01}, 145 | {0x538b, 0x98}, 146 | 147 | {0x5480, 0x01}, 148 | // {0x5481, 0x05}, 149 | // {0x5482, 0x09}, 150 | // {0x5483, 0x10}, 151 | // {0x5484, 0x3a}, 152 | // {0x5485, 0x4c}, 153 | // {0x5486, 0x5a}, 154 | // {0x5487, 0x68}, 155 | // {0x5488, 0x74}, 156 | // {0x5489, 0x80}, 157 | // {0x548a, 0x8e}, 158 | // {0x548b, 0xa4}, 159 | // {0x548c, 0xb4}, 160 | // {0x548d, 0xc8}, 161 | // {0x548e, 0xde}, 162 | // {0x548f, 0xf0}, 163 | // {0x5490, 0x15}, 164 | 165 | {0x5000, 0xa7}, 166 | {0x5800, 0x0C}, 167 | {0x5801, 0x09}, 168 | {0x5802, 0x0C}, 169 | {0x5803, 0x0C}, 170 | {0x5804, 0x0D}, 171 | {0x5805, 0x17}, 172 | {0x5806, 0x06}, 173 | {0x5807, 0x05}, 174 | {0x5808, 0x04}, 175 | {0x5809, 0x06}, 176 | {0x580a, 0x09}, 177 | {0x580b, 0x0E}, 178 | {0x580c, 0x05}, 179 | {0x580d, 0x01}, 180 | {0x580e, 0x01}, 181 | {0x580f, 0x01}, 182 | {0x5810, 0x05}, 183 | {0x5811, 0x0D}, 184 | {0x5812, 0x05}, 185 | {0x5813, 0x01}, 186 | {0x5814, 0x01}, 187 | {0x5815, 0x01}, 188 | {0x5816, 0x05}, 189 | {0x5817, 0x0D}, 190 | {0x5818, 0x08}, 191 | {0x5819, 0x06}, 192 | {0x581a, 0x05}, 193 | {0x581b, 0x07}, 194 | {0x581c, 0x0B}, 195 | {0x581d, 0x0D}, 196 | {0x581e, 0x12}, 197 | {0x581f, 0x0D}, 198 | {0x5820, 0x0E}, 199 | {0x5821, 0x10}, 200 | {0x5822, 0x10}, 201 | {0x5823, 0x1E}, 202 | {0x5824, 0x53}, 203 | {0x5825, 0x15}, 204 | {0x5826, 0x05}, 205 | {0x5827, 0x14}, 206 | {0x5828, 0x54}, 207 | {0x5829, 0x25}, 208 | {0x582a, 0x33}, 209 | {0x582b, 0x33}, 210 | {0x582c, 0x34}, 211 | {0x582d, 0x16}, 212 | {0x582e, 0x24}, 213 | {0x582f, 0x41}, 214 | {0x5830, 0x50}, 215 | {0x5831, 0x42}, 216 | {0x5832, 0x15}, 217 | {0x5833, 0x25}, 218 | {0x5834, 0x34}, 219 | {0x5835, 0x33}, 220 | {0x5836, 0x24}, 221 | {0x5837, 0x26}, 222 | {0x5838, 0x54}, 223 | {0x5839, 0x25}, 224 | {0x583a, 0x15}, 225 | {0x583b, 0x25}, 226 | {0x583c, 0x53}, 227 | {0x583d, 0xCF}, 228 | 229 | {0x3a0f, 0x30}, 230 | {0x3a10, 0x28}, 231 | {0x3a1b, 0x30}, 232 | {0x3a1e, 0x28}, 233 | {0x3a11, 0x60}, 234 | {0x3a1f, 0x14}, 235 | 236 | {0x5302, 0x28}, 237 | {0x5303, 0x20}, 238 | 239 | {0x5306, 0x1c}, //de-noise offset 1 240 | {0x5307, 0x28}, //de-noise offset 2 241 | 242 | {0x4002, 0xc5}, 243 | {0x4003, 0x81}, 244 | {0x4005, 0x12}, 245 | 246 | {0x5688, 0x11}, 247 | {0x5689, 0x11}, 248 | {0x568a, 0x11}, 249 | {0x568b, 0x11}, 250 | {0x568c, 0x11}, 251 | {0x568d, 0x11}, 252 | {0x568e, 0x11}, 253 | {0x568f, 0x11}, 254 | 255 | {0x5580, 0x06}, 256 | {0x5588, 0x00}, 257 | {0x5583, 0x40}, 258 | {0x5584, 0x2c}, 259 | 260 | {ISP_CONTROL_01, 0x83}, // turn color matrix, awb and SDE 261 | {REGLIST_TAIL, 0x00}, // tail 262 | }; 263 | 264 | static const DRAM_ATTR uint16_t sensor_fmt_jpeg[][2] = { 265 | {FORMAT_CTRL, 0x00}, // YUV422 266 | {FORMAT_CTRL00, 0x30}, // YUYV 267 | {0x3002, 0x00},//0x1c to 0x00 !!! 268 | {0x3006, 0xff},//0xc3 to 0xff !!! 269 | {0x471c, 0x50},//0xd0 to 0x50 !!! 270 | {REGLIST_TAIL, 0x00}, // tail 271 | }; 272 | 273 | static const DRAM_ATTR uint16_t sensor_fmt_raw[][2] = { 274 | {FORMAT_CTRL00, 0x00}, // RAW 275 | {REGLIST_TAIL, 0x00} 276 | }; 277 | 278 | static const DRAM_ATTR uint16_t sensor_fmt_grayscale[][2] = { 279 | {FORMAT_CTRL, 0x00}, // YUV422 280 | {FORMAT_CTRL00, 0x10}, // Y8 281 | {REGLIST_TAIL, 0x00} 282 | }; 283 | 284 | static const DRAM_ATTR uint16_t sensor_fmt_yuv422[][2] = { 285 | {FORMAT_CTRL, 0x00}, // YUV422 286 | {FORMAT_CTRL00, 0x30}, // YUYV 287 | {REGLIST_TAIL, 0x00} 288 | }; 289 | 290 | static const DRAM_ATTR uint16_t sensor_fmt_rgb565[][2] = { 291 | {FORMAT_CTRL, 0x01}, // RGB 292 | {FORMAT_CTRL00, 0x61}, // RGB565 (BGR) 293 | {REGLIST_TAIL, 0x00} 294 | }; 295 | 296 | static const DRAM_ATTR uint8_t sensor_saturation_levels[9][11] = { 297 | {0x1d, 0x60, 0x03, 0x07, 0x48, 0x4f, 0x4b, 0x40, 0x0b, 0x01, 0x98},//-4 298 | {0x1d, 0x60, 0x03, 0x08, 0x54, 0x5c, 0x58, 0x4b, 0x0d, 0x01, 0x98},//-3 299 | {0x1d, 0x60, 0x03, 0x0a, 0x60, 0x6a, 0x64, 0x56, 0x0e, 0x01, 0x98},//-2 300 | {0x1d, 0x60, 0x03, 0x0b, 0x6c, 0x77, 0x70, 0x60, 0x10, 0x01, 0x98},//-1 301 | {0x1d, 0x60, 0x03, 0x0c, 0x78, 0x84, 0x7d, 0x6b, 0x12, 0x01, 0x98},//0 302 | {0x1d, 0x60, 0x03, 0x0d, 0x84, 0x91, 0x8a, 0x76, 0x14, 0x01, 0x98},//+1 303 | {0x1d, 0x60, 0x03, 0x0e, 0x90, 0x9e, 0x96, 0x80, 0x16, 0x01, 0x98},//+2 304 | {0x1d, 0x60, 0x03, 0x10, 0x9c, 0xac, 0xa2, 0x8b, 0x17, 0x01, 0x98},//+3 305 | {0x1d, 0x60, 0x03, 0x11, 0xa8, 0xb9, 0xaf, 0x96, 0x19, 0x01, 0x98},//+4 306 | }; 307 | 308 | static const DRAM_ATTR uint8_t sensor_special_effects[7][4] = { 309 | {0x06, 0x40, 0x2c, 0x08},//Normal 310 | {0x46, 0x40, 0x28, 0x08},//Negative 311 | {0x1e, 0x80, 0x80, 0x08},//Grayscale 312 | {0x1e, 0x80, 0xc0, 0x08},//Red Tint 313 | {0x1e, 0x60, 0x60, 0x08},//Green Tint 314 | {0x1e, 0xa0, 0x40, 0x08},//Blue Tint 315 | {0x1e, 0x40, 0xa0, 0x08},//Sepia 316 | }; 317 | 318 | #endif 319 | -------------------------------------------------------------------------------- /esp-idf_components_esp32-camera/sensors/private_include/ov5640.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef __OV5640_H__ 3 | #define __OV5640_H__ 4 | 5 | #include "sensor.h" 6 | 7 | int ov5640_init(sensor_t *sensor); 8 | 9 | #endif // __OV5640_H__ 10 | -------------------------------------------------------------------------------- /esp-idf_components_esp32-camera/sensors/private_include/ov5640_regs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * OV5640 register definitions. 3 | */ 4 | #ifndef __OV5640_REG_REGS_H__ 5 | #define __OV5640_REG_REGS_H__ 6 | 7 | /* system control registers */ 8 | #define SYSTEM_CTROL0 0x3008 // Bit[7]: Software reset 9 | // Bit[6]: Software power down 10 | // Bit[5]: Reserved 11 | // Bit[4]: SRB clock SYNC enable 12 | // Bit[3]: Isolation suspend select 13 | // Bit[2:0]: Not used 14 | 15 | #define DRIVE_CAPABILITY 0x302c // Bit[7:6]: 16 | // 00: 1x 17 | // 01: 2x 18 | // 10: 3x 19 | // 11: 4x 20 | 21 | #define SC_PLLS_CTRL0 0x303a // Bit[7]: PLLS bypass 22 | #define SC_PLLS_CTRL1 0x303b // Bit[4:0]: PLLS multiplier 23 | #define SC_PLLS_CTRL2 0x303c // Bit[6:4]: PLLS charge pump control 24 | // Bit[3:0]: PLLS system divider 25 | #define SC_PLLS_CTRL3 0x303d // Bit[5:4]: PLLS pre-divider 26 | // 00: 1 27 | // 01: 1.5 28 | // 10: 2 29 | // 11: 3 30 | // Bit[2]: PLLS root-divider - 1 31 | // Bit[1:0]: PLLS seld5 32 | // 00: 1 33 | // 01: 1 34 | // 10: 2 35 | // 11: 2.5 36 | 37 | /* AEC/AGC control functions */ 38 | #define AEC_PK_MANUAL 0x3503 // AEC Manual Mode Control 39 | // Bit[7:6]: Reserved 40 | // Bit[5]: Gain delay option 41 | // Valid when 0x3503[4]=1’b0 42 | // 0: Delay one frame latch 43 | // 1: One frame latch 44 | // Bit[4:2]: Reserved 45 | // Bit[1]: AGC manual 46 | // 0: Auto enable 47 | // 1: Manual enable 48 | // Bit[0]: AEC manual 49 | // 0: Auto enable 50 | // 1: Manual enable 51 | 52 | //gain = {0x350A[1:0], 0x350B[7:0]} / 16 53 | 54 | 55 | #define X_ADDR_ST_H 0x3800 //Bit[3:0]: X address start[11:8] 56 | #define X_ADDR_ST_L 0x3801 //Bit[7:0]: X address start[7:0] 57 | #define Y_ADDR_ST_H 0x3802 //Bit[2:0]: Y address start[10:8] 58 | #define Y_ADDR_ST_L 0x3803 //Bit[7:0]: Y address start[7:0] 59 | #define X_ADDR_END_H 0x3804 //Bit[3:0]: X address end[11:8] 60 | #define X_ADDR_END_L 0x3805 //Bit[7:0]: 61 | #define Y_ADDR_END_H 0x3806 //Bit[2:0]: Y address end[10:8] 62 | #define Y_ADDR_END_L 0x3807 //Bit[7:0]: 63 | // Size after scaling 64 | #define X_OUTPUT_SIZE_H 0x3808 //Bit[3:0]: DVP output horizontal width[11:8] 65 | #define X_OUTPUT_SIZE_L 0x3809 //Bit[7:0]: 66 | #define Y_OUTPUT_SIZE_H 0x380a //Bit[2:0]: DVP output vertical height[10:8] 67 | #define Y_OUTPUT_SIZE_L 0x380b //Bit[7:0]: 68 | #define X_TOTAL_SIZE_H 0x380c //Bit[3:0]: Total horizontal size[11:8] 69 | #define X_TOTAL_SIZE_L 0x380d //Bit[7:0]: 70 | #define Y_TOTAL_SIZE_H 0x380e //Bit[7:0]: Total vertical size[15:8] 71 | #define Y_TOTAL_SIZE_L 0x380f //Bit[7:0]: 72 | #define X_OFFSET_H 0x3810 //Bit[3:0]: ISP horizontal offset[11:8] 73 | #define X_OFFSET_L 0x3811 //Bit[7:0]: 74 | #define Y_OFFSET_H 0x3812 //Bit[2:0]: ISP vertical offset[10:8] 75 | #define Y_OFFSET_L 0x3813 //Bit[7:0]: 76 | #define X_INCREMENT 0x3814 //Bit[7:4]: Horizontal odd subsample increment 77 | //Bit[3:0]: Horizontal even subsample increment 78 | #define Y_INCREMENT 0x3815 //Bit[7:4]: Vertical odd subsample increment 79 | //Bit[3:0]: Vertical even subsample increment 80 | // Size before scaling 81 | //#define X_INPUT_SIZE (X_ADDR_END - X_ADDR_ST + 1 - (2 * X_OFFSET)) 82 | //#define Y_INPUT_SIZE (Y_ADDR_END - Y_ADDR_ST + 1 - (2 * Y_OFFSET)) 83 | 84 | /* mirror and flip registers */ 85 | #define TIMING_TC_REG20 0x3820 // Timing Control Register 86 | // Bit[2:1]: Vertical flip enable 87 | // 00: Normal 88 | // 11: Vertical flip 89 | // Bit[0]: Vertical binning enable 90 | #define TIMING_TC_REG21 0x3821 // Timing Control Register 91 | // Bit[5]: Compression Enable 92 | // Bit[2:1]: Horizontal mirror enable 93 | // 00: Normal 94 | // 11: Horizontal mirror 95 | // Bit[0]: Horizontal binning enable 96 | 97 | #define PCLK_RATIO 0x3824 // Bit[4:0]: PCLK ratio manual 98 | 99 | /* frame control registers */ 100 | #define FRAME_CTRL01 0x4201 // Control Passed Frame Number When both ON and OFF number set to 0x00,frame control is in bypass mode 101 | // Bit[7:4]: Not used 102 | // Bit[3:0]: Frame ON number 103 | #define FRAME_CTRL02 0x4202 // Control Masked Frame Number When both ON and OFF number set to 0x00,frame control is in bypass mode 104 | // Bit[7:4]: Not used 105 | // BIT[3:0]: Frame OFF number 106 | 107 | /* format control registers */ 108 | #define FORMAT_CTRL00 0x4300 109 | 110 | #define CLOCK_POL_CONTROL 0x4740// Bit[5]: PCLK polarity 0: active low 111 | // 1: active high 112 | // Bit[3]: Gate PCLK under VSYNC 113 | // Bit[2]: Gate PCLK under HREF 114 | // Bit[1]: HREF polarity 115 | // 0: active low 116 | // 1: active high 117 | // Bit[0] VSYNC polarity 118 | // 0: active low 119 | // 1: active high 120 | 121 | #define ISP_CONTROL_01 0x5001 // Bit[5]: Scale enable 122 | // 0: Disable 123 | // 1: Enable 124 | 125 | /* output format control registers */ 126 | #define FORMAT_CTRL 0x501F // Format select 127 | // Bit[2:0]: 128 | // 000: YUV422 129 | // 001: RGB 130 | // 010: Dither 131 | // 011: RAW after DPC 132 | // 101: RAW after CIP 133 | 134 | /* ISP top control registers */ 135 | #define PRE_ISP_TEST_SETTING_1 0x503D // Bit[7]: Test enable 136 | // 0: Test disable 137 | // 1: Color bar enable 138 | // Bit[6]: Rolling 139 | // Bit[5]: Transparent 140 | // Bit[4]: Square black and white 141 | // Bit[3:2]: Color bar style 142 | // 00: Standard 8 color bar 143 | // 01: Gradual change at vertical mode 1 144 | // 10: Gradual change at horizontal 145 | // 11: Gradual change at vertical mode 2 146 | // Bit[1:0]: Test select 147 | // 00: Color bar 148 | // 01: Random data 149 | // 10: Square data 150 | // 11: Black image 151 | 152 | //exposure = {0x3500[3:0], 0x3501[7:0], 0x3502[7:0]} / 16 × tROW 153 | 154 | #define SCALE_CTRL_1 0x5601 // Bit[6:4]: HDIV RW 155 | // DCW scale times 156 | // 000: DCW 1 time 157 | // 001: DCW 2 times 158 | // 010: DCW 4 times 159 | // 100: DCW 8 times 160 | // 101: DCW 16 times 161 | // Others: DCW 16 times 162 | // Bit[2:0]: VDIV RW 163 | // DCW scale times 164 | // 000: DCW 1 time 165 | // 001: DCW 2 times 166 | // 010: DCW 4 times 167 | // 100: DCW 8 times 168 | // 101: DCW 16 times 169 | // Others: DCW 16 times 170 | 171 | #define SCALE_CTRL_2 0x5602 // X_SCALE High Bits 172 | #define SCALE_CTRL_3 0x5603 // X_SCALE Low Bits 173 | #define SCALE_CTRL_4 0x5604 // Y_SCALE High Bits 174 | #define SCALE_CTRL_5 0x5605 // Y_SCALE Low Bits 175 | #define SCALE_CTRL_6 0x5606 // Bit[3:0]: V Offset 176 | 177 | #define VFIFO_CTRL0C 0x460C // Bit[1]: PCLK manual enable 178 | // 0: Auto 179 | // 1: Manual by PCLK_RATIO 180 | 181 | #define VFIFO_X_SIZE_H 0x4602 182 | #define VFIFO_X_SIZE_L 0x4603 183 | #define VFIFO_Y_SIZE_H 0x4604 184 | #define VFIFO_Y_SIZE_L 0x4605 185 | 186 | #define COMPRESSION_CTRL00 0x4400 // 187 | #define COMPRESSION_CTRL01 0x4401 // 188 | #define COMPRESSION_CTRL02 0x4402 // 189 | #define COMPRESSION_CTRL03 0x4403 // 190 | #define COMPRESSION_CTRL04 0x4404 // 191 | #define COMPRESSION_CTRL05 0x4405 // 192 | #define COMPRESSION_CTRL06 0x4406 // 193 | #define COMPRESSION_CTRL07 0x4407 // Bit[5:0]: QS 194 | #define COMPRESSION_ISI_CTRL 0x4408 // 195 | #define COMPRESSION_CTRL09 0x4409 // 196 | #define COMPRESSION_CTRL0a 0x440a // 197 | #define COMPRESSION_CTRL0b 0x440b // 198 | #define COMPRESSION_CTRL0c 0x440c // 199 | #define COMPRESSION_CTRL0d 0x440d // 200 | #define COMPRESSION_CTRL0E 0x440e // 201 | 202 | /** 203 | * @brief register value 204 | */ 205 | #define TEST_COLOR_BAR 0xC0 /* Enable Color Bar roling Test */ 206 | 207 | #define AEC_PK_MANUAL_AGC_MANUALEN 0x02 /* Enable AGC Manual enable */ 208 | #define AEC_PK_MANUAL_AEC_MANUALEN 0x01 /* Enable AEC Manual enable */ 209 | 210 | #define TIMING_TC_REG20_VFLIP 0x06 /* Vertical flip enable */ 211 | #define TIMING_TC_REG21_HMIRROR 0x06 /* Horizontal mirror enable */ 212 | 213 | #endif // __OV3660_REG_REGS_H__ 214 | -------------------------------------------------------------------------------- /esp-idf_components_esp32-camera/sensors/private_include/ov5640_settings.h: -------------------------------------------------------------------------------- 1 | #ifndef _OV5640_SETTINGS_H_ 2 | #define _OV5640_SETTINGS_H_ 3 | 4 | #include 5 | #include 6 | #include "esp_attr.h" 7 | #include "ov5640_regs.h" 8 | 9 | static const ratio_settings_t ratio_table[] = { 10 | // mw, mh, sx, sy, ex, ey, ox, oy, tx, ty 11 | { 2560, 1920, 0, 0, 2623, 1951, 32, 16, 2844, 1968 }, //4x3 12 | { 2560, 1704, 0, 110, 2623, 1843, 32, 16, 2844, 1752 }, //3x2 13 | { 2560, 1600, 0, 160, 2623, 1791, 32, 16, 2844, 1648 }, //16x10 14 | { 2560, 1536, 0, 192, 2623, 1759, 32, 16, 2844, 1584 }, //5x3 15 | { 2560, 1440, 0, 240, 2623, 1711, 32, 16, 2844, 1488 }, //16x9 16 | { 2560, 1080, 0, 420, 2623, 1531, 32, 16, 2844, 1128 }, //21x9 17 | { 2400, 1920, 80, 0, 2543, 1951, 32, 16, 2684, 1968 }, //5x4 18 | { 1920, 1920, 320, 0, 2543, 1951, 32, 16, 2684, 1968 }, //1x1 19 | { 1088, 1920, 736, 0, 1887, 1951, 32, 16, 1884, 1968 } //9x16 20 | }; 21 | 22 | #define REG_DLY 0xffff 23 | #define REGLIST_TAIL 0x0000 24 | 25 | static const DRAM_ATTR uint16_t sensor_default_regs[][2] = { 26 | {SYSTEM_CTROL0, 0x82}, // software reset 27 | {REG_DLY, 10}, // delay 10ms 28 | {SYSTEM_CTROL0, 0x42}, // power down 29 | 30 | //enable pll 31 | {0x3103, 0x13}, 32 | 33 | //io direction 34 | {0x3017, 0xff}, 35 | {0x3018, 0xff}, 36 | 37 | {DRIVE_CAPABILITY, 0xc3}, 38 | {CLOCK_POL_CONTROL, 0x21}, 39 | 40 | {0x4713, 0x02},//jpg mode select 41 | 42 | {ISP_CONTROL_01, 0x83}, // turn color matrix, awb and SDE 43 | 44 | //sys reset 45 | {0x3000, 0x00}, 46 | {0x3002, 0x1c}, 47 | 48 | //clock enable 49 | {0x3004, 0xff}, 50 | {0x3006, 0xc3}, 51 | 52 | //isp control 53 | {0x5000, 0xa7}, 54 | {ISP_CONTROL_01, 0xa3},//+scaling? 55 | {0x5003, 0x08},//special_effect 56 | 57 | //unknown 58 | {0x370c, 0x02},//!!IMPORTANT 59 | {0x3634, 0x40},//!!IMPORTANT 60 | 61 | //AEC/AGC 62 | {0x3a02, 0x03}, 63 | {0x3a03, 0xd8}, 64 | {0x3a08, 0x01}, 65 | {0x3a09, 0x27}, 66 | {0x3a0a, 0x00}, 67 | {0x3a0b, 0xf6}, 68 | {0x3a0d, 0x04}, 69 | {0x3a0e, 0x03}, 70 | {0x3a0f, 0x30},//ae_level 71 | {0x3a10, 0x28},//ae_level 72 | {0x3a11, 0x60},//ae_level 73 | {0x3a13, 0x43}, 74 | {0x3a14, 0x03}, 75 | {0x3a15, 0xd8}, 76 | {0x3a18, 0x00},//gainceiling 77 | {0x3a19, 0xf8},//gainceiling 78 | {0x3a1b, 0x30},//ae_level 79 | {0x3a1e, 0x26},//ae_level 80 | {0x3a1f, 0x14},//ae_level 81 | 82 | //vcm debug 83 | {0x3600, 0x08}, 84 | {0x3601, 0x33}, 85 | 86 | //50/60Hz 87 | {0x3c01, 0xa4}, 88 | {0x3c04, 0x28}, 89 | {0x3c05, 0x98}, 90 | {0x3c06, 0x00}, 91 | {0x3c07, 0x08}, 92 | {0x3c08, 0x00}, 93 | {0x3c09, 0x1c}, 94 | {0x3c0a, 0x9c}, 95 | {0x3c0b, 0x40}, 96 | 97 | {0x460c, 0x22},//disable jpeg footer 98 | 99 | //BLC 100 | {0x4001, 0x02}, 101 | {0x4004, 0x02}, 102 | 103 | //AWB 104 | {0x5180, 0xff}, 105 | {0x5181, 0xf2}, 106 | {0x5182, 0x00}, 107 | {0x5183, 0x14}, 108 | {0x5184, 0x25}, 109 | {0x5185, 0x24}, 110 | {0x5186, 0x09}, 111 | {0x5187, 0x09}, 112 | {0x5188, 0x09}, 113 | {0x5189, 0x75}, 114 | {0x518a, 0x54}, 115 | {0x518b, 0xe0}, 116 | {0x518c, 0xb2}, 117 | {0x518d, 0x42}, 118 | {0x518e, 0x3d}, 119 | {0x518f, 0x56}, 120 | {0x5190, 0x46}, 121 | {0x5191, 0xf8}, 122 | {0x5192, 0x04}, 123 | {0x5193, 0x70}, 124 | {0x5194, 0xf0}, 125 | {0x5195, 0xf0}, 126 | {0x5196, 0x03}, 127 | {0x5197, 0x01}, 128 | {0x5198, 0x04}, 129 | {0x5199, 0x12}, 130 | {0x519a, 0x04}, 131 | {0x519b, 0x00}, 132 | {0x519c, 0x06}, 133 | {0x519d, 0x82}, 134 | {0x519e, 0x38}, 135 | 136 | //color matrix (Saturation) 137 | {0x5381, 0x1e}, 138 | {0x5382, 0x5b}, 139 | {0x5383, 0x08}, 140 | {0x5384, 0x0a}, 141 | {0x5385, 0x7e}, 142 | {0x5386, 0x88}, 143 | {0x5387, 0x7c}, 144 | {0x5388, 0x6c}, 145 | {0x5389, 0x10}, 146 | {0x538a, 0x01}, 147 | {0x538b, 0x98}, 148 | 149 | //CIP control (Sharpness) 150 | {0x5300, 0x10},//sharpness 151 | {0x5301, 0x10},//sharpness 152 | {0x5302, 0x18},//sharpness 153 | {0x5303, 0x19},//sharpness 154 | {0x5304, 0x10}, 155 | {0x5305, 0x10}, 156 | {0x5306, 0x08},//denoise 157 | {0x5307, 0x16}, 158 | {0x5308, 0x40}, 159 | {0x5309, 0x10},//sharpness 160 | {0x530a, 0x10},//sharpness 161 | {0x530b, 0x04},//sharpness 162 | {0x530c, 0x06},//sharpness 163 | 164 | //GAMMA 165 | {0x5480, 0x01}, 166 | {0x5481, 0x00}, 167 | {0x5482, 0x1e}, 168 | {0x5483, 0x3b}, 169 | {0x5484, 0x58}, 170 | {0x5485, 0x66}, 171 | {0x5486, 0x71}, 172 | {0x5487, 0x7d}, 173 | {0x5488, 0x83}, 174 | {0x5489, 0x8f}, 175 | {0x548a, 0x98}, 176 | {0x548b, 0xa6}, 177 | {0x548c, 0xb8}, 178 | {0x548d, 0xca}, 179 | {0x548e, 0xd7}, 180 | {0x548f, 0xe3}, 181 | {0x5490, 0x1d}, 182 | 183 | //Special Digital Effects (SDE) (UV adjust) 184 | {0x5580, 0x06},//enable brightness and contrast 185 | {0x5583, 0x40},//special_effect 186 | {0x5584, 0x10},//special_effect 187 | {0x5586, 0x20},//contrast 188 | {0x5587, 0x00},//brightness 189 | {0x5588, 0x00},//brightness 190 | {0x5589, 0x10}, 191 | {0x558a, 0x00}, 192 | {0x558b, 0xf8}, 193 | {0x501d, 0x40},// enable manual offset of contrast 194 | 195 | //power on 196 | {0x3008, 0x02}, 197 | 198 | //50Hz 199 | {0x3c00, 0x04}, 200 | 201 | {REG_DLY, 300}, 202 | {REGLIST_TAIL, 0x00}, // tail 203 | }; 204 | 205 | static const DRAM_ATTR uint16_t sensor_fmt_jpeg[][2] = { 206 | {FORMAT_CTRL, 0x00}, // YUV422 207 | {FORMAT_CTRL00, 0x30}, // YUYV 208 | {0x3002, 0x00},//0x1c to 0x00 !!! 209 | {0x3006, 0xff},//0xc3 to 0xff !!! 210 | {0x471c, 0x50},//0xd0 to 0x50 !!! 211 | {REGLIST_TAIL, 0x00}, // tail 212 | }; 213 | 214 | static const DRAM_ATTR uint16_t sensor_fmt_raw[][2] = { 215 | {FORMAT_CTRL, 0x03}, // RAW (DPC) 216 | {FORMAT_CTRL00, 0x00}, // RAW 217 | {REGLIST_TAIL, 0x00} 218 | }; 219 | 220 | static const DRAM_ATTR uint16_t sensor_fmt_grayscale[][2] = { 221 | {FORMAT_CTRL, 0x00}, // YUV422 222 | {FORMAT_CTRL00, 0x10}, // Y8 223 | {REGLIST_TAIL, 0x00} 224 | }; 225 | 226 | static const DRAM_ATTR uint16_t sensor_fmt_yuv422[][2] = { 227 | {FORMAT_CTRL, 0x00}, // YUV422 228 | {FORMAT_CTRL00, 0x30}, // YUYV 229 | {REGLIST_TAIL, 0x00} 230 | }; 231 | 232 | static const DRAM_ATTR uint16_t sensor_fmt_rgb565[][2] = { 233 | {FORMAT_CTRL, 0x01}, // RGB 234 | {FORMAT_CTRL00, 0x61}, // RGB565 (BGR) 235 | {REGLIST_TAIL, 0x00} 236 | }; 237 | 238 | static const DRAM_ATTR uint8_t sensor_saturation_levels[9][11] = { 239 | {0x1d, 0x60, 0x03, 0x07, 0x48, 0x4f, 0x4b, 0x40, 0x0b, 0x01, 0x98},//-4 240 | {0x1d, 0x60, 0x03, 0x08, 0x54, 0x5c, 0x58, 0x4b, 0x0d, 0x01, 0x98},//-3 241 | {0x1d, 0x60, 0x03, 0x0a, 0x60, 0x6a, 0x64, 0x56, 0x0e, 0x01, 0x98},//-2 242 | {0x1d, 0x60, 0x03, 0x0b, 0x6c, 0x77, 0x70, 0x60, 0x10, 0x01, 0x98},//-1 243 | {0x1d, 0x60, 0x03, 0x0c, 0x78, 0x84, 0x7d, 0x6b, 0x12, 0x01, 0x98},//0 244 | {0x1d, 0x60, 0x03, 0x0d, 0x84, 0x91, 0x8a, 0x76, 0x14, 0x01, 0x98},//+1 245 | {0x1d, 0x60, 0x03, 0x0e, 0x90, 0x9e, 0x96, 0x80, 0x16, 0x01, 0x98},//+2 246 | {0x1d, 0x60, 0x03, 0x10, 0x9c, 0xac, 0xa2, 0x8b, 0x17, 0x01, 0x98},//+3 247 | {0x1d, 0x60, 0x03, 0x11, 0xa8, 0xb9, 0xaf, 0x96, 0x19, 0x01, 0x98},//+4 248 | }; 249 | 250 | static const DRAM_ATTR uint8_t sensor_special_effects[7][4] = { 251 | {0x06, 0x40, 0x2c, 0x08},//Normal 252 | {0x46, 0x40, 0x28, 0x08},//Negative 253 | {0x1e, 0x80, 0x80, 0x08},//Grayscale 254 | {0x1e, 0x80, 0xc0, 0x08},//Red Tint 255 | {0x1e, 0x60, 0x60, 0x08},//Green Tint 256 | {0x1e, 0xa0, 0x40, 0x08},//Blue Tint 257 | {0x1e, 0x40, 0xa0, 0x08},//Sepia 258 | }; 259 | 260 | static const DRAM_ATTR uint16_t sensor_regs_gamma0[][2] = { 261 | {0x5480, 0x01}, 262 | {0x5481, 0x08}, 263 | {0x5482, 0x14}, 264 | {0x5483, 0x28}, 265 | {0x5484, 0x51}, 266 | {0x5485, 0x65}, 267 | {0x5486, 0x71}, 268 | {0x5487, 0x7d}, 269 | {0x5488, 0x87}, 270 | {0x5489, 0x91}, 271 | {0x548a, 0x9a}, 272 | {0x548b, 0xaa}, 273 | {0x548c, 0xb8}, 274 | {0x548d, 0xcd}, 275 | {0x548e, 0xdd}, 276 | {0x548f, 0xea}, 277 | {0x5490, 0x1d} 278 | }; 279 | 280 | static const DRAM_ATTR uint16_t sensor_regs_gamma1[][2] = { 281 | {0x5480, 0x1}, 282 | {0x5481, 0x0}, 283 | {0x5482, 0x1e}, 284 | {0x5483, 0x3b}, 285 | {0x5484, 0x58}, 286 | {0x5485, 0x66}, 287 | {0x5486, 0x71}, 288 | {0x5487, 0x7d}, 289 | {0x5488, 0x83}, 290 | {0x5489, 0x8f}, 291 | {0x548a, 0x98}, 292 | {0x548b, 0xa6}, 293 | {0x548c, 0xb8}, 294 | {0x548d, 0xca}, 295 | {0x548e, 0xd7}, 296 | {0x548f, 0xe3}, 297 | {0x5490, 0x1d} 298 | }; 299 | 300 | static const DRAM_ATTR uint16_t sensor_regs_awb0[][2] = { 301 | {0x5180, 0xff}, 302 | {0x5181, 0xf2}, 303 | {0x5182, 0x00}, 304 | {0x5183, 0x14}, 305 | {0x5184, 0x25}, 306 | {0x5185, 0x24}, 307 | {0x5186, 0x09}, 308 | {0x5187, 0x09}, 309 | {0x5188, 0x09}, 310 | {0x5189, 0x75}, 311 | {0x518a, 0x54}, 312 | {0x518b, 0xe0}, 313 | {0x518c, 0xb2}, 314 | {0x518d, 0x42}, 315 | {0x518e, 0x3d}, 316 | {0x518f, 0x56}, 317 | {0x5190, 0x46}, 318 | {0x5191, 0xf8}, 319 | {0x5192, 0x04}, 320 | {0x5193, 0x70}, 321 | {0x5194, 0xf0}, 322 | {0x5195, 0xf0}, 323 | {0x5196, 0x03}, 324 | {0x5197, 0x01}, 325 | {0x5198, 0x04}, 326 | {0x5199, 0x12}, 327 | {0x519a, 0x04}, 328 | {0x519b, 0x00}, 329 | {0x519c, 0x06}, 330 | {0x519d, 0x82}, 331 | {0x519e, 0x38} 332 | }; 333 | 334 | #endif 335 | -------------------------------------------------------------------------------- /esp-idf_components_esp32-camera/sensors/private_include/ov7725.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the OpenMV project. 3 | * Copyright (c) 2013/2014 Ibrahim Abdelkader 4 | * This work is licensed under the MIT license, see the file LICENSE for details. 5 | * 6 | * OV7725 driver. 7 | * 8 | */ 9 | #ifndef __OV7725_H__ 10 | #define __OV7725_H__ 11 | #include "sensor.h" 12 | 13 | int ov7725_init(sensor_t *sensor); 14 | #endif // __OV7725_H__ 15 | -------------------------------------------------------------------------------- /micropython_ports/esp32/boards/basic_cam_8mb_OV2640/manifest.py: -------------------------------------------------------------------------------- 1 | folder_board = "STRAGA_factory_8mb" 2 | 3 | freeze('$(PORT_DIR)/modules', ('_boot.py', 'flashbdev.py','inisetup.py')) 4 | freeze('$(MPY_DIR)/tools', ('upip_utarfile.py')) 5 | freeze('$(MPY_DIR)/ports/esp8266/modules', 'ntptime.py') 6 | freeze('$(MPY_DIR)/drivers/onewire') 7 | include("$(MPY_DIR)/extmod/webrepl/manifest.py") 8 | 9 | # freeze('$(PORT_DIR)/boards/modules/ftp_recovery') 10 | # freeze('$(PORT_DIR)/boards/modules/uiot_control') 11 | 12 | 13 | #freeze('$(MPY_DIR)/tools', ('upip.py', 'upip_utarfile.py')) 14 | 15 | -------------------------------------------------------------------------------- /micropython_ports/esp32/boards/basic_cam_8mb_OV2640/mpconfigboard.h: -------------------------------------------------------------------------------- 1 | #define MICROPY_HW_BOARD_NAME "ANY" 2 | #define MICROPY_HW_MCU_NAME "ESP32" 3 | -------------------------------------------------------------------------------- /micropython_ports/esp32/boards/basic_cam_8mb_OV2640/mpconfigboard.mk: -------------------------------------------------------------------------------- 1 | #ESPIDF = /upy/esp-idf/ 2 | #PORT = /dev/ttyUSB0 3 | #FLASH_MODE = dio 4 | #FLASH_SIZE = 16MB 5 | 6 | 7 | SDKCONFIG += boards/sdkconfig.base 8 | SDKCONFIG += boards/sdkconfig.spiram 9 | SDKCONFIG += boards/sdkconfig.esp32cam_OV2640 10 | 11 | SDKCONFIG += boards/STRAGA_factory_8mb/sdkconfig.mod 12 | PART_SRC = boards/STRAGA_factory_8mb/partitions.csv 13 | FROZEN_MANIFEST = boards/STRAGA_factory_8mb/manifest.py -------------------------------------------------------------------------------- /micropython_ports/esp32/boards/basic_cam_8mb_OV2640/partitions.csv: -------------------------------------------------------------------------------- 1 | # Name, Type, SubType, Offset, Size, Flags 2 | # Note: if you change the phy_init or app partition offset, make sure to change the offset in Kconfig.projbuild 3 | nvs, data, nvs, , 0x4000, 4 | otadata, data, ota, , 0x2000, 5 | phy_init, data, phy, , 0x1000, 6 | factory, app, factory, , 2200K, 7 | ota_0, app, ota_0, , 2200K, 8 | vfs, data, fat, , 3100k, 9 | -------------------------------------------------------------------------------- /micropython_ports/esp32/boards/basic_cam_8mb_OV2640/sdkconfig.mod: -------------------------------------------------------------------------------- 1 | 2 | # MOD 3 | #CONFIG_LOG_BOOTLOADER_LEVEL_VERBOSE=y 4 | #CONFIG_LOG_BOOTLOADER_LEVEL=5 5 | 6 | #CONFIG_BOOTLOADER_LOG_LEVEL_VERBOSE=y 7 | #CONFIG_BOOTLOADER_LOG_LEVEL=5 8 | 9 | CONFIG_BOOTLOADER_LOG_LEVEL_DEBUG=y 10 | CONFIG_BOOTLOADER_LOG_LEVEL=4 11 | 12 | 13 | # LWIP 14 | CONFIG_LWIP_MAX_ACTIVE_TCP=32 15 | CONFIG_LWIP_MAX_SOCKETS=16 -------------------------------------------------------------------------------- /micropython_ports/esp32/boards/sdkconfig.esp32cam_OV2640: -------------------------------------------------------------------------------- 1 | 2 | # ESP32-CAMERA 3 | CONFIG_OV2640_SUPPORT=y 4 | #CONFIG_OV7725_SUPPORT=y -------------------------------------------------------------------------------- /micropython_ports/esp32/boards/sdkconfig.esp32cam_OV7725: -------------------------------------------------------------------------------- 1 | 2 | # ESP32-CAMERA 3 | CONFIG_OV7725_SUPPORT=y -------------------------------------------------------------------------------- /micropython_ports/esp32/modcamera.c: -------------------------------------------------------------------------------- 1 | // Code adapted from https://github.com/espressif/esp32-camera 2 | 3 | #include "esp_camera.h" 4 | #include "esp_log.h" 5 | 6 | #include "py/nlr.h" 7 | #include "py/obj.h" 8 | #include "py/runtime.h" 9 | #include "py/binary.h" 10 | 11 | #define TAG "camera" 12 | 13 | //WROVER-KIT PIN Map 14 | #define CAM_PIN_PWDN 32 //power down is not used 15 | #define CAM_PIN_RESET -1 //software reset will be performed 16 | #define CAM_PIN_XCLK 0 17 | #define CAM_PIN_SIOD 26 // SDA 18 | #define CAM_PIN_SIOC 27 // SCL 19 | 20 | #define CAM_PIN_D7 35 21 | #define CAM_PIN_D6 34 22 | #define CAM_PIN_D5 39 23 | #define CAM_PIN_D4 36 24 | #define CAM_PIN_D3 21 25 | #define CAM_PIN_D2 19 26 | #define CAM_PIN_D1 18 27 | #define CAM_PIN_D0 5 28 | #define CAM_PIN_VSYNC 25 29 | #define CAM_PIN_HREF 23 30 | #define CAM_PIN_PCLK 22 31 | 32 | static camera_config_t camera_config = { 33 | .pin_pwdn = CAM_PIN_PWDN, 34 | .pin_reset = CAM_PIN_RESET, 35 | .pin_xclk = CAM_PIN_XCLK, 36 | .pin_sscb_sda = CAM_PIN_SIOD, 37 | .pin_sscb_scl = CAM_PIN_SIOC, 38 | 39 | .pin_d7 = CAM_PIN_D7, 40 | .pin_d6 = CAM_PIN_D6, 41 | .pin_d5 = CAM_PIN_D5, 42 | .pin_d4 = CAM_PIN_D4, 43 | .pin_d3 = CAM_PIN_D3, 44 | .pin_d2 = CAM_PIN_D2, 45 | .pin_d1 = CAM_PIN_D1, 46 | .pin_d0 = CAM_PIN_D0, 47 | .pin_vsync = CAM_PIN_VSYNC, 48 | .pin_href = CAM_PIN_HREF, 49 | .pin_pclk = CAM_PIN_PCLK, 50 | 51 | //XCLK 20MHz or 10MHz for OV2640 double FPS (Experimental) 52 | .xclk_freq_hz = 20000000, 53 | .ledc_timer = LEDC_TIMER_0, 54 | .ledc_channel = LEDC_CHANNEL_0, 55 | 56 | .pixel_format = PIXFORMAT_JPEG,//YUV422,GRAYSCALE,RGB565,JPEG 57 | .frame_size = FRAMESIZE_SVGA, //FRAMESIZE_UXGA,//QQVGA-UXGA Do not use sizes above QVGA when not JPEG FRAMESIZE_CIF 58 | 59 | .jpeg_quality = 12, //0-63 lower number means higher quality 60 | .fb_count = 1 //if more than one, i2s runs in continuous mode. Use only with JPEG 61 | }; 62 | 63 | // FRAMESIZE_96X96, // 96x96 64 | // FRAMESIZE_QQVGA, // 160x120 65 | // FRAMESIZE_QCIF, // 176x144 66 | // FRAMESIZE_HQVGA, // 240x176 67 | // FRAMESIZE_240X240, // 240x240 68 | // FRAMESIZE_QVGA, // 320x240 69 | // FRAMESIZE_CIF, // 400x296 70 | // FRAMESIZE_HVGA, // 480x320 71 | // FRAMESIZE_VGA, // 640x480 72 | // FRAMESIZE_SVGA, // 800x600 73 | // FRAMESIZE_XGA, // 1024x768 74 | // FRAMESIZE_HD, // 1280x720 75 | // FRAMESIZE_SXGA, // 1280x1024 76 | // FRAMESIZE_UXGA, // 1600x1200 77 | 78 | #include "esp_system.h" 79 | #include "esp_spi_flash.h" 80 | 81 | 82 | STATIC mp_obj_t camera_init(){ 83 | esp_err_t err = esp_camera_init(&camera_config); 84 | if (err != ESP_OK) { 85 | ESP_LOGE(TAG, "Camera init failed with error 0x%x", err); 86 | return mp_const_false; 87 | } 88 | 89 | return mp_const_true; 90 | } 91 | STATIC MP_DEFINE_CONST_FUN_OBJ_0(camera_init_obj, camera_init); 92 | 93 | 94 | STATIC mp_obj_t camera_deinit(){ 95 | esp_err_t err = esp_camera_deinit(); 96 | if (err != ESP_OK) { 97 | ESP_LOGE(TAG, "Camera deinit Failed"); 98 | return mp_const_false; 99 | } 100 | 101 | return mp_const_true; 102 | } 103 | STATIC MP_DEFINE_CONST_FUN_OBJ_0(camera_deinit_obj, camera_deinit); 104 | 105 | 106 | STATIC mp_obj_t camera_capture(){ 107 | //acquire a frame 108 | camera_fb_t * fb = esp_camera_fb_get(); 109 | if (!fb) { 110 | ESP_LOGE(TAG, "Camera Capture Failed"); 111 | return mp_const_false; 112 | } 113 | 114 | mp_obj_t image = mp_obj_new_bytes(fb->buf, fb->len); 115 | 116 | //return the frame buffer back to the driver for reuse 117 | esp_camera_fb_return(fb); 118 | return image; 119 | } 120 | STATIC MP_DEFINE_CONST_FUN_OBJ_0(camera_capture_obj, camera_capture); 121 | 122 | 123 | STATIC const mp_rom_map_elem_t camera_module_globals_table[] = { 124 | { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_camera) }, 125 | 126 | { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&camera_init_obj) }, 127 | { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&camera_deinit_obj) }, 128 | { MP_ROM_QSTR(MP_QSTR_capture), MP_ROM_PTR(&camera_capture_obj) }, 129 | }; 130 | 131 | STATIC MP_DEFINE_CONST_DICT(camera_module_globals, camera_module_globals_table); 132 | 133 | const mp_obj_module_t mp_module_camera = { 134 | .base = { &mp_type_module }, 135 | .globals = (mp_obj_dict_t*)&camera_module_globals, 136 | }; -------------------------------------------------------------------------------- /micropython_ports/esp32/mpconfigport.h: -------------------------------------------------------------------------------- 1 | // Options to control how MicroPython is built for this port, 2 | // overriding defaults in py/mpconfig.h. 3 | 4 | // Board-specific definitions 5 | #include "mpconfigboard.h" 6 | 7 | #include 8 | #include 9 | 10 | #if !MICROPY_ESP_IDF_4 11 | #include "rom/ets_sys.h" 12 | #endif 13 | 14 | // object representation and NLR handling 15 | #define MICROPY_OBJ_REPR (MICROPY_OBJ_REPR_A) 16 | #define MICROPY_NLR_SETJMP (1) 17 | 18 | // memory allocation policies 19 | #define MICROPY_ALLOC_PATH_MAX (128) 20 | 21 | // emitters 22 | #define MICROPY_PERSISTENT_CODE_LOAD (1) 23 | #define MICROPY_EMIT_XTENSAWIN (1) 24 | 25 | // compiler configuration 26 | #define MICROPY_COMP_MODULE_CONST (1) 27 | #define MICROPY_COMP_TRIPLE_TUPLE_ASSIGN (1) 28 | 29 | // optimisations 30 | #define MICROPY_OPT_COMPUTED_GOTO (1) 31 | #define MICROPY_OPT_MPZ_BITWISE (1) 32 | 33 | // Python internal features 34 | #define MICROPY_READER_VFS (1) 35 | #define MICROPY_ENABLE_GC (1) 36 | #define MICROPY_ENABLE_FINALISER (1) 37 | #define MICROPY_STACK_CHECK (1) 38 | #define MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF (1) 39 | #define MICROPY_KBD_EXCEPTION (1) 40 | #define MICROPY_HELPER_REPL (1) 41 | #define MICROPY_REPL_EMACS_KEYS (1) 42 | #define MICROPY_REPL_AUTO_INDENT (1) 43 | #define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_MPZ) 44 | #define MICROPY_ENABLE_SOURCE_LINE (1) 45 | #define MICROPY_ERROR_REPORTING (MICROPY_ERROR_REPORTING_NORMAL) 46 | #define MICROPY_WARNINGS (1) 47 | #define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_FLOAT) 48 | #define MICROPY_CPYTHON_COMPAT (1) 49 | #define MICROPY_STREAMS_NON_BLOCK (1) 50 | #define MICROPY_STREAMS_POSIX_API (1) 51 | #define MICROPY_MODULE_BUILTIN_INIT (1) 52 | #define MICROPY_MODULE_WEAK_LINKS (1) 53 | #define MICROPY_MODULE_FROZEN_STR (0) 54 | #define MICROPY_MODULE_FROZEN_MPY (1) 55 | #define MICROPY_QSTR_EXTRA_POOL mp_qstr_frozen_const_pool 56 | #define MICROPY_CAN_OVERRIDE_BUILTINS (1) 57 | #define MICROPY_USE_INTERNAL_ERRNO (1) 58 | #define MICROPY_USE_INTERNAL_PRINTF (0) // ESP32 SDK requires its own printf 59 | #define MICROPY_ENABLE_SCHEDULER (1) 60 | #define MICROPY_SCHEDULER_DEPTH (8) 61 | #define MICROPY_VFS (1) 62 | 63 | // control over Python builtins 64 | #define MICROPY_PY_FUNCTION_ATTRS (1) 65 | #define MICROPY_PY_DESCRIPTORS (1) 66 | #define MICROPY_PY_STR_BYTES_CMP_WARN (1) 67 | #define MICROPY_PY_BUILTINS_STR_UNICODE (1) 68 | #define MICROPY_PY_BUILTINS_STR_CENTER (1) 69 | #define MICROPY_PY_BUILTINS_STR_PARTITION (1) 70 | #define MICROPY_PY_BUILTINS_STR_SPLITLINES (1) 71 | #define MICROPY_PY_BUILTINS_BYTEARRAY (1) 72 | #define MICROPY_PY_BUILTINS_MEMORYVIEW (1) 73 | #define MICROPY_PY_BUILTINS_SET (1) 74 | #define MICROPY_PY_BUILTINS_SLICE (1) 75 | #define MICROPY_PY_BUILTINS_SLICE_ATTRS (1) 76 | #define MICROPY_PY_BUILTINS_SLICE_INDICES (1) 77 | #define MICROPY_PY_BUILTINS_FROZENSET (1) 78 | #define MICROPY_PY_BUILTINS_PROPERTY (1) 79 | #define MICROPY_PY_BUILTINS_RANGE_ATTRS (1) 80 | #define MICROPY_PY_BUILTINS_ROUND_INT (1) 81 | #define MICROPY_PY_BUILTINS_TIMEOUTERROR (1) 82 | #define MICROPY_PY_ALL_SPECIAL_METHODS (1) 83 | #define MICROPY_PY_BUILTINS_COMPILE (1) 84 | #define MICROPY_PY_BUILTINS_ENUMERATE (1) 85 | #define MICROPY_PY_BUILTINS_EXECFILE (1) 86 | #define MICROPY_PY_BUILTINS_FILTER (1) 87 | #define MICROPY_PY_BUILTINS_REVERSED (1) 88 | #define MICROPY_PY_BUILTINS_NOTIMPLEMENTED (1) 89 | #define MICROPY_PY_BUILTINS_INPUT (1) 90 | #define MICROPY_PY_BUILTINS_MIN_MAX (1) 91 | #define MICROPY_PY_BUILTINS_POW3 (1) 92 | #define MICROPY_PY_BUILTINS_HELP (1) 93 | #define MICROPY_PY_BUILTINS_HELP_TEXT esp32_help_text 94 | #define MICROPY_PY_BUILTINS_HELP_MODULES (1) 95 | #define MICROPY_PY___FILE__ (1) 96 | #define MICROPY_PY_MICROPYTHON_MEM_INFO (1) 97 | #define MICROPY_PY_ARRAY (1) 98 | #define MICROPY_PY_ARRAY_SLICE_ASSIGN (1) 99 | #define MICROPY_PY_ATTRTUPLE (1) 100 | #define MICROPY_PY_COLLECTIONS (1) 101 | #define MICROPY_PY_COLLECTIONS_DEQUE (1) 102 | #define MICROPY_PY_COLLECTIONS_ORDEREDDICT (1) 103 | #define MICROPY_PY_MATH (1) 104 | #define MICROPY_PY_MATH_SPECIAL_FUNCTIONS (1) 105 | #define MICROPY_PY_MATH_ISCLOSE (1) 106 | #define MICROPY_PY_CMATH (1) 107 | #define MICROPY_PY_GC (1) 108 | #define MICROPY_PY_IO (1) 109 | #define MICROPY_PY_IO_IOBASE (1) 110 | #define MICROPY_PY_IO_FILEIO (1) 111 | #define MICROPY_PY_IO_BYTESIO (1) 112 | #define MICROPY_PY_IO_BUFFEREDWRITER (1) 113 | #define MICROPY_PY_STRUCT (1) 114 | #define MICROPY_PY_SYS (1) 115 | #define MICROPY_PY_SYS_MAXSIZE (1) 116 | #define MICROPY_PY_SYS_MODULES (1) 117 | #define MICROPY_PY_SYS_EXIT (1) 118 | #define MICROPY_PY_SYS_STDFILES (1) 119 | #define MICROPY_PY_SYS_STDIO_BUFFER (1) 120 | #define MICROPY_PY_UERRNO (1) 121 | #define MICROPY_PY_USELECT (1) 122 | #define MICROPY_PY_UTIME_MP_HAL (1) 123 | #define MICROPY_PY_THREAD (1) 124 | #define MICROPY_PY_THREAD_GIL (1) 125 | #define MICROPY_PY_THREAD_GIL_VM_DIVISOR (32) 126 | 127 | // extended modules 128 | #define MICROPY_PY_UCTYPES (1) 129 | #define MICROPY_PY_UZLIB (1) 130 | #define MICROPY_PY_UJSON (1) 131 | #define MICROPY_PY_URE (1) 132 | #define MICROPY_PY_URE_SUB (1) 133 | #define MICROPY_PY_UHEAPQ (1) 134 | #define MICROPY_PY_UTIMEQ (1) 135 | #define MICROPY_PY_UHASHLIB (1) 136 | #define MICROPY_PY_UHASHLIB_SHA1 (1) 137 | #define MICROPY_PY_UHASHLIB_SHA256 (1) 138 | #define MICROPY_PY_UCRYPTOLIB (1) 139 | #define MICROPY_PY_UBINASCII (1) 140 | #define MICROPY_PY_UBINASCII_CRC32 (1) 141 | #define MICROPY_PY_URANDOM (1) 142 | #define MICROPY_PY_URANDOM_EXTRA_FUNCS (1) 143 | #define MICROPY_PY_OS_DUPTERM (1) 144 | #define MICROPY_PY_MACHINE (1) 145 | #define MICROPY_PY_MACHINE_PIN_MAKE_NEW mp_pin_make_new 146 | #define MICROPY_PY_MACHINE_PULSE (1) 147 | #define MICROPY_PY_MACHINE_I2C (1) 148 | #define MICROPY_PY_MACHINE_I2C_MAKE_NEW machine_hw_i2c_make_new 149 | #define MICROPY_PY_MACHINE_SPI (1) 150 | #define MICROPY_PY_MACHINE_SPI_MSB (0) 151 | #define MICROPY_PY_MACHINE_SPI_LSB (1) 152 | #define MICROPY_PY_MACHINE_SPI_MAKE_NEW machine_hw_spi_make_new 153 | #define MICROPY_HW_ENABLE_SDCARD (1) 154 | #define MICROPY_HW_SOFTSPI_MIN_DELAY (0) 155 | #define MICROPY_HW_SOFTSPI_MAX_BAUDRATE (ets_get_cpu_frequency() * 1000000 / 200) // roughly 156 | #define MICROPY_PY_USSL (1) 157 | #define MICROPY_SSL_MBEDTLS (1) 158 | #define MICROPY_PY_USSL_FINALISER (1) 159 | #define MICROPY_PY_UWEBSOCKET (1) 160 | #define MICROPY_PY_WEBREPL (1) 161 | #define MICROPY_PY_FRAMEBUF (1) 162 | #define MICROPY_PY_USOCKET_EVENTS (MICROPY_PY_WEBREPL) 163 | #define MICROPY_PY_BLUETOOTH_RANDOM_ADDR (1) 164 | #define MICROPY_PY_BLUETOOTH_DEFAULT_NAME ("ESP32") 165 | 166 | // fatfs configuration 167 | #define MICROPY_FATFS_ENABLE_LFN (1) 168 | #define MICROPY_FATFS_RPATH (2) 169 | #define MICROPY_FATFS_MAX_SS (4096) 170 | #define MICROPY_FATFS_LFN_CODE_PAGE 437 /* 1=SFN/ANSI 437=LFN/U.S.(OEM) */ 171 | #define mp_type_fileio mp_type_vfs_fat_fileio 172 | #define mp_type_textio mp_type_vfs_fat_textio 173 | 174 | // use vfs's functions for import stat and builtin open 175 | #define mp_import_stat mp_vfs_import_stat 176 | #define mp_builtin_open mp_vfs_open 177 | #define mp_builtin_open_obj mp_vfs_open_obj 178 | 179 | // extra built in names to add to the global namespace 180 | #define MICROPY_PORT_BUILTINS \ 181 | { MP_OBJ_NEW_QSTR(MP_QSTR_input), (mp_obj_t)&mp_builtin_input_obj }, \ 182 | { MP_OBJ_NEW_QSTR(MP_QSTR_open), (mp_obj_t)&mp_builtin_open_obj }, 183 | 184 | // extra built in modules to add to the list of known ones 185 | extern const struct _mp_obj_module_t esp_module; 186 | extern const struct _mp_obj_module_t esp32_module; 187 | extern const struct _mp_obj_module_t utime_module; 188 | extern const struct _mp_obj_module_t uos_module; 189 | extern const struct _mp_obj_module_t mp_module_usocket; 190 | extern const struct _mp_obj_module_t mp_module_machine; 191 | extern const struct _mp_obj_module_t mp_module_network; 192 | extern const struct _mp_obj_module_t mp_module_onewire; 193 | // cam 194 | extern const struct _mp_obj_module_t mp_module_camera; 195 | 196 | #define MICROPY_PORT_BUILTIN_MODULES \ 197 | { MP_OBJ_NEW_QSTR(MP_QSTR_esp), (mp_obj_t)&esp_module }, \ 198 | { MP_OBJ_NEW_QSTR(MP_QSTR_esp32), (mp_obj_t)&esp32_module }, \ 199 | { MP_OBJ_NEW_QSTR(MP_QSTR_utime), (mp_obj_t)&utime_module }, \ 200 | { MP_OBJ_NEW_QSTR(MP_QSTR_uos), (mp_obj_t)&uos_module }, \ 201 | { MP_OBJ_NEW_QSTR(MP_QSTR_usocket), (mp_obj_t)&mp_module_usocket }, \ 202 | { MP_OBJ_NEW_QSTR(MP_QSTR_machine), (mp_obj_t)&mp_module_machine }, \ 203 | { MP_OBJ_NEW_QSTR(MP_QSTR_network), (mp_obj_t)&mp_module_network }, \ 204 | { MP_OBJ_NEW_QSTR(MP_QSTR__onewire), (mp_obj_t)&mp_module_onewire }, \ 205 | { MP_OBJ_NEW_QSTR(MP_QSTR_uhashlib), (mp_obj_t)&mp_module_uhashlib }, \ 206 | { MP_OBJ_NEW_QSTR(MP_QSTR_camera), (mp_obj_t)&mp_module_camera }, \ 207 | 208 | #define MP_STATE_PORT MP_STATE_VM 209 | 210 | struct _machine_timer_obj_t; 211 | 212 | #if MICROPY_BLUETOOTH_NIMBLE 213 | struct mp_bluetooth_nimble_root_pointers_t; 214 | #define MICROPY_PORT_ROOT_POINTER_BLUETOOTH_NIMBLE struct _mp_bluetooth_nimble_root_pointers_t *bluetooth_nimble_root_pointers; 215 | #else 216 | #define MICROPY_PORT_ROOT_POINTER_BLUETOOTH_NIMBLE 217 | #endif 218 | 219 | #define MICROPY_PORT_ROOT_POINTERS \ 220 | const char *readline_hist[8]; \ 221 | mp_obj_t machine_pin_irq_handler[40]; \ 222 | struct _machine_timer_obj_t *machine_timer_obj_head; \ 223 | MICROPY_PORT_ROOT_POINTER_BLUETOOTH_NIMBLE 224 | 225 | // type definitions for the specific machine 226 | 227 | #define BYTES_PER_WORD (4) 228 | #define MICROPY_MAKE_POINTER_CALLABLE(p) ((void *)((mp_uint_t)(p))) 229 | #define MP_PLAT_PRINT_STRN(str, len) mp_hal_stdout_tx_strn_cooked(str, len) 230 | void *esp_native_code_commit(void *, size_t, void *); 231 | #define MP_PLAT_COMMIT_EXEC(buf, len, reloc) esp_native_code_commit(buf, len, reloc) 232 | #define MP_SSIZE_MAX (0x7fffffff) 233 | 234 | // Note: these "critical nested" macros do not ensure cross-CPU exclusion, 235 | // the only disable interrupts on the current CPU. To full manage exclusion 236 | // one should use portENTER_CRITICAL/portEXIT_CRITICAL instead. 237 | #include "freertos/FreeRTOS.h" 238 | #define MICROPY_BEGIN_ATOMIC_SECTION() portENTER_CRITICAL_NESTED() 239 | #define MICROPY_END_ATOMIC_SECTION(state) portEXIT_CRITICAL_NESTED(state) 240 | 241 | #if MICROPY_PY_USOCKET_EVENTS 242 | #define MICROPY_PY_USOCKET_EVENTS_HANDLER extern void usocket_events_handler(void); usocket_events_handler(); 243 | #else 244 | #define MICROPY_PY_USOCKET_EVENTS_HANDLER 245 | #endif 246 | 247 | #if MICROPY_PY_THREAD 248 | #define MICROPY_EVENT_POLL_HOOK \ 249 | do { \ 250 | extern void mp_handle_pending(bool); \ 251 | mp_handle_pending(true); \ 252 | MICROPY_PY_USOCKET_EVENTS_HANDLER \ 253 | MP_THREAD_GIL_EXIT(); \ 254 | MP_THREAD_GIL_ENTER(); \ 255 | } while (0); 256 | #else 257 | #define MICROPY_EVENT_POLL_HOOK \ 258 | do { \ 259 | extern void mp_handle_pending(bool); \ 260 | mp_handle_pending(true); \ 261 | MICROPY_PY_USOCKET_EVENTS_HANDLER \ 262 | asm ("waiti 0"); \ 263 | } while (0); 264 | #endif 265 | 266 | // Functions that should go in IRAM 267 | #define MICROPY_WRAP_MP_KEYBOARD_INTERRUPT(f) IRAM_ATTR f 268 | 269 | #define UINT_FMT "%u" 270 | #define INT_FMT "%d" 271 | 272 | typedef int32_t mp_int_t; // must be pointer size 273 | typedef uint32_t mp_uint_t; // must be pointer size 274 | typedef long mp_off_t; 275 | // ssize_t, off_t as required by POSIX-signatured functions in stream.h 276 | #include 277 | 278 | // board specifics 279 | #define MICROPY_PY_SYS_PLATFORM "esp32" 280 | 281 | #ifndef MICROPY_HW_ENABLE_MDNS_QUERIES 282 | #define MICROPY_HW_ENABLE_MDNS_QUERIES (1) 283 | #endif 284 | 285 | #ifndef MICROPY_HW_ENABLE_MDNS_RESPONDER 286 | #define MICROPY_HW_ENABLE_MDNS_RESPONDER (1) 287 | #endif 288 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | Info 2 | 3 | https://github.com/tsaarni/micropython-with-esp32-cam/wiki 4 | https://github.com/espressif/esp32-camera 5 | 6 | micropython - 8d34344dceb367844b651deccadff2b55f20c55c 7 | _ 8 | 9 | esp_cam module with resolder - 8/16mb flash 10 | 11 | Alredy have micropython and esp-idf 12 | 13 | step 1. v4. esp-idf/components 14 | 15 | copy esp-idf_components_esp32-camera to esp-idf/components/esp32-camera 16 | 17 | 18 | step 2. micropython/ports/esp32 19 | git branche/checkout from master to cam 20 | copy micropython_ports to micropython/ports 21 | 22 | 23 | step 3. Export env 24 | 25 | export PATH="$PATH:$HOME/upy/xtensa-esp32-elf/bin" 26 | export IDF_PATH="$HOME/upy/esp-idf" 27 | 28 | step 4. Build/Deploy 29 | 30 | make -j4 BOARD=cam_8mb 31 | make -j4 BOARD=basic_cam_8mb_OV2640 PORT=/dev/ttyS3 BAUD=921600 erase 32 | make -j4 BOARD=basic_cam_8mb_OV2640 PORT=/dev/ttyS3 BAUD=921600 deploy 33 | 34 | step 5. Camera Inii and capture to buff 35 | 36 | import camera 37 | camera.init() 38 | 39 | buf = camera.capture() 40 | 41 | step 6. Do file save.py with code and put on the board. 42 | 43 | def save_image(buf, file="test.jpeg"): 44 | 45 | try: 46 | with open(file, "wb") as f: 47 | f.write(buf) 48 | except OSError as e: 49 | print("exception .. {}".format(e)) 50 | 51 | print(file) 52 | 53 | 54 | step 7. Sav buf to flash and get file for view. 55 | 56 | imprort save 57 | save.save_image(buf) 58 | 59 | will be test.jpg on flash --------------------------------------------------------------------------------