- No longer using interupts for switch inputs. Debouncing on clock tick.
- Updated DB25 M2 breakout diagram.
- Enabled AVR watchdog.
Buildbotics CNC Controller Firmware Change Log
==============================================
+## v0.3.12
+ - Updated DB25 M2 breakout diagram.
+ - Enabled AVR watchdog.
+
## v0.3.11
- Supressed ``firmware rebooted`` warning.
- Error on unexpected AVR reboot.
- - Enabled switch input slew rate limiting.
+ - Fixed pin fault output.
+ - No longer using interupts for switch inputs. Debouncing on clock tick.
## v0.3.10
- Fixed "Flood" display, changed to "Load 1" and "Load 2". #108
{
"name": "bbctrl",
- "version": "0.3.11",
+ "version": "0.3.12",
"homepage": "http://buildbotics.com/",
"repository": "https://github.com/buildbotics/bbctrl-firmware",
"license": "GPL-3.0+",
#include "cpp_magic.h"
#ifdef __AVR__
-#include <avr/wdt.h>
#include <util/atomic.h>
#else
#define ATOMIC_BLOCK(x)
// Switch settings. See switch.c
-#define SWITCH_INTLVL PORT_INT0LVL_MED_gc
+#define SWITCH_DEBOUNCE 5 // ms
// Motor ISRs
void hw_request_hard_reset() {hw.hard_reset = true;}
-/// Hard reset using watchdog timer
-/// software hard reset using the watchdog timer
void hw_hard_reset() {
usart_flush();
cli();
}
-uint8_t hw_disable_watchdog() {
- uint8_t state = WDT.CTRL;
- wdt_disable();
- return state;
-}
-
-
-void hw_restore_watchdog(uint8_t state) {
- cli();
- CCP = CCP_IOREG_gc;
- WDT.CTRL = state | WDT_CEN_bm;
- sei();
-}
-
-
-const char *get_hw_id() {
- return hw.id;
-}
+const char *get_hw_id() {return hw.id;}
void hw_request_hard_reset();
void hw_hard_reset();
void hw_reset_handler();
-
-uint8_t hw_disable_watchdog();
-void hw_restore_watchdog(uint8_t state);
int main() {
- //wdt_enable(WDTO_250MS); TODO
+ wdt_enable(WDTO_250MS);
// Init
cli(); // disable interrupts
state_callback(); // manage state
command_callback(); // process next command
report_callback(); // report changes
- wdt_reset();
}
return 0;
#include <avr/io.h>
#include <avr/interrupt.h>
+#include <avr/wdt.h>
#include <string.h>
hy_rtc_callback();
if (!(ticks & 255)) motor_rtc_callback();
lcd_rtc_callback();
+ wdt_reset();
}
switch_callback_t cb;
bool state;
- bool triggered;
+ int8_t debounce;
} switch_t;
const int num_switches = sizeof(switches) / sizeof (switch_t);
-static bool _read_state(const switch_t *s) {return IN_PIN(s->pin);}
-
-
-static void _switch_isr() {
- for (int i = 0; i < num_switches; i++) {
- switch_t *s = &switches[i];
- if (s->type == SW_DISABLED || s->triggered) continue;
- s->triggered = _read_state(s) != s->state;
- if (s->triggered) PORT(s->pin)->INT0MASK &= ~BM(s->pin); // Disable INT0
- }
-}
-
-
-// Switch interrupt handler vectors
-ISR(PORTA_INT0_vect) {_switch_isr();}
-ISR(PORTB_INT0_vect) {_switch_isr();}
-ISR(PORTC_INT0_vect) {_switch_isr();}
-ISR(PORTD_INT0_vect) {_switch_isr();}
-ISR(PORTE_INT0_vect) {_switch_isr();}
-ISR(PORTF_INT0_vect) {_switch_isr();}
-
-
-void _switch_enable(switch_t *s, bool enable) {
- if (enable) {
- s->triggered = false;
- s->state = _read_state(s); // Initialize state
- PORT(s->pin)->INT0MASK |= BM(s->pin); // Enable INT0
-
- } else PORT(s->pin)->INT0MASK &= ~BM(s->pin); // Disable INT0
-}
-
-
void switch_init() {
for (int i = 0; i < num_switches; i++) {
switch_t *s = &switches[i];
-
- // Pull up, trigger on both edges and enable slew rate limiting
- PINCTRL_PIN(s->pin) =
- PORT_OPC_PULLUP_gc | PORT_ISC_BOTHEDGES_gc;// | PORT_SRLEN_bm;
+ PINCTRL_PIN(s->pin) = PORT_OPC_PULLUP_gc; // Pull up
DIRCLR_PIN(s->pin); // Input
- PORT(s->pin)->INTCTRL |= SWITCH_INTLVL; // Set interrupt level
-
- _switch_enable(s, s->type != SW_DISABLED);
}
}
for (int i = 0; i < num_switches; i++) {
switch_t *s = &switches[i];
- if (s->type == SW_DISABLED || !s->triggered) continue;
-
- bool state = _read_state(s);
- s->triggered = false;
- PORT(s->pin)->INT0MASK |= BM(s->pin); // Reenable INT0
+ if (s->type == SW_DISABLED) continue;
- if (state != s->state) {
+ // Debounce switch
+ bool state = IN_PIN(s->pin);
+ if (state == s->state) s->debounce = 0;
+ else if (++s->debounce == SWITCH_DEBOUNCE) {
s->state = state;
+ s->debounce = 0;
if (s->cb) s->cb(i, switch_is_active(i));
}
}
switch_t *s = &switches[index];
if (s->type != type) {
+ bool wasActive = switch_is_active(index);
s->type = type;
- _switch_enable(s, type != SW_DISABLED);
+ bool isActive = switch_is_active(index);
+ if (wasActive != isActive && s->cb) s->cb(index, isActive);
}
}
void vars_report(bool full) {
- // Save and disable watchdog
- uint8_t wd_state = hw_disable_watchdog();
-
bool reported = false;
#define VAR(NAME, CODE, TYPE, INDEX, ...) \
#undef VAR
if (reported) printf("}\n");
-
- // Restore watchdog
- hw_restore_watchdog(wd_state);
}
void vars_report_all(bool enable) {
"\"help\":\"%"PRPSTR"\"";
static const char index_fmt[] PROGMEM = ",\"index\":\"%s\"";
- // Save and disable watchdog
- uint8_t wd_state = hw_disable_watchdog();
-
#define VAR(NAME, CODE, TYPE, INDEX, ...) \
if (first) first = false; else putchar(','); \
printf_P(fmt, #CODE, NAME##_name, type_get_##TYPE##_name_pgm(), \
putchar('}');
#include "vars.def"
#undef VAR
-
- // Restore watchdog
- hw_restore_watchdog(wd_state);
}
float square(float x) {return x * x;}
void i2c_set_read_callback(i2c_read_cb_t cb) {}
void print_status_flags(uint8_t flags) {DEBUG_CALL();}
-uint8_t hw_disable_watchdog() {return 0;}
-void hw_restore_watchdog(uint8_t state) {}
bool estop = false;