Skip to content

Fix camera probe detecting non-camera peripheral #756

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jul 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 31 additions & 23 deletions driver/esp_camera.c
Original file line number Diff line number Diff line change
Expand Up @@ -224,30 +224,39 @@ static esp_err_t camera_probe(const camera_config_t *config, camera_model_t *out
ESP_LOGD(TAG, "Searching for camera address");
vTaskDelay(10 / portTICK_PERIOD_MS);

uint8_t slv_addr = SCCB_Probe();

if (slv_addr == 0) {
ret = ESP_ERR_NOT_FOUND;
goto err;
}

ESP_LOGI(TAG, "Detected camera at address=0x%02x", slv_addr);
s_state->sensor.slv_addr = slv_addr;
s_state->sensor.xclk_freq_hz = config->xclk_freq_hz;
int camera_model_id;
uint8_t slv_addr = 0x0;

/**
* Read sensor ID and then initialize sensor
* Attention: Some sensors have the same SCCB address. Therefore, several attempts may be made in the detection process
* This loop probes each known sensor until a supported camera is detected
*/
sensor_id_t *id = &s_state->sensor.id;
for (size_t i = 0; i < sizeof(g_sensors) / sizeof(sensor_func_t); i++) {
if (g_sensors[i].detect(slv_addr, id)) {
camera_sensor_info_t *info = esp_camera_sensor_get_info(id);
if (NULL != info) {
*out_camera_model = info->model;
ESP_LOGI(TAG, "Detected %s camera", info->name);
g_sensors[i].init(&s_state->sensor);
break;
for(camera_model_id = 0; *out_camera_model == CAMERA_NONE && camera_model_id < CAMERA_MODEL_MAX ; camera_model_id++) {
slv_addr = camera_sensor[camera_model_id].sccb_addr;

if (ESP_OK != SCCB_Probe(slv_addr)) {
continue;
}

s_state->sensor.slv_addr = slv_addr;
s_state->sensor.xclk_freq_hz = config->xclk_freq_hz;

/**
* Read sensor ID and then initialize sensor
* Attention: Some sensors have the same SCCB address. Therefore, several attempts may be made in the detection process
*/
sensor_id_t *id = &s_state->sensor.id;

for (size_t i = 0; i < sizeof(g_sensors) / sizeof(sensor_func_t); i++) {
if (g_sensors[i].detect(slv_addr, id)) {
ESP_LOGI(TAG, "Camera PID=0x%02x VER=0x%02x MIDL=0x%02x MIDH=0x%02x",
id->PID, id->VER, id->MIDH, id->MIDL);
camera_sensor_info_t *info = esp_camera_sensor_get_info(id);
if (NULL != info) {
*out_camera_model = info->model;
ESP_LOGI(TAG, "Detected %s camera", info->name);
g_sensors[i].init(&s_state->sensor);
break;
}
}
}
}
Expand All @@ -258,8 +267,7 @@ static esp_err_t camera_probe(const camera_config_t *config, camera_model_t *out
goto err;
}

ESP_LOGI(TAG, "Camera PID=0x%02x VER=0x%02x MIDL=0x%02x MIDH=0x%02x",
id->PID, id->VER, id->MIDH, id->MIDL);
ESP_LOGI(TAG, "Detected camera at address=0x%02x", slv_addr);

ESP_LOGD(TAG, "Doing SW reset of sensor");
vTaskDelay(10 / portTICK_PERIOD_MS);
Expand Down
2 changes: 1 addition & 1 deletion driver/private_include/sccb.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
int SCCB_Init(int pin_sda, int pin_scl);
int SCCB_Use_Port(int sccb_i2c_port);
int SCCB_Deinit(void);
uint8_t SCCB_Probe(void);
int SCCB_Probe(uint8_t slv_addr);
uint8_t SCCB_Read(uint8_t slv_addr, uint8_t reg);
int SCCB_Write(uint8_t slv_addr, uint8_t reg, uint8_t data);
uint8_t SCCB_Read16(uint8_t slv_addr, uint16_t reg);
Expand Down
27 changes: 7 additions & 20 deletions driver/sccb-ng.c
Original file line number Diff line number Diff line change
Expand Up @@ -198,9 +198,8 @@ int SCCB_Deinit(void)
return ESP_OK;
}

uint8_t SCCB_Probe(void)
int SCCB_Probe(uint8_t slv_addr)
{
uint8_t slave_addr = 0x0;
esp_err_t ret;
i2c_master_bus_handle_t bus_handle;

Expand All @@ -211,26 +210,14 @@ uint8_t SCCB_Probe(void)
return ret;
}

for (size_t i = 0; i < CAMERA_MODEL_MAX; i++)
{
if (slave_addr == camera_sensor[i].sccb_addr)
{
continue;
}
slave_addr = camera_sensor[i].sccb_addr;
ret = i2c_master_probe(bus_handle, slv_addr, TIMEOUT_MS);

ret = i2c_master_probe(bus_handle, slave_addr, TIMEOUT_MS);

if (ret == ESP_OK)
{
if (SCCB_Install_Device(slave_addr) != 0)
{
return 0;
}
return slave_addr;
}
if (ret == ESP_OK)
{
return SCCB_Install_Device(slv_addr);
}
return 0;

return ret;
}

uint8_t SCCB_Read(uint8_t slv_addr, uint8_t reg)
Expand Down
27 changes: 8 additions & 19 deletions driver/sccb.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,26 +93,15 @@ int SCCB_Deinit(void)
return i2c_driver_delete(sccb_i2c_port);
}

uint8_t SCCB_Probe(void)
int SCCB_Probe(uint8_t slv_addr)
{
uint8_t slave_addr = 0x0;

for (size_t i = 0; i < CAMERA_MODEL_MAX; i++) {
if (slave_addr == camera_sensor[i].sccb_addr) {
continue;
}
slave_addr = camera_sensor[i].sccb_addr;
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, ( slave_addr << 1 ) | WRITE_BIT, ACK_CHECK_EN);
i2c_master_stop(cmd);
esp_err_t ret = i2c_master_cmd_begin(sccb_i2c_port, cmd, 1000 / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd);
if( ret == ESP_OK) {
return slave_addr;
}
}
return 0;
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, ( slv_addr << 1 ) | WRITE_BIT, ACK_CHECK_EN);
i2c_master_stop(cmd);
esp_err_t ret = i2c_master_cmd_begin(sccb_i2c_port, cmd, 1000 / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd);
return ret;
}

uint8_t SCCB_Read(uint8_t slv_addr, uint8_t reg)
Expand Down