Buildbotics CNC Controller Firmware Changelog
==============================================
-## v0.4.3
+## v0.4.5
+ - Fix for random errors while running VFD.
+ - Fix bug where planner would not continue after optional pause (M1).
+
+## v0.4.4
- Write version to log file.
- Write time to log file periodically.
- Show simulation progress with or with out 3D view.
{
"name": "bbctrl",
- "version": "0.4.4",
+ "version": "0.4.5",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
{
"name": "bbctrl",
- "version": "0.4.4",
+ "version": "0.4.5",
"homepage": "http://buildbotics.com/",
"repository": "https://github.com/buildbotics/bbctrl-firmware",
"license": "GPL-3.0+",
void i2c_init() {
i2c_set_write_callback(_i2c_default_write_cb);
- I2C_DEV.SLAVE.CTRLA = TWI_SLAVE_INTLVL_MED_gc | TWI_SLAVE_DIEN_bm |
+ I2C_DEV.SLAVE.CTRLA = TWI_SLAVE_INTLVL_LO_gc | TWI_SLAVE_DIEN_bm |
TWI_SLAVE_ENABLE_bm | TWI_SLAVE_APIEN_bm | TWI_SLAVE_PIEN_bm;
I2C_DEV.SLAVE.ADDR = I2C_ADDR << 1;
}
static void _set_dre_interrupt(bool enable) {
- INTLVL_ENABLE(RS485_PORT.CTRLA, USART_DRE, MED, enable);
+ INTLVL_ENABLE(RS485_PORT.CTRLA, USART_DRE, LO, enable);
}
static void _set_txc_interrupt(bool enable) {
- INTLVL_ENABLE(RS485_PORT.CTRLA, USART_TXC, MED, enable);
+ INTLVL_ENABLE(RS485_PORT.CTRLA, USART_TXC, LO, enable);
}
static void _set_rxc_interrupt(bool enable) {
- INTLVL_ENABLE(RS485_PORT.CTRLA, USART_RXC, MED, enable);
+ INTLVL_ENABLE(RS485_PORT.CTRLA, USART_RXC, LO, enable);
}
bool resuming;
bool stop_requested;
bool pause_requested;
- bool optional_pause_requested;
bool unpause_requested;
state_t state;
PGM_P state_get_hold_reason_pgmstr(hold_reason_t reason) {
switch (reason) {
- case HOLD_REASON_USER_PAUSE: return PSTR("User pause");
- case HOLD_REASON_USER_STOP: return PSTR("User stop");
- case HOLD_REASON_PROGRAM_PAUSE: return PSTR("Program pause");
- case HOLD_REASON_SWITCH_FOUND: return PSTR("Switch found");
+ case HOLD_REASON_USER_PAUSE: return PSTR("User pause");
+ case HOLD_REASON_USER_STOP: return PSTR("User stop");
+ case HOLD_REASON_PROGRAM_PAUSE: return PSTR("Program pause");
+ case HOLD_REASON_OPTIONAL_PAUSE: return PSTR("Optional pause");
+ case HOLD_REASON_SWITCH_FOUND: return PSTR("Switch found");
}
return PSTR("INVALID");
}
-void state_pause() {
- _set_hold_reason(HOLD_REASON_PROGRAM_PAUSE);
- state_holding();
-}
-
-
void state_running() {
if (state_get() == STATE_READY) _set_state(STATE_RUNNING);
}
// Var callbacks
PGM_P get_state() {return state_get_pgmstr(state_get());}
PGM_P get_hold_reason() {return state_get_hold_reason_pgmstr(s.hold_reason);}
-bool get_optional_pause() {return s.optional_pause_requested;}
-void set_optional_pause(bool x) {s.optional_pause_requested = x;}
// Command callbacks
void command_pause_exec(void *data) {
switch (*(pause_t *)data) {
case PAUSE_PROGRAM_OPTIONAL:
- if (!s.optional_pause_requested) return;
- s.optional_pause_requested = false;
- // Fall through
+ _set_hold_reason(HOLD_REASON_OPTIONAL_PAUSE);
+ break;
- case PAUSE_PROGRAM: state_pause(); break;
- default: break;
+ case PAUSE_PROGRAM: _set_hold_reason(HOLD_REASON_PROGRAM_PAUSE); break;
+ default: return;
}
+
+ state_holding();
}
HOLD_REASON_USER_PAUSE,
HOLD_REASON_USER_STOP,
HOLD_REASON_PROGRAM_PAUSE,
+ HOLD_REASON_OPTIONAL_PAUSE,
HOLD_REASON_SWITCH_FOUND,
} hold_reason_t;
VAR(id, id, u16, 0, 1, 1) // Last executed command ID
VAR(feed_override, fo, u16, 0, 1, 1) // Feed rate override
VAR(speed_override, so, u16, 0, 1, 1) // Spindle speed override
-VAR(optional_pause, op, b8, 0, 1, 1) // Optional pause state
// System
VAR(velocity, v, f32, 0, 0, 1) // Current velocity
def _is_paused(self):
if not self._is_holding() or self.unpausing: return False
- return self._get_pause_reason() in ('User pause', 'Program pause')
+ return self._get_pause_reason() in (
+ 'User pause', 'Program pause', 'Optional pause')
def _begin_cycle(self, cycle):
self.ctrl.state.set('cycle', self.last_cycle)
# Automatically unpause after seek or stop hold
+ op = self.ctrl.state.get('optional_pause', False)
+ pr = self._get_pause_reason()
if (('xx' in update or 'pr' in update) and self._is_holding() and
- self._get_pause_reason() in ('Switch found', 'User stop')):
+ (pr in ('Switch found', 'User stop') or
+ (pr == 'Optional pause' and not op))):
self._unpause()
def unpause(self):
- if self._is_paused(): self._unpause()
+ if self._is_paused():
+ self.ctrl.state.set('optional_pause', False)
+ self._unpause()
def optional_pause(self, enable = True):
- super().queue_command('$op=%d' % enable)
+ self.ctrl.state.set('optional_pause', enable)
def set_position(self, axis, position):
return Cmd.dwell(block['seconds'])
if type == 'pause': return Cmd.pause(block['pause-type'])
+
if type == 'seek':
return Cmd.seek(block['switch'], block['active'], block['error'])
+
if type == 'end': return '' # Sends id
raise Exception('Unknown planner command "%s"' % type)