Skip to content
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

i2c_ll_disable_intr_mask Core 0 panic'ed (LoadProhibited) when calling esp_camera_init multiple times #485

Closed
petercipov opened this issue Dec 8, 2022 · 3 comments

Comments

@petercipov
Copy link

petercipov commented Dec 8, 2022

Problem

I (24) boot: ESP-IDF v5.1-dev-2066-g7869f4e151 2nd stage bootloader
I (24) boot: compile time Dec  7 2022 20:47:47
I (25) boot: chip revision: v0.1
I (29) qio_mode: Enabling default flash chip QIO
I (34) boot.esp32s3: Boot SPI Speed : 80MHz
I (39) boot.esp32s3: SPI Mode       : QIO
I (43) boot.esp32s3: SPI Flash Size : 8MB
I (48) boot: Enabling RNG early entropy source...
I (54) boot: Partition Table:
I (57) boot: ## Label            Usage          Type ST Offset   Length
I (64) boot:  0 nvs              WiFi data        01 02 00009000 00006000
I (72) boot:  1 phy_init         RF data          01 01 0000f000 00001000
I (79) boot:  2 factory          factory app      00 00 00010000 00100000
I (87) boot: End of partition table
I (91) esp_image: segment 0: paddr=00010020 vaddr=3c040020 size=0f9b0h ( 63920) map
I (109) esp_image: segment 1: paddr=0001f9d8 vaddr=3fc94500 size=00640h (  1600) load
I (110) esp_image: segment 2: paddr=00020020 vaddr=42000020 size=30fd0h (200656) map
I (147) esp_image: segment 3: paddr=00050ff8 vaddr=3fc94b40 size=037d4h ( 14292) load
I (150) esp_image: segment 4: paddr=000547d4 vaddr=40374000 size=1040ch ( 66572) load
I (172) boot: Loaded app from partition at offset 0x10000
I (172) boot: Disabling RNG early entropy source...
I (173) octal_psram: vendor id    : 0x0d (AP)
I (178) octal_psram: dev id       : 0x02 (generation 3)
I (183) octal_psram: density      : 0x03 (64 Mbit)
I (189) octal_psram: good-die     : 0x01 (Pass)
I (194) octal_psram: Latency      : 0x01 (Fixed)
I (199) octal_psram: VCC          : 0x01 (3V)
I (204) octal_psram: SRF          : 0x01 (Fast Refresh)
I (210) octal_psram: BurstType    : 0x01 (Hybrid Wrap)
I (216) octal_psram: BurstLen     : 0x01 (32 Byte)
I (222) octal_psram: Readlatency  : 0x02 (10 cycles@Fixed)
I (228) octal_psram: DriveStrength: 0x00 (1/1)
W (233) PSRAM: DO NOT USE FOR MASS PRODUCTION! Timing parameters will be updated in future IDF version.
I (244) esp_psram: Found 8MB PSRAM device
I (248) esp_psram: Speed: 80MHz
I (252) cpu_start: Pro cpu up.
I (255) cpu_start: Starting app cpu, entry point is 0x40375548
0x40375548: call_start_cpu1 at /Users/petercipov/esp/esp-idf/components/esp_system/port/cpu_start.c:145

I (0) cpu_start: App cpu up.
I (583) esp_psram: SPI SRAM memory test OK
I (592) cpu_start: Pro cpu start user code
I (592) cpu_start: cpu freq: 240000000 Hz
I (592) cpu_start: Application information:
I (592) cpu_start: Project name:     main_test
I (592) cpu_start: App version:      38f24e5-dirty
I (592) cpu_start: Compile time:     Dec  7 2022 21:09:08
I (593) cpu_start: ELF file SHA256:  801fd3d13956245e...
I (593) cpu_start: ESP-IDF:          v5.1-dev-2066-g7869f4e151
I (593) cpu_start: Min chip rev:     v0.0
I (593) cpu_start: Max chip rev:     v0.99
I (593) cpu_start: Chip rev:         v0.1
I (594) heap_init: Initializing. RAM available for dynamic allocation:
I (594) heap_init: At 3FC98F40 len 000507D0 (321 KiB): D/IRAM
I (594) heap_init: At 3FCE9710 len 00005724 (21 KiB): STACK/DRAM
I (594) heap_init: At 600FE010 len 00001FF0 (7 KiB): RTCRAM
I (595) esp_psram: Adding pool of 8192K of PSRAM memory to heap allocator
I (596) spi_flash: detected chip: generic
I (596) spi_flash: flash io: qio
I (596) cpu_start: Starting scheduler on PRO CPU.
I (0) cpu_start: Starting scheduler on APP CPU.
Running Camera driver init, deinit test...
I (597) s3 ll_cam: DMA Channel=4
I (597) cam_hal: cam init ok
I (597) sccb: pin_sda 4 pin_scl 5
I (597) sccb: sccb_i2c_port=1

