#define VOLTAGE_MIN 11
#define VOLTAGE_MAX 39
#define CURRENT_MAX 25
-#define LOAD_CURRENT_MAX 8
#define CURRENT_OVERTEMP 16 // Should read ~21A but over 11.86A is faulty
-#define LOAD_LIMIT_TICKS 10
+#define LOAD_OVERTEMP_MAX 10
#define MOTOR_SHUTDOWN_THRESH 10
#define VOLTAGE_SETTLE_COUNT 5
#define VOLTAGE_SETTLE_PERIOD 20 // ms
// Non fatal
LOAD1_OVERTEMP_FLAG = 1 << 6,
LOAD2_OVERTEMP_FLAG = 1 << 7,
- LOAD1_LIMITING_FLAG = 1 << 8,
- LOAD2_LIMITING_FLAG = 1 << 9,
};
typedef struct {
const regs_t reg;
const uint8_t pin;
- volatile uint8_t limit;
- volatile uint8_t count;
- volatile uint8_t lockout;
+ volatile uint8_t overtemp;
+ volatile bool shutdown;
} load_t;
load_t loads[2] = {
- {LOAD1_REG, LOAD1_PIN, 5, 0, 0},
- {LOAD2_REG, LOAD2_PIN, 5, 0, 0},
+ {LOAD1_REG, LOAD1_PIN, 0, false},
+ {LOAD2_REG, LOAD2_PIN, 0, false},
};
static void check_load(load_t *load) {
- bool overtemp = CURRENT_OVERTEMP * 100 < regs[load->reg];
- if (overtemp && !load->lockout) {
- load->lockout = true;
- if (load->limit < LOAD_LIMIT_TICKS) load->limit++;
- }
-
- if (!overtemp) load->lockout = false;
-}
-
+ if (load->shutdown) return;
-void limit_load(load_t *load) {
- if (load->count < load->limit || load->lockout) {
- IO_PORT_CLR(load->pin); // Lo
- IO_DDR_SET(load->pin); // Output
-
- } else IO_DDR_CLR(load->pin); // Float
-
- if (++load->count == LOAD_LIMIT_TICKS) load->count = 0;
+ bool overtemp = CURRENT_OVERTEMP * 100 < regs[load->reg];
+ if (overtemp) {
+ if (++load->overtemp == LOAD_OVERTEMP_MAX) {
+ load->shutdown = true;
+ IO_PORT_CLR(load->pin); // Lo
+ IO_DDR_SET(load->pin); // Output
+ }
+ } else if (load->overtemp) load->overtemp--;
}
ISR(TIMER0_OVF_vect) {
static uint8_t tick = 0;
- // Calling these too fast disrupts the I2C bus
- if ((tick & 3) == 0) limit_load(&loads[0]);
- if ((tick & 3) == 2) limit_load(&loads[1]);
-
if (++tick == 31) {
time++;
tick = 0;
if (CURRENT_MAX < get_total_current()) flags |= OVER_CURRENT_FLAG;
if (shunt_overload) flags |= SHUNT_OVERLOAD_FLAG;
if (MOTOR_SHUTDOWN_THRESH <= motor_overload) flags |= MOTOR_OVERLOAD_FLAG;
- if (loads[0].limit == LOAD_LIMIT_TICKS) flags |= LOAD1_OVERTEMP_FLAG;
- if (loads[1].limit == LOAD_LIMIT_TICKS) flags |= LOAD2_OVERTEMP_FLAG;
- if (loads[0].limit) flags |= LOAD1_LIMITING_FLAG;
- if (loads[1].limit) flags |= LOAD2_LIMITING_FLAG;
+ if (loads[0].shutdown) flags |= LOAD1_OVERTEMP_FLAG;
+ if (loads[1].shutdown) flags |= LOAD2_OVERTEMP_FLAG;
regs[FLAGS_REG] = flags;
if (flags & FATAL_FLAG_MASK) shutdown(flags);