I'm trying to generate a 100 kHz signal with ESP32 timers.
I tried to do this with the gptimer but the ESP32 keeps resetting!
Which timer can I use for this? How?
Generate signal with timer
-
- Posts: 1706
- Joined: Mon Oct 17, 2022 7:38 pm
- Location: Europe, Germany
Re: Generate signal with timer
That's not going to happen.saeidi_majid wrote: ↑Fri Apr 12, 2024 8:12 amI'm trying to generate a 100 kHz signal with ESP32 timers.
Look into generating PWM in hardware, e.g. via the LEDC peripheral.Which timer can I use for this? How?
Re: Generate signal with timer
I tested it with LEDC and it works properly, but I want to know how to do it with GPTimer functions.
I've set the timer resolution to 1MHz, so each tick equals 1 microsecond. Therefore, if I set the alarm count value to 10, an interrupt occurs every 10 microseconds, during which I can toggle a port get my frequency
Now, when I do this, the ESP32 resets.
I've set the timer resolution to 1MHz, so each tick equals 1 microsecond. Therefore, if I set the alarm count value to 10, an interrupt occurs every 10 microseconds, during which I can toggle a port get my frequency
Now, when I do this, the ESP32 resets.
- #include <stdio.h>
- #include "freertos/FreeRTOS.h"
- #include "freertos/task.h"
- #include "freertos/queue.h"
- #include "driver/gptimer.h"
- #include "driver/gpio.h"
- #define FREQ_OUT_PIN GPIO_NUM_5
- static QueueHandle_t timer_alarm_queue = NULL;
- gptimer_handle_t gptimer = NULL;
- typedef struct {
- uint64_t event_count;
- uint64_t event_alarm;
- }queue_element_t;
- //************************************************************************************************************
- static bool IRAM_ATTR timrt_alarm_callback(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_data)
- {
- BaseType_t high_task_awoken = pdFALSE;
- queue_element_t queue_data = {
- .event_count = edata->count_value,
- .event_alarm = edata->alarm_value,
- };
- xQueueSendFromISR(timer_alarm_queue, &queue_data, &high_task_awoken);
- return (high_task_awoken == pdTRUE);
- }
- //************************************************************************************************************
- static void timer_alarm_task(void* arg)
- {
- int isOn = 0;
- queue_element_t data;
- while (true)
- {
- if(xQueueReceive(timer_alarm_queue, &data, portMAX_DELAY))
- {
- isOn =! isOn;
- gpio_set_level(LED_GPIO, isOn);
- }
- }
- }
- //************************************************************************************************************
- void app_main(void)
- {
- gpio_set_direction(LED_GPIO, GPIO_MODE_OUTPUT);
- gptimer_config_t timer_config = {
- .clk_src = GPTIMER_CLK_SRC_APB,
- .direction = GPTIMER_COUNT_UP,
- .resolution_hz = 1000000,
- .intr_priority = 0,
- .flags.intr_shared = false,
- };
- gptimer_new_timer(&timer_config, &gptimer);
- gptimer_event_callbacks_t timerCallback = {
- .on_alarm = timrt_alarm_callback,
- };
- gptimer_register_event_callbacks(gptimer, &timerCallback, NULL);
- gptimer_alarm_config_t alarm_config = {
- .alarm_count = 5000,
- .reload_count = 0,
- .flags.auto_reload_on_alarm = true,
- };
- gptimer_set_alarm_action(gptimer, &alarm_config);
- timer_alarm_queue = xQueueCreate(1, sizeof(uint32_t));
- xTaskCreate(timer_alarm_task, "timer_alarm_task", 2048, NULL, 5, NULL);
- gptimer_enable(gptimer);
- gptimer_start(gptimer);
- while(1)
- {
- vTaskDelay(1000 / portTICK_PERIOD_MS);
- }
- }
-
- Posts: 1706
- Joined: Mon Oct 17, 2022 7:38 pm
- Location: Europe, Germany
Re: Generate signal with timer
This is the actual problem. When accounting for the overhead of entering and exiting an ISR plus the xQueueSendFromISR(...), plus the context switch to the timer_alarm_task, 10us won't leave much time, if any, for anything else on that CPU core. I don't know if that's actually what causes the resets in your case (e.g. by angering the watchdog timer), but 100kHz is still likely too much for an ISR; and if it doesn't crash the system, the jitter in signal timing you'd get is probably inacceptable.an interrupt occurs every 10 microseconds
However, you can try to do the GPIO toggling directly from the ISR instead of communicating to a task to significantly reduce the overhead.
Re: Generate signal with timer
I directly changed the GPIO from the ISR, but it resets again.
The ESP32 has a high operating frequency, which is why it surprises me why this is happening!
What is your suggestion for generating 100 kilohertz frequency other than LEDC?
Do you have any sample code
Thanks
The ESP32 has a high operating frequency, which is why it surprises me why this is happening!
What is your suggestion for generating 100 kilohertz frequency other than LEDC?
Do you have any sample code
Thanks
-
- Posts: 9730
- Joined: Thu Nov 26, 2015 4:08 am
Re: Generate signal with timer
Do you have an issue specific with the LEDC? If so, you can also use the MCPWM or the RMT, or even hack stuff up using e.g. I2s, to generate such a signal. If you specifically want to generate a signal using a software interrupt, it would really help if you would tell us why exactly. (And the answer might be: 'you can't'. The features that make the ESP32 core very fast, also make it a bit sluggish when it comes to interrupt handling and context switching. That is why they have so many flexible peripherals on board, like the LEDC.)
Re: Generate signal with timer
I don't have any issues with LEDC. in fact, I wanted to set up an ultrasonic SR-04 module, which actually worked fine with LEDC. However, as I'm currently learning ESP-IDF and reading the GPTimer documentation, I tried to generate 100 kHz frequency for the SR-04 using GPTimer to get familiar with different methods and applications of GPTimer.
I have another question about GPTimer.
Since the ESP32 has two Timer groups, each containing 2 timers, how can I configure a different setup and a separate ISR for each?
Thanks.
I have another question about GPTimer.
Since the ESP32 has two Timer groups, each containing 2 timers, how can I configure a different setup and a separate ISR for each?
Thanks.
Re: Generate signal with timer
I don't understand! What's the relationship between GPTimer and Timer Group?
If a timer group includes 4 timers, then which one does GPTimer work with?
And do I need to use multiple gptimer_handle_t with different configurations to create multiple timers with GPTimer?
If a timer group includes 4 timers, then which one does GPTimer work with?
And do I need to use multiple gptimer_handle_t with different configurations to create multiple timers with GPTimer?
-
- Posts: 9730
- Joined: Thu Nov 26, 2015 4:08 am
Re: Generate signal with timer
Not sure where you get that a timer group contains 4 timers. From the TRM: 'The ESP32 contains two timer modules, each containing two timers. '. In general, the gptimer driver abstracts away over this: if you ask it for a timer, it'll give you the first one that is free.
Who is online
Users browsing this forum: No registered users and 118 guests