Open Ankith-A-Muralidhar opened 4 years ago
Hey, I'm having a similar problem. The i2c is causing resets in assembly. @Alvin1Zhang
Facing similar issue here!
The third parameter of WRITE_RTC_REG is bit_width, not a mask: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/ulp_instruction_set.html#convenience-macros-for-peripheral-registers-access
What is the intention here? Setting START_FORCE will prevent the ULP I2C instruction from working...
WRITE_RTC_FIELD(SENS_SAR_I2C_CTRL_REG, SENS_SAR_I2C_START_FORCE, 1)
WRITE_RTC_FIELD(SENS_SAR_I2C_CTRL_REG, SENS_SAR_I2C_CTRL, 0x000A000)
It's generally much more convenient and robust for the SoC to handle initialisation of the RTC I2C peripheral, especially while troubleshooting. Is there any reason for having the ULP handle all this?
See here for working initialisation (tested just now) https://github.com/boarchuz/HULP/blob/fbc9b61d57c6b83079def9ddb6ced9c30d1f7bb7/src/hulp.cpp#L108-L184
Thanks for reporting and sorry for the inconvenience, we will look into.
- The third parameter of WRITE_RTC_REG is bit_width, not a mask: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/ulp_instruction_set.html#convenience-macros-for-peripheral-registers-access
- What is the intention here? Setting START_FORCE will prevent the ULP I2C instruction from working...
WRITE_RTC_FIELD(SENS_SAR_I2C_CTRL_REG, SENS_SAR_I2C_START_FORCE, 1) WRITE_RTC_FIELD(SENS_SAR_I2C_CTRL_REG, SENS_SAR_I2C_CTRL, 0x000A000)
- It's generally much more convenient and robust for the SoC to handle initialisation of the RTC I2C peripheral, especially while troubleshooting. Is there any reason for having the ULP handle all this?
See here for working initialisation (tested just now) https://github.com/boarchuz/HULP/blob/fbc9b61d57c6b83079def9ddb6ced9c30d1f7bb7/src/hulp.cpp#L108-L184
I tried the same set up as mentioned. but the code still resets as soon as I2C command is read. The code I tried is below: rtc_gpio_init(GPIO_NUM_2); rtc_gpio_set_level(GPIO_NUM_2, 0); rtc_gpio_pulldown_dis(GPIO_NUM_2); rtc_gpio_pullup_dis(GPIO_NUM_2);
rtc_gpio_init(GPIO_NUM_15); rtc_gpio_set_level(GPIO_NUM_15, 0); rtc_gpio_pulldown_dis(GPIO_NUM_15); rtc_gpio_pullup_en(GPIO_NUM_15);
REG_SET_FIELD(RTC_IO_SAR_I2C_IO_REG, RTC_IO_SAR_I2C_SCL_SEL, 1); REG_SET_FIELD(RTC_IO_SAR_I2C_IO_REG, RTC_IO_SAR_I2C_SDA_SEL, 1);
SET_PERI_REG_BITS(rtc_gpio_desc[hulp_gtr(GPIO_NUM_2)].reg, RTC_IO_TOUCH_PAD1_FUN_SEL_V, 0x3, rtc_gpio_desc[hulp_gtr(GPIO_NUM_2)].func); SET_PERI_REG_BITS(rtc_gpio_desc[hulp_gtr(GPIO_NUM_15)].reg, RTC_IO_TOUCH_PAD1_FUN_SEL_V, 0x3, rtc_gpio_desc[hulp_gtr(GPIO_NUM_15)].func);
REG_SET_FIELD(RTC_I2C_CTRL_REG, RTC_I2C_RX_LSB_FIRST, 1); REG_SET_FIELD(RTC_I2C_CTRL_REG, RTC_I2C_TX_LSB_FIRST, 1); REG_SET_FIELD(RTC_I2C_CTRL_REG, RTC_I2C_SCL_FORCE_OUT, 0); REG_SET_FIELD(RTC_I2C_CTRL_REG, RTC_I2C_SDA_FORCE_OUT, 0);
REG_SET_FIELD(RTC_I2C_SCL_LOW_PERIOD_REG, RTC_I2C_SCL_LOW_PERIOD, 40); REG_SET_FIELD(RTC_I2C_SCL_HIGH_PERIOD_REG, RTC_I2C_SCL_HIGH_PERIOD, 40); REG_SET_FIELD(RTC_I2C_SDA_DUTY_REG, RTC_I2C_SDA_DUTY, 16); REG_SET_FIELD(RTC_I2C_SCL_START_PERIOD_REG, RTC_I2C_SCL_START_PERIOD, 30); REG_SET_FIELD(RTC_I2C_SCL_STOP_PERIOD_REG, RTC_I2C_SCL_STOP_PERIOD, 44); REG_SET_FIELD(RTC_I2C_TIMEOUT_REG, RTC_I2C_TIMEOUT, 10000); REG_SET_FIELD(RTC_I2C_CTRL_REG, RTC_I2C_MS_MODE, 1);
SET_PERI_REG_BITS(SENS_SAR_SLAVE_ADDR1_REG, SENS_I2C_SLAVE_ADDR0, 0x29, SENS_I2C_SLAVE_ADDR0_S);
I am still unsure why the i2c is not initialized. I tried to initiate it through the SoC rather than ULP core. Any help would be appreciated.
For using I2C in ULP, maybe this one could be helpful.
https://github.com/espressif/esp-iot-solution/tree/master/examples/ulp_examples/ulp_i2c_bitbang
I have tried this as well but no avail. I did the i2c in a different .s file and called it in the main assembly file. Yet the situation is still the same. I initialize the i2c and then make a read and then give a global variable a constant value. so even if the read value is not valid I will know if the command works. But the constant is never transferred to the global variable. So If anyone has any insights it will be greatly appreciated! Thank you!
Environment
git describe --tags
to find it): // v3.3xtensa-esp32-elf-gcc --version
to find it): // 8.2.0Problem Description
While programming for ULP core in Assembly using the instruction set, The code resets after the I2C_rd and I2C_WR command. While reading or writing using the I2C command, the information was not sending. to test this we had an two global variables and print these in the main.c, but the one before the I2C command was printing and not the one after. It always shows zero.
Expected Behavior
Need to get some values using I2C_RD command
Actual Behavior
Code resets to begin as soon as I2C command is encountered
Steps to reproduce
After initialization, giving the I2C command will give this problem
// If possible, attach a picture of your setup/wiring here.
Code to reproduce this issue