The ESP32 only has a single-precision FPU; the compiler generates code to handle double-precision floats without the FPU. Change your 'double' variables to 'float' variables and the FPU instructions should show up.
However...
Note that the state of the FPU isn't saved on an interrupt; it can be in whatever state the last task left it, or the FPU can even be disabled so when a task needs it, the contents of the FPU registers can be lazily saved. You're very likely going to run into issues if you naively put FPU instructions into your interrupt handler.
Need help on High-Level Interrupts
Re: Need help on High-Level Interrupts
I see! Thank you ESP_Sprite!
Is it the same on ESP32-S3?
float is not accurate enough to equally divide 240M into thousands of intervals, so I will implement a calculation by myself to divide it.
I have another question, I'm going to toggle GPIO pins in the interrupt handle to read data from an external ADC, is the speed of toggling pins in assemble manually similar with the speed of SPI driver can do, or much slower than SPI driver?
Best,
Wayne
Is it the same on ESP32-S3?
float is not accurate enough to equally divide 240M into thousands of intervals, so I will implement a calculation by myself to divide it.
I have another question, I'm going to toggle GPIO pins in the interrupt handle to read data from an external ADC, is the speed of toggling pins in assemble manually similar with the speed of SPI driver can do, or much slower than SPI driver?
Best,
Wayne
-
- Posts: 9739
- Joined: Thu Nov 26, 2015 4:08 am
Re: Need help on High-Level Interrupts
ESP32-S3 also only has float hardware support.
I'd suggest you look into a fixed-point solution instead, then; it saves you the hassle of FPU context saving and restoring and it's likely good enough given that you sound like you're working with known orders-of-magnitude.
On the 'classic' ESP32, toggling GPIOs manually is going to be slower regardless of it's in assembly or C (you'll get a give-or-take 20MHz toggle rate at max, if memory serves). Newer chips all have some dedicated fast GPIO that can toggle pins faster.
I'd suggest you look into a fixed-point solution instead, then; it saves you the hassle of FPU context saving and restoring and it's likely good enough given that you sound like you're working with known orders-of-magnitude.
On the 'classic' ESP32, toggling GPIOs manually is going to be slower regardless of it's in assembly or C (you'll get a give-or-take 20MHz toggle rate at max, if memory serves). Newer chips all have some dedicated fast GPIO that can toggle pins faster.
Re: Need help on High-Level Interrupts
Got it, thanks a lot!!
Take 240M /12345 as example, what I'm currently calculating is similar with: int A = (240M<<3) /12345; int B= (((240M<<3) % 12345)<<16) / 12345. Not perfect, but works with low/no risk, accuracy is 1.0/2^19.
Toggling GPIO pin 32 times as well as reading GPIO_IN 16 times takes around 800 CPU cycles, so the max speed is 9.6M/s GPIO operation with data collection in my case. It is fast enough for my project.
Thank you for everyone's help!!
Best regards,
Wayne
Take 240M /12345 as example, what I'm currently calculating is similar with: int A = (240M<<3) /12345; int B= (((240M<<3) % 12345)<<16) / 12345. Not perfect, but works with low/no risk, accuracy is 1.0/2^19.
Toggling GPIO pin 32 times as well as reading GPIO_IN 16 times takes around 800 CPU cycles, so the max speed is 9.6M/s GPIO operation with data collection in my case. It is fast enough for my project.
Thank you for everyone's help!!
Best regards,
Wayne
Re: Need help on High-Level Interrupts
Just recalled an interesting thing related level-5 timer interrupt of ccompare_2.
The ccount and ccompare_2 should be able to trigger level 5 timer interrupt. I didn't find too much information on internet, but it seems the ccompare_2 interrupt is the source of interrupt 16. However, I can't find an interrupt source defination from SOC.h to exactly match the ccompare_2. And it is stated in SOC.h that interrupt 16 is reserved. So I use 'ETS_FROM_CPU_INTR1_SOURCE' as the best match I can find, and call intr_matrix_set(1, ETS_FROM_CPU_INTR1_SOURCE,16); to register the interrupt. It works as I expected, setting ccompare_2 can set the time of triggering the interrupt. Interestingly, if I register interrupt 16 with any other source, it is still ccompare_2 that triggers the interrupt. So I guess the interrupt 16 is connect to ccompare_2 no matter which source is specified with intr_matrix_set()
Is my guess right?
The ccount and ccompare_2 should be able to trigger level 5 timer interrupt. I didn't find too much information on internet, but it seems the ccompare_2 interrupt is the source of interrupt 16. However, I can't find an interrupt source defination from SOC.h to exactly match the ccompare_2. And it is stated in SOC.h that interrupt 16 is reserved. So I use 'ETS_FROM_CPU_INTR1_SOURCE' as the best match I can find, and call intr_matrix_set(1, ETS_FROM_CPU_INTR1_SOURCE,16); to register the interrupt. It works as I expected, setting ccompare_2 can set the time of triggering the interrupt. Interestingly, if I register interrupt 16 with any other source, it is still ccompare_2 that triggers the interrupt. So I guess the interrupt 16 is connect to ccompare_2 no matter which source is specified with intr_matrix_set()
Is my guess right?
Code: Select all
#define ETS_FROM_CPU_INTR0_SOURCE 24/**< interrupt0 generated from a CPU, level*/ /* Used for FreeRTOS */
#define ETS_FROM_CPU_INTR1_SOURCE 25/**< interrupt1 generated from a CPU, level*/ /* Used for FreeRTOS */
#define ETS_FROM_CPU_INTR2_SOURCE 26/**< interrupt2 generated from a CPU, level*/ /* Used for IPC_ISR */
#define ETS_FROM_CPU_INTR3_SOURCE 27/**< interrupt3 generated from a CPU, level*/ /* Used for IPC_ISR */
-
- Posts: 9739
- Joined: Thu Nov 26, 2015 4:08 am
Re: Need help on High-Level Interrupts
That is interesting... I am not aware of the ESP32 having two ccompare registers. ETS_FROM_CPU_INTR1_SOURCE is normally used for inter-CPU communication; are you sure you're not seeing those interrupts and thinking they come from the ccompare module?
(Btw, you should be able to use the first ccompare register... I don't think esp-idf uses it.)
(Btw, you should be able to use the first ccompare register... I don't think esp-idf uses it.)
Re: Need help on High-Level Interrupts
There are 3 ccompare (for each core?) in specreg.h, so I guess there could be 3 timers, corresponding to the 3 interrupt for timers:
Interrupt 6 (level 1);
Interrupt 15 (level 3);
Interrupt 16 (level 5);
In the interrupt handler, I read the REG INTERRUPT, and find bit 16 are (sometimes?) 1. The interrupt does happen at the time specified in ccompare_2, and setting ccompare_2 will clear the interrupt flag, so I think the interrupt comes from ccompare_2. I also noticed that INTERRUPT bit 15 sometimes are 1, but bit 15 didn't trigger level-5 interrupt. Could bit 15 be the inter-CPU communication?
Best,
Wayne
Interrupt 6 (level 1);
Interrupt 15 (level 3);
Interrupt 16 (level 5);
In the interrupt handler, I read the REG INTERRUPT, and find bit 16 are (sometimes?) 1. The interrupt does happen at the time specified in ccompare_2, and setting ccompare_2 will clear the interrupt flag, so I think the interrupt comes from ccompare_2. I also noticed that INTERRUPT bit 15 sometimes are 1, but bit 15 didn't trigger level-5 interrupt. Could bit 15 be the inter-CPU communication?
Code: Select all
#define CCOMPARE_0 240
#define CCOMPARE_1 241
#define CCOMPARE_2 242
Best,
Wayne
Re: Need help on High-Level Interrupts
I got another problem.
If I set ESP32 as the target, the following line can register the level 5 interrupt normally. But if I set ESP32-S3 as the target, it can not register the interrupt on core 1. If I change the core id to 0, it works. Could it be a bug of ESP-IDF? Since I have to run the interrupt on core 1, it there any way to fix this problem or work around?
Best,
Wayne
If I set ESP32 as the target, the following line can register the level 5 interrupt normally. But if I set ESP32-S3 as the target, it can not register the interrupt on core 1. If I change the core id to 0, it works. Could it be a bug of ESP-IDF? Since I have to run the interrupt on core 1, it there any way to fix this problem or work around?
Code: Select all
intr_matrix_set(1, ETS_GPIO_INTR_SOURCE, 31);
Wayne
Who is online
Users browsing this forum: Google [Bot] and 102 guests