11/* ************************************************************************************
2- * ESP8266TimerInterrupt.h
3- * For ESP8266 boards
4- * Written by Khoi Hoang
5- *
6- * Built by Khoi Hoang https://github.com/khoih-prog/ESP32TimerInterrupt
7- * Licensed under MIT license
8- * Version: 1.0.1
9- *
10- * The ESP8266 timers are badly designed, using only 23-bit counter along with maximum 256 prescaler. They're only better than UNO / Mega.
11- * The ESP8266 has two hardware timers, but timer0 has been used for WiFi and it's not advisable to use. Only timer1 is available.
12- * The timer1's 23-bit counter terribly can count only up to 8,388,607. So the timer1 maximum interval is very short.
13- * Using 256 prescaler, maximum timer1 interval is only 26.843542 seconds !!!
14- *
15- * Version Modified By Date Comments
16- * ------- ----------- ---------- -----------
17- * 1.0.0 K Hoang 23/11/2019 Initial coding
18- * 1.0.1 K Hoang 25/11/2019 New release fixing compiler error
2+ ESP8266TimerInterrupt.h
3+ For ESP8266 boards
4+ Written by Khoi Hoang
5+
6+ Built by Khoi Hoang https://github.com/khoih-prog/ESP32TimerInterrupt
7+ Licensed under MIT license
8+ Version: 1.0.1
9+
10+ The ESP8266 timers are badly designed, using only 23-bit counter along with maximum 256 prescaler. They're only better than UNO / Mega.
11+ The ESP8266 has two hardware timers, but timer0 has been used for WiFi and it's not advisable to use. Only timer1 is available.
12+ The timer1's 23-bit counter terribly can count only up to 8,388,607. So the timer1 maximum interval is very short.
13+ Using 256 prescaler, maximum timer1 interval is only 26.843542 seconds !!!
14+
15+ Version Modified By Date Comments
16+ ------- ----------- ---------- -----------
17+ 1.0.0 K Hoang 23/11/2019 Initial coding
18+ 1.0.1 K Hoang 25/11/2019 New release fixing compiler error
1919****************************************************************************************/
2020
2121#ifndef ESP8266TimerInterrupt_h
3131
3232/* From /arduino-1.8.10/hardware/esp8266com/esp8266/cores/esp8266/esp8266_peri.h
3333
34- #define ESP8266_REG(addr) *((volatile uint32_t *)(0x60000000+(addr)))
35- #define ESP8266_DREG(addr) *((volatile uint32_t *)(0x3FF00000+(addr)))
36- #define ESP8266_CLOCK 80000000UL
34+ #define ESP8266_REG(addr) *((volatile uint32_t *)(0x60000000+(addr)))
35+ #define ESP8266_DREG(addr) *((volatile uint32_t *)(0x3FF00000+(addr)))
36+ #define ESP8266_CLOCK 80000000UL
3737
38- //CPU Register
39- #define CPU2X ESP8266_DREG(0x14) //when bit 0 is set, F_CPU = 160MHz
38+ //CPU Register
39+ #define CPU2X ESP8266_DREG(0x14) //when bit 0 is set, F_CPU = 160MHz
4040*/
4141
4242/* From /arduino-1.8.10/hardware/esp8266com/esp8266/cores/esp8266/Arduino.h
4343
44- //timer dividers
45- enum TIM_DIV_ENUM {
44+ //timer dividers
45+ enum TIM_DIV_ENUM {
4646 TIM_DIV1 = 0, // 80 / 160 MHz (80 / 160 ticks/us - 104857.588 us max)
4747 TIM_DIV16 = 1, // 5 / 10 MHz (5 / 10 ticks/us - 1677721.4 us max)
4848 TIM_DIV256 = 3 // 312.5 / 625 Khz (1 tick = 3.2 / 1.6 us - 26843542.4 us max)
49- };
49+ };
5050
51- //timer int_types
52- #define TIM_EDGE 0
53- #define TIM_LEVEL 1
54- //timer reload values
55- #define TIM_SINGLE 0 //on interrupt routine you need to write a new value to start the timer again
56- #define TIM_LOOP 1 //on interrupt the counter will start with the same value again
51+ //timer int_types
52+ #define TIM_EDGE 0
53+ #define TIM_LEVEL 1
54+ //timer reload values
55+ #define TIM_SINGLE 0 //on interrupt routine you need to write a new value to start the timer again
56+ #define TIM_LOOP 1 //on interrupt the counter will start with the same value again
5757
5858*/
5959
@@ -70,109 +70,109 @@ typedef void (*timer_callback) (void);
7070
7171class ESP8266TimerInterrupt
7272{
73- private:
73+ private:
7474 timer_callback _callback; // pointer to the callback function
7575 float _frequency; // Timer frequency
7676 uint32_t _timerCount; // count to activate timer
77-
77+
7878 public:
7979
80- ESP8266TimerInterrupt ()
81- {
82- _frequency = 0 ;
83- _timerCount = 0 ;
84- _callback = NULL ;
85- };
86-
87- // frequency (in hertz) and duration (in milliseconds). Duration = 0 or not specified => run indefinitely
88- // No params and duration now. To be addes in the future by adding similar functions here or to esp32-hal-timer.c
89- bool setFrequency (float frequency, timer_callback callback)
90- {
91- bool isOKFlag = true ;
92-
93- // ESP8266 only has one usable timer1, max count is only 8,388,607. So to get longer time, we use max available 256 divider
94- // Will use later if very low frequency is needed.
95- _frequency = 80000000 / 256 ;
96- _timerCount = (uint32_t ) _frequency / frequency;
97- _callback = callback;
98-
99- if ( _timerCount > MAX_ESP8266_COUNT)
80+ ESP8266TimerInterrupt ()
81+ {
82+ _frequency = 0 ;
83+ _timerCount = 0 ;
84+ _callback = NULL ;
85+ };
86+
87+ // frequency (in hertz) and duration (in milliseconds). Duration = 0 or not specified => run indefinitely
88+ // No params and duration now. To be addes in the future by adding similar functions here or to esp32-hal-timer.c
89+ bool setFrequency (float frequency, timer_callback callback)
90+ {
91+ bool isOKFlag = true ;
92+
93+ // ESP8266 only has one usable timer1, max count is only 8,388,607. So to get longer time, we use max available 256 divider
94+ // Will use later if very low frequency is needed.
95+ _frequency = 80000000 / 256 ;
96+ _timerCount = (uint32_t ) _frequency / frequency;
97+ _callback = callback;
98+
99+ if ( _timerCount > MAX_ESP8266_COUNT)
100+ {
101+ _timerCount = MAX_ESP8266_COUNT;
102+ // Flag error
103+ isOKFlag = false ;
104+ }
105+
106+ // count up
107+ #if (TIMER_INTERRUPT_DEBUG > 0)
108+ Serial.println (" ESP8266TimerInterrupt: _fre = " + String (_frequency) + " , _count = " + String (_timerCount));
109+ #endif
110+
111+ // Clock to timer (prescaler) is always 80MHz, even F_CPU is 160 MHz
112+
113+ timer1_attachInterrupt (callback);
114+
115+ timer1_write (_timerCount);
116+
117+ // Interrupt on EGDE, autoloop
118+ timer1_enable (TIM_DIV256, TIM_EDGE, TIM_LOOP);
119+
120+ return isOKFlag;
121+ }
122+
123+ // interval (in microseconds) and duration (in milliseconds). Duration = 0 or not specified => run indefinitely
124+ // No params and duration now. To be addes in the future by adding similar functions here or to esp32-hal-timer.c
125+ bool setInterval (unsigned long interval, timer_callback callback)
126+ {
127+ return setFrequency ((float ) (1000000 .0f / interval), callback);
128+ }
129+
130+ bool attachInterrupt (float frequency, timer_callback callback)
131+ {
132+ return setFrequency (frequency, callback);
133+ }
134+
135+ // interval (in microseconds) and duration (in milliseconds). Duration = 0 or not specified => run indefinitely
136+ // No params and duration now. To be addes in the future by adding similar functions here or to esp32-hal-timer.c
137+ bool attachInterruptInterval (unsigned long interval, timer_callback callback)
138+ {
139+ return setFrequency ( (float ) ( 1000000 .0f / interval), callback);
140+ }
141+
142+ void detachInterrupt ()
143+ {
144+ timer1_disable ();
145+ }
146+
147+ void disableTimer (void )
148+ {
149+ timer1_disable ();
150+ }
151+
152+ // Duration (in milliseconds). Duration = 0 or not specified => run indefinitely
153+ void reattachInterrupt ()
154+ {
155+ if ( (_frequency != 0 ) && (_timerCount != 0 ) && (_callback != NULL ) )
156+ setFrequency (_frequency, _callback);
157+ }
158+
159+ // Duration (in milliseconds). Duration = 0 or not specified => run indefinitely
160+ void enableTimer (void )
161+ {
162+ reattachInterrupt ();
163+ }
164+
165+ // Just stop clock source, clear the count
166+ void stopTimer (void )
167+ {
168+ timer1_disable ();
169+ }
170+
171+ // Just reconnect clock source, start current count from 0
172+ void restartTimer (void )
100173 {
101- _timerCount = MAX_ESP8266_COUNT;
102- // Flag error
103- isOKFlag = false ;
174+ enableTimer ();
104175 }
105-
106- // count up
107- #if (TIMER_INTERRUPT_DEBUG > 0)
108- Serial.println (" ESP8266TimerInterrupt: _fre = " + String (_frequency) + " , _count = " + String (_timerCount));
109- #endif
110-
111- // Clock to timer (prescaler) is always 80MHz, even F_CPU is 160 MHz
112-
113- timer1_attachInterrupt (callback);
114-
115- timer1_write (_timerCount);
116-
117- // Interrupt on EGDE, autoloop
118- timer1_enable (TIM_DIV256, TIM_EDGE, TIM_LOOP);
119-
120- return isOKFlag;
121- }
122-
123- // interval (in microseconds) and duration (in milliseconds). Duration = 0 or not specified => run indefinitely
124- // No params and duration now. To be addes in the future by adding similar functions here or to esp32-hal-timer.c
125- bool setInterval (unsigned long interval, timer_callback callback)
126- {
127- return setFrequency ((float ) (1000000 .0f / interval), callback);
128- }
129-
130- bool attachInterrupt (float frequency, timer_callback callback)
131- {
132- return setFrequency (frequency, callback);
133- }
134-
135- // interval (in microseconds) and duration (in milliseconds). Duration = 0 or not specified => run indefinitely
136- // No params and duration now. To be addes in the future by adding similar functions here or to esp32-hal-timer.c
137- bool attachInterruptInterval (unsigned long interval, timer_callback callback)
138- {
139- return setFrequency ( (float ) ( 1000000 .0f / interval), callback);
140- }
141-
142- void detachInterrupt ()
143- {
144- timer1_disable ();
145- }
146-
147- void disableTimer (void )
148- {
149- timer1_disable ();
150- }
151-
152- // Duration (in milliseconds). Duration = 0 or not specified => run indefinitely
153- void reattachInterrupt ()
154- {
155- if ( (_frequency != 0 ) && (_timerCount != 0 ) && (_callback != NULL ) )
156- setFrequency (_frequency, _callback);
157- }
158-
159- // Duration (in milliseconds). Duration = 0 or not specified => run indefinitely
160- void enableTimer (void )
161- {
162- reattachInterrupt ();
163- }
164-
165- // Just stop clock source, clear the count
166- void stopTimer (void )
167- {
168- timer1_disable ();
169- }
170-
171- // Just reconnect clock source, start current count from 0
172- void restartTimer (void )
173- {
174- enableTimer ();
175- }
176176}; // class ESP8266TimerInterrupt
177177
178178#endif // #ifndef ESP8266TimerInterrupt_h
0 commit comments