Consolidate interrupt management in core as esp/interrupts.h & esp_interrupts.c
This commit is contained in:
parent
65307aed75
commit
ed8470631f
8 changed files with 83 additions and 98 deletions
|
@ -265,60 +265,3 @@ void IRAM vPortExitCritical( void )
|
||||||
portENABLE_INTERRUPTS();
|
portENABLE_INTERRUPTS();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
/* Main ISR handler for FreeRTOS side of the ESP libs?
|
|
||||||
|
|
||||||
As far as I can tell, the "real" Xtensa ISRs ("Exceptions") are
|
|
||||||
handled in libmain.a (xtensa_vectors.o) which then can call into here
|
|
||||||
passing an interrupt mask.
|
|
||||||
*/
|
|
||||||
|
|
||||||
_xt_isr isr[16];
|
|
||||||
|
|
||||||
void IRAM _xt_isr_attach(uint8_t i, _xt_isr func)
|
|
||||||
{
|
|
||||||
isr[i] = func;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t IRAM _xt_isr_handler(uint16_t i)
|
|
||||||
{
|
|
||||||
uint8_t index;
|
|
||||||
|
|
||||||
/* I think this is implementing some kind of interrupt priority or
|
|
||||||
short-circuiting an expensive ffs for most common interrupts - ie
|
|
||||||
WDT And GPIO are common or high priority, then remaining flags.
|
|
||||||
*/
|
|
||||||
if (i & (1 << INUM_WDT)) {
|
|
||||||
index = INUM_WDT;
|
|
||||||
}
|
|
||||||
else if (i & (1 << INUM_GPIO)) {
|
|
||||||
index = INUM_GPIO;
|
|
||||||
}else {
|
|
||||||
index = __builtin_ffs(i) - 1;
|
|
||||||
|
|
||||||
if (index == INUM_MAX) {
|
|
||||||
/* I don't understand what happens here. INUM_MAX is not
|
|
||||||
the highest interrupt number listed (and the isr array
|
|
||||||
has 16 entries).
|
|
||||||
|
|
||||||
Clearing that flag and then setting index to
|
|
||||||
__builtin_ffs(i)-1 may result in index == 255 if no
|
|
||||||
higher flags are set, unless this is guarded against
|
|
||||||
somehow by the caller?
|
|
||||||
|
|
||||||
I also don't understand why the code is written like
|
|
||||||
this in esp_iot_rtos_sdk instead of just putting the i
|
|
||||||
&= line near the top... Probably no good reason?
|
|
||||||
*/
|
|
||||||
i &= ~(1 << INUM_MAX);
|
|
||||||
index = __builtin_ffs(i) - 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_xt_clear_ints(1<<index);
|
|
||||||
|
|
||||||
isr[index]();
|
|
||||||
|
|
||||||
return i & ~(1 << index);
|
|
||||||
}
|
|
||||||
|
|
|
@ -73,8 +73,8 @@ extern "C" {
|
||||||
#include "esp8266.h"
|
#include "esp8266.h"
|
||||||
#include "espressif/esp8266/ets_sys.h"
|
#include "espressif/esp8266/ets_sys.h"
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "xtensa_rtos.h"
|
#include "xtensa_rtos.h"
|
||||||
#include "xtensa_interrupts.h"
|
#include <esp/interrupts.h>
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Port specific definitions for ESP8266
|
* Port specific definitions for ESP8266
|
||||||
|
|
60
core/esp_interrupts.c
Normal file
60
core/esp_interrupts.c
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
/* ESP8266 Xtensa interrupt management functions
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Part of esp-open-rtos
|
||||||
|
* Copyright (C) 2015 Angus Gratton
|
||||||
|
* BSD Licensed as described in the file LICENSE
|
||||||
|
*/
|
||||||
|
#include <esp/interrupts.h>
|
||||||
|
|
||||||
|
_xt_isr isr[16];
|
||||||
|
|
||||||
|
void IRAM _xt_isr_attach(uint8_t i, _xt_isr func)
|
||||||
|
{
|
||||||
|
isr[i] = func;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This ISR handler is taken directly from the FreeRTOS port and
|
||||||
|
probably could use a cleanup.
|
||||||
|
*/
|
||||||
|
uint16_t IRAM _xt_isr_handler(uint16_t i)
|
||||||
|
{
|
||||||
|
uint8_t index;
|
||||||
|
|
||||||
|
/* I think this is implementing some kind of interrupt priority or
|
||||||
|
short-circuiting an expensive ffs for most common interrupts - ie
|
||||||
|
WDT And GPIO are common or high priority, then remaining flags.
|
||||||
|
*/
|
||||||
|
if (i & (1 << INUM_WDT)) {
|
||||||
|
index = INUM_WDT;
|
||||||
|
}
|
||||||
|
else if (i & (1 << INUM_GPIO)) {
|
||||||
|
index = INUM_GPIO;
|
||||||
|
}else {
|
||||||
|
index = __builtin_ffs(i) - 1;
|
||||||
|
|
||||||
|
if (index == INUM_MAX) {
|
||||||
|
/* I don't understand what happens here. INUM_MAX is not
|
||||||
|
the highest interrupt number listed (and the isr array
|
||||||
|
has 16 entries).
|
||||||
|
|
||||||
|
Clearing that flag and then setting index to
|
||||||
|
__builtin_ffs(i)-1 may result in index == 255 if no
|
||||||
|
higher flags are set, unless this is guarded against
|
||||||
|
somehow by the caller?
|
||||||
|
|
||||||
|
I also don't understand why the code is written like
|
||||||
|
this in esp_iot_rtos_sdk instead of just putting the i
|
||||||
|
&= line near the top... Probably no good reason?
|
||||||
|
*/
|
||||||
|
i &= ~(1 << INUM_MAX);
|
||||||
|
index = __builtin_ffs(i) - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_xt_clear_ints(1<<index);
|
||||||
|
|
||||||
|
isr[index]();
|
||||||
|
|
||||||
|
return i & ~(1 << index);
|
||||||
|
}
|
|
@ -1,33 +0,0 @@
|
||||||
/* esp/cpu.h
|
|
||||||
*
|
|
||||||
* Details relating to the ESP8266 Xtensa core.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#ifndef _ESP_CPU_H
|
|
||||||
#define _ESP_CPU_H
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
/* Interrupt numbers for level 1 exception handler.
|
|
||||||
*
|
|
||||||
* Currently the UserExceptionVector calls down to _xt_isr_handler,
|
|
||||||
* defined in port.c, for at least some of these interrupts. Some are handled
|
|
||||||
* on the SDK side, though.
|
|
||||||
*/
|
|
||||||
typedef enum {
|
|
||||||
INUM_SPI = 2,
|
|
||||||
INUM_GPIO = 4,
|
|
||||||
INUM_UART = 5,
|
|
||||||
INUM_MAX = 6, /* in some places this is documented as timer0 CCOMPARE0 interrupt */
|
|
||||||
INUM_SOFT = 7,
|
|
||||||
INUM_WDT = 8,
|
|
||||||
INUM_TIMER_FRC1 = 9,
|
|
||||||
|
|
||||||
/* FRC2 default handler. Configured by sdk_ets_timer_init, which
|
|
||||||
runs as part of default libmain.a startup code, assigns
|
|
||||||
interrupt handler to sdk_vApplicationTickHook+0x68
|
|
||||||
*/
|
|
||||||
INUM_TIMER_FRC2 = 10,
|
|
||||||
} xt_isr_num_t;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -11,8 +11,7 @@
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include "esp/gpio_regs.h"
|
#include "esp/gpio_regs.h"
|
||||||
#include "esp/iomux.h"
|
#include "esp/iomux.h"
|
||||||
#include "esp/cpu.h"
|
#include "esp/interrupts.h"
|
||||||
#include "xtensa_interrupts.h"
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
GPIO_INPUT,
|
GPIO_INPUT,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* Xtensa interrupt management functions
|
/* ESP8266 Xtensa interrupt management functions
|
||||||
*
|
*
|
||||||
* Some (w/ sdk_ prefix) are implemented in binary libs, rest are
|
* Some (w/ sdk_ prefix) are implemented in binary libs, rest are
|
||||||
* inlines replacing functions in the binary libraries.
|
* inlines replacing functions in the binary libraries.
|
||||||
|
@ -15,6 +15,23 @@
|
||||||
#include <xtensa/hal.h>
|
#include <xtensa/hal.h>
|
||||||
#include <common_macros.h>
|
#include <common_macros.h>
|
||||||
|
|
||||||
|
/* Interrupt numbers for level 1 exception handler. */
|
||||||
|
typedef enum {
|
||||||
|
INUM_SPI = 2,
|
||||||
|
INUM_GPIO = 4,
|
||||||
|
INUM_UART = 5,
|
||||||
|
INUM_MAX = 6, /* in some places this is documented as timer0 CCOMPARE0 interrupt */
|
||||||
|
INUM_SOFT = 7,
|
||||||
|
INUM_WDT = 8,
|
||||||
|
INUM_TIMER_FRC1 = 9,
|
||||||
|
|
||||||
|
/* FRC2 default handler. Configured by sdk_ets_timer_init, which
|
||||||
|
runs as part of default libmain.a startup code, assigns
|
||||||
|
interrupt handler to sdk_vApplicationTickHook+0x68
|
||||||
|
*/
|
||||||
|
INUM_TIMER_FRC2 = 10,
|
||||||
|
} xt_isr_num_t;
|
||||||
|
|
||||||
void sdk__xt_int_exit (void);
|
void sdk__xt_int_exit (void);
|
||||||
void _xt_user_exit (void);
|
void _xt_user_exit (void);
|
||||||
void sdk__xt_tick_timer_init (void);
|
void sdk__xt_tick_timer_init (void);
|
|
@ -10,9 +10,8 @@
|
||||||
#define _ESP_TIMER_H
|
#define _ESP_TIMER_H
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <xtensa_interrupts.h>
|
|
||||||
#include "esp/timer_regs.h"
|
#include "esp/timer_regs.h"
|
||||||
#include "esp/cpu.h"
|
#include "esp/interrupts.h"
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
FRC1 = 0,
|
FRC1 = 0,
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
#include "common_macros.h"
|
#include "common_macros.h"
|
||||||
#include "esp/registers.h"
|
#include "esp/registers.h"
|
||||||
#include "esp/cpu.h"
|
#include "esp/interrupts.h"
|
||||||
#include "esp/iomux.h"
|
#include "esp/iomux.h"
|
||||||
#include "esp/gpio.h"
|
#include "esp/gpio.h"
|
||||||
#include "esp/timer.h"
|
#include "esp/timer.h"
|
||||||
|
|
Loading…
Reference in a new issue