xtensa_interrupts: Add _xt_disable_interrupts/_xt_restore_interrupts inline functions
This commit is contained in:
parent
a3c4469b1f
commit
4217a1029e
2 changed files with 45 additions and 16 deletions
|
@ -73,7 +73,6 @@ 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 <xtruntime.h>
|
|
||||||
#include "xtensa_rtos.h"
|
#include "xtensa_rtos.h"
|
||||||
#include "xtensa_interrupts.h"
|
#include "xtensa_interrupts.h"
|
||||||
|
|
||||||
|
@ -144,33 +143,31 @@ extern char sdk_NMIIrqIsOn;
|
||||||
extern char level1_int_disabled;
|
extern char level1_int_disabled;
|
||||||
extern unsigned cpu_sr;
|
extern unsigned cpu_sr;
|
||||||
|
|
||||||
/* ESPTODO: Currently we store the old interrupt level (ps) in a
|
/* Disable interrupts, store old ps level in global variable cpu_sr.
|
||||||
global variable cpu_sr. It may not be necessary to do this,
|
|
||||||
especially as lx106 has only one real interrupt level + NMI, but it
|
Note: cpu_sr is also referenced by the binary SDK.
|
||||||
all depends on how the blob libraries call into these functions.
|
|
||||||
|
Where possible (and when writing non-FreeRTOS specific code),
|
||||||
|
prefer to _xt_disable_interrupts & _xt_enable_interrupts and store
|
||||||
|
the ps value in a local variable - that approach is recursive-safe
|
||||||
|
and generally better.
|
||||||
*/
|
*/
|
||||||
inline static __attribute__((always_inline)) void _esp_disable_interrupts(void)
|
inline static __attribute__((always_inline)) void portDISABLE_INTERRUPTS(void)
|
||||||
{
|
{
|
||||||
if(!sdk_NMIIrqIsOn && !level1_int_disabled) {
|
if(!sdk_NMIIrqIsOn && !level1_int_disabled) {
|
||||||
__asm__ volatile ("rsil %0, " XTSTR(XCHAL_EXCM_LEVEL) : "=a" (cpu_sr) :: "memory");
|
cpu_sr = _xt_disable_interrupts();
|
||||||
level1_int_disabled = 1;
|
level1_int_disabled = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline static __attribute__((always_inline)) void _esp_enable_interrupts(void)
|
inline static __attribute__((always_inline)) void portENABLE_INTERRUPTS(void)
|
||||||
{
|
{
|
||||||
if(!sdk_NMIIrqIsOn && level1_int_disabled) {
|
if(!sdk_NMIIrqIsOn && level1_int_disabled) {
|
||||||
level1_int_disabled = 0;
|
level1_int_disabled = 0;
|
||||||
__asm__ volatile ("wsr %0, ps" :: "a" (cpu_sr) : "memory");
|
_xt_restore_interrupts(cpu_sr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Disable interrupts, saving previous state in cpu_sr */
|
|
||||||
#define portDISABLE_INTERRUPTS() _esp_disable_interrupts()
|
|
||||||
|
|
||||||
/* Restore interrupts to previous level saved in cpu_sr */
|
|
||||||
#define portENABLE_INTERRUPTS() _esp_enable_interrupts()
|
|
||||||
|
|
||||||
/* Critical section management. */
|
/* Critical section management. */
|
||||||
void vPortEnterCritical( void );
|
void vPortEnterCritical( void );
|
||||||
void vPortExitCritical( void );
|
void vPortExitCritical( void );
|
||||||
|
|
|
@ -10,13 +10,45 @@
|
||||||
#ifndef _XTENSA_INTERRUPTS_H
|
#ifndef _XTENSA_INTERRUPTS_H
|
||||||
#define _XTENSA_INTERRUPTS_H
|
#define _XTENSA_INTERRUPTS_H
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <xtruntime.h>
|
||||||
#include <xtensa/hal.h>
|
#include <xtensa/hal.h>
|
||||||
|
#include <common_macros.h>
|
||||||
|
|
||||||
void sdk__xt_int_exit (void);
|
void sdk__xt_int_exit (void);
|
||||||
void sdk__xt_user_exit (void);
|
void sdk__xt_user_exit (void);
|
||||||
void sdk__xt_tick_timer_init (void);
|
void sdk__xt_tick_timer_init (void);
|
||||||
void sdk__xt_timer_int1(void);
|
void sdk__xt_timer_int1(void);
|
||||||
|
|
||||||
|
INLINED uint32_t _xt_get_intlevel(void)
|
||||||
|
{
|
||||||
|
uint32_t level;
|
||||||
|
__asm__ volatile("rsr %0, intlevel" : "=a"(level));
|
||||||
|
return level;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Disable interrupts and return the old ps value, to pass into
|
||||||
|
_xt_restore_interrupts later.
|
||||||
|
|
||||||
|
This is desirable to use in place of
|
||||||
|
portDISABLE_INTERRUPTS/portENABLE_INTERRUPTS for
|
||||||
|
non-FreeRTOS & non-portable code.
|
||||||
|
*/
|
||||||
|
INLINED uint32_t _xt_disable_interrupts(void)
|
||||||
|
{
|
||||||
|
uint32_t old_level;
|
||||||
|
__asm__ volatile ("rsil %0, " XTSTR(XCHAL_EXCM_LEVEL) : "=a" (old_level));
|
||||||
|
return old_level;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Restore PS level. Intended to be used with _xt_disable_interrupts */
|
||||||
|
INLINED void _xt_restore_interrupts(uint32_t new_ps)
|
||||||
|
{
|
||||||
|
__asm__ volatile ("wsr %0, ps; rsync" :: "a" (new_ps));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ESPTODO: the mask/unmask functions aren't thread safe */
|
||||||
|
|
||||||
INLINED void _xt_isr_unmask(uint32_t unmask)
|
INLINED void _xt_isr_unmask(uint32_t unmask)
|
||||||
{
|
{
|
||||||
uint32_t intenable;
|
uint32_t intenable;
|
||||||
|
|
Loading…
Reference in a new issue