LoadProhibited Error with MAX30102 Driver

tenshioxide
Posts: 3
Joined: Wed Sep 25, 2024 1:45 am

LoadProhibited Error with MAX30102 Driver

Postby tenshioxide » Wed Sep 25, 2024 2:01 am

Hi! I'm new to the ESP-IDF platform. I have an old driver for the MAX30102 sensor that was written for the STM32 series that I want to modify to work on the ESP32.

I've spent several days trying to fix a LoadProhibited error to no avail. I wrote two functions, max30102_read and max30102_read_fifo that use i2c_master API's to read/write. I created a global variable polling_num for debugging purposes. When polling_num reaches 2, the task hangs and the watchdog timer reboots the system. When I disabled the watchdog timer, polling_num goes to 3 then a LoadProhibited error occurs.

Would greatly appreciate help.
  1. void max30102_read_fifo(i2c_master_dev_handle_t *dev_handle)
  2. {
  3.     // First transaction: Get the FIFO_WR_PTR
  4.     uint8_t wr_ptr = 0, rd_ptr = 0;
  5.  
  6.     max30102_read(dev_handle, MAX30102_FIFO_RD_PTR, &rd_ptr, 1);
  7.     max30102_read(dev_handle, MAX30102_FIFO_WR_PTR, &wr_ptr, 1);
  8.  
  9.     vTaskDelay(pdMS_TO_TICKS(100));
  10.  
  11.     int8_t num_samples;
  12.  
  13.     printf("wr_ptr: %d, rd_ptr: %d\n", wr_ptr, rd_ptr);
  14.  
  15.     num_samples = (int8_t)wr_ptr - (int8_t)rd_ptr;
  16.     if (num_samples < 1)
  17.     {
  18.         num_samples += 32;
  19.     }
  20.  
  21.     // Second transaction: Read NUM_SAMPLES_TO_READ samples from the FIFO
  22.     for (int8_t i = 0; i < num_samples; i++)
  23.     {
  24.         uint8_t sample[6];
  25.         max30102_read(dev_handle, MAX30102_FIFO_DATA, sample, 6);
  26.  
  27.         uint32_t ir_sample = ((uint32_t)(sample[0] << 16) | (uint32_t)(sample[1] << 8) | (uint32_t)(sample[2])) & 0x3ffff;
  28.         uint32_t red_sample = ((uint32_t)(sample[3] << 16) | (uint32_t)(sample[4] << 8) | (uint32_t)(sample[5])) & 0x3ffff;
  29.         printf("%ld ", ir_sample);
  30.     }
  31.     printf("\n");
  32. }
  1. esp_err_t max30102_read(i2c_master_dev_handle_t *dev_handle, uint8_t reg, uint8_t *buf, uint16_t buflen)
  2. {
  3.     vTaskDelay(pdMS_TO_TICKS(10));
  4.  
  5.     uint8_t reg_addr = reg;
  6.  
  7.     // Transmit the register address over I2C
  8.     esp_err_t res = i2c_master_transmit(*dev_handle, &reg_addr, 1, -1);
  9.     if (res != ESP_OK) {
  10.         printf("I2C write error: %s\n", esp_err_to_name(res));
  11.         return res;
  12.     }
  13.  
  14.     // Receive data from the I2C device
  15.     res = i2c_master_receive(*dev_handle, buf, buflen, -1);
  16.     res = ESP_OK;
  17.     if (res != ESP_OK) {
  18.         printf("I2C read error: %s\n", esp_err_to_name(res));
  19.     }
  20.  
  21.     vTaskDelay(pdMS_TO_TICKS(10));
  22.  
  23.     return res;
  24. }
  1. rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
  2. configsip: 0, SPIWP:0xee
  3. clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
  4. mode:DIO, clock div:2
  5. load:0x3fff0030,len:7176
  6. load:0x40078000,len:15564
  7. ho 0 tail 12 room 4
  8. load:0x40080400,len:4
  9. --- 0x40080400: _init at ??:?
  10.  
  11. load:0x40080404,len:3904
  12. entry 0x40080640
  13. I (31) boot: ESP-IDF v5.3.1-244-g4d0db7045d 2nd stage bootloader
  14. I (31) boot: compile time Sep 23 2024 22:36:41
  15. I (33) boot: Multicore bootloader
  16. I (37) boot: chip revision: v3.1
  17. I (41) boot.esp32: SPI Speed      : 40MHz
  18. I (45) boot.esp32: SPI Mode       : DIO
  19. I (50) boot.esp32: SPI Flash Size : 2MB
  20. I (54) boot: Enabling RNG early entropy source...
  21. I (60) boot: Partition Table:
  22. I (63) boot: ## Label            Usage          Type ST Offset   Length
  23. I (71) boot:  0 nvs              WiFi data        01 02 00009000 00006000
  24. I (78) boot:  1 phy_init         RF data          01 01 0000f000 00001000
  25. I (86) boot:  2 factory          factory app      00 00 00010000 00100000
  26. I (93) boot: End of partition table
  27. I (97) esp_image: segment 0: paddr=00010020 vaddr=3f400020 size=0abbch ( 43964) map
  28. I (121) esp_image: segment 1: paddr=0001abe4 vaddr=3ffb0000 size=02348h (  9032) load
  29. I (124) esp_image: segment 2: paddr=0001cf34 vaddr=40080000 size=030e4h ( 12516) load
  30. I (132) esp_image: segment 3: paddr=00020020 vaddr=400d0020 size=16e7ch ( 93820) map
  31. I (167) esp_image: segment 4: paddr=00036ea4 vaddr=400830e4 size=09e40h ( 40512) load
  32. I (190) boot: Loaded app from partition at offset 0x10000
  33. I (190) boot: Disabling RNG early entropy source...
  34. I (202) cpu_start: Multicore app
  35. I (211) cpu_start: Pro cpu start user code
  36. I (211) cpu_start: cpu freq: 160000000 Hz
  37. I (211) app_init: Application information:
  38. I (214) app_init: Project name:     hth-test-stuff
  39. I (219) app_init: App version:      863dd75-dirty
  40. I (224) app_init: Compile time:     Sep 23 2024 22:36:20
  41. I (230) app_init: ELF file SHA256:  c12088eff...
  42. I (236) app_init: ESP-IDF:          v5.3.1-244-g4d0db7045d
  43. I (242) efuse_init: Min chip rev:     v0.0
  44. I (247) efuse_init: Max chip rev:     v3.99
  45. I (252) efuse_init: Chip rev:         v3.1
  46. I (257) heap_init: Initializing. RAM available for dynamic allocation:
  47. I (264) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM
  48. I (270) heap_init: At 3FFB2C10 len 0002D3F0 (180 KiB): DRAM
  49. I (276) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
  50. I (282) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
  51. I (289) heap_init: At 4008CF24 len 000130DC (76 KiB): IRAM
  52. I (296) spi_flash: detected chip: generic
  53. I (300) spi_flash: flash io: dio
  54. W (303) spi_flash: Detected size(4096k) larger than the size in the binary image header(2048k). Using the size in the binary image header.
  55. I (317) main_task: Started on CPU0
  56. I (327) main_task: Calling app_main()
  57. start of task
  58. D (327) i2c.common: new bus(0) at 0x3ffaff70
  59. I (327) gpio: GPIO[21]| InputEn: 1| OutputEn: 1| OpenDrain: 1| Pullup: 1| Pulldown: 0| Intr:0
  60. I (337) gpio: GPIO[22]| InputEn: 1| OutputEn: 1| OpenDrain: 1| Pullup: 1| Pulldown: 0| Intr:0
  61. D (347) i2c.common: bus clock source frequency: 80000000hz
  62. W (347) i2c.master: Please note i2c asynchronous is only used for specific scenario currently. It's experimental for other users because user cannot get bus error from API. And It's not compatible with ``i2c_master_probe``. If user makes sure there won't be any error on bus and tested with no problem, this message can be ignored.
  63. bus: ESP_OK
  64. device: ESP_OK
  65. led pulse width set
  66. sampling rate set
  67. Writing to register 0x0A with data 0x11
  68. ADC resolution set successfully
  69. adc resolution set
  70. led current 1 set
  71. led current 2 set
  72. led mode set
  73. fifo configured
  74. done configuration
  75. wr_ptr: 23, rd_ptr: 5
  76. 122032 122026 122140 122033 122066 122126 122066 122036 122048 122051 122161 122045 122269 122059 122058 122180 122226 122011
  77. polling_num: 1
  78. wr_ptr: 26, rd_ptr: 22
  79. 122075 122157 122177 122228
  80. polling_num: 2
  81. wr_ptr: 31, rd_ptr: 26
  82. 122146 122042 122076 122039 122039
  83. polling_num: 3
  84. Guru Meditation Error: Core  0 panic'ed (LoadProhibited). Exception was unhandled.
  85.  
  86. Core  0 register dump:
  87. PC      : 0x400da203  PS      : 0x00060c30  A0      : 0x800d6278  A1      : 0x3ffb3df0
  88. --- 0x400da203: i2c_master_transmit at C:/Users/benja/esp/v5.3/esp-idf/components/esp_driver_i2c/i2c_master.c:1073
  89.  
  90. A2      : 0x3ffb9258  A3      : 0x3ffb3e50  A4      : 0x00000001  A5      : 0xffffffff
  91. A6      : 0x3ffb3d50  A7      : 0xff000000  A8      : 0x00000000  A9      : 0x00001800
  92. A10     : 0x00000800  A11     : 0x00000000  A12     : 0x00000030  A13     : 0x3ffb3e30
  93. A14     : 0x0000021a  A15     : 0x00000003  SAR     : 0x00000004  EXCCAUSE: 0x0000001c
  94. EXCVADDR: 0x000000a1  LBEG    : 0x4000c46c  LEND    : 0x4000c477  LCOUNT  : 0x00000000
  95. --- 0x4000c46c: memset in ROM
  96. 0x4000c477: memset in ROM
  97.  
  98.  
  99.  
  100. Backtrace: 0x400da200:0x3ffb3df0 0x400d6275:0x3ffb3e50 0x400d6504:0x3ffb3e80 0x400d6671:0x3ffb3eb0 0x400e63e9:0x3ffb3f10 0x40086335:0x3ffb3f30
  101. --- 0x400da200: i2c_master_transmit at C:/Users/benja/esp/v5.3/esp-idf/components/esp_driver_i2c/i2c_master.c:1067
  102. 0x400d6275: max30102_read at C:/vscode-esp32-workspace/hth-test-stuff/main/main.c:61
  103. 0x400d6504: max30102_read_fifo at C:/vscode-esp32-workspace/hth-test-stuff/main/main.c:221
  104. 0x400d6671: app_main at C:/vscode-esp32-workspace/hth-test-stuff/main/main.c:49
  105. 0x400e63e9: main_task at C:/Users/benja/esp/v5.3/esp-idf/components/freertos/app_startup.c:208
  106. 0x40086335: vPortTaskWrapper at C:/Users/benja/esp/v5.3/esp-idf/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c:134
Last edited by tenshioxide on Sat Sep 28, 2024 6:48 pm, edited 1 time in total.

MicroController
Posts: 1725
Joined: Mon Oct 17, 2022 7:38 pm
Location: Europe, Germany

Re: LoadProhibited Error with MAX30102 Driver

Postby MicroController » Wed Sep 25, 2024 11:14 am

Probably a corrput i2c_master_dev_handle_t *dev_handle. (There's no need to take a pointer to the i2c_master_dev_handle_t as argument, just take/pass the i2c_master_dev_handle_t by value.)

Can you show the code that 1) initializes the device handle and 2) calls max30102_read_fifo ()?

tenshioxide
Posts: 3
Joined: Wed Sep 25, 2024 1:45 am

Re: LoadProhibited Error with MAX30102 Driver

Postby tenshioxide » Wed Sep 25, 2024 8:19 pm

Sure!
  1. void app_main(void)
  2. {
  3.     printf("start of task\n");
  4.  
  5.     i2c_master_bus_config_t i2c_bus_config = {
  6.         .i2c_port = 0,
  7.         .sda_io_num = SDA_GPIO,
  8.         .scl_io_num = SCL_GPIO,
  9.         .clk_source = I2C_CLK_SRC_DEFAULT,
  10.         .glitch_ignore_cnt = 7,
  11.         .intr_priority = 0,
  12.         .trans_queue_depth = 100,
  13.         .flags.enable_internal_pullup = true,
  14.     };
  15.  
  16.     i2c_master_bus_handle_t i2c_bus_handle;
  17.    
  18.     esp_err_t res = ( i2c_new_master_bus(&i2c_bus_config, &i2c_bus_handle) ); // create master bus
  19.     printf("bus: %s\n", esp_err_to_name(res));
  20.  
  21.     i2c_device_config_t i2c_max30102_config = {
  22.         .dev_addr_length = I2C_ADDR_BIT_LEN_7,
  23.         .device_address = ADDR, // max30102 i2c write address
  24.         .scl_speed_hz = I2C_FREQ_HZ
  25.     };
  26.  
  27.     i2c_master_dev_handle_t i2c_max30102_handle;
  28.     esp_err_t res2 = ( i2c_master_bus_add_device(i2c_bus_handle, &i2c_max30102_config, &i2c_max30102_handle) ); // add max30102 to master bus as a slave device
  29.     printf("device: %s\n", esp_err_to_name(res2));
  30.  
  31.     max30102_config(&i2c_max30102_handle);
  32.  
  33.     while (1) {
  34.         vTaskDelay(pdMS_TO_TICKS(1000));
  35.         polling_num++;  
  36.         max30102_read_fifo(&i2c_max30102_handle);
  37.         printf("polling_num: %ld\n", polling_num);
  38.     }
  39. }

tenshioxide
Posts: 3
Joined: Wed Sep 25, 2024 1:45 am

Re: LoadProhibited Error with MAX30102 Driver

Postby tenshioxide » Thu Sep 26, 2024 12:39 am

I passed the handle by value instead of passing a pointer and I still run into the same issue. After further testing, it seems once the FIFO fills up with 32 samples and the ESP tries to read it the program crashes.
Last edited by tenshioxide on Sat Sep 28, 2024 6:49 pm, edited 1 time in total.

MicroController
Posts: 1725
Joined: Mon Oct 17, 2022 7:38 pm
Location: Europe, Germany

Re: LoadProhibited Error with MAX30102 Driver

Postby MicroController » Thu Sep 26, 2024 12:42 pm

Hmm. Can't find anything wrong in your code.
Yet there seems to be some memory corruption to be happening.
Maybe try increasing the main task's stack space by a kilobyte or two (via menuconfig).

Who is online

Users browsing this forum: Bing [Bot] and 428 guests