ESP32 Peripherals Interruptions
Posted: Sun Nov 27, 2022 1:03 pm
Dear all, I would like to clarify that I am quite new using ESP32 so I apologise for my noob errors. I am trying to do my own peripherals libraries by modifying esp32 registers. It worked great for GPIO outputs and DAC but when I try to create my own timer libreary it all went wrong...
I have been able to set up Timer Group 0 Timers 0/1 with my own functions as well as to set up its alarm. This alarm creates an interruption and if I monitor TIMGn_Tx_INT_RAW_REG register I can clearly see that an interruption occurs when Timer Value >= Alarm Value (as expected). However, I am not able to associate a handler to this interruption
Main.c file is shown below. On it I just set the timer and I add some traces to see if interruption is handled:
timer_set function is defined on timer.h header and timer.c files:
Can anybody help me please?? I do not know what else can I do
I have been able to set up Timer Group 0 Timers 0/1 with my own functions as well as to set up its alarm. This alarm creates an interruption and if I monitor TIMGn_Tx_INT_RAW_REG register I can clearly see that an interruption occurs when Timer Value >= Alarm Value (as expected). However, I am not able to associate a handler to this interruption
Main.c file is shown below. On it I just set the timer and I add some traces to see if interruption is handled:
Code: Select all
[Codebox=c file=Untitled.c]////////////////// LIBRARIES DEFINITION //////////////////
#include <gpio.h> // Own GPIO Library
#include <stdio.h> // Standard Input-Output Definition Library
#include <stdlib.h> // Standard Types Library
#include <stdbool.h> // Standard Bool Library
#include "driver/timer.h" // Timer Library
#include "freertos/FreeRTOS.h" // FreeRTOS Library
#include "freertos/task.h" // Tasks Library (used for vTaskDelay)
#include "soc/soc.h"
#include "libs/defs.h" // Own Constants Definitions
#include "libs/gpio.h" // Own GPIO Definitions
#include "libs/dac.h" // Own DAC Definitions
#include "libs/timer.h" // Own Timer Definitions
////////////////// VARIABLE DEFINITION //////////////////
bool flag = 0;
////////////////// HANDLER DEFINITION //////////////////
void timer_group_isr_callback(void *args) {
printf("Interruption\n");
flag = 1;
}
////////////////// MAIN //////////////////
void app_main() {
printf("Starting configuration.................\n");
esp_intr_alloc(ETS_TG1_T0_EDGE_INTR_SOURCE, 0, timer_group_isr_callback, NULL, NULL);
timer_set(TIMER0, INCREASE, ENABLE, 0x05, 0x00, ALARM_ON, 0x00FFFFFF);
while(1) {
if(flag){
printf("He entrado!!\n");
flag = 0;
}
}
}[/Codebox]
Code: Select all
[Codebox=c file=Untitled.c]#ifndef MAIN_LIBS_TIMER_H_
#define MAIN_LIBS_TIMER_H_
////////////////// LIBRARIES DEFINITION //////////////////
#include <stdio.h> // Standard Input-Output Definition Library
#include <stdlib.h> // Standard Library
#include <stdbool.h> // Standard Bool Library
#include "defs.h" // Own Constants Definitions
// TIMER REGISTER DEFINITION //
#define TIMER_0_CONFIG_REG 0x3FF5F000 // Timer 0 Configuration Register
#define TIMER_0_ALARM_LO_REG 0x3FF5F010 // Timer 0 Alarm Low Value Register
#define TIMER_0_ALARM_HI_REG 0x3FF5F014 // Timer 0 Alarm High Value Register
#define TIMER_0_RELOAD_LO_REG 0x3FF5F018 // Timer 0 Alarm Reload Low Value Register
#define TIMER_0_RELOAD_HI_REG 0x3FF5F01C // Timer 0 Alarm Reload High Value Register
#define TIMER_0_RELOAD_REG 0x3FF5F020 // Timer 0 Alarm Reload Register
#define TIMER_0_VALUE_REF 0x3FF5F00C // Timer 0 Value Register
#define TIMER_0_NOW_LO_REG 0x3FF5F004 // Timer 0 Current Low Value Register
#define TIMER_0_NOW_HI_REG 0x3FF5F008 // Timer 0 Current Low Value Register
#define TIMER_1_VALUE_REF 0x3FF5F030 // Timer 1 Value Register
#define TIMER_1_NOW_LO_REG 0x3FF5F028 // Timer 1 Current Low Value Register
#define TIMER_1_NOW_HI_REG 0x3FF5F02C // Timer 1 Current Low Value Register
#define TIMER_INT_ENA_REG 0x3FF5F098 // Timer Interrupt Enable Register
#define TIMER_INT_RAW_REG 0x3FF5F09C // Timer Interrupt Raw Register
#define TIMER_INT_MSK_REG 0x3FF5F0A0 // Timer Interrupt Masked Register
#define TIMER_INT_CLR_REG 0x3FF5F0A4 // Timer Interrupt Clear Register
// TIMER CONSTANTS DEFINIRION //
#define TIMER0 0 // Timer 0
#define TIMER1 1 // Timer 1
#define INCREASE 1 // Timer Increase
#define DECREASE 0 // Timer Decrease
#define ENABLE 1 // Timer Enable
#define DISABLE 0 // Timer Disable
#define ALARM_OFF 0 // Timer Alarm Off
#define ALARM_ON 1 // Timer Alarm On
// TIMER FUNCTIONS //
void timer_set(uint8_t, uint8_t, uint8_t, uint16_t, uint64_t, uint8_t, uint64_t);
#endif /* MAIN_LIBS_TIMER_H_ */[/Codebox]
Code: Select all
[Codebox=c file=Untitled.c]////////////////// LIBRARIES DEFINITION //////////////////
#include "timer.h" // Own Timer Library
////////////////////////////////////////////////////////////
/// timer_set function initializes selected Timer ///
/// ///
/// Parms: ///
/// - timer: timer to be initialized ///
/// - inc_dec: 0 - counter decreases ///
// 1 - counter increase ///
/// - ena: 0 - timer disabled ///
// 1 - timer enabled ///
/// - divider: timer prescaler ///
/// - init_value: timer initial value ///
/// - alarm: 0 - alarm off ///
/// 1 - alarm on ///
/// - alarm_value: alarm interrupt value ///
/// - autoreload: 0 - alarm not autoreloaded ///
/// 1 - alarm autoreloaded ///
/// ///
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
void timer_set(uint8_t timer, uint8_t inc_dec, uint8_t ena, uint16_t divider, uint64_t init_value, uint8_t alarm, uint64_t alarm_value){
uint8_t AUTORELOAD = 0;
uint8_t INT_TYPE = 1;
if (divider < 2){
divider = 2;
printf("Unexpected divider value...... Divider set as 2!\n");
}
uint32_t init_value_hi = ((init_value & 0xFFFFFFFF00000000) >> 0x20);
uint32_t init_value_lo = (init_value & 0x00000000FFFFFFFF);
*((volatile uint32_t*)(TIMER_0_CONFIG_REG|0x24*timer)) &= 0x000003FF;
*((volatile uint32_t*)(TIMER_0_CONFIG_REG|0x24*timer)) |= ((inc_dec<<0x1E)|(AUTORELOAD<<0x1D)|(divider<<0x0D)|(INT_TYPE<<0x0B));
*((volatile uint32_t*)(TIMER_0_RELOAD_HI_REG|0x24*timer)) &= 0x00;
*((volatile uint32_t*)(TIMER_0_RELOAD_HI_REG|0x24*timer)) |= init_value_hi;
*((volatile uint32_t*)(TIMER_0_RELOAD_LO_REG|0x24*timer)) &= 0x00;
*((volatile uint32_t*)(TIMER_0_RELOAD_LO_REG|0x24*timer)) |= init_value_lo;
*((volatile uint32_t*)(TIMER_0_RELOAD_REG|0x24*timer)) |= 0x01;
uint32_t alarm_value_hi = ((alarm_value & 0xFFFFFFFF00000000) >> 0x20);
uint32_t alarm_value_lo = (alarm_value & 0x00000000FFFFFFFF);
*((volatile uint32_t*)(TIMER_0_ALARM_HI_REG|0x24*timer)) &= 0x00;
*((volatile uint32_t*)(TIMER_0_ALARM_HI_REG|0x24*timer)) |= alarm_value_hi;
*((volatile uint32_t*)(TIMER_0_ALARM_LO_REG|0x24*timer)) &= 0x00;
*((volatile uint32_t*)(TIMER_0_ALARM_LO_REG|0x24*timer)) |= alarm_value_lo;
if (timer == 0){
*((volatile uint32_t*)(TIMER_INT_ENA_REG)) &= 0x06;
*((volatile uint32_t*)(TIMER_INT_ENA_REG)) |= alarm;
*((volatile uint32_t*)(TIMER_INT_CLR_REG)) |= 0x01;
} else {
*((volatile uint32_t*)(TIMER_INT_ENA_REG)) &= 0x05;
*((volatile uint32_t*)(TIMER_INT_ENA_REG)) |= (alarm << 0x01);
*((volatile uint32_t*)(TIMER_INT_CLR_REG)) |= (0x01 << 0x01);
}
*((volatile uint32_t*)(TIMER_0_CONFIG_REG|0x24*timer)) |= ((ena<<0x1F)|(alarm<<0x0A));
}[/Codebox]