mirror of
https://github.com/esp8266/Arduino.git
synced 2025-06-07 16:23:38 +03:00
commit
a0172dd93a
@ -137,17 +137,29 @@ void timer0_detachInterrupt(void);
|
|||||||
void ets_intr_lock();
|
void ets_intr_lock();
|
||||||
void ets_intr_unlock();
|
void ets_intr_unlock();
|
||||||
|
|
||||||
// level (0-15),
|
#ifndef __STRINGIFY
|
||||||
// level 15 will disable ALL interrupts,
|
#define __STRINGIFY(a) #a
|
||||||
// level 0 will disable most software interrupts
|
#endif
|
||||||
|
|
||||||
|
// these low level routines provide a replacement for SREG interrupt save that AVR uses
|
||||||
|
// but are esp8266 specific. A normal use pattern is like
|
||||||
//
|
//
|
||||||
#define xt_disable_interrupts(state, level) __asm__ __volatile__("rsil %0," __STRINGIFY(level) : "=a" (state))
|
//{
|
||||||
#define xt_enable_interrupts(state) __asm__ __volatile__("wsr %0,ps; isync" :: "a" (state) : "memory")
|
// uint32_t savedPS = xt_rsil(1); // this routine will allow level 2 and above
|
||||||
|
// // do work here
|
||||||
|
// xt_wsr_ps(savedPS); // restore the state
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
// level (0-15), interrupts of the given level and above will be active
|
||||||
|
// level 15 will disable ALL interrupts,
|
||||||
|
// level 0 will enable ALL interrupts,
|
||||||
|
//
|
||||||
|
#define xt_rsil(level) (__extension__({uint32_t state; __asm__ __volatile__("rsil %0," __STRINGIFY(level) : "=a" (state)); state;}))
|
||||||
|
#define xt_wsr_ps(state) __asm__ __volatile__("wsr %0,ps; isync" :: "a" (state) : "memory")
|
||||||
|
|
||||||
extern uint32_t interruptsState;
|
#define interrupts() xt_rsil(0)
|
||||||
|
#define noInterrupts() xt_rsil(15)
|
||||||
|
|
||||||
#define interrupts() xt_enable_interrupts(interruptsState)
|
|
||||||
#define noInterrupts() __asm__ __volatile__("rsil %0,15" : "=a" (interruptsState))
|
|
||||||
|
|
||||||
#define clockCyclesPerMicrosecond() ( F_CPU / 1000000L )
|
#define clockCyclesPerMicrosecond() ( F_CPU / 1000000L )
|
||||||
#define clockCyclesToMicroseconds(a) ( (a) / clockCyclesPerMicrosecond() )
|
#define clockCyclesToMicroseconds(a) ( (a) / clockCyclesPerMicrosecond() )
|
||||||
|
@ -32,7 +32,13 @@ static volatile timercallback timer1_user_cb = NULL;
|
|||||||
void timer1_isr_handler(void *para){
|
void timer1_isr_handler(void *para){
|
||||||
if ((T1C & ((1 << TCAR) | (1 << TCIT))) == 0) TEIE &= ~TEIE1;//edge int disable
|
if ((T1C & ((1 << TCAR) | (1 << TCIT))) == 0) TEIE &= ~TEIE1;//edge int disable
|
||||||
T1I = 0;
|
T1I = 0;
|
||||||
if (timer1_user_cb) timer1_user_cb();
|
if (timer1_user_cb) {
|
||||||
|
// to make ISR compatible to Arduino AVR model where interrupts are disabled
|
||||||
|
// we disable them before we call the client ISR
|
||||||
|
uint32_t savedPS = xt_rsil(15); // stop other interrupts
|
||||||
|
timer1_user_cb();
|
||||||
|
xt_wsr_ps(savedPS);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void timer1_isr_init(){
|
void timer1_isr_init(){
|
||||||
@ -72,7 +78,11 @@ static volatile timercallback timer0_user_cb = NULL;
|
|||||||
|
|
||||||
void timer0_isr_handler(void* para){
|
void timer0_isr_handler(void* para){
|
||||||
if (timer0_user_cb) {
|
if (timer0_user_cb) {
|
||||||
|
// to make ISR compatible to Arduino AVR model where interrupts are disabled
|
||||||
|
// we disable them before we call the client ISR
|
||||||
|
uint32_t savedPS = xt_rsil(15); // stop other interrupts
|
||||||
timer0_user_cb();
|
timer0_user_cb();
|
||||||
|
xt_wsr_ps(savedPS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,7 +123,11 @@ void interrupt_handler(void *arg) {
|
|||||||
if (handler->fn &&
|
if (handler->fn &&
|
||||||
(handler->mode == CHANGE ||
|
(handler->mode == CHANGE ||
|
||||||
(handler->mode & 1) == digitalRead(i))) {
|
(handler->mode & 1) == digitalRead(i))) {
|
||||||
|
// to make ISR compatible to Arduino AVR model where interrupts are disabled
|
||||||
|
// we disable them before we call the client ISR
|
||||||
|
uint32_t savedPS = xt_rsil(15); // stop other interrupts
|
||||||
handler->fn();
|
handler->fn();
|
||||||
|
xt_wsr_ps(savedPS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ETS_GPIO_INTR_ENABLE();
|
ETS_GPIO_INTR_ENABLE();
|
||||||
@ -152,9 +156,6 @@ extern void __detachInterrupt(uint8_t pin) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// stored state for the noInterrupts/interrupts methods
|
|
||||||
uint32_t interruptsState = 0;
|
|
||||||
|
|
||||||
void initPins() {
|
void initPins() {
|
||||||
//Disable UART interrupts
|
//Disable UART interrupts
|
||||||
system_set_os_print(0);
|
system_set_os_print(0);
|
||||||
|
@ -8,23 +8,51 @@ extern "C" {
|
|||||||
#include "ets_sys.h"
|
#include "ets_sys.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// these auto classes wrap up xt_rsil so your code can be simplier, but can only be
|
||||||
|
// used in an ino or cpp files.
|
||||||
|
|
||||||
#define xt_disable_interrupts(state, level) __asm__ __volatile__("rsil %0," __STRINGIFY(level) : "=a" (state))
|
// InterruptLock is used when you want to completely disable locks
|
||||||
#define xt_enable_interrupts(state) __asm__ __volatile__("wsr %0,ps; isync" :: "a" (state) : "memory")
|
//{
|
||||||
|
// {
|
||||||
|
// InterruptLock lock;
|
||||||
|
// // do work within interrupt lock here
|
||||||
|
// }
|
||||||
|
// do work outside of interrupt lock here outside its scope
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
|
||||||
class InterruptLock {
|
class InterruptLock {
|
||||||
public:
|
public:
|
||||||
InterruptLock() {
|
InterruptLock() {
|
||||||
xt_disable_interrupts(_state, 15);
|
_state = xt_rsil(15);
|
||||||
}
|
}
|
||||||
|
|
||||||
~InterruptLock() {
|
~InterruptLock() {
|
||||||
xt_enable_interrupts(_state);
|
xt_wsr_ps(_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
uint32_t _state;
|
uint32_t _state;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// AutoInterruptLock is when you need to set a specific level, A normal use pattern is like
|
||||||
|
//
|
||||||
|
//{
|
||||||
|
// {
|
||||||
|
// AutoInterruptLock(1); // this routine will allow level 2 and above
|
||||||
|
// // do work within interrupt lock here
|
||||||
|
// }
|
||||||
|
// do work outside of interrupt lock here outside its scope
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
#define AutoInterruptLock(intrLevel) \
|
||||||
|
class _AutoDisableIntr { \
|
||||||
|
public: \
|
||||||
|
_AutoDisableIntr() { _savedPS = xt_rsil(intrLevel); } \
|
||||||
|
~_AutoDisableIntr() { xt_wsr_ps(_savedPS); } \
|
||||||
|
private: \
|
||||||
|
uint32_t _savedPS; \
|
||||||
|
}; \
|
||||||
|
_AutoDisableIntr _autoDisableIntr
|
||||||
|
|
||||||
#endif //INTERRUPTS_H
|
#endif //INTERRUPTS_H
|
||||||
|
@ -59,8 +59,6 @@ static uint8_t s_servoCount = 0; // the total number of attached s_se
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
template <class T> void Servo_Handler(T* timer)
|
template <class T> void Servo_Handler(T* timer)
|
||||||
{
|
{
|
||||||
noInterrupts();
|
|
||||||
|
|
||||||
uint8_t servoIndex;
|
uint8_t servoIndex;
|
||||||
|
|
||||||
// clear interrupt
|
// clear interrupt
|
||||||
@ -101,8 +99,6 @@ template <class T> void Servo_Handler(T* timer)
|
|||||||
|
|
||||||
timer->setEndOfCycle();
|
timer->setEndOfCycle();
|
||||||
}
|
}
|
||||||
|
|
||||||
interrupts();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void initISR(ServoTimerSequence timerId)
|
static void initISR(ServoTimerSequence timerId)
|
||||||
|
@ -65,8 +65,8 @@ inline bool ETS_INTR_WITHINISR()
|
|||||||
{
|
{
|
||||||
uint32_t ps;
|
uint32_t ps;
|
||||||
__asm__ __volatile__("rsr %0,ps":"=a" (ps));
|
__asm__ __volatile__("rsr %0,ps":"=a" (ps));
|
||||||
// PS.EXCM bit check
|
// PS.INTLEVEL check
|
||||||
return ((ps & (1 << 4)) != 0);
|
return ((ps & 0x0f) != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline uint32_t ETS_INTR_ENABLED(void)
|
inline uint32_t ETS_INTR_ENABLED(void)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user