Could RMT split "rmt_symbols" by time, not by level change?

imShara
Posts: 10
Joined: Wed Feb 19, 2020 2:00 pm

Re: Could RMT split "rmt_symbols" by time, not by level change?

Postby imShara » Fri May 09, 2025 5:35 pm

I need to read [...] in non blocking mode.
Maybe you don't. At 5MHz clock frequency, transferring 27 bits takes ~5.4 micro-seconds, or ~1300 CPU cycles @ 240MHz. This may be less than the overhead incurred (context switching,...) for an asynchronous transfer.

What kind of code you suggest to achieve that timings? Something like this?

Code: Select all

portENTER_CRITICAL();
for(int i=0; i < 24 ; i++)
{
    gpio_set_level SCK 1
    gpio_get_level DO
    delay
    gpio_set_level SCK 0
    delay
}
portEXIT_CRITICAL();
But how could you make sub µs delays? __asm__ volatile("nop"); ?

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

Re: Could RMT split "rmt_symbols" by time, not by level change?

Postby MicroController » Fri May 09, 2025 6:52 pm

I'd suggest using SPI in 'polling' mode.

Alternatively, you can use esp_cpu_get_cycle_count() to time/delay sub-microseconds.

imShara
Posts: 10
Joined: Wed Feb 19, 2020 2:00 pm

Re: Could RMT split "rmt_symbols" by time, not by level change?

Postby imShara » Fri May 09, 2025 8:23 pm

I'd suggest using SPI in 'polling' mode.

Thanks, will check it.

I made ≈333ns this way:
It's possible to down it to ~250ns, but not stable.

333us.png
333us.png (14.57 KiB) Viewed 82 times

Code: Select all

portMUX_TYPE my_mux = portMUX_INITIALIZER_UNLOCKED;
...

portENTER_CRITICAL(&mux);

// Set PD_SCK to HI level by bit set
GPIO.out_w1ts = (1 << GPIO_SCK);

// Wait ~ 300ns @ 240mhz
start = esp_cpu_get_cycle_count();
while (xthal_get_ccount() - start < 30) {}

// Shift bits left
value = value << 1;

// Set last bit depends on DOUT level (GPIO.in for 0–31 pin, GPIO.in1.data for 32–39 pin)
if ((GPIO.in >> hx711->dout_io_num) & 1) {
    value++;
}

// Set PD_SCK to LOW level by bit clear
GPIO.out_w1tc = (1 << hx711->pd_sck_io_num);

// wait ~ 300ns @ 240mhz
start = esp_cpu_get_cycle_count();
while (xthal_get_ccount() - start < 40) {}

...

portEXIT_CRITICAL(&mux);

PS. gpio_set_level 5.5 times slower than setting gpio level by register

gpio_set_level vs out_w1ts.png
gpio_set_level vs out_w1ts.png (17.11 KiB) Viewed 82 times

imShara
Posts: 10
Joined: Wed Feb 19, 2020 2:00 pm

Re: Could RMT split "rmt_symbols" by time, not by level change?

Postby imShara » Fri May 09, 2025 11:47 pm

And one more problem. When I push code into real enviroment with wifi an others - it seems like portENTER_CRITICAL not works as expected. Here is example - left side of clock is 24 bit read, right side - three bits for next conversion selection. And between this loops there is a long delay. Even if portENTER_CRITICAL used and even if portDISABLE_INTERRUPTS added.

one more problem.png
one more problem.png (5.65 KiB) Viewed 74 times

Code: Select all

portENTER_CRITICAL(&mux);
portDISABLE_INTERRUPTS(); // No luck too

for (uint8_t i=0; i < 24 ; i++)
{
...
}

--- break appears here ---

for (uint8_t i = 0; i < 3; i++) 
{
...
}

portENABLE_INTERRUPTS();
portEXIT_CRITICAL(&mux);

I thought it could work only on core1, separated from other hardware stuff.

Who is online

Users browsing this forum: DuckDuckGo [Bot], Google [Bot] and 1 guest