I (597) gpio: GPIO[43]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0
I (617) gpio: GPIO[44]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0
I (647) camera: Detected camera at address=0x30
I (647) camera: Detected OV2640 camera
I (647) camera: Camera PID=0x26 VER=0x42 MIDL=0x7f MIDH=0xa2
I (717) s3 ll_cam: node_size: 3840, nodes_per_line: 1, lines_per_node: 6
I (717) s3 ll_cam: dma_half_buffer_min:  3840, dma_half_buffer: 15360, lines_per_half_buffer: 24, dma_buffer_size: 30720
I (717) cam_hal: buffer_size: 30720, half_buffer_size: 15360, node_buffer_size: 3840, node_cnt: 8, total_cnt: 10
I (717) cam_hal: Allocating 153600 Byte frame buffer in PSRAM
I (717) cam_hal: Allocating 153600 Byte frame buffer in PSRAM
I (717) cam_hal: cam config ok
I (717) ov2640: Set PLL: clk_2x: 1, clk_div: 3, pclk_auto: 1, pclk_div: 8
/Users/petercipov/projects/aoe-firmware/components/aoe_camera/test/test_camera.c:155:Camera driver init, deinit test:PASS
Running Camera driver init 2, deinit test...
I (777) s3 ll_cam: DMA Channel=4
I (777) cam_hal: cam init ok
I (777) sccb: pin_sda 4 pin_scl 5
I (777) sccb: sccb_i2c_port=1

Guru Meditation Error: Core  0 panic'ed (LoadProhibited). Exception was unhandled.

Core  0 register dump:
PC      : 0x42019f19  PS      : 0x00060c33  A0      : 0x8200c623  A1      : 0x3fc9c800
0x42019f19: i2c_ll_disable_intr_mask at /Users/petercipov/esp/esp-idf/components/hal/esp32s3/include/hal/i2c_ll.h:229
 (inlined by) i2c_param_config at /Users/petercipov/esp/esp-idf/components/driver/i2c.c:760

A2      : 0x00000001  A3      : 0x3fc9c840  A4      : 0x00000000  A5      : 0x0000000b
A6      : 0x3fc94d0c  A7      : 0x00000000  A8      : 0x82019f14  A9      : 0x3fc9c7d0
A10     : 0x00000001  A11     : 0x3fc987b0  A12     : 0x00060c20  A13     : 0x00060c23
A14     : 0x00000001  A15     : 0x0000cdcd  SAR     : 0x00000005  EXCCAUSE: 0x0000001c
EXCVADDR: 0x00000028  LBEG    : 0x400556d5  LEND    : 0x400556e5  LCOUNT  : 0xfffffffe


Backtrace: 0x42019f16:0x3fc9c800 0x4200c620:0x3fc9c830 0x4200b666:0x3fc9c880 0x4200b8b8:0x3fc9c8d0 0x42002272:0x3fc9c910 0x420022dc:0x3fc9c9b0 0x420085de:0x3fc9c9d0 0x4200871d:0x3fc9ca00 0x4200878e:0x3fc9ca20 0x42014929:0x3fc9ca40 0x420308c8:0x3fc9ca60 0x4037e739:0x3fc9ca80
0x42019f16: i2c_ll_disable_intr_mask at /Users/petercipov/esp/esp-idf/components/hal/esp32s3/include/hal/i2c_ll.h:229
 (inlined by) i2c_param_config at /Users/petercipov/esp/esp-idf/components/driver/i2c.c:760
0x4200c620: SCCB_Init at /Users/petercipov/projects/aoe-firmware/components/esp32-camera/driver/sccb.c:68
0x4200b666: camera_probe at /Users/petercipov/projects/aoe-firmware/components/esp32-camera/driver/esp_camera.c:168 (discriminator 15)
0x4200b8b8: esp_camera_init at /Users/petercipov/projects/aoe-firmware/components/esp32-camera/driver/esp_camera.c:282
0x42002272: init_camera at /Users/petercipov/projects/aoe-firmware/components/aoe_camera/test/test_camera.c:145
0x420022dc: test_func_162 at /Users/petercipov/projects/aoe-firmware/components/aoe_camera/test/test_camera.c:164
0x420085de: unity_default_test_run at /Users/petercipov/esp/esp-idf/components/unity/unity_runner.c:70
0x4200871d: unity_run_single_test at /Users/petercipov/esp/esp-idf/components/unity/unity_runner.c:117
0x4200878e: unity_run_all_tests at /Users/petercipov/esp/esp-idf/components/unity/unity_runner.c:176 (discriminator 3)
0x42014929: app_main at /Users/petercipov/projects/aoe-firmware/test/main/main_test.cc:6
0x420308c8: main_task at /Users/petercipov/esp/esp-idf/components/freertos/FreeRTOS-Kernel/portable/port_common.c:131
0x4037e739: vPortTaskWrapper at /Users/petercipov/esp/esp-idf/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c:154

Steps to reproduce

ESP-IDF v5.1-dev-2066-g7869f4e151
ESP32_S3_EYE v2.2
esp32-camera git hash 9e8d7cd
run simple init deinit test scenario twice (example taken from this repo unit test and stripped to minimum)

#include "unity.h"
#include "esp_log.h"
#include "esp_camera.h"


#define BOARD_CAMERA_MODEL_ESP32_S3_EYE 1

// WROVER-KIT PIN Map
#if BOARD_WROVER_KIT

#define PWDN_GPIO_NUM -1  //power down is not used
#define RESET_GPIO_NUM -1 //software reset will be performed
#define XCLK_GPIO_NUM 21
#define SIOD_GPIO_NUM 26
#define SIOC_GPIO_NUM 27

#define Y9_GPIO_NUM 35
#define Y8_GPIO_NUM 34
#define Y7_GPIO_NUM 39
#define Y6_GPIO_NUM 36
#define Y5_GPIO_NUM 19
#define Y4_GPIO_NUM 18
#define Y3_GPIO_NUM 5
#define Y2_GPIO_NUM 4
#define VSYNC_GPIO_NUM 25
#define HREF_GPIO_NUM 23
#define PCLK_GPIO_NUM 22

// ESP32Cam (AiThinker) PIN Map
#elif BOARD_ESP32CAM_AITHINKER

#define PWDN_GPIO_NUM 32
#define RESET_GPIO_NUM -1 //software reset will be performed
#define XCLK_GPIO_NUM 0
#define SIOD_GPIO_NUM 26
#define SIOC_GPIO_NUM 27

#define Y9_GPIO_NUM 35
#define Y8_GPIO_NUM 34
#define Y7_GPIO_NUM 39
#define Y6_GPIO_NUM 36
#define Y5_GPIO_NUM 21
#define Y4_GPIO_NUM 19
#define Y3_GPIO_NUM 18
#define Y2_GPIO_NUM 5
#define VSYNC_GPIO_NUM 25
#define HREF_GPIO_NUM 23
#define PCLK_GPIO_NUM 22

#elif BOARD_CAMERA_MODEL_ESP32S2

#define PWDN_GPIO_NUM     -1
#define RESET_GPIO_NUM    -1

#define VSYNC_GPIO_NUM    21
#define HREF_GPIO_NUM     38
#define PCLK_GPIO_NUM     11
#define XCLK_GPIO_NUM     40

#define SIOD_GPIO_NUM     17
#define SIOC_GPIO_NUM     18

#define Y9_GPIO_NUM       39
#define Y8_GPIO_NUM       41
#define Y7_GPIO_NUM       42
#define Y6_GPIO_NUM       12
#define Y5_GPIO_NUM       3
#define Y4_GPIO_NUM       14
#define Y3_GPIO_NUM       37
#define Y2_GPIO_NUM       13

#elif BOARD_CAMERA_MODEL_ESP32_S3_EYE

#define PWDN_GPIO_NUM     43
#define RESET_GPIO_NUM    44

#define VSYNC_GPIO_NUM    6
#define HREF_GPIO_NUM     7
#define PCLK_GPIO_NUM     13
#define XCLK_GPIO_NUM     15

#define SIOD_GPIO_NUM     4
#define SIOC_GPIO_NUM     5

#define Y9_GPIO_NUM       16
#define Y8_GPIO_NUM       17
#define Y7_GPIO_NUM       18
#define Y6_GPIO_NUM       12
#define Y5_GPIO_NUM       11
#define Y4_GPIO_NUM       10
#define Y3_GPIO_NUM       9
#define Y2_GPIO_NUM       8

#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 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;
    if (PIXFORMAT_JPEG == pixel_format && FRAMESIZE_SVGA > frame_size) {
        frame_size = FRAMESIZE_HD;
    }
    camera_config_t camera_config = {
        .pin_pwdn = PWDN_GPIO_NUM,
        .pin_reset = RESET_GPIO_NUM,
        .pin_xclk = XCLK_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_sccb_scl = SIOC_GPIO_NUM,
        .sccb_i2c_port = sccb_port,

        .pin_d7 = Y9_GPIO_NUM,
        .pin_d6 = Y8_GPIO_NUM,
        .pin_d5 = Y7_GPIO_NUM,
        .pin_d4 = Y6_GPIO_NUM,
        .pin_d3 = Y5_GPIO_NUM,
        .pin_d2 = Y4_GPIO_NUM,
        .pin_d1 = Y3_GPIO_NUM,
        .pin_d0 = Y2_GPIO_NUM,
        .pin_vsync = VSYNC_GPIO_NUM,
        .pin_href = HREF_GPIO_NUM,
        .pin_pclk = PCLK_GPIO_NUM,

        //EXPERIMENTAL: Set to 16MHz on ESP32-S2 or ESP32-S3 to enable EDMA mode
        .xclk_freq_hz = xclk_freq_hz,
        .ledc_timer = LEDC_TIMER_0,
        .ledc_channel = LEDC_CHANNEL_0,

        .pixel_format = pixel_format, //YUV422,GRAYSCALE,RGB565,JPEG
        .frame_size = frame_size,    //QQVGA-UXGAQQVGA-UXGA, For ESP32, do not use sizes above QVGA when not JPEG. The performance of the ESP32-S series has improved a lot, but JPEG mode always gives better frame rates.

        .jpeg_quality = 12, //0-63, for OV series camera sensors, lower number means higher quality
        .fb_count = fb_count,       //When jpeg mode is used, if fb_count more than one, the driver will work in continuous mode.
        .grab_mode = CAMERA_GRAB_WHEN_EMPTY
    };

    //initialize the camera
    esp_err_t ret = esp_camera_init(&camera_config);

    if (ESP_OK == ret && PIXFORMAT_JPEG == pixel_format && FRAMESIZE_SVGA > size_bak) {
        sensor_t *s = esp_camera_sensor_get();
        s->set_framesize(s, size_bak);
    }

    return ret;
}

TEST_CASE("Camera driver init, deinit test", "[camera]")
{
    TEST_ESP_OK(init_camera(20000000, PIXFORMAT_RGB565, FRAMESIZE_QVGA, 2, SIOD_GPIO_NUM, -1));

    TEST_ESP_OK(esp_camera_deinit());
}

TEST_CASE("Camera driver init 2, deinit test", "[camera]")
{
    TEST_ESP_OK(init_camera(20000000, PIXFORMAT_RGB565, FRAMESIZE_QVGA, 2, SIOD_GPIO_NUM, -1));

    TEST_ESP_OK(esp_camera_deinit());
}

Expected behaviour

core does not crash
camara is initialized/deinitialized multiple times if needed

@v44r
Copy link

v44r commented Jan 6, 2023

Same here... and I suppose this is the only way to change pixformat, because sensor->set_pixformat causes problems with the frame buffer size; either "cam_hal: FB-SIZE: 7680 != 153600" when going from RGB565 to JPEG or "cam_hal: NO-SOI." when going from JPEG to RGB565.

@filipbudisa
Copy link

Hey there! Had the same problem and after some debugging, I think I found the source of the crash.

It seems esp_camera_deinit ends up with a call to i2c_driver_delete, which deletes the I2C driver's p_i2c_obj[i2c_num] object. As far as I can tell, the object isn't created again anywhere by the time esp_camera_init ends up at the i2c_param_config call, which tries to read from the now deleted p_i2c_obj[i2c_num]. This is on IDF v5.1.0 (commit 4c98bee ).

A workaround is to manually initialize the i2c driver once, and pass the i2c port by camera_config.sccb_i2c_port. Something like this:

	ESP_ERROR_CHECK(i2c_driver_install(I2C_NUM_0, I2C_MODE_MASTER, 0, 0, 0));

	i2c_config_t conf = {};
	conf.mode = I2C_MODE_MASTER;
	conf.sda_io_num = cam_pin_sda;
	conf.scl_io_num = cam_pin_scl;
	conf.sda_pullup_en = GPIO_PULLUP_ENABLE;
	conf.scl_pullup_en = GPIO_PULLUP_ENABLE;
	conf.master.clk_speed = CONFIG_SCCB_CLK_FREQ;
	ESP_ERROR_CHECK(i2c_param_config(I2C_NUM_0, &conf));

Replace cam_pin_sda and cam_pin_scl with your i2c pins.
Camera config then needs to be changed like this:

	camera_config.pin_sccb_sda = -1;
	camera_config.pin_sccb_scl = -1;
	config.sccb_i2c_port = I2C_NUM_0;

pin_sccb_sda is set to -1 so the camera driver uses the already initialized port. Change I2C_NUM_0 to I2C_NUM_1 in both the camera config and i2c config if you wish to use the other i2c port.

@petercipov
Copy link
Author

@filipbudisa I have checked whether this is bug in esp-idf i2c library. Indeed it was. In latest master (5.1.x) branch it was already fixed.

espressif/esp-idf#10163

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants