mirror of
https://github.com/espressif/esp32-camera.git
synced 2025-07-03 23:55:31 +08:00
Fix Support for OV7725
This commit is contained in:
@ -10,16 +10,27 @@
|
||||
|
||||
#include "jpge.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
#include "esp_heap_caps.h"
|
||||
|
||||
#define JPGE_MAX(a,b) (((a)>(b))?(a):(b))
|
||||
#define JPGE_MIN(a,b) (((a)<(b))?(a):(b))
|
||||
|
||||
namespace jpge {
|
||||
|
||||
static inline void *jpge_malloc(size_t nSize) { return malloc(nSize); }
|
||||
static inline void *jpge_malloc(size_t nSize) {
|
||||
void * b = malloc(nSize);
|
||||
if(b){
|
||||
return b;
|
||||
}
|
||||
return heap_caps_malloc(nSize, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
|
||||
}
|
||||
static inline void jpge_free(void *p) { free(p); }
|
||||
|
||||
// Various JPEG enums and tables.
|
||||
@ -596,7 +607,9 @@ namespace jpge {
|
||||
m_image_bpl_mcu = m_image_x_mcu * m_num_components;
|
||||
m_mcus_per_row = m_image_x_mcu / m_mcu_x;
|
||||
|
||||
if ((m_mcu_lines[0] = static_cast<uint8*>(jpge_malloc(m_image_bpl_mcu * m_mcu_y))) == NULL) return false;
|
||||
if ((m_mcu_lines[0] = static_cast<uint8*>(jpge_malloc(m_image_bpl_mcu * m_mcu_y))) == NULL) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 1; i < m_mcu_y; i++)
|
||||
m_mcu_lines[i] = m_mcu_lines[i-1] + m_image_bpl_mcu;
|
||||
|
||||
|
@ -1083,7 +1083,7 @@ esp_err_t camera_init(const camera_config_t* config)
|
||||
}
|
||||
s_state->in_bytes_per_pixel = 1; // camera sends Y8
|
||||
} else {
|
||||
if (is_hs_mode()) {
|
||||
if (is_hs_mode() && s_state->sensor.id.PID != OV7725_PID) {
|
||||
s_state->sampling_mode = SM_0A00_0B00;
|
||||
s_state->dma_filter = &dma_filter_grayscale_highspeed;
|
||||
} else {
|
||||
@ -1095,7 +1095,7 @@ esp_err_t camera_init(const camera_config_t* config)
|
||||
s_state->fb_bytes_per_pixel = 1; // frame buffer stores Y8
|
||||
} else if (pix_format == PIXFORMAT_YUV422 || pix_format == PIXFORMAT_RGB565) {
|
||||
s_state->fb_size = s_state->width * s_state->height * 2;
|
||||
if (is_hs_mode()) {
|
||||
if (is_hs_mode() && s_state->sensor.id.PID != OV7725_PID) {
|
||||
s_state->sampling_mode = SM_0A00_0B00;
|
||||
s_state->dma_filter = &dma_filter_yuyv_highspeed;
|
||||
} else {
|
||||
|
@ -28,8 +28,8 @@ static const uint8_t default_regs[][2] = {
|
||||
{COM3, COM3_SWAP_YUV},
|
||||
{COM7, COM7_RES_QVGA | COM7_FMT_YUV},
|
||||
|
||||
{COM4, 0x01}, /* bypass PLL */
|
||||
{CLKRC, 0xC0}, /* Res/Bypass pre-scalar */
|
||||
{COM4, 0x01 | 0x00}, /* bypass PLL (0x00:off, 0x40:4x, 0x80:6x, 0xC0:8x) */
|
||||
{CLKRC, 0x80 | 0x03}, /* Res/Bypass pre-scalar (0x40:bypass, 0x00-0x3F:prescaler PCLK=XCLK/(prescaler + 1)/2 ) */
|
||||
|
||||
// QVGA Window Size
|
||||
{HSTART, 0x3F},
|
||||
@ -41,9 +41,9 @@ static const uint8_t default_regs[][2] = {
|
||||
// Scale down to QVGA Resolution
|
||||
{HOUTSIZE, 0x50},
|
||||
{VOUTSIZE, 0x78},
|
||||
{EXHCH, 0x00},
|
||||
|
||||
{COM12, 0x03},
|
||||
{EXHCH, 0x00},
|
||||
{TGT_B, 0x7F},
|
||||
{FIXGAIN, 0x09},
|
||||
{AWB_CTRL0, 0xE0},
|
||||
@ -148,6 +148,7 @@ static int reset(sensor_t *sensor)
|
||||
static int set_pixformat(sensor_t *sensor, pixformat_t pixformat)
|
||||
{
|
||||
int ret=0;
|
||||
sensor->pixformat = pixformat;
|
||||
// Read register COM7
|
||||
uint8_t reg = SCCB_Read(sensor->slv_addr, COM7);
|
||||
|
||||
@ -177,17 +178,31 @@ static int set_framesize(sensor_t *sensor, framesize_t framesize)
|
||||
int ret=0;
|
||||
uint16_t w = resolution[framesize][0];
|
||||
uint16_t h = resolution[framesize][1];
|
||||
uint8_t reg = SCCB_Read(sensor->slv_addr, COM7);
|
||||
|
||||
sensor->status.framesize = framesize;
|
||||
|
||||
// Write MSBs
|
||||
ret |= SCCB_Write(sensor->slv_addr, HOUTSIZE, w>>2);
|
||||
ret |= SCCB_Write(sensor->slv_addr, VOUTSIZE, h>>1);
|
||||
|
||||
ret |= SCCB_Write(sensor->slv_addr, HSIZE, w>>2);
|
||||
ret |= SCCB_Write(sensor->slv_addr, VSIZE, h>>1);
|
||||
|
||||
// Write LSBs
|
||||
ret |= SCCB_Write(sensor->slv_addr, EXHCH, ((w&0x3) | ((h&0x1) << 2)));
|
||||
ret |= SCCB_Write(sensor->slv_addr, HREF, ((w&0x3) | ((h&0x1) << 2)));
|
||||
|
||||
if (framesize < FRAMESIZE_VGA) {
|
||||
// Enable auto-scaling/zooming factors
|
||||
ret |= SCCB_Write(sensor->slv_addr, DSPAUTO, 0xFF);
|
||||
|
||||
ret |= SCCB_Write(sensor->slv_addr, HSTART, 0x3F);
|
||||
ret |= SCCB_Write(sensor->slv_addr, VSTART, 0x03);
|
||||
|
||||
ret |= SCCB_Write(sensor->slv_addr, COM7, reg | COM7_RES_QVGA);
|
||||
|
||||
ret |= SCCB_Write(sensor->slv_addr, CLKRC, 0x80 | 0x01);
|
||||
|
||||
} else {
|
||||
// Disable auto-scaling/zooming factors
|
||||
ret |= SCCB_Write(sensor->slv_addr, DSPAUTO, 0xF3);
|
||||
@ -196,6 +211,13 @@ static int set_framesize(sensor_t *sensor, framesize_t framesize)
|
||||
ret |= SCCB_Write(sensor->slv_addr, SCAL0, 0x00);
|
||||
ret |= SCCB_Write(sensor->slv_addr, SCAL1, 0x00);
|
||||
ret |= SCCB_Write(sensor->slv_addr, SCAL2, 0x00);
|
||||
|
||||
ret |= SCCB_Write(sensor->slv_addr, HSTART, 0x23);
|
||||
ret |= SCCB_Write(sensor->slv_addr, VSTART, 0x07);
|
||||
|
||||
ret |= SCCB_Write(sensor->slv_addr, COM7, reg & ~COM7_RES_QVGA);
|
||||
|
||||
ret |= SCCB_Write(sensor->slv_addr, CLKRC, 0x80 | 0x03);
|
||||
}
|
||||
|
||||
// Delay
|
||||
@ -208,6 +230,7 @@ static int set_colorbar(sensor_t *sensor, int enable)
|
||||
{
|
||||
int ret=0;
|
||||
uint8_t reg;
|
||||
sensor->status.colorbar = enable;
|
||||
|
||||
// Read reg COM3
|
||||
reg = SCCB_Read(sensor->slv_addr, COM3);
|
||||
@ -231,6 +254,7 @@ static int set_whitebal(sensor_t *sensor, int enable)
|
||||
// Read register COM8
|
||||
uint8_t reg = SCCB_Read(sensor->slv_addr, COM8);
|
||||
|
||||
sensor->status.awb = enable;
|
||||
// Set white bal on/off
|
||||
reg = COM8_SET_AWB(reg, enable);
|
||||
|
||||
@ -240,6 +264,7 @@ static int set_whitebal(sensor_t *sensor, int enable)
|
||||
|
||||
static int set_gain_ctrl(sensor_t *sensor, int enable)
|
||||
{
|
||||
sensor->status.agc = enable;
|
||||
// Read register COM8
|
||||
uint8_t reg = SCCB_Read(sensor->slv_addr, COM8);
|
||||
|
||||
@ -252,6 +277,7 @@ static int set_gain_ctrl(sensor_t *sensor, int enable)
|
||||
|
||||
static int set_exposure_ctrl(sensor_t *sensor, int enable)
|
||||
{
|
||||
sensor->status.aec = enable;
|
||||
// Read register COM8
|
||||
uint8_t reg = SCCB_Read(sensor->slv_addr, COM8);
|
||||
|
||||
@ -264,6 +290,7 @@ static int set_exposure_ctrl(sensor_t *sensor, int enable)
|
||||
|
||||
static int set_hmirror(sensor_t *sensor, int enable)
|
||||
{
|
||||
sensor->status.hmirror = enable;
|
||||
// Read register COM3
|
||||
uint8_t reg = SCCB_Read(sensor->slv_addr, COM3);
|
||||
|
||||
@ -276,6 +303,7 @@ static int set_hmirror(sensor_t *sensor, int enable)
|
||||
|
||||
static int set_vflip(sensor_t *sensor, int enable)
|
||||
{
|
||||
sensor->status.vflip = enable;
|
||||
// Read register COM3
|
||||
uint8_t reg = SCCB_Read(sensor->slv_addr, COM3);
|
||||
|
||||
@ -286,10 +314,24 @@ static int set_vflip(sensor_t *sensor, int enable)
|
||||
return SCCB_Write(sensor->slv_addr, COM3, reg);
|
||||
}
|
||||
|
||||
static int init_status(sensor_t *sensor)
|
||||
{
|
||||
sensor->status.awb = 0;//get_reg_bits(sensor, BANK_DSP, CTRL1, 3, 1);
|
||||
sensor->status.aec = 0;
|
||||
sensor->status.agc = 0;
|
||||
sensor->status.hmirror = 0;
|
||||
sensor->status.vflip = 0;
|
||||
sensor->status.colorbar = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_dummy(sensor_t *sensor, int val){ return -1; }
|
||||
|
||||
int ov7725_init(sensor_t *sensor)
|
||||
{
|
||||
// Set function pointers
|
||||
sensor->reset = reset;
|
||||
sensor->init_status = init_status;
|
||||
sensor->set_pixformat = set_pixformat;
|
||||
sensor->set_framesize = set_framesize;
|
||||
sensor->set_colorbar = set_colorbar;
|
||||
@ -299,6 +341,34 @@ int ov7725_init(sensor_t *sensor)
|
||||
sensor->set_hmirror = set_hmirror;
|
||||
sensor->set_vflip = set_vflip;
|
||||
|
||||
//not supported
|
||||
sensor->set_brightness= set_dummy;
|
||||
sensor->set_saturation= set_dummy;
|
||||
sensor->set_quality = set_dummy;
|
||||
sensor->set_gainceiling = set_dummy;
|
||||
sensor->set_gain_ctrl = set_dummy;
|
||||
sensor->set_exposure_ctrl = set_dummy;
|
||||
sensor->set_hmirror = set_dummy;
|
||||
sensor->set_vflip = set_dummy;
|
||||
sensor->set_whitebal = set_dummy;
|
||||
sensor->set_aec2 = set_dummy;
|
||||
sensor->set_aec_value = set_dummy;
|
||||
sensor->set_special_effect = set_dummy;
|
||||
sensor->set_wb_mode = set_dummy;
|
||||
sensor->set_ae_level = set_dummy;
|
||||
sensor->set_dcw = set_dummy;
|
||||
sensor->set_bpc = set_dummy;
|
||||
sensor->set_wpc = set_dummy;
|
||||
sensor->set_awb_gain = set_dummy;
|
||||
sensor->set_agc_gain = set_dummy;
|
||||
sensor->set_raw_gma = set_dummy;
|
||||
sensor->set_lenc = set_dummy;
|
||||
sensor->set_sharpness = set_dummy;
|
||||
sensor->set_denoise = set_dummy;
|
||||
|
||||
|
||||
|
||||
|
||||
// Retrieve sensor's signature
|
||||
sensor->id.MIDH = SCCB_Read(sensor->slv_addr, REG_MIDH);
|
||||
sensor->id.MIDL = SCCB_Read(sensor->slv_addr, REG_MIDL);
|
||||
|
Reference in New Issue
Block a user