I try to work with I2C within a wake up stub on my esp32. To this end I wrote a function to initialize I2C and a function to send something.
These functions only use macros and are placed in RTC fast memory. I tested these function with the main CPU (within the RTOS) and it works fine. When I tried to call the within the wake up stub the watchdog triggered a system reset.
I thought the I2C communication take to much time so I deactivated the watchdog within the wake-up stub to realize that the initialization function stops execution.
The function is shown below.
Code: Select all
void RTC_IRAM_ATTR stub_init_i2c(uint32_t scl_pin, uint32_t sda_pin)
{
/* GPIO Settings */
REG_SET_BIT(GPIO_OUT_W1TS_REG, (1 << scl_pin));
REG_SET_BIT(GPIO_OUT_W1TS_REG, (1 << sda_pin));
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[scl_pin], PIN_FUNC_GPIO);
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[sda_pin], PIN_FUNC_GPIO);
REG_SET_BIT(GPIO_PIN_MUX_REG[scl_pin], FUN_IE);
REG_SET_BIT(GPIO_PIN_MUX_REG[sda_pin], FUN_IE);
REG_SET_BIT(GPIO_ENABLE_W1TS_REG, (1 << scl_pin));
REG_SET_BIT(GPIO_ENABLE_W1TS_REG, (1 << sda_pin));
STUB_GPIO_PIN_REG(scl_pin) |= (1 << 2);
STUB_GPIO_PIN_REG(sda_pin) |= (1 << 2);
REG_SET_BIT(GPIO_PIN_MUX_REG[scl_pin], (1 << 8));
REG_SET_BIT(GPIO_PIN_MUX_REG[sda_pin], (1 << 8));
REG_CLR_BIT(GPIO_PIN_MUX_REG[scl_pin], (1 << 7));
REG_CLR_BIT(GPIO_PIN_MUX_REG[sda_pin], (1 << 7));
STUB_GPIO_FUNC_OUT_SEL_REG(sda_pin) = 30;
STUB_GPIO_FUNC_OUT_SEL_REG(scl_pin) = 29;
STUB_GPIO_FUNC_IN_SEL_REG(30) = sda_pin;
STUB_GPIO_FUNC_IN_SEL_REG(29) = scl_pin;
/*DPORT Settings (Clock and reset) */
/* Activate I2C0 */
DPORT_REG_CLR_BIT(DPORT_PERIP_RST_EN_REG, (1 << 7)); <<== This call stops execution
#if 0
/* Activate I2C0 Clock */
DPORT_REG_SET_BIT(DPORT_PERIP_CLK_EN_REG, (1 << 7));
/* I2C Settings */
uint32_t half_cycles = 400;
REG_WRITE(I2C_SCL_LOW_PERIOD_REG(0), half_cycles);
REG_WRITE(I2C_SCL_HIGH_PERIOD_REG(0), half_cycles);
REG_WRITE(I2C_SDA_HOLD_REG(0),half_cycles/2);
REG_WRITE(I2C_SDA_SAMPLE_REG(0), half_cycles/2);
REG_WRITE(I2C_SCL_START_HOLD_REG(0), half_cycles);
REG_WRITE(I2C_SCL_RSTART_SETUP_REG(0), half_cycles);
REG_WRITE(I2C_SCL_STOP_SETUP_REG(0), half_cycles);
REG_WRITE(I2C_SCL_STOP_HOLD_REG(0),half_cycles);
REG_WRITE(I2C_TO_REG(0), half_cycles*20);
/* Enable master mode*/
REG_WRITE(I2C_CTR_REG(0), 19);
/* Enable I2C_NONFIFO_EN as stated in technical reference manual*/
REG_WRITE(I2C_TO_REG(0), 8000);
REG_WRITE(I2C_SCL_FILTER_CFG_REG(0), 17);
REG_WRITE(I2C_SDA_FILTER_CFG_REG(0), 17);
#endif
As the memory mapped access to DPORT hangs, it seems to me DPORT has to be initialized before accessing it. Unfortunately reading the eps32 technical reference manual did not reveal what I have to do before accessing the DPORT registers.
Does anyone have any idea why this access is not working?
Thank you very much.
BR
Thomas