ESP32-S2 ULP-RISC-V clock frequency? Microsecond delay
Posted: Thu May 13, 2021 11:49 pm
I'm trying to communicate with a sensor using the 1-Wire protocol from the ULP-RISC-V coprocessor on the ESP32-S2. To do this I need microsecond-ish precision delays.
There is an older post on the forum looking at how to implement a cycle-based wait, similar to the wait instruction for the ULP-FSM, that didn't get much traction. I implemented a wait() function in assembly that seems to reliably do nothing for a certain number of iterations N.
However, in order to set N I need to know the frequency the ULP-RISC-V is running at with some precision, and how many cycles per iteration are used by my wait function.
According to Table 176 of the technical reference, the Work Clock Frequency of both coprocessors is 8 MHz (RTC_FAST_CLK). The manual is pretty clear that the ULP-FSM is clocked from RTC_FAST_CLK with a prescaler of 256 (so at 8 MHz / 256 = 31.25 kHz).
I wrote a simple test (available on GitHub) that toggles a pin with a delay of wait(1000). It seems to take about 1.54 us per iteration, implying a frequency of around 650 kHz.
I also tried using
to find the periods of the RTC_MUX and RTC_8MD256 clocks. I get the results
which indicates clock periods of 5.6 and 15.7 us, respectively (or 180 kHz or 64 kHz). Strangely, these are about twice as fast as I would have expected? The first should correspond to the RTC slow clock, which section 2.2.2 of the technical reference says runs at 90 kHz. The second should be 8 MHz / 256 = 31.25 kHz.
Puzzling factors of two aside, does anybody know how to determine using something like rtc_clk_cal() how fast the ULP-RISC-V is operating?
Also, how many cycles do the instructions of my wait() function take (beq, addi, j)? The older post I mentioned uses 16 cycles per iteration. 8 MHz / 16 = 500 kHz is pretty close to what I'm measuring. Table 183 of the technical reference lists the number of cycles used for multiplication and division, but there doesn't seem to be any documentation for addition (addi).
Thanks!
There is an older post on the forum looking at how to implement a cycle-based wait, similar to the wait instruction for the ULP-FSM, that didn't get much traction. I implemented a wait() function in assembly that seems to reliably do nothing for a certain number of iterations N.
However, in order to set N I need to know the frequency the ULP-RISC-V is running at with some precision, and how many cycles per iteration are used by my wait function.
According to Table 176 of the technical reference, the Work Clock Frequency of both coprocessors is 8 MHz (RTC_FAST_CLK). The manual is pretty clear that the ULP-FSM is clocked from RTC_FAST_CLK with a prescaler of 256 (so at 8 MHz / 256 = 31.25 kHz).
I wrote a simple test (available on GitHub) that toggles a pin with a delay of wait(1000). It seems to take about 1.54 us per iteration, implying a frequency of around 650 kHz.
I also tried using
Code: Select all
rtc_clk_cal(RTC_CAL_RTC_MUX, 100);
rtc_clk_cal(RTC_CAL_8MD256, 100);
Code: Select all
I (260) esp32s2-ulp-riscv-delay: RTC_CAL_RTC_MUX clock period = 5637276
I (270) esp32s2-ulp-riscv-delay: RTC_CAL_8MD256 clock period = 15681061
Puzzling factors of two aside, does anybody know how to determine using something like rtc_clk_cal() how fast the ULP-RISC-V is operating?
Also, how many cycles do the instructions of my wait() function take (beq, addi, j)? The older post I mentioned uses 16 cycles per iteration. 8 MHz / 16 = 500 kHz is pretty close to what I'm measuring. Table 183 of the technical reference lists the number of cycles used for multiplication and division, but there doesn't seem to be any documentation for addition (addi).
Thanks!