Page 1 of 1

ESP32 Peripherals Interruptions

Posted: Sun Nov 27, 2022 1:03 pm
by AlejandroJimenez
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 :cry: :cry:

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]
timer_set function is defined on timer.h header and timer.c files:

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]
Can anybody help me please?? I do not know what else can I do :(