aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias P. Braendli <matthias.braendli@mpb.li>2019-11-03 19:44:40 +0100
committerMatthias P. Braendli <matthias.braendli@mpb.li>2019-11-03 19:44:40 +0100
commit17628af1e4f7da4931286fa47cc2057e2c7cbfdd (patch)
treef813298bec625a7b7539ef9f3199c47b91f3d285
parent4193ec1618230f7bbc927e1d2280976a9d5dd464 (diff)
downloadglutte-batteries-17628af1e4f7da4931286fa47cc2057e2c7cbfdd.tar.gz
glutte-batteries-17628af1e4f7da4931286fa47cc2057e2c7cbfdd.tar.bz2
glutte-batteries-17628af1e4f7da4931286fa47cc2057e2c7cbfdd.zip
Rework timer_t to use microseconds
-rw-r--r--sw/common.hpp37
-rw-r--r--sw/main.cpp41
-rw-r--r--sw/relays.cpp4
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;