diff options
author | Matthias P. Braendli <matthias.braendli@mpb.li> | 2019-11-03 19:44:40 +0100 |
---|---|---|
committer | Matthias P. Braendli <matthias.braendli@mpb.li> | 2019-11-03 19:44:40 +0100 |
commit | 17628af1e4f7da4931286fa47cc2057e2c7cbfdd (patch) | |
tree | f813298bec625a7b7539ef9f3199c47b91f3d285 /sw | |
parent | 4193ec1618230f7bbc927e1d2280976a9d5dd464 (diff) | |
download | glutte-batteries-17628af1e4f7da4931286fa47cc2057e2c7cbfdd.tar.gz glutte-batteries-17628af1e4f7da4931286fa47cc2057e2c7cbfdd.tar.bz2 glutte-batteries-17628af1e4f7da4931286fa47cc2057e2c7cbfdd.zip |
Rework timer_t to use microseconds
Diffstat (limited to 'sw')
-rw-r--r-- | sw/common.hpp | 37 | ||||
-rw-r--r-- | sw/main.cpp | 41 | ||||
-rw-r--r-- | sw/relays.cpp | 4 |
3 files changed, 40 insertions, 42 deletions
diff --git a/sw/common.hpp b/sw/common.hpp index fa0ee8e..ea5751f 100644 --- a/sw/common.hpp +++ b/sw/common.hpp @@ -29,11 +29,11 @@ #include <avr/interrupt.h> struct timer_t { - uint32_t seconds_ = 0; /* Timer in seconds */ - uint8_t ticks_ = 0; /* Timer in 100ms steps */ + uint32_t seconds_ = 0; + uint32_t microsecs_ = 0; timer_t() {} - timer_t(uint32_t seconds, uint8_t ticks) : seconds_(seconds), ticks_(ticks) {} + timer_t(uint32_t seconds, uint32_t microsecs) : seconds_(seconds), microsecs_(microsecs) {} timer_t get_atomic_copy() const { cli(); @@ -49,52 +49,47 @@ struct timer_t { return s; } - uint8_t get_ticks_atomic() const { - /* Returning an uint8_t is atomic */ - return ticks_; + uint32_t get_microsecs_atomic() const { + cli(); + uint32_t t = microsecs_; + sei(); + return t; } bool operator>(const timer_t& rhs) const { return (seconds_ > rhs.seconds_) or - (seconds_ == rhs.seconds_ and ticks_ > rhs.ticks_); + (seconds_ == rhs.seconds_ and microsecs_ > rhs.microsecs_); } bool operator<(const timer_t& rhs) const { return (seconds_ < rhs.seconds_) or - (seconds_ == rhs.seconds_ and ticks_ < rhs.ticks_); + (seconds_ == rhs.seconds_ and microsecs_ < rhs.microsecs_); } void normalise() { - while (ticks_ >= 10) { + while (microsecs_ >= 1000000uL) { seconds_++; - ticks_ -= 10; + microsecs_ -= 1000000uL; } } timer_t operator+(const timer_t& rhs) const { timer_t t; t.seconds_ = seconds_ + rhs.seconds_; - t.ticks_ = ticks_ + rhs.ticks_; + t.microsecs_ = microsecs_ + rhs.microsecs_; t.normalise(); return t; } - timer_t operator+(uint8_t ticks) const { - timer_t t = timer_t(0, ticks); - return *this + t; - } - void operator+=(const timer_t& inc) { seconds_ += inc.seconds_; - ticks_ += inc.ticks_; + microsecs_ += inc.microsecs_; normalise(); } - void operator+=(uint8_t ticks) { - *this += timer_t(0, ticks); + void operator+=(uint32_t mirosecs) { + *this += timer_t(0, mirosecs); } - - static constexpr int ms_to_ticks(int ms) { return ms / 100; } }; diff --git a/sw/main.cpp b/sw/main.cpp index fc61986..5b40491 100644 --- a/sw/main.cpp +++ b/sw/main.cpp @@ -84,9 +84,24 @@ timer_t last_ltc2400_measure; timer_t last_ltc2400_print_time; /* Timer at approximately 100ms. - * Since this timer is updated in an ISR, care has to be taken + * + * Setup 100Hz timer, assuming F_CPU at 16MHz / 8: + * + * overflow for 100ms: F_CPU [ticks/s] / prescaler [unitless] * interval [s] = [ticks/s*s] = [ticks] + * interval [s] = 0.1 = 1 / 10 + * + * Actual interval after rounding: + * interval [s] = overflow [ticks] / (F_CPU [ticks/s] / prescaler [unit-less]) + * = 99.84 ms + */ +constexpr uint8_t TIMER_OVERFLOW = (uint8_t)(F_CPU / 1024 / 10); +constexpr double TIMER_TICK_INTERVAL = (double)TIMER_OVERFLOW / ((double)F_CPU / 1024.0); // == 0.099840 s +constexpr uint32_t TIMER_TICK_INTERVAL_US = (uint32_t)(TIMER_TICK_INTERVAL * 1000000.0); + +/* Since this timer is updated in an ISR, care has to be taken * when reading it, because all operations involving variables - * larger than 1 byte are not atomic on AVR. */ + * larger than 1 byte are not atomic on AVR. + */ static timer_t system_timer; /* At reset, save the mcusr register to find out why we got reset. @@ -95,7 +110,7 @@ uint8_t mcusr_mirror __attribute__ ((section (".noinit"))); ISR(TIMER0_COMPA_vect) { - system_timer += 1; + system_timer += timer_t{0, TIMER_TICK_INTERVAL_US}; } enum class error_type_t { @@ -248,23 +263,11 @@ int main() else { send_message("Startup"); } - - /* Setup 100Hz timer, assuming F_CPU at 16MHz / 8: - * - * overflow for 100ms: F_CPU [ticks/s] / prescaler [unit-less] * interval [s] = [ticks/s*s] = [ticks] - * interval [s] = 0.1 = 1 / 10 - * - * Actual interval after rounding: - * interval [s] = overflow [ticks] / (F_CPU [ticks/s] / prescaler [unit-less]) - * = 99.84 ms - */ system_timer = timer_t(0, 0); TCCR0B |= _BV(WGM02); // Set timer mode to CTC (datasheet 15.7.2) TIMSK0 |= _BV(TOIE0); // enable overflow interrupt - const uint8_t overflow = (uint8_t)(F_CPU / 1024 / 10); // Overflow at 99.84 ms - OCR0A = overflow; + OCR0A = TIMER_OVERFLOW; TCCR0B |= _BV(CS02) | _BV(CS00); // Start timer at Fcpu/1024 - const double tick_interval = (double)overflow / ((double)F_CPU / 1024.0 / 10.0); /* Load capacity stored in EEPROM */ current_capacity = 0; @@ -287,13 +290,13 @@ int main() const auto time_now = system_timer.get_atomic_copy(); - pins_set_status(time_now.get_ticks_atomic() == 0); + pins_set_status(time_now.get_microsecs_atomic() < 500000uL); if (last_store_time_seconds + 3600 * 5 >= time_now.seconds_) { store_capacity_to_eeprom(); } - constexpr auto ltc2400_measure_interval = timer_t::ms_to_ticks(100); + const auto ltc2400_measure_interval = timer_t{0, 100000uL}; if (last_ltc2400_measure + ltc2400_measure_interval > time_now) { last_ltc2400_measure += ltc2400_measure_interval; @@ -312,7 +315,7 @@ int main() /* Vout - 2.5V = Ishunt * Rshunt * 20 */ const double i_shunt = (adc_voltage - 2.5) / (20.0 * R_SHUNT); - accum += i_shunt * tick_interval; + accum += i_shunt * TIMER_TICK_INTERVAL; if (accum < 0) { accum = 0; } if (accum > MAX_CAPACITY) { accum = MAX_CAPACITY; } diff --git a/sw/relays.cpp b/sw/relays.cpp index cb83626..d06395f 100644 --- a/sw/relays.cpp +++ b/sw/relays.cpp @@ -35,7 +35,7 @@ struct pending_event_t { bool pending; }; -static constexpr int RELAY_SIGNAL_HOLD_TIME_MS = 400; +static constexpr int RELAY_SIGNAL_HOLD_TIME_US = 400000uL; static constexpr size_t PENDING_EVENTS_SIZE = 8; @@ -119,7 +119,7 @@ bool relays_toggle(relay_id_t relay, bool set_not_reset, const timer_t& when) pending_events[i].pending = true; pending_events[i].relay = relay; pending_events[i].when = when + - timer_t{0, timer_t::ms_to_ticks(RELAY_SIGNAL_HOLD_TIME_MS)}; + timer_t{0, RELAY_SIGNAL_HOLD_TIME_US}; pending_events[i].level = false; pending_events[i].set_not_reset = set_not_reset; |