this is my first post here. So if I'm in the wrong topic or anything else feel free to correct me .
Normally I am working with Atmel Xmega controllers, but as soon as i discovered the ESP32 I fell in love with it . So here I am, trying to understand FreeRtos and the ESP-IDF API. After reading the FreeRtos Tutorial, I am currently trying to get the hardware timers to work. At the moment everything works fine, as long as I am using 1 Timer out of 1 group. When I try to use both timers, some weird things are happening (stuck in Interrupt?)
Here's my library for the timers:
Code: Select all
#ifndef HW_Timer_H
#define HW_Timer_H
#include <stdio.h>
#include "driver/timer.h"
#include "freertos/FreeRTOS.h"
#include "freertos/semphr.h"
#include "freertos/task.h"
//define Struct
typedef struct
{
timer_idx_t Timer_id;
TaskHandle_t Taskptr;
}Timer_Spec_t;
/*Timer Init
Timer is counting up!
Timer Group = TIMER_GROUP_0 or TIMER_GROUP_1
Timer_id= TIMER_0 or TIMER_1
Division= Division Faktor on the 80Mhz Pher-Clock
Timer_Ovfl= Value when the ISR is triggered
Timer_reload= TIMER_AUTORELOAD_EN/TIMER_AUTORELOAD_DIS
*/
void Timer_Init(timer_group_t Timer_Group, timer_idx_t Timer_id, uint32_t Divider, uint64_t Timer_Ovfl, bool Timer_reload,TaskHandle_t *Taskptr);
//ISR Handling Routine of Timer_Group_0
void IRAM_ATTR timer_group0_isr(void *para);
#endif // !HW_Timer_H
Code: Select all
#include "HW_Timers2.h"
//*************************************************************************************************************************/
// FUNKTIONEN
//*************************************************************************************************************************/
void Timer_Init(timer_group_t Timer_Group, timer_idx_t Timer_id, uint32_t Divider, uint64_t Timer_Ovfl, bool Timer_reload, TaskHandle_t *Taskptr)
{
//define Struct for ISR Pointer
static Timer_Spec_t Timer_Specs;
Timer_Specs.Taskptr = *Taskptr;
Timer_Specs.Timer_id = Timer_id;
//Timer Init. Group0, Timer0
timer_config_t Zeitbasis;
Zeitbasis.divider = Divider;
Zeitbasis.counter_dir = TIMER_COUNT_UP;
Zeitbasis.counter_en = TIMER_PAUSE;
Zeitbasis.alarm_en = TIMER_ALARM_EN;
Zeitbasis.auto_reload = Timer_reload;
Zeitbasis.intr_type = TIMER_INTR_LEVEL;
//Init Timer
timer_init(Timer_Group, Timer_id, &Zeitbasis);
//Set timer to start value
timer_set_counter_value(Timer_Group, Timer_id, 0x00000000ULL);
//Set timer alarm
timer_set_alarm_value(Timer_Group, Timer_id, Timer_Ovfl);
//Interrupt enable
timer_enable_intr(Timer_Group, Timer_id);
if (Timer_Group == TIMER_GROUP_0)
{
timer_isr_register(Timer_Group, Timer_id, timer_group0_isr, (void *) &Timer_Specs, ESP_INTR_FLAG_IRAM, NULL);
}
else
{
//TODO
}
//Timer start
timer_start(Timer_Group, Timer_id);
}
//*************************************************************************************************************************/
// Interrupt Service
//*************************************************************************************************************************/
void IRAM_ATTR timer_group0_isr(void *para)
{
//save the data from the pointer
Timer_Spec_t Settings = *((Timer_Spec_t *) para);
//Get interrupt status
uint32_t intr_status = TIMERG0.int_st_timers.val;
//Delete interrupt flags
if((intr_status & BIT(Settings.Timer_id)) && (Settings.Timer_id) == TIMER_0)
{
TIMERG0.int_clr_timers.t0 = 1;
}
else if((intr_status & BIT(Settings.Timer_id)) && (Settings.Timer_id) == TIMER_1)
{
TIMERG0.int_clr_timers.t1 = 1;
}
//Reactivate alarm
TIMERG0.hw_timer[Settings.Timer_id].config.alarm_en = TIMER_ALARM_EN;
//TaskNotify
xTaskNotifyFromISR(Settings.Taskptr,0x00,eNoAction,NULL);
portYIELD_FROM_ISR();
}
Code: Select all
#include <stdio.h>
#include "esp_types.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "soc/timer_group_struct.h"
#include "driver/periph_ctrl.h"
#include "driver/timer.h"
#include "HW_Timers2.h"
void Handler(void *para)
{
static int i;
while (true)
{
xTaskNotifyWait(0x00, 0xffffffff, NULL, portMAX_DELAY);
if (i == 0)
{
i = 1;
gpio_set_level(2, 0);
}
else
{
i = 0;
gpio_set_level(2, 1);
}
}
}
void Handler2(void *para)
{
static int i;
while (true)
{
xTaskNotifyWait(0x00, 0xffffffff, NULL, portMAX_DELAY);
if (i == 0)
{
i = 1;
gpio_set_level(4, 0);
}
else
{
i = 0;
gpio_set_level(4, 1);
}
}
}
void app_main()
{
TaskHandle_t Handle;
TaskHandle_t Handle2;
//Debug
gpio_pad_select_gpio(2);
gpio_set_direction(2, GPIO_MODE_OUTPUT);
gpio_set_level(2, 0);
gpio_pad_select_gpio(4);
gpio_set_direction(4, GPIO_MODE_OUTPUT);
gpio_set_level(4, 0);
xTaskCreate(Handler, "Handler_task", 2048, NULL, 4, &Handle);
xTaskCreate(Handler2, "Handler_task2", 2048, NULL, 3, &Handle2);
Timer_Init(TIMER_GROUP_0, TIMER_0, 16, 12140, TIMER_AUTORELOAD_EN,&Handle);
Timer_Init(TIMER_GROUP_0, TIMER_1, 64, 23150, TIMER_AUTORELOAD_EN, &Handle2);
}
But why? Does the interrupt get constantly triggered?
Greetings from Germany,
Florian