YAHAL
Yet Another Hardware Abstraction Library
Loading...
Searching...
No Matches
timer_esp8266.cpp
1// ---------------------------------------------
2// This file is part of
3// _ _ __ _ _ __ __
4// ( \/ ) /__\ ( )_( ) /__\ ( )
5// \ / /(__)\ ) _ ( /(__)\ )(__
6// (__)(__)(__)(_) (_)(__)(__)(____)
7//
8// Yet Another HW Abstraction Library
9// Copyright (C) Andreas Terstegge
10// BSD Licensed (see file LICENSE)
11//
12// ---------------------------------------------
13//
14// Timer implementation for ESP8266.
15//
16#include "timer_esp8266.h"
17#include "ESP8266.h"
18#include <cassert>
19
20extern "C" {
21#include "ets_sys.h"
22}
23
24timer_esp8266::timer_esp8266() {
25 _TIMER_::TIMER.FRC1_CTRL = 0;
26 _period_us = 0;
27 _period_load = 0;
28 _divider = 1;
29}
30
31timer_esp8266::~timer_esp8266() {
32 _TIMER_::TIMER.FRC1_CTRL = 0; // stop the timer and
33 TM1_EDGE_INT_DISABLE(); // disable the interrupts
34 ETS_FRC1_INTR_DISABLE();
35}
36
37void timer_esp8266::setPeriod(uint32_t us, TIMER::timer_mode mode) {
38 _TIMER_::TIMER.FRC1_CTRL.RELOAD = (mode == TIMER::PERIODIC); // ? 1 : 0);
39 // Start with divider = 1
40 _period_us = us;
41 _period_load = 80 * us;
42 _divider = 1;
43 _TIMER_::TIMER.FRC1_CTRL.DIVIDER = _TIMER_::FRC1_CTRL_DIVIDER__1;
44 // check if we need a divider = 16
45 if (_period_load > 0x7fffff) {
46 _period_load /= 16;
47 _divider *= 16;
48 _TIMER_::TIMER.FRC1_CTRL.DIVIDER = _TIMER_::FRC1_CTRL_DIVIDER__16;
49 // even a divider = 256 ?
50 if (_period_load > 0x7fffff) {
51 _period_load /= 16;
52 _divider *= 16;
53 _TIMER_::TIMER.FRC1_CTRL.DIVIDER = _TIMER_::FRC1_CTRL_DIVIDER__256;
54 }
55 }
56 // the period should be in the valid range now
57 assert(_period_load <= 0x7fffff);
58 _TIMER_::TIMER.FRC1_LOAD = _period_load;
59}
60
61uint32_t timer_esp8266::getPeriod() {
62 return _period_us;
63}
64
65void timer_esp8266::setCallback(function<void()> f) {
66 _handler = f;
67 _TIMER_::TIMER.FRC1_CTRL.INT_TYPE = _TIMER_::FRC1_CTRL_INT_TYPE__EDGE;
68 ETS_FRC_TIMER1_INTR_ATTACH(timer_irq_handler, this);
69 TM1_EDGE_INT_ENABLE();
70 ETS_FRC1_INTR_ENABLE();
71}
72
73void timer_esp8266::start() {
74 _TIMER_::TIMER.FRC1_CTRL.ENABLE = 1;
75}
76
77void timer_esp8266::stop() {
78 _TIMER_::TIMER.FRC1_CTRL.ENABLE = 0;
79}
80
81bool timer_esp8266::isRunning() {
82 return _TIMER_::TIMER.FRC1_CTRL.ENABLE;
83}
84
85uint32_t timer_esp8266::getCounter() {
86 return (_period_load - _TIMER_::TIMER.FRC1_COUNT) * _divider / 80;
87}
88
89void timer_esp8266::resetCounter() {
90 _TIMER_::TIMER.FRC1_LOAD = _period_load;
91}
92
93void timer_irq_handler(timer_esp8266 *timer) {
94 if(timer->_handler) timer->_handler();
95}