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…
	
	Add table
		Add a link
		
	
		Reference in a new issue