Skip to content

Commit 8393dfc

Browse files
committed
Expose Chip CCompare0 timer
1 parent 912c79d commit 8393dfc

File tree

4 files changed

+77
-3
lines changed

4 files changed

+77
-3
lines changed

cores/esp8266/Arduino.h

+16-2
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,20 @@ void timer1_attachInterrupt(void (*userFunc)(void));
107107
void timer1_detachInterrupt(void);
108108
void timer1_write(uint32_t ticks); //maximum ticks 8388607
109109

110+
// timer0 is a special CPU timer that has very high resolution but with
111+
// limited control.
112+
// it uses CCOUNT (ESP.GetCycleCount()) as the non-resetable timer counter
113+
// it does not support divide, type, or reload flags
114+
// it is auto-disabled when the compare value matches CCOUNT
115+
// it is auto-enabled when the compare value changes
116+
#define timer0_interrupted() (ETS_INTR_PENDING() & (_BV(ETS_COMPARE0_INUM)))
117+
#define timer0_read() (ESP.getCycleCompare0())
118+
#define timer0_write(ticks) (ESP.setCycleCompare0(ticks))
119+
120+
void timer0_isr_init(void);
121+
void timer0_attachInterrupt(void(*userFunc)(void));
122+
void timer0_detachInterrupt(void);
123+
110124
// undefine stdlib's abs if encountered
111125
#ifdef abs
112126
#undef abs
@@ -126,13 +140,13 @@ void ets_intr_unlock();
126140
// level 15 will disable ALL interrupts,
127141
// level 0 will disable most software interrupts
128142
//
129-
#define xt_disable_interrupts(state, level) __asm__ __volatile__("rsil %0," __STRINGIFY(level) "; esync; isync; dsync" : "=a" (state))
143+
#define xt_disable_interrupts(state, level) __asm__ __volatile__("rsil %0," __STRINGIFY(level) : "=a" (state))
130144
#define xt_enable_interrupts(state) __asm__ __volatile__("wsr %0,ps; esync" :: "a" (state) : "memory")
131145

132146
extern uint32_t interruptsState;
133147

134148
#define interrupts() xt_enable_interrupts(interruptsState)
135-
#define noInterrupts() __asm__ __volatile__("rsil %0,15; esync; isync; dsync" : "=a" (interruptsState))
149+
#define noInterrupts() __asm__ __volatile__("rsil %0,15" : "=a" (interruptsState))
136150

137151
#define clockCyclesPerMicrosecond() ( F_CPU / 1000000L )
138152
#define clockCyclesToMicroseconds(a) ( (a) / clockCyclesPerMicrosecond() )

cores/esp8266/Esp.h

+17-1
Original file line numberDiff line numberDiff line change
@@ -99,15 +99,31 @@ class EspClass {
9999
uint32_t getFlashChipSizeByChipId(void);
100100

101101
inline uint32_t getCycleCount(void);
102+
inline uint32_t getCycleCompare0(void);
103+
inline void setCycleCompare0(uint32_t count);
102104
};
103105

104106
uint32_t EspClass::getCycleCount(void)
105107
{
106108
uint32_t ccount;
107-
__asm__ __volatile__("rsr %0,ccount":"=a" (ccount));
109+
__asm__ __volatile__("esync; rsr %0,ccount":"=a" (ccount));
108110
return ccount;
109111
}
110112

113+
// this returns a value in the range of (0 - 2^32)
114+
uint32_t EspClass::getCycleCompare0(void)
115+
{
116+
uint32_t count;
117+
__asm__ __volatile__("esync; rsr %0,ccompare0":"=a" (count));
118+
return count;
119+
}
120+
121+
// this takes a value in the range of (0 - 2^32)
122+
void EspClass::setCycleCompare0(uint32_t count)
123+
{
124+
__asm__ __volatile__("wsr %0,ccompare0; esync"::"a" (count) : "memory");
125+
}
126+
111127
extern EspClass ESP;
112128

113129
#endif //ESP_H

cores/esp8266/core_esp8266_timer.c

+22
Original file line numberDiff line numberDiff line change
@@ -59,3 +59,25 @@ void timer1_disable(){
5959
T1C = 0;
6060
T1I = 0;
6161
}
62+
63+
void(*timer0_user_cb)(void);
64+
65+
void timer0_isr_handler(void *para){
66+
if (timer0_user_cb) {
67+
timer0_user_cb();
68+
}
69+
}
70+
71+
void timer0_isr_init(){
72+
ETS_CCOMPARE0_INTR_ATTACH(timer0_isr_handler, NULL);
73+
}
74+
75+
void timer0_attachInterrupt(void(*userFunc)(void)) {
76+
timer1_user_cb = userFunc;
77+
ETS_CCOMPARE0_ENABLE();
78+
}
79+
80+
void timer0_detachInterrupt() {
81+
timer1_user_cb = NULL;
82+
ETS_CCOMPARE0_DISABLE();
83+
}

tools/sdk/include/ets_sys.h

+22
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ typedef void (*int_handler_t)(void*);
4343
#define ETS_GPIO_INUM 4
4444
#define ETS_UART_INUM 5
4545
#define ETS_UART1_INUM 5
46+
#define ETS_CCOMPARE0_INUM 6
4647
#define ETS_FRC_TIMER1_INUM 9 /* use edge*/
4748

4849
#define ETS_INTR_LOCK() \
@@ -51,6 +52,9 @@ typedef void (*int_handler_t)(void*);
5152
#define ETS_INTR_UNLOCK() \
5253
ets_intr_unlock()
5354

55+
#define ETS_CCOMPARE0_INTR_ATTACH(func, arg) \
56+
ets_isr_attach(ETS_CCOMPARE0_INUM, (int_handler_t)(func), (void *)(arg))
57+
5458
#define ETS_FRC_TIMER1_INTR_ATTACH(func, arg) \
5559
ets_isr_attach(ETS_FRC_TIMER1_INUM, (int_handler_t)(func), (void *)(arg))
5660

@@ -69,6 +73,18 @@ typedef void (*int_handler_t)(void*);
6973
#define ETS_INTR_DISABLE(inum) \
7074
ets_isr_mask((1<<inum))
7175

76+
{
77+
uint32_t enabled;
78+
__asm__ __volatile__("esync; rsr %0,intenable":"=a" (enabled));
79+
return enabled;
80+
}
81+
82+
{
83+
uint32_t pending;
84+
__asm__ __volatile__("esync; rsr %0,interrupt":"=a" (pending));
85+
return pending;
86+
}
87+
7288
#define ETS_SPI_INTR_ENABLE() \
7389
ETS_INTR_ENABLE(ETS_SPI_INUM)
7490

@@ -78,6 +94,12 @@ typedef void (*int_handler_t)(void*);
7894
#define ETS_UART_INTR_DISABLE() \
7995
ETS_INTR_DISABLE(ETS_UART_INUM)
8096

97+
#define ETS_CCOMPARE0_ENABLE() \
98+
ETS_INTR_ENABLE(ETS_CCOMPARE0_INUM)
99+
100+
#define ETS_CCOMPARE0_DISABLE() \
101+
ETS_INTR_DISABLE(ETS_CCOMPARE0_INUM)
102+
81103
#define ETS_FRC1_INTR_ENABLE() \
82104
ETS_INTR_ENABLE(ETS_FRC_TIMER1_INUM)
83105

0 commit comments

Comments
 (0)