Browse Source

feat: change sccb APIs for sharing i2c port with other devices

pull/413/head
Wang Yu Xin 3 years ago
parent
commit
77d71b03f3
  1. 4
      README.md
  2. 32
      driver/esp_camera.c
  3. 16
      driver/include/esp_camera.h
  4. 2
      driver/include/sensor.h
  5. 1
      driver/private_include/sccb.h
  6. 65
      driver/sccb.c
  7. 4
      examples/main/take_picture.c
  8. 53
      test/test_camera.c

4
README.md

@ -131,8 +131,8 @@ static camera_config_t camera_config = {
.pin_pwdn = CAM_PIN_PWDN, .pin_pwdn = CAM_PIN_PWDN,
.pin_reset = CAM_PIN_RESET, .pin_reset = CAM_PIN_RESET,
.pin_xclk = CAM_PIN_XCLK, .pin_xclk = CAM_PIN_XCLK,
.pin_sscb_sda = CAM_PIN_SIOD, .pin_sccb_sda = CAM_PIN_SIOD,
.pin_sscb_scl = CAM_PIN_SIOC, .pin_sccb_scl = CAM_PIN_SIOC,
.pin_d7 = CAM_PIN_D7, .pin_d7 = CAM_PIN_D7,
.pin_d6 = CAM_PIN_D6, .pin_d6 = CAM_PIN_D6,

32
driver/esp_camera.c

@ -141,6 +141,7 @@ static const sensor_func_t g_sensors[] = {
static esp_err_t camera_probe(const camera_config_t *config, camera_model_t *out_camera_model) static esp_err_t camera_probe(const camera_config_t *config, camera_model_t *out_camera_model)
{ {
esp_err_t ret = ESP_OK;
*out_camera_model = CAMERA_NONE; *out_camera_model = CAMERA_NONE;
if (s_state != NULL) { if (s_state != NULL) {
return ESP_ERR_INVALID_STATE; return ESP_ERR_INVALID_STATE;
@ -156,9 +157,17 @@ static esp_err_t camera_probe(const camera_config_t *config, camera_model_t *out
CAMERA_ENABLE_OUT_CLOCK(config); CAMERA_ENABLE_OUT_CLOCK(config);
} }
if (config->pin_sscb_sda != -1) { if (config->pin_sccb_sda != -1) {
ESP_LOGD(TAG, "Initializing SSCB"); ESP_LOGD(TAG, "Initializing SCCB");
SCCB_Init(config->pin_sscb_sda, config->pin_sscb_scl); ret = SCCB_Init(config->pin_sccb_sda, config->pin_sccb_scl);
} else {
ESP_LOGD(TAG, "Using existing I2C port");
ret = SCCB_Use_Port(config->sccb_i2c_port);
}
if(ret != ESP_OK) {
ESP_LOGE(TAG, "sccb init err");
goto err;
} }
if (config->pin_pwdn >= 0) { if (config->pin_pwdn >= 0) {
@ -188,15 +197,14 @@ static esp_err_t camera_probe(const camera_config_t *config, camera_model_t *out
vTaskDelay(10 / portTICK_PERIOD_MS); vTaskDelay(10 / portTICK_PERIOD_MS);
} }
ESP_LOGD(TAG, "Searching for camera address"); ESP_LOGD(TAG, "Searching for camera address");
vTaskDelay(10 / portTICK_PERIOD_MS); vTaskDelay(10 / portTICK_PERIOD_MS);
uint8_t slv_addr = SCCB_Probe(); uint8_t slv_addr = SCCB_Probe();
if (slv_addr == 0) { if (slv_addr == 0) {
CAMERA_DISABLE_OUT_CLOCK(); ret = ESP_ERR_NOT_FOUND;
return ESP_ERR_NOT_FOUND; goto err;
} }
ESP_LOGI(TAG, "Detected camera at address=0x%02x", slv_addr); ESP_LOGI(TAG, "Detected camera at address=0x%02x", slv_addr);
@ -221,9 +229,9 @@ static esp_err_t camera_probe(const camera_config_t *config, camera_model_t *out
} }
if (CAMERA_NONE == *out_camera_model) { //If no supported sensors are detected if (CAMERA_NONE == *out_camera_model) { //If no supported sensors are detected
CAMERA_DISABLE_OUT_CLOCK();
ESP_LOGE(TAG, "Detected camera not supported."); ESP_LOGE(TAG, "Detected camera not supported.");
return ESP_ERR_NOT_SUPPORTED; ret = ESP_ERR_NOT_SUPPORTED;
goto err;
} }
ESP_LOGI(TAG, "Camera PID=0x%02x VER=0x%02x MIDL=0x%02x MIDH=0x%02x", ESP_LOGI(TAG, "Camera PID=0x%02x VER=0x%02x MIDL=0x%02x MIDH=0x%02x",
@ -231,9 +239,11 @@ static esp_err_t camera_probe(const camera_config_t *config, camera_model_t *out
ESP_LOGD(TAG, "Doing SW reset of sensor"); ESP_LOGD(TAG, "Doing SW reset of sensor");
vTaskDelay(10 / portTICK_PERIOD_MS); vTaskDelay(10 / portTICK_PERIOD_MS);
s_state->sensor.reset(&s_state->sensor);
return s_state->sensor.reset(&s_state->sensor);
return ESP_OK; err :
CAMERA_DISABLE_OUT_CLOCK();
return ret;
} }
#if CONFIG_CAMERA_CONVERTER_ENABLED #if CONFIG_CAMERA_CONVERTER_ENABLED

16
driver/include/esp_camera.h

@ -18,8 +18,8 @@
.pin_pwdn = PIN_PWDN, .pin_pwdn = PIN_PWDN,
.pin_reset = PIN_RESET, .pin_reset = PIN_RESET,
.pin_xclk = PIN_XCLK, .pin_xclk = PIN_XCLK,
.pin_sscb_sda = PIN_SIOD, .pin_sccb_sda = PIN_SIOD,
.pin_sscb_scl = PIN_SIOC, .pin_sccb_scl = PIN_SIOC,
.pin_d7 = PIN_D7, .pin_d7 = PIN_D7,
.pin_d6 = PIN_D6, .pin_d6 = PIN_D6,
.pin_d5 = PIN_D5, .pin_d5 = PIN_D5,
@ -112,8 +112,14 @@ typedef struct {
int pin_pwdn; /*!< GPIO pin for camera power down line */ int pin_pwdn; /*!< GPIO pin for camera power down line */
int pin_reset; /*!< GPIO pin for camera reset line */ int pin_reset; /*!< GPIO pin for camera reset line */
int pin_xclk; /*!< GPIO pin for camera XCLK line */ int pin_xclk; /*!< GPIO pin for camera XCLK line */
int pin_sscb_sda; /*!< GPIO pin for camera SDA line */ union {
int pin_sscb_scl; /*!< GPIO pin for camera SCL line */ int pin_sccb_sda; /*!< GPIO pin for camera SDA line */
int pin_sscb_sda __attribute__((deprecated("please use pin_sccb_sda instead"))); /*!< GPIO pin for camera SDA line (legacy name) */
};
union {
int pin_sccb_scl; /*!< GPIO pin for camera SCL line */
int pin_sscb_scl __attribute__((deprecated("please use pin_sccb_scl instead"))); /*!< GPIO pin for camera SCL line (legacy name) */
};
int pin_d7; /*!< GPIO pin for camera D7 line */ int pin_d7; /*!< GPIO pin for camera D7 line */
int pin_d6; /*!< GPIO pin for camera D6 line */ int pin_d6; /*!< GPIO pin for camera D6 line */
int pin_d5; /*!< GPIO pin for camera D5 line */ int pin_d5; /*!< GPIO pin for camera D5 line */
@ -141,6 +147,8 @@ typedef struct {
#if CONFIG_CAMERA_CONVERTER_ENABLED #if CONFIG_CAMERA_CONVERTER_ENABLED
camera_conv_mode_t conv_mode; /*!< RGB<->YUV Conversion mode */ camera_conv_mode_t conv_mode; /*!< RGB<->YUV Conversion mode */
#endif #endif
int sccb_i2c_port; /*!< If pin_sccb_sda is -1, use the already configured I2C bus by number */
} camera_config_t; } camera_config_t;
/** /**

2
driver/include/sensor.h

@ -209,7 +209,7 @@ typedef struct _sensor {
// Sensor function pointers // Sensor function pointers
int (*init_status) (sensor_t *sensor); int (*init_status) (sensor_t *sensor);
int (*reset) (sensor_t *sensor); int (*reset) (sensor_t *sensor); // Reset the configuration of the sensor, and return ESP_OK if reset is successful
int (*set_pixformat) (sensor_t *sensor, pixformat_t pixformat); int (*set_pixformat) (sensor_t *sensor, pixformat_t pixformat);
int (*set_framesize) (sensor_t *sensor, framesize_t framesize); int (*set_framesize) (sensor_t *sensor, framesize_t framesize);
int (*set_contrast) (sensor_t *sensor, int level); int (*set_contrast) (sensor_t *sensor, int level);

1
driver/private_include/sccb.h

@ -10,6 +10,7 @@
#define __SCCB_H__ #define __SCCB_H__
#include <stdint.h> #include <stdint.h>
int SCCB_Init(int pin_sda, int pin_scl); int SCCB_Init(int pin_sda, int pin_scl);
int SCCB_Use_Port(int sccb_i2c_port);
int SCCB_Deinit(void); int SCCB_Deinit(void);
uint8_t SCCB_Probe(); uint8_t SCCB_Probe();
uint8_t SCCB_Read(uint8_t slv_addr, uint8_t reg); uint8_t SCCB_Read(uint8_t slv_addr, uint8_t reg);

65
driver/sccb.c

@ -38,16 +38,26 @@ static const char* TAG = "sccb";
#define ACK_VAL 0x0 /*!< I2C ack value */ #define ACK_VAL 0x0 /*!< I2C ack value */
#define NACK_VAL 0x1 /*!< I2C nack value */ #define NACK_VAL 0x1 /*!< I2C nack value */
#if CONFIG_SCCB_HARDWARE_I2C_PORT1 #if CONFIG_SCCB_HARDWARE_I2C_PORT1
const int SCCB_I2C_PORT = 1; const int SCCB_I2C_PORT_DEFAULT = 1;
#else #else
const int SCCB_I2C_PORT = 0; const int SCCB_I2C_PORT_DEFAULT = 0;
#endif #endif
static int sccb_i2c_port;
static bool sccb_owns_i2c_port;
int SCCB_Init(int pin_sda, int pin_scl) int SCCB_Init(int pin_sda, int pin_scl)
{ {
ESP_LOGI(TAG, "pin_sda %d pin_scl %d", pin_sda, pin_scl); ESP_LOGI(TAG, "pin_sda %d pin_scl %d", pin_sda, pin_scl);
i2c_config_t conf; i2c_config_t conf;
esp_err_t ret;
memset(&conf, 0, sizeof(i2c_config_t)); memset(&conf, 0, sizeof(i2c_config_t));
sccb_i2c_port = SCCB_I2C_PORT_DEFAULT;
sccb_owns_i2c_port = true;
ESP_LOGI(TAG, "sccb_i2c_port=%d\n", sccb_i2c_port);
conf.mode = I2C_MODE_MASTER; conf.mode = I2C_MODE_MASTER;
conf.sda_io_num = pin_sda; conf.sda_io_num = pin_sda;
conf.sda_pullup_en = GPIO_PULLUP_ENABLE; conf.sda_pullup_en = GPIO_PULLUP_ENABLE;
@ -55,30 +65,37 @@ int SCCB_Init(int pin_sda, int pin_scl)
conf.scl_pullup_en = GPIO_PULLUP_ENABLE; conf.scl_pullup_en = GPIO_PULLUP_ENABLE;
conf.master.clk_speed = SCCB_FREQ; conf.master.clk_speed = SCCB_FREQ;
i2c_param_config(SCCB_I2C_PORT, &conf); if ((ret = i2c_param_config(sccb_i2c_port, &conf)) != ESP_OK) {
i2c_driver_install(SCCB_I2C_PORT, conf.mode, 0, 0, 0); return ret;
return 0; }
return i2c_driver_install(sccb_i2c_port, conf.mode, 0, 0, 0);
}
int SCCB_Use_Port(int i2c_num) { // sccb use an already initialized I2C port
if (sccb_owns_i2c_port) {
SCCB_Deinit();
}
if (i2c_num < 0 || i2c_num > I2C_NUM_MAX) {
return ESP_ERR_INVALID_ARG;
}
sccb_i2c_port = i2c_num;
return ESP_OK;
} }
int SCCB_Deinit(void) int SCCB_Deinit(void)
{ {
return i2c_driver_delete(SCCB_I2C_PORT); if (!sccb_owns_i2c_port) {
return ESP_OK;
}
sccb_owns_i2c_port = false;
return i2c_driver_delete(sccb_i2c_port);
} }
uint8_t SCCB_Probe(void) uint8_t SCCB_Probe(void)
{ {
uint8_t slave_addr = 0x0; uint8_t slave_addr = 0x0;
// for (size_t i = 1; i < 0x80; i++) {
// i2c_cmd_handle_t cmd = i2c_cmd_link_create();
// i2c_master_start(cmd);
// i2c_master_write_byte(cmd, ( i << 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) {
// ESP_LOGW(TAG, "Found I2C Device at 0x%02X", i);
// }
// }
for (size_t i = 0; i < CAMERA_MODEL_MAX; i++) { for (size_t i = 0; i < CAMERA_MODEL_MAX; i++) {
if (slave_addr == camera_sensor[i].sccb_addr) { if (slave_addr == camera_sensor[i].sccb_addr) {
continue; continue;
@ -88,7 +105,7 @@ uint8_t SCCB_Probe(void)
i2c_master_start(cmd); i2c_master_start(cmd);
i2c_master_write_byte(cmd, ( slave_addr << 1 ) | WRITE_BIT, ACK_CHECK_EN); i2c_master_write_byte(cmd, ( slave_addr << 1 ) | WRITE_BIT, ACK_CHECK_EN);
i2c_master_stop(cmd); i2c_master_stop(cmd);
esp_err_t ret = i2c_master_cmd_begin(SCCB_I2C_PORT, cmd, 1000 / portTICK_RATE_MS); esp_err_t ret = i2c_master_cmd_begin(sccb_i2c_port, cmd, 1000 / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd); i2c_cmd_link_delete(cmd);
if( ret == ESP_OK) { if( ret == ESP_OK) {
return slave_addr; return slave_addr;
@ -106,7 +123,7 @@ uint8_t SCCB_Read(uint8_t slv_addr, uint8_t reg)
i2c_master_write_byte(cmd, ( slv_addr << 1 ) | WRITE_BIT, ACK_CHECK_EN); i2c_master_write_byte(cmd, ( slv_addr << 1 ) | WRITE_BIT, ACK_CHECK_EN);
i2c_master_write_byte(cmd, reg, ACK_CHECK_EN); i2c_master_write_byte(cmd, reg, ACK_CHECK_EN);
i2c_master_stop(cmd); i2c_master_stop(cmd);
ret = i2c_master_cmd_begin(SCCB_I2C_PORT, cmd, 1000 / portTICK_RATE_MS); ret = i2c_master_cmd_begin(sccb_i2c_port, cmd, 1000 / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd); i2c_cmd_link_delete(cmd);
if(ret != ESP_OK) return -1; if(ret != ESP_OK) return -1;
cmd = i2c_cmd_link_create(); cmd = i2c_cmd_link_create();
@ -114,7 +131,7 @@ uint8_t SCCB_Read(uint8_t slv_addr, uint8_t reg)
i2c_master_write_byte(cmd, ( slv_addr << 1 ) | READ_BIT, ACK_CHECK_EN); i2c_master_write_byte(cmd, ( slv_addr << 1 ) | READ_BIT, ACK_CHECK_EN);
i2c_master_read_byte(cmd, &data, NACK_VAL); i2c_master_read_byte(cmd, &data, NACK_VAL);
i2c_master_stop(cmd); i2c_master_stop(cmd);
ret = i2c_master_cmd_begin(SCCB_I2C_PORT, cmd, 1000 / portTICK_RATE_MS); ret = i2c_master_cmd_begin(sccb_i2c_port, cmd, 1000 / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd); i2c_cmd_link_delete(cmd);
if(ret != ESP_OK) { if(ret != ESP_OK) {
ESP_LOGE(TAG, "SCCB_Read Failed addr:0x%02x, reg:0x%02x, data:0x%02x, ret:%d", slv_addr, reg, data, ret); 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)
i2c_master_write_byte(cmd, reg, ACK_CHECK_EN); i2c_master_write_byte(cmd, reg, ACK_CHECK_EN);
i2c_master_write_byte(cmd, data, ACK_CHECK_EN); i2c_master_write_byte(cmd, data, ACK_CHECK_EN);
i2c_master_stop(cmd); i2c_master_stop(cmd);
ret = i2c_master_cmd_begin(SCCB_I2C_PORT, cmd, 1000 / portTICK_RATE_MS); ret = i2c_master_cmd_begin(sccb_i2c_port, cmd, 1000 / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd); i2c_cmd_link_delete(cmd);
if(ret != ESP_OK) { if(ret != ESP_OK) {
ESP_LOGE(TAG, "SCCB_Write Failed addr:0x%02x, reg:0x%02x, data:0x%02x, ret:%d", slv_addr, reg, data, ret); ESP_LOGE(TAG, "SCCB_Write Failed addr:0x%02x, reg:0x%02x, data:0x%02x, ret:%d", slv_addr, reg, data, ret);
@ -151,7 +168,7 @@ uint8_t SCCB_Read16(uint8_t slv_addr, uint16_t reg)
i2c_master_write_byte(cmd, reg_u8[0], ACK_CHECK_EN); i2c_master_write_byte(cmd, reg_u8[0], ACK_CHECK_EN);
i2c_master_write_byte(cmd, reg_u8[1], ACK_CHECK_EN); i2c_master_write_byte(cmd, reg_u8[1], ACK_CHECK_EN);
i2c_master_stop(cmd); i2c_master_stop(cmd);
ret = i2c_master_cmd_begin(SCCB_I2C_PORT, cmd, 1000 / portTICK_RATE_MS); ret = i2c_master_cmd_begin(sccb_i2c_port, cmd, 1000 / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd); i2c_cmd_link_delete(cmd);
if(ret != ESP_OK) return -1; if(ret != ESP_OK) return -1;
cmd = i2c_cmd_link_create(); cmd = i2c_cmd_link_create();
@ -159,7 +176,7 @@ uint8_t SCCB_Read16(uint8_t slv_addr, uint16_t reg)
i2c_master_write_byte(cmd, ( slv_addr << 1 ) | READ_BIT, ACK_CHECK_EN); i2c_master_write_byte(cmd, ( slv_addr << 1 ) | READ_BIT, ACK_CHECK_EN);
i2c_master_read_byte(cmd, &data, NACK_VAL); i2c_master_read_byte(cmd, &data, NACK_VAL);
i2c_master_stop(cmd); i2c_master_stop(cmd);
ret = i2c_master_cmd_begin(SCCB_I2C_PORT, cmd, 1000 / portTICK_RATE_MS); ret = i2c_master_cmd_begin(sccb_i2c_port, cmd, 1000 / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd); i2c_cmd_link_delete(cmd);
if(ret != ESP_OK) { if(ret != ESP_OK) {
ESP_LOGE(TAG, "W [%04x]=%02x fail\n", reg, data); 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)
i2c_master_write_byte(cmd, reg_u8[1], ACK_CHECK_EN); i2c_master_write_byte(cmd, reg_u8[1], ACK_CHECK_EN);
i2c_master_write_byte(cmd, data, ACK_CHECK_EN); i2c_master_write_byte(cmd, data, ACK_CHECK_EN);
i2c_master_stop(cmd); i2c_master_stop(cmd);
ret = i2c_master_cmd_begin(SCCB_I2C_PORT, cmd, 1000 / portTICK_RATE_MS); ret = i2c_master_cmd_begin(sccb_i2c_port, cmd, 1000 / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd); i2c_cmd_link_delete(cmd);
if(ret != ESP_OK) { if(ret != ESP_OK) {
ESP_LOGE(TAG, "W [%04x]=%02x %d fail\n", reg, data, i++); ESP_LOGE(TAG, "W [%04x]=%02x %d fail\n", reg, data, i++);

4
examples/main/take_picture.c

@ -99,8 +99,8 @@ static camera_config_t camera_config = {
.pin_pwdn = CAM_PIN_PWDN, .pin_pwdn = CAM_PIN_PWDN,
.pin_reset = CAM_PIN_RESET, .pin_reset = CAM_PIN_RESET,
.pin_xclk = CAM_PIN_XCLK, .pin_xclk = CAM_PIN_XCLK,
.pin_sscb_sda = CAM_PIN_SIOD, .pin_sccb_sda = CAM_PIN_SIOD,
.pin_sscb_scl = CAM_PIN_SIOC, .pin_sccb_scl = CAM_PIN_SIOC,
.pin_d7 = CAM_PIN_D7, .pin_d7 = CAM_PIN_D7,
.pin_d6 = CAM_PIN_D6, .pin_d6 = CAM_PIN_D6,

53
test/test_camera.c

@ -6,6 +6,7 @@
#include "unity.h" #include "unity.h"
#include <mbedtls/base64.h> #include <mbedtls/base64.h>
#include "esp_log.h" #include "esp_log.h"
#include "driver/i2c.h"
#include "esp_camera.h" #include "esp_camera.h"
@ -105,11 +106,16 @@
#endif #endif
#define I2C_MASTER_SCL_IO 4 /*!< GPIO number used for I2C master clock */
#define I2C_MASTER_SDA_IO 5 /*!< GPIO number used for I2C master data */
#define I2C_MASTER_NUM 0 /*!< I2C master i2c port number, the number of i2c peripheral interfaces available will depend on the chip */
#define I2C_MASTER_FREQ_HZ 100000 /*!< I2C master clock frequency */
static const char *TAG = "test camera"; static const char *TAG = "test camera";
typedef void (*decode_func_t)(uint8_t *jpegbuffer, uint32_t size, uint8_t *outbuffer); typedef void (*decode_func_t)(uint8_t *jpegbuffer, uint32_t size, uint8_t *outbuffer);
static esp_err_t init_camera(uint32_t xclk_freq_hz, pixformat_t pixel_format, framesize_t frame_size, uint8_t fb_count) static esp_err_t init_camera(uint32_t xclk_freq_hz, pixformat_t pixel_format, framesize_t frame_size, uint8_t fb_count, int sccb_sda_gpio_num, int sccb_port)
{ {
framesize_t size_bak = frame_size; framesize_t size_bak = frame_size;
if (PIXFORMAT_JPEG == pixel_format && FRAMESIZE_SVGA > frame_size) { if (PIXFORMAT_JPEG == pixel_format && FRAMESIZE_SVGA > frame_size) {
@ -119,8 +125,9 @@ static esp_err_t init_camera(uint32_t xclk_freq_hz, pixformat_t pixel_format, fr
.pin_pwdn = PWDN_GPIO_NUM, .pin_pwdn = PWDN_GPIO_NUM,
.pin_reset = RESET_GPIO_NUM, .pin_reset = RESET_GPIO_NUM,
.pin_xclk = XCLK_GPIO_NUM, .pin_xclk = XCLK_GPIO_NUM,
.pin_sscb_sda = SIOD_GPIO_NUM, .pin_sccb_sda = sccb_sda_gpio_num, // If pin_sccb_sda is -1, sccb will use the already initialized i2c port specified by `sccb_i2c_port`.
.pin_sscb_scl = SIOC_GPIO_NUM, .pin_sccb_scl = SIOC_GPIO_NUM,
.sccb_i2c_port = sccb_port,
.pin_d7 = Y9_GPIO_NUM, .pin_d7 = Y9_GPIO_NUM,
.pin_d6 = Y8_GPIO_NUM, .pin_d6 = Y8_GPIO_NUM,
@ -226,7 +233,7 @@ static void camera_performance_test(uint32_t xclk_freq, uint32_t pic_num)
{ {
esp_err_t ret = ESP_OK; esp_err_t ret = ESP_OK;
//detect sensor information //detect sensor information
TEST_ESP_OK(init_camera(20000000, PIXFORMAT_RGB565, FRAMESIZE_QVGA, 2)); TEST_ESP_OK(init_camera(20000000, PIXFORMAT_RGB565, FRAMESIZE_QVGA, 2, SIOD_GPIO_NUM, -1));
sensor_t *s = esp_camera_sensor_get(); sensor_t *s = esp_camera_sensor_get();
camera_sensor_info_t *info = esp_camera_sensor_get_info(&s->id); camera_sensor_info_t *info = esp_camera_sensor_get_info(&s->id);
TEST_ASSERT_NOT_NULL(info); TEST_ASSERT_NOT_NULL(info);
@ -249,7 +256,7 @@ static void camera_performance_test(uint32_t xclk_freq, uint32_t pic_num)
for (; format_s <= format_e; format_s++) { for (; format_s <= format_e; format_s++) {
for (size_t i = 0; i <= max_size; i++) { for (size_t i = 0; i <= max_size; i++) {
ESP_LOGI(TAG, "\n\n===> Testing format:%s resolution: %d x %d <===", get_cam_format_name(*format_s), resolution[i].width, resolution[i].height); ESP_LOGI(TAG, "\n\n===> Testing format:%s resolution: %d x %d <===", get_cam_format_name(*format_s), resolution[i].width, resolution[i].height);
ret = init_camera(xclk_freq, *format_s, i, 2); ret = init_camera(xclk_freq, *format_s, i, 2, SIOD_GPIO_NUM, -1);
vTaskDelay(100 / portTICK_RATE_MS); vTaskDelay(100 / portTICK_RATE_MS);
if (ESP_OK != ret) { if (ESP_OK != ret) {
ESP_LOGW(TAG, "Testing init failed :-(, skip this item"); ESP_LOGW(TAG, "Testing init failed :-(, skip this item");
@ -276,7 +283,7 @@ static void camera_performance_test(uint32_t xclk_freq, uint32_t pic_num)
TEST_CASE("Camera driver init, deinit test", "[camera]") TEST_CASE("Camera driver init, deinit test", "[camera]")
{ {
uint64_t t1 = esp_timer_get_time(); uint64_t t1 = esp_timer_get_time();
TEST_ESP_OK(init_camera(20000000, PIXFORMAT_RGB565, FRAMESIZE_QVGA, 2)); TEST_ESP_OK(init_camera(20000000, PIXFORMAT_RGB565, FRAMESIZE_QVGA, 2, SIOD_GPIO_NUM, -1));
uint64_t t2 = esp_timer_get_time(); uint64_t t2 = esp_timer_get_time();
ESP_LOGI(TAG, "Camera init time %llu ms", (t2 - t1) / 1000); ESP_LOGI(TAG, "Camera init time %llu ms", (t2 - t1) / 1000);
@ -285,7 +292,7 @@ TEST_CASE("Camera driver init, deinit test", "[camera]")
TEST_CASE("Camera driver take RGB565 picture test", "[camera]") TEST_CASE("Camera driver take RGB565 picture test", "[camera]")
{ {
TEST_ESP_OK(init_camera(10000000, PIXFORMAT_RGB565, FRAMESIZE_QVGA, 2)); TEST_ESP_OK(init_camera(10000000, PIXFORMAT_RGB565, FRAMESIZE_QVGA, 2, SIOD_GPIO_NUM, -1));
vTaskDelay(500 / portTICK_RATE_MS); vTaskDelay(500 / portTICK_RATE_MS);
ESP_LOGI(TAG, "Taking picture..."); ESP_LOGI(TAG, "Taking picture...");
camera_fb_t *pic = esp_camera_fb_get(); camera_fb_t *pic = esp_camera_fb_get();
@ -301,7 +308,7 @@ TEST_CASE("Camera driver take RGB565 picture test", "[camera]")
TEST_CASE("Camera driver take YUV422 picture test", "[camera]") TEST_CASE("Camera driver take YUV422 picture test", "[camera]")
{ {
TEST_ESP_OK(init_camera(10000000, PIXFORMAT_YUV422, FRAMESIZE_QVGA, 2)); TEST_ESP_OK(init_camera(10000000, PIXFORMAT_YUV422, FRAMESIZE_QVGA, 2, SIOD_GPIO_NUM, -1));
vTaskDelay(500 / portTICK_RATE_MS); vTaskDelay(500 / portTICK_RATE_MS);
ESP_LOGI(TAG, "Taking picture..."); ESP_LOGI(TAG, "Taking picture...");
camera_fb_t *pic = esp_camera_fb_get(); camera_fb_t *pic = esp_camera_fb_get();
@ -317,7 +324,7 @@ TEST_CASE("Camera driver take YUV422 picture test", "[camera]")
TEST_CASE("Camera driver take JPEG picture test", "[camera]") TEST_CASE("Camera driver take JPEG picture test", "[camera]")
{ {
TEST_ESP_OK(init_camera(20000000, PIXFORMAT_JPEG, FRAMESIZE_QVGA, 2)); TEST_ESP_OK(init_camera(20000000, PIXFORMAT_JPEG, FRAMESIZE_QVGA, 2, SIOD_GPIO_NUM, -1));
vTaskDelay(500 / portTICK_RATE_MS); vTaskDelay(500 / portTICK_RATE_MS);
ESP_LOGI(TAG, "Taking picture..."); ESP_LOGI(TAG, "Taking picture...");
camera_fb_t *pic = esp_camera_fb_get(); camera_fb_t *pic = esp_camera_fb_get();
@ -484,6 +491,25 @@ static void img_jpeg_decode_test(uint16_t pic_index, uint16_t lib_index)
jpg_decode_test(lib_index, DECODE_RGB565, imgs[pic_index].buf, imgs[pic_index].length, imgs[pic_index].w, imgs[pic_index].h, 16); jpg_decode_test(lib_index, DECODE_RGB565, imgs[pic_index].buf, imgs[pic_index].length, imgs[pic_index].w, imgs[pic_index].h, 16);
} }
/**
* @brief i2c master initialization
*/
static esp_err_t i2c_master_init(int i2c_port)
{
i2c_config_t conf = {
.mode = I2C_MODE_MASTER,
.sda_io_num = I2C_MASTER_SDA_IO,
.scl_io_num = I2C_MASTER_SCL_IO,
.sda_pullup_en = GPIO_PULLUP_ENABLE,
.scl_pullup_en = GPIO_PULLUP_ENABLE,
.master.clk_speed = I2C_MASTER_FREQ_HZ,
};
i2c_param_config(i2c_port, &conf);
return i2c_driver_install(i2c_port, conf.mode, 0, 0, 0);
}
TEST_CASE("Conversions image 227x149 jpeg decode test", "[camera]") TEST_CASE("Conversions image 227x149 jpeg decode test", "[camera]")
{ {
img_jpeg_decode_test(0, 0); img_jpeg_decode_test(0, 0);
@ -498,3 +524,12 @@ TEST_CASE("Conversions image 480x320 jpeg decode test", "[camera]")
{ {
img_jpeg_decode_test(2, 0); img_jpeg_decode_test(2, 0);
} }
TEST_CASE("Camera driver uses an i2c port initialized by other devices test", "[camera]")
{
TEST_ESP_OK(i2c_master_init(I2C_MASTER_NUM));
TEST_ESP_OK(init_camera(20000000, PIXFORMAT_JPEG, FRAMESIZE_QVGA, 2, -1, I2C_MASTER_NUM));
vTaskDelay(500 / portTICK_RATE_MS);
TEST_ESP_OK(esp_camera_deinit());
TEST_ESP_OK(i2c_driver_delete(I2C_MASTER_NUM));
}

Loading…
Cancel
Save