Page 1 of 1

Embedding assembly code fragment in main source file in ESP-IDF

Posted: Tue Feb 27, 2024 6:52 am
by Vilius
Hi,

I am developing a code (on ESP32 WROOVER-E) that could potentially hugely benefit from rewriting some short fragment of C code in assembly language. Having said that, I still want to preserve the rest of the source file unchanged. Can you please provide me with some short snipet or pseudocode what is the syntax for such scenario? I will write the assembly on my own, I just need some guidance, are there any specific includes needed for it, is there specific syntax highlighting the assembly code beginning and end? Thank you in advance.

The code:

#includes
.
.
.
void app main(){
.
.
.
while(1){

//This part will be rewritten in assembly
REG_WRITE(GPIO_OUT_W1TS_REG, (1 << GPIO_CLOCK));
data_array[k] = REG_READ(GPIO_IN_REG);
data_array[k + 1] = REG_READ(GPIO_IN1_REG);
k = (k + 2) % NUM_CYCLES;
REG_WRITE(GPIO_OUT_W1TC_REG, (1 << GPIO_CLOCK));
//assembly section ends here

}
}

Re: Embedding assembly code fragment in main source file in ESP-IDF

Posted: Tue Feb 27, 2024 8:19 am
by MicroController
See https://gcc.gnu.org/onlinedocs/gcc/exte ... -code.html

However, your code snippet is really simple and chances are that gcc already generates pretty optimal code. Before resorting to assembler, you generally should check gcc's output to verify if there actually is any potential for further optimization.

Re: Embedding assembly code fragment in main source file in ESP-IDF

Posted: Tue Feb 27, 2024 8:40 am
by Vilius
Reading the datasheet implies that it is still worth trying. So can you provide me the assembly details? I tried to do it by myself, but ESP-IDF was giving me syntax errors. Does anyone have a very simple and working assembly block syntax template?

Re: Embedding assembly code fragment in main source file in ESP-IDF

Posted: Tue Feb 27, 2024 9:13 am
by MicroController
Your code could start with something like this:

Code: Select all

uint32_t* dataPtr = data_array;
uint32_t tmp;
asm volatile (
  "S32I %[clk], %[w1ts], 0" "\n"
  "memw" "\n"
  
  "L32I %[tmp], %[in0], 0" "\n"
  "S32I %[tmp], %[dataPtr], 0" "\n"
  "L32I %[tmp], %[in1], 0" "\n"
  "S32I %[tmp], %[dataPtr], 4" "\n"
  
  "memw" "\n"
  "S32I %[clk], %[w1tc], 0" "\n"
  "memw" "\n"
  
  "ADDI %[dataPtr], %[dataPtr], 8" "\n"
  ...
  : [dataPtr] "+r" (dataPtr),
    [tmp] "=&r" (tmp),
    "=m" (data_array)
  : [w1ts] "r" (w1ts_reg_addr),
    [w1tc] "r" (w1tc_reg_addr),
    [clk] "r" (1<<GPIO_CLOCK),
    [in0] "r" (gpio_in_addr),
    [in1] "r" (gpio_in1_addr)
);

Re: Embedding assembly code fragment in main source file in ESP-IDF

Posted: Tue Feb 27, 2024 9:58 am
by MicroController
Btw, note that GPIO on the ESP is slow; the CPU is usually not the bottleneck.

Re: Embedding assembly code fragment in main source file in ESP-IDF

Posted: Tue Feb 27, 2024 11:24 am
by DrMickeyLauer
How slow is "slow"? I have a design where one GPIO is toggling VSYS (12V) to an external pin and another GPIO can be used to read that pin. I'm working on my board testing code and in my first naive attempts I was under the assumption that the moment gpio_set_level(outputPin) returns, the pin has changed its level and I can gpio_get_level(inputPin). Alas that doesn't work and I need to add a delay between these two instructions. I'd like to find out how long I need to wait.

Re: Embedding assembly code fragment in main source file in ESP-IDF

Posted: Wed Feb 28, 2024 1:41 am
by ESP_Sprite
Independent of latency of the GPIO, writes and reads are always done 'in order', that is, a write always completes before a read instruction that follows it is executed. I think your issue may be more one of an analog nature, e.g. there might be some capacitance on the pin that initially keeps it on the same level. (Note that if you program in assembly, you may need to have a memw between the read and write, so the CPU also keeps the execution in order. In C, this is already handled automatically.)