espressif / esp-idf

Espressif IoT Development Framework. Official development framework for Espressif SoCs.
Apache License 2.0
13.61k stars 7.27k forks source link

PR fixing I2C causes esp32-camera not able to probe the camera (IDFGH-9956) #11249

Closed wuyuanyi135 closed 1 year ago

wuyuanyi135 commented 1 year ago

Answers checklist.

IDF version.

3bc3f8720974da676192569e885867095f3808fd (fauty)

Operating System used.

Windows

How did you build your project?

Command line with Make

If you are using Windows, please specify command line type.

PowerShell

Development Kit.

ESP32-S3-WROOM-1-N16R2

Power Supply used.

USB

What is the expected behavior?

commit before 3bc3f8720974da676192569e885867095f3808fd did not cause the error:

I (00:19:00.522) camera: Detected camera at address=0x3c
I (00:19:00.523) camera: Detected OV5640 camera
I (00:19:00.523) camera: Camera PID=0x5640 VER=0x00 MIDL=0x00 MIDH=0x00
I (00:19:01.171) cam_hal: buffer_size: 16384, half_buffer_size: 1024, node_buffer_size: 1024, node_cnt: 16, total_cnt: 375
I (00:19:01.172) cam_hal: Allocating 384000 Byte frame buffer in PSRAM
I (00:19:01.172) cam_hal: Allocating 384000 Byte frame buffer in PSRAM
I (00:19:01.173) cam_hal: cam config ok
I (00:19:01.178) ov5640: Set PLL: bypass: 0, multiplier: 200, sys_div: 4, pre_div: 2, root_2x: 0, pclk_root_div: 2, pclk_manual: 1, pclk_div: 4
I (00:19:01.179) ov5640: Calculated XVCLK: 8000000 Hz, REFIN: 4000000 Hz, VCO: 800000000 Hz, PLL_CLK: 80000000 Hz, SYSCLK: 20000000 Hz, PCLK: 5000000 Hz
I (00:19:01.193) ov5640: Set PLL: bypass: 0, multiplier: 200, sys_div: 4, pre_div: 2, root_2x: 0, pclk_root_div: 2, pclk_manual: 1, pclk_div: 4
I (00:19:01.194) ov5640: Calculated XVCLK: 8000000 Hz, REFIN: 4000000 Hz, VCO: 800000000 Hz, PLL_CLK: 80000000 Hz, SYSCLK: 20000000 Hz, PCLK: 5000000 Hz

What is the actual behavior?

after commit 3bc3f8720974da676192569e885867095f3808fd

I (00:21:21.531) s3 ll_cam: DMA Channel=4
I (00:21:21.531) cam_hal: cam init ok
I (00:21:21.532) camera: Detected camera at address=0x3c
I (00:21:21.533) ov5640: Mismatch PID=0x0
E (00:21:21.533) camera: Detected camera not supported.
E (00:21:21.533) camera: Camera probe failed with error 0x106(ESP_ERR_NOT_SUPPORTED)

Steps to reproduce.

Debug Logs.

No response

More Information.

Camera configuration:

camera_config_t camera_config = {
      -1, -1, 44, {-1}, {-1}, 4, 5, 6, 7, 15, 16, 40, 41, 1, 2, 42, 8'000'000,
      LEDC_TIMER_0, LEDC_CHANNEL_0,
      PIXFORMAT_JPEG, FRAMESIZE_UXGA, 12,
      2, CAMERA_FB_IN_PSRAM, CAMERA_GRAB_WHEN_EMPTY,
      i2c1->get_i2c_port()}
o-marshmallow commented 1 year ago

Hello @wuyuanyi135 ,

Are you using an Espressif board, such as the ESP32-S3-EYE or your own custom board? I don't have the ov5640 camera here to test in the same conditions, I did test the I2C changes on an ESP32-S3 and a simpler device (GPIO expander with read/write/write-read, all worked)

I see from your config that you are using I2C Port 1. How are you configuring/initializing it? What frequency are you using? Internal or external pull-ups?

I see that the camera could be detected. Do you have a logic analyzer to check what is going on the bus during an I2C read?

wuyuanyi135 commented 1 year ago

Hi @o-marshmallow

It's my own board designed for a product. I used i2c port 1 with 400khz frequency and external pull-ups. I bisected the commit log and discovered the above-mentioned commit caused the issue.

I also had a i2c gpio expander (AW9523) on the same bus and it worked properly. It's the camera probe on SCCB bus that caused the issue.

Afaik, the esp32-camera uses the i2c periph for the SCCB protocol. I am not sure if they were using some low-level functions to emulate the protocol, which causes the invalid operations after this commit?

Sorry, I don't have a logic analyzer at this moment. Can you test the espressif board with camera? I think any DVP camera like ov2640 should reproduce the issue

o-marshmallow commented 1 year ago

Hi @wuyuanyi135 ,

Thanks for the info! I was able to get an ESP32-S3-EYE on my end which is equipped with an OV2640 camera, I tested it with the esp_camera example from ESP-BSP (https://github.com/espressif/esp-bsp/tree/master/examples/display_camera) and it worked successfully on my end, even with the latest IDF master, which includes the I2C SDA timing fix. I tested several time to make sure it's stable and yes it is.

Here is the output I got:

I (505) cam_hal: cam init ok
I (515) camera: Detected camera at address=0x30
I (515) camera: Detected OV2640 camera
I (515) camera: Camera PID=0x26 VER=0x42 MIDL=0x7f MIDH=0xa2
I (565) s3 ll_cam: node_size: 3072, nodes_per_line: 1, lines_per_node: 16
[...]

In my opinion, the problem is a timing issue, so it may be related to the transition delays. In fact, the fix I pushed lets the I2C hardware component module sample the SDA level at the middle of the high-period of SCL line.

Before the fix, the SDA sample timing had an invalid value which was larger than the SCL high-period duration. Thus, I suspect that SDA sampling was triggered at the end of the high-period, so the transition SDA line from low to high had more time that now. (twice more time)

To verify the hypothesis, can you try reducing the frequency a bit until you reach a one that is stable enough to communicate with the camera? (370KHz? 350KHz?)

Also, most importantly, which value did you choosing for your pull-up resistors?

wuyuanyi135 commented 1 year ago

@o-marshmallow Thanks for your clear explanation about how the fix works. If I understand correctly, the SDA was sampled at a time point that was later than when it should have sampled. It was working for me because of high line capacitance, so when sampled the value was correct, as if the frequency was a bit lower. After the fix was applied, because the sampling occurs eariler, the value SDA was not still on the rising edge, causing invalid sample?

I am using 2.2K Ohms pullups to 3.3V for both lines. There are three slave devices on the bus: AW9523 (3pF), INA219 (6pF), OV5640 (10pF). The board was about 7cm so I don't really think the frequency would cause the trouble. But I will give it a try to reduce the frequency.

o-marshmallow commented 1 year ago

@wuyuanyi135 This is my hypothesis yes. Now we need to verify it. In fact, 2.2KOhm pull-ups sounds good for 400KHz and your capacitance, that is also the value used on the ESP32-S3-EYE's pull-ups.

Ideally having an oscilloscope would help a lot to see the slope of SDA and SCL lines going high and low.

Reducing the frequency would give more time to the slaves to set SDA line. Another trick to modify the SDA sample time would be to use I2C1.sda_sample.sda_sample_time += n. Of course this is just a workaround to debug the problem, not a solution. You could try lowering resistor values too, but that's slower to put in place that the previous software tricks.

wuyuanyi135 commented 1 year ago

In the latest manufacturered unit the issue is gone. Probably electronic issue in my previous board. Though not sure if there has been some change to the I2C component since the issue. Close for now.

o-marshmallow commented 1 year ago

@wuyuanyi135 Good to hear! No changes from our side on the I2C so far, may be a hardware issue indeed.