ESP32-S2 ULP Adding values into an array within a loop

Sheepling
Posts: 12
Joined: Sun Feb 11, 2024 1:48 pm

ESP32-S2 ULP Adding values into an array within a loop

Postby Sheepling » Sat Mar 16, 2024 7:59 pm

This code is based off the existing adc threshold example for the ESP32S2 (https://github.com/espressif/esp-idf/tr ... sm/ulp_adc).
I need to store ADC values into an array in the ULP FSM mode so that the chip can undergo multiple deep-sleep cycles whilst still retaining the data to be printed in active mode, I declared an array in assembly as such:
  1.    
  2. .global adc_reading
  3. adc_reading:
  4.     .long 0
  5.     .long 0
  6.     .long 0
  7.     .long 0
  8.     .long 0
In the entry part of the code (which runs everytime the ULP timer wakes the ULP co-processor), I incremented the sample counter and used it as the offset for adding to the array as such:
  1.    
  2. adc r1, 1, adc_channel + 3 //saradc1
  3.     add r0, r0, r1
  4.     rsh r0, r0, adc_oversampling_factor_log
  5.     move r3, adc_reading
  6.     st r0, r3, sample_counter
However, the array returns 0s, unless the st instruction's 3rd argument (sample_counter) is a constant like 0 or 4. Does anyone know how to effectively store the value of data collected in deep-sleep in an array over multiple deep sleep cycles?
Last edited by Sheepling on Mon Mar 18, 2024 3:09 pm, edited 1 time in total.

JoeSensoric
Posts: 29
Joined: Fri Mar 03, 2017 10:31 am

Re: ESP32-S2 ULP

Postby JoeSensoric » Sun Mar 17, 2024 11:10 am

By which value do you increment the sample_counter? I think you need to increment it by 4. The third argument of the ST command is a number of bytes, not words.
See https://docs.espressif.com/projects/esp ... addressing

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

Re: ESP32-S2 ULP

Postby MicroController » Sun Mar 17, 2024 10:32 pm

Code: Select all

st r0, r3, sample_counter
Note that the 3rd argument to the ST instruction must be a constant. The assembler takes the 'address' of the label 'sample_counter' as the constant value.

Maybe try something like this:

Code: Select all

    move r3, sample_counter
    ld r3, r3, 0 // load sample counter value into r3
    st r0, r3, adc_reading // store r0 to (adc_reading + r3*4)

Sheepling
Posts: 12
Joined: Sun Feb 11, 2024 1:48 pm

Re: ESP32-S2 ULP

Postby Sheepling » Mon Mar 18, 2024 2:37 pm

JoeSensoric wrote:
Sun Mar 17, 2024 11:10 am
By which value do you increment the sample_counter? I think you need to increment it by 4. The third argument of the ST command is a number of bytes, not words.
See https://docs.espressif.com/projects/esp ... addressing
I've set it to increment by 4, but it still doesn't save the value unless I place a constant number like 4, 8, etc. as the 3rd argument in storing into the array

i.e.,
  1.     adc r1, 1, adc_channel + 3 //saradc1
  2.     add r0, r0, r1
  3.     rsh r0, r0, adc_oversampling_factor_log
  4.     move r3, adc_reading
  5.     st r0, r3, 4
will store the value into adc_reading[1], changing 4 to 8 will store to adc_reading[2], so on and so forth. It seems to have an issue when this argument is not a constant (sample_counter in my case).

Sheepling
Posts: 12
Joined: Sun Feb 11, 2024 1:48 pm

Re: ESP32-S2 ULP

Postby Sheepling » Mon Mar 18, 2024 2:57 pm

MicroController wrote:
Sun Mar 17, 2024 10:32 pm

Code: Select all

st r0, r3, sample_counter
Note that the 3rd argument to the ST instruction must be a constant. The assembler takes the 'address' of the label 'sample_counter' as the constant value.

Maybe try something like this:

Code: Select all

    move r3, sample_counter
    ld r3, r3, 0 // load sample counter value into r3
    st r0, r3, adc_reading // store r0 to (adc_reading + r3*4)
Thanks for the reply, and apologies if I'm mistaken in my understanding, but wouldn't the store instruction store the value of r0 into r3 instead of into the adc_reading array?
Having set the sample_counter to increment by 4 per entry in the loop still didn't work for me. :(

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

Re: ESP32-S2 ULP Adding values into an array within a loop

Postby MicroController » Mon Mar 18, 2024 3:32 pm

According to https://docs.espressif.com/projects/esp ... the-memory ST does:

Code: Select all

Mem[Rdst + offset / 4]{31:0} = {PC[10:0], 3'b0, Rdst, Rsrc[15:0]}
where 'offset' can be a (signed) 13-bit value - coincidentally just enough to address 8kb of RAM...
So the instruction set supports this. The only thing I'm not sure about is how the assembler will handle a label as offset, i.e., if it uses the label's byte address as needed here, or if it 'helpfully' divides the byte address by 4, which would be wrong for this case.

If the assembler won't bend, you can still calculate the address yourself by adding the sample count value to the address of adc_reading and ST to that address with offset 0..

Sheepling
Posts: 12
Joined: Sun Feb 11, 2024 1:48 pm

Re: ESP32-S2 ULP Adding values into an array within a loop

Postby Sheepling » Tue Mar 19, 2024 3:32 pm

MicroController wrote:
Mon Mar 18, 2024 3:32 pm
According to https://docs.espressif.com/projects/esp ... the-memory ST does:

Code: Select all

Mem[Rdst + offset / 4]{31:0} = {PC[10:0], 3'b0, Rdst, Rsrc[15:0]}
where 'offset' can be a (signed) 13-bit value - coincidentally just enough to address 8kb of RAM...
So the instruction set supports this. The only thing I'm not sure about is how the assembler will handle a label as offset, i.e., if it uses the label's byte address as needed here, or if it 'helpfully' divides the byte address by 4, which would be wrong for this case.

If the assembler won't bend, you can still calculate the address yourself by adding the sample count value to the address of adc_reading and ST to that address with offset 0..
Thank you so much for the advice, I've finally got it working now. :D

Here's what I did, I created a new variable called 'offset', set it to 0 and incremented it after the loop. Using this offset to calculate the address by adding the sample count value, as per https://docs.espressif.com/projects/esp ... addressing.
  1.     adc r1, 1, adc_channel + 3 //saradc1
  2.     add r0, r0, r1
  3.     rsh r0, r0, adc_oversampling_factor_log
  4.     move r3, adc_reading
  5.     move r1, offset //initialized at 0
  6.     ld r1, r1, 0 //load the offset value
  7.     add r3, r3, r1 //calculate the offset
  8.     st r0, r3, 0 //store into adc_reading[offset]
  9.  
  10.     /* increment offset */
  11.     move r3, offset
  12.     move r1, 0
  13.     ld r1, r3, 0
  14.     add r1, r1, 1
  15.     st r1, r3, 0

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

Re: ESP32-S2 ULP Adding values into an array within a loop

Postby MicroController » Tue Mar 19, 2024 5:05 pm

Glad you got it working :) And thanks for sharing your solution.

Who is online

Users browsing this forum: ccrause and 183 guests