camera_config_t camera_config = {
.ledc_channel = LEDC_CHANNEL_0,
.ledc_timer = LEDC_TIMER_0,
.pin_d0 = CONFIG_D0,
.pin_d1 = CONFIG_D1,
.pin_d2 = CONFIG_D2,
.pin_d3 = CONFIG_D3,
.pin_d4 = CONFIG_D4,
.pin_d5 = CONFIG_D5,
.pin_d6 = CONFIG_D6,
.pin_d7 = CONFIG_D7,
.pin_xclk = CONFIG_XCLK,
.pin_pclk = CONFIG_PCLK,
.pin_vsync = CONFIG_VSYNC,
.pin_href = CONFIG_HREF,
.pin_sscb_sda = CONFIG_SDA,
.pin_sscb_scl = CONFIG_SCL,
.pin_reset = CONFIG_RESET,
.xclk_freq_hz = CONFIG_XCLK_FREQ,
};
typedef enum {
CAMERA_NONE = 0,
CAMERA_UNKNOWN = 1,
CAMERA_OV7725 = 7725,
CAMERA_OV2640 = 2640,
} camera_model_t;
typedef struct {
int pin_reset; /*!< GPIO pin for camera reset line */
int pin_xclk; /*!< GPIO pin for camera XCLK line */
int pin_sscb_sda; /*!< GPIO pin for camera SDA line */
int pin_sscb_scl; /*!< GPIO pin for camera SCL line */
int pin_d7; /*!< GPIO pin for camera D7 line */
int pin_d6; /*!< GPIO pin for camera D6 line */
int pin_d5; /*!< GPIO pin for camera D5 line */
int pin_d4; /*!< GPIO pin for camera D4 line */
int pin_d3; /*!< GPIO pin for camera D3 line */
int pin_d2; /*!< GPIO pin for camera D2 line */
int pin_d1; /*!< GPIO pin for camera D1 line */
int pin_d0; /*!< GPIO pin for camera D0 line */
int pin_vsync; /*!< GPIO pin for camera VSYNC line */
int pin_href; /*!< GPIO pin for camera HREF line */
int pin_pclk; /*!< GPIO pin for camera PCLK line */
int xclk_freq_hz; /*!< Frequency of XCLK signal, in Hz */
ledc_timer_t ledc_timer; /*!< LEDC timer to be used for generating XCLK */
ledc_channel_t ledc_channel; /*!< LEDC channel to be used for generating XCLK */
camera_pixelformat_t pixel_format;
camera_framesize_t frame_size;
int jpeg_quality;
} camera_config_t;
esp_err_t camera_probe(const camera_config_t* config,
camera_model_t* out_camera_model) {
if (s_state != NULL) {
return ESP_ERR_INVALID_STATE;
}
s_state = (camera_state_t*) calloc(sizeof(*s_state), 1);
if (!s_state) {
return ESP_ERR_NO_MEM;
}
ESP_LOGD(TAG, "Enabling XCLK output");
camera_enable_out_clock(config);
ESP_LOGD(TAG, "Initializing SSCB");
SCCB_Init(config->pin_sscb_sda, config->pin_sscb_scl);
ESP_LOGD(TAG, "Resetting camera");
gpio_config_t conf = { 0 };
conf.pin_bit_mask = 1LL << config->pin_reset;
conf.mode = GPIO_MODE_OUTPUT;
gpio_config(&conf);
gpio_set_level(config->pin_reset, 1);
delay(3000);
gpio_set_level(config->pin_reset, 0);
delay(1000);
#if CONFIG_OV2640_SUPPORT
uint8_t buf[] = {0xff, 0x01};
twi_writeTo(0x30, buf, 2, true);
#endif
ESP_LOGD(TAG, "Searching for camera address");
/* Probe the sensor */
delay(10);
uint8_t slv_addr = SCCB_Probe();
if (slv_addr == 0) {
*out_camera_model = CAMERA_NONE;
return ESP_ERR_CAMERA_NOT_DETECTED;
}
s_state->sensor.slv_addr = slv_addr;
ESP_LOGD(TAG, "Detected camera at address=0x%02x", slv_addr);
sensor_id_t* id = &s_state->sensor.id;
id->PID = SCCB_Read(slv_addr, REG_PID);
id->VER = SCCB_Read(slv_addr, REG_VER);
id->MIDL = SCCB_Read(slv_addr, REG_MIDL);
id->MIDH = SCCB_Read(slv_addr, REG_MIDH);
delay(10);
ESP_LOGD(TAG, "Camera PID=0x%02x VER=0x%02x MIDL=0x%02x MIDH=0x%02x",
id->PID, id->VER, id->MIDH, id->MIDL);
switch (id->PID) {
#if CONFIG_OV2640_SUPPORT
case OV2640_PID:
*out_camera_model = CAMERA_OV2640;
ov2640_init(&s_state->sensor);
break;
#endif
#if CONFIG_OV7725_SUPPORT
case OV7725_PID:
*out_camera_model = CAMERA_OV7725;
ov7725_init(&s_state->sensor);
break;
#endif
default:
id->PID = 0;
*out_camera_model = CAMERA_UNKNOWN;
ESP_LOGD(TAG, "Detected camera not supported.")
;
return ESP_ERR_CAMERA_NOT_SUPPORTED;
}
ESP_LOGD(TAG, "Doing SW reset of sensor");
s_state->sensor.reset(&s_state->sensor);
return ESP_OK;
}
typedef enum {
CAMERA_NONE = 0,
CAMERA_UNKNOWN = 1,
CAMERA_OV7725 = 7725,
CAMERA_OV2640 = 2640,
} camera_model_t;
下一步研究OpenCV移植到ESP32
https://github.com/joachimBurket/esp32-opencv