Skip to content

Commit 77d71b0

Browse files
committed
feat: change sccb APIs for sharing i2c port with other devices
1 parent 7b6f020 commit 77d71b0

File tree

8 files changed

+124
-53
lines changed

8 files changed

+124
-53
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,8 @@ static camera_config_t camera_config = {
131131
.pin_pwdn = CAM_PIN_PWDN,
132132
.pin_reset = CAM_PIN_RESET,
133133
.pin_xclk = CAM_PIN_XCLK,
134-
.pin_sscb_sda = CAM_PIN_SIOD,
135-
.pin_sscb_scl = CAM_PIN_SIOC,
134+
.pin_sccb_sda = CAM_PIN_SIOD,
135+
.pin_sccb_scl = CAM_PIN_SIOC,
136136

137137
.pin_d7 = CAM_PIN_D7,
138138
.pin_d6 = CAM_PIN_D6,

driver/esp_camera.c

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ static const sensor_func_t g_sensors[] = {
141141

142142
static esp_err_t camera_probe(const camera_config_t *config, camera_model_t *out_camera_model)
143143
{
144+
esp_err_t ret = ESP_OK;
144145
*out_camera_model = CAMERA_NONE;
145146
if (s_state != NULL) {
146147
return ESP_ERR_INVALID_STATE;
@@ -156,9 +157,17 @@ static esp_err_t camera_probe(const camera_config_t *config, camera_model_t *out
156157
CAMERA_ENABLE_OUT_CLOCK(config);
157158
}
158159

159-
if (config->pin_sscb_sda != -1) {
160-
ESP_LOGD(TAG, "Initializing SSCB");
161-
SCCB_Init(config->pin_sscb_sda, config->pin_sscb_scl);
160+
if (config->pin_sccb_sda != -1) {
161+
ESP_LOGD(TAG, "Initializing SCCB");
162+
ret = SCCB_Init(config->pin_sccb_sda, config->pin_sccb_scl);
163+
} else {
164+
ESP_LOGD(TAG, "Using existing I2C port");
165+
ret = SCCB_Use_Port(config->sccb_i2c_port);
166+
}
167+
168+
if(ret != ESP_OK) {
169+
ESP_LOGE(TAG, "sccb init err");
170+
goto err;
162171
}
163172

164173
if (config->pin_pwdn >= 0) {
@@ -188,15 +197,14 @@ static esp_err_t camera_probe(const camera_config_t *config, camera_model_t *out
188197
vTaskDelay(10 / portTICK_PERIOD_MS);
189198
}
190199

191-
192200
ESP_LOGD(TAG, "Searching for camera address");
193201
vTaskDelay(10 / portTICK_PERIOD_MS);
194202

195203
uint8_t slv_addr = SCCB_Probe();
196204

197205
if (slv_addr == 0) {
198-
CAMERA_DISABLE_OUT_CLOCK();
199-
return ESP_ERR_NOT_FOUND;
206+
ret = ESP_ERR_NOT_FOUND;
207+
goto err;
200208
}
201209

202210
ESP_LOGI(TAG, "Detected camera at address=0x%02x", slv_addr);
@@ -221,19 +229,21 @@ static esp_err_t camera_probe(const camera_config_t *config, camera_model_t *out
221229
}
222230

223231
if (CAMERA_NONE == *out_camera_model) { //If no supported sensors are detected
224-
CAMERA_DISABLE_OUT_CLOCK();
225232
ESP_LOGE(TAG, "Detected camera not supported.");
226-
return ESP_ERR_NOT_SUPPORTED;
233+
ret = ESP_ERR_NOT_SUPPORTED;
234+
goto err;
227235
}
228236

229237
ESP_LOGI(TAG, "Camera PID=0x%02x VER=0x%02x MIDL=0x%02x MIDH=0x%02x",
230238
id->PID, id->VER, id->MIDH, id->MIDL);
231239

232240
ESP_LOGD(TAG, "Doing SW reset of sensor");
233241
vTaskDelay(10 / portTICK_PERIOD_MS);
234-
s_state->sensor.reset(&s_state->sensor);
235-
236-
return ESP_OK;
242+
243+
return s_state->sensor.reset(&s_state->sensor);
244+
err :
245+
CAMERA_DISABLE_OUT_CLOCK();
246+
return ret;
237247
}
238248

239249
#if CONFIG_CAMERA_CONVERTER_ENABLED

driver/include/esp_camera.h

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@
1818
.pin_pwdn = PIN_PWDN,
1919
.pin_reset = PIN_RESET,
2020
.pin_xclk = PIN_XCLK,
21-
.pin_sscb_sda = PIN_SIOD,
22-
.pin_sscb_scl = PIN_SIOC,
21+
.pin_sccb_sda = PIN_SIOD,
22+
.pin_sccb_scl = PIN_SIOC,
2323
.pin_d7 = PIN_D7,
2424
.pin_d6 = PIN_D6,
2525
.pin_d5 = PIN_D5,
@@ -112,8 +112,14 @@ typedef struct {
112112
int pin_pwdn; /*!< GPIO pin for camera power down line */
113113
int pin_reset; /*!< GPIO pin for camera reset line */
114114
int pin_xclk; /*!< GPIO pin for camera XCLK line */
115-
int pin_sscb_sda; /*!< GPIO pin for camera SDA line */
116-
int pin_sscb_scl; /*!< GPIO pin for camera SCL line */
115+
union {
116+
int pin_sccb_sda; /*!< GPIO pin for camera SDA line */
117+
int pin_sscb_sda __attribute__((deprecated("please use pin_sccb_sda instead"))); /*!< GPIO pin for camera SDA line (legacy name) */
118+
};
119+
union {
120+
int pin_sccb_scl; /*!< GPIO pin for camera SCL line */
121+
int pin_sscb_scl __attribute__((deprecated("please use pin_sccb_scl instead"))); /*!< GPIO pin for camera SCL line (legacy name) */
122+
};
117123
int pin_d7; /*!< GPIO pin for camera D7 line */
118124
int pin_d6; /*!< GPIO pin for camera D6 line */
119125
int pin_d5; /*!< GPIO pin for camera D5 line */
@@ -141,6 +147,8 @@ typedef struct {
141147
#if CONFIG_CAMERA_CONVERTER_ENABLED
142148
camera_conv_mode_t conv_mode; /*!< RGB<->YUV Conversion mode */
143149
#endif
150+
151+
int sccb_i2c_port; /*!< If pin_sccb_sda is -1, use the already configured I2C bus by number */
144152
} camera_config_t;
145153

146154
/**

driver/include/sensor.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ typedef struct _sensor {
209209

210210
// Sensor function pointers
211211
int (*init_status) (sensor_t *sensor);
212-
int (*reset) (sensor_t *sensor);
212+
int (*reset) (sensor_t *sensor); // Reset the configuration of the sensor, and return ESP_OK if reset is successful
213213
int (*set_pixformat) (sensor_t *sensor, pixformat_t pixformat);
214214
int (*set_framesize) (sensor_t *sensor, framesize_t framesize);
215215
int (*set_contrast) (sensor_t *sensor, int level);

driver/private_include/sccb.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#define __SCCB_H__
1111
#include <stdint.h>
1212
int SCCB_Init(int pin_sda, int pin_scl);
13+
int SCCB_Use_Port(int sccb_i2c_port);
1314
int SCCB_Deinit(void);
1415
uint8_t SCCB_Probe();
1516
uint8_t SCCB_Read(uint8_t slv_addr, uint8_t reg);

driver/sccb.c

Lines changed: 41 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -38,47 +38,64 @@ static const char* TAG = "sccb";
3838
#define ACK_VAL 0x0 /*!< I2C ack value */
3939
#define NACK_VAL 0x1 /*!< I2C nack value */
4040
#if CONFIG_SCCB_HARDWARE_I2C_PORT1
41-
const int SCCB_I2C_PORT = 1;
41+
const int SCCB_I2C_PORT_DEFAULT = 1;
4242
#else
43-
const int SCCB_I2C_PORT = 0;
43+
const int SCCB_I2C_PORT_DEFAULT = 0;
4444
#endif
4545

46+
static int sccb_i2c_port;
47+
static bool sccb_owns_i2c_port;
48+
4649
int SCCB_Init(int pin_sda, int pin_scl)
4750
{
4851
ESP_LOGI(TAG, "pin_sda %d pin_scl %d", pin_sda, pin_scl);
4952
i2c_config_t conf;
53+
esp_err_t ret;
54+
5055
memset(&conf, 0, sizeof(i2c_config_t));
56+
57+
sccb_i2c_port = SCCB_I2C_PORT_DEFAULT;
58+
sccb_owns_i2c_port = true;
59+
ESP_LOGI(TAG, "sccb_i2c_port=%d\n", sccb_i2c_port);
60+
5161
conf.mode = I2C_MODE_MASTER;
5262
conf.sda_io_num = pin_sda;
5363
conf.sda_pullup_en = GPIO_PULLUP_ENABLE;
5464
conf.scl_io_num = pin_scl;
5565
conf.scl_pullup_en = GPIO_PULLUP_ENABLE;
5666
conf.master.clk_speed = SCCB_FREQ;
5767

58-
i2c_param_config(SCCB_I2C_PORT, &conf);
59-
i2c_driver_install(SCCB_I2C_PORT, conf.mode, 0, 0, 0);
60-
return 0;
68+
if ((ret = i2c_param_config(sccb_i2c_port, &conf)) != ESP_OK) {
69+
return ret;
70+
}
71+
72+
return i2c_driver_install(sccb_i2c_port, conf.mode, 0, 0, 0);
73+
}
74+
75+
int SCCB_Use_Port(int i2c_num) { // sccb use an already initialized I2C port
76+
if (sccb_owns_i2c_port) {
77+
SCCB_Deinit();
78+
}
79+
if (i2c_num < 0 || i2c_num > I2C_NUM_MAX) {
80+
return ESP_ERR_INVALID_ARG;
81+
}
82+
sccb_i2c_port = i2c_num;
83+
return ESP_OK;
6184
}
6285

6386
int SCCB_Deinit(void)
6487
{
65-
return i2c_driver_delete(SCCB_I2C_PORT);
88+
if (!sccb_owns_i2c_port) {
89+
return ESP_OK;
90+
}
91+
sccb_owns_i2c_port = false;
92+
return i2c_driver_delete(sccb_i2c_port);
6693
}
6794

6895
uint8_t SCCB_Probe(void)
6996
{
7097
uint8_t slave_addr = 0x0;
71-
// for (size_t i = 1; i < 0x80; i++) {
72-
// i2c_cmd_handle_t cmd = i2c_cmd_link_create();
73-
// i2c_master_start(cmd);
74-
// i2c_master_write_byte(cmd, ( i << 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_LOGW(TAG, "Found I2C Device at 0x%02X", i);
80-
// }
81-
// }
98+
8299
for (size_t i = 0; i < CAMERA_MODEL_MAX; i++) {
83100
if (slave_addr == camera_sensor[i].sccb_addr) {
84101
continue;
@@ -88,7 +105,7 @@ uint8_t SCCB_Probe(void)
88105
i2c_master_start(cmd);
89106
i2c_master_write_byte(cmd, ( slave_addr << 1 ) | WRITE_BIT, ACK_CHECK_EN);
90107
i2c_master_stop(cmd);
91-
esp_err_t ret = i2c_master_cmd_begin(SCCB_I2C_PORT, cmd, 1000 / portTICK_RATE_MS);
108+
esp_err_t ret = i2c_master_cmd_begin(sccb_i2c_port, cmd, 1000 / portTICK_RATE_MS);
92109
i2c_cmd_link_delete(cmd);
93110
if( ret == ESP_OK) {
94111
return slave_addr;
@@ -106,15 +123,15 @@ uint8_t SCCB_Read(uint8_t slv_addr, uint8_t reg)
106123
i2c_master_write_byte(cmd, ( slv_addr << 1 ) | WRITE_BIT, ACK_CHECK_EN);
107124
i2c_master_write_byte(cmd, reg, ACK_CHECK_EN);
108125
i2c_master_stop(cmd);
109-
ret = i2c_master_cmd_begin(SCCB_I2C_PORT, cmd, 1000 / portTICK_RATE_MS);
126+
ret = i2c_master_cmd_begin(sccb_i2c_port, cmd, 1000 / portTICK_RATE_MS);
110127
i2c_cmd_link_delete(cmd);
111128
if(ret != ESP_OK) return -1;
112129
cmd = i2c_cmd_link_create();
113130
i2c_master_start(cmd);
114131
i2c_master_write_byte(cmd, ( slv_addr << 1 ) | READ_BIT, ACK_CHECK_EN);
115132
i2c_master_read_byte(cmd, &data, NACK_VAL);
116133
i2c_master_stop(cmd);
117-
ret = i2c_master_cmd_begin(SCCB_I2C_PORT, cmd, 1000 / portTICK_RATE_MS);
134+
ret = i2c_master_cmd_begin(sccb_i2c_port, cmd, 1000 / portTICK_RATE_MS);
118135
i2c_cmd_link_delete(cmd);
119136
if(ret != ESP_OK) {
120137
ESP_LOGE(TAG, "SCCB_Read Failed addr:0x%02x, reg:0x%02x, data:0x%02x, ret:%d", slv_addr, reg, data, ret);
@@ -131,7 +148,7 @@ uint8_t SCCB_Write(uint8_t slv_addr, uint8_t reg, uint8_t data)
131148
i2c_master_write_byte(cmd, reg, ACK_CHECK_EN);
132149
i2c_master_write_byte(cmd, data, ACK_CHECK_EN);
133150
i2c_master_stop(cmd);
134-
ret = i2c_master_cmd_begin(SCCB_I2C_PORT, cmd, 1000 / portTICK_RATE_MS);
151+
ret = i2c_master_cmd_begin(sccb_i2c_port, cmd, 1000 / portTICK_RATE_MS);
135152
i2c_cmd_link_delete(cmd);
136153
if(ret != ESP_OK) {
137154
ESP_LOGE(TAG, "SCCB_Write Failed addr:0x%02x, reg:0x%02x, data:0x%02x, ret:%d", slv_addr, reg, data, ret);
@@ -151,15 +168,15 @@ uint8_t SCCB_Read16(uint8_t slv_addr, uint16_t reg)
151168
i2c_master_write_byte(cmd, reg_u8[0], ACK_CHECK_EN);
152169
i2c_master_write_byte(cmd, reg_u8[1], ACK_CHECK_EN);
153170
i2c_master_stop(cmd);
154-
ret = i2c_master_cmd_begin(SCCB_I2C_PORT, cmd, 1000 / portTICK_RATE_MS);
171+
ret = i2c_master_cmd_begin(sccb_i2c_port, cmd, 1000 / portTICK_RATE_MS);
155172
i2c_cmd_link_delete(cmd);
156173
if(ret != ESP_OK) return -1;
157174
cmd = i2c_cmd_link_create();
158175
i2c_master_start(cmd);
159176
i2c_master_write_byte(cmd, ( slv_addr << 1 ) | READ_BIT, ACK_CHECK_EN);
160177
i2c_master_read_byte(cmd, &data, NACK_VAL);
161178
i2c_master_stop(cmd);
162-
ret = i2c_master_cmd_begin(SCCB_I2C_PORT, cmd, 1000 / portTICK_RATE_MS);
179+
ret = i2c_master_cmd_begin(sccb_i2c_port, cmd, 1000 / portTICK_RATE_MS);
163180
i2c_cmd_link_delete(cmd);
164181
if(ret != ESP_OK) {
165182
ESP_LOGE(TAG, "W [%04x]=%02x fail\n", reg, data);
@@ -180,7 +197,7 @@ uint8_t SCCB_Write16(uint8_t slv_addr, uint16_t reg, uint8_t data)
180197
i2c_master_write_byte(cmd, reg_u8[1], ACK_CHECK_EN);
181198
i2c_master_write_byte(cmd, data, ACK_CHECK_EN);
182199
i2c_master_stop(cmd);
183-
ret = i2c_master_cmd_begin(SCCB_I2C_PORT, cmd, 1000 / portTICK_RATE_MS);
200+
ret = i2c_master_cmd_begin(sccb_i2c_port, cmd, 1000 / portTICK_RATE_MS);
184201
i2c_cmd_link_delete(cmd);
185202
if(ret != ESP_OK) {
186203
ESP_LOGE(TAG, "W [%04x]=%02x %d fail\n", reg, data, i++);

examples/main/take_picture.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,8 @@ static camera_config_t camera_config = {
9999
.pin_pwdn = CAM_PIN_PWDN,
100100
.pin_reset = CAM_PIN_RESET,
101101
.pin_xclk = CAM_PIN_XCLK,
102-
.pin_sscb_sda = CAM_PIN_SIOD,
103-
.pin_sscb_scl = CAM_PIN_SIOC,
102+
.pin_sccb_sda = CAM_PIN_SIOD,
103+
.pin_sccb_scl = CAM_PIN_SIOC,
104104

105105
.pin_d7 = CAM_PIN_D7,
106106
.pin_d6 = CAM_PIN_D6,

0 commit comments

Comments
 (0)