pru: Support config_reset command to manually reset mcu
Add support for resetting the MCU via a software only mechanism. This is useful on the PRU. Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
parent
7b7f57e01c
commit
7083a33ecd
|
@ -430,14 +430,17 @@ class MCU:
|
||||||
self._shutdown_msg = ""
|
self._shutdown_msg = ""
|
||||||
self._timeout_timer = printer.reactor.register_timer(
|
self._timeout_timer = printer.reactor.register_timer(
|
||||||
self.timeout_handler)
|
self.timeout_handler)
|
||||||
rmethods = {m: m for m in ['arduino', 'command', 'rpi_usb']}
|
self._restart_method = 'command'
|
||||||
self._restart_method = config.getchoice(
|
if baud:
|
||||||
'restart_method', rmethods, 'arduino')
|
rmethods = {m: m for m in ['arduino', 'command', 'rpi_usb']}
|
||||||
|
self._restart_method = config.getchoice(
|
||||||
|
'restart_method', rmethods, 'arduino')
|
||||||
# Config building
|
# Config building
|
||||||
if printer.bglogger is not None:
|
if printer.bglogger is not None:
|
||||||
printer.bglogger.set_rollover_info("mcu", None)
|
printer.bglogger.set_rollover_info("mcu", None)
|
||||||
pins.get_printer_pins(printer).register_chip("mcu", self)
|
pins.get_printer_pins(printer).register_chip("mcu", self)
|
||||||
self._emergency_stop_cmd = self._reset_cmd = None
|
self._emergency_stop_cmd = None
|
||||||
|
self._reset_cmd = self._config_reset_cmd = None
|
||||||
self._oid_count = 0
|
self._oid_count = 0
|
||||||
self._config_objects = []
|
self._config_objects = []
|
||||||
self._init_cmds = []
|
self._init_cmds = []
|
||||||
|
@ -502,10 +505,8 @@ class MCU:
|
||||||
self._stats_sumsq_base = self.serial.msgparser.get_constant_float(
|
self._stats_sumsq_base = self.serial.msgparser.get_constant_float(
|
||||||
'STATS_SUMSQ_BASE')
|
'STATS_SUMSQ_BASE')
|
||||||
self._emergency_stop_cmd = self.lookup_command("emergency_stop")
|
self._emergency_stop_cmd = self.lookup_command("emergency_stop")
|
||||||
try:
|
self._reset_cmd = self.try_lookup_command("reset")
|
||||||
self._reset_cmd = self.lookup_command("reset")
|
self._config_reset_cmd = self.try_lookup_command("config_reset")
|
||||||
except self.serial.msgparser.error as e:
|
|
||||||
pass
|
|
||||||
self.register_msg(self.handle_shutdown, 'shutdown')
|
self.register_msg(self.handle_shutdown, 'shutdown')
|
||||||
self.register_msg(self.handle_shutdown, 'is_shutdown')
|
self.register_msg(self.handle_shutdown, 'is_shutdown')
|
||||||
self.register_msg(self.handle_mcu_stats, 'stats')
|
self.register_msg(self.handle_mcu_stats, 'stats')
|
||||||
|
@ -560,11 +561,21 @@ class MCU:
|
||||||
if self._restart_method == 'command':
|
if self._restart_method == 'command':
|
||||||
last_clock, last_clock_time = self.serial.get_last_clock()
|
last_clock, last_clock_time = self.serial.get_last_clock()
|
||||||
eventtime = reactor.monotonic()
|
eventtime = reactor.monotonic()
|
||||||
if (self._reset_cmd is None
|
if ((self._reset_cmd is None and self._config_reset_cmd is None)
|
||||||
or eventtime > last_clock_time + self.COMM_TIMEOUT):
|
or eventtime > last_clock_time + self.COMM_TIMEOUT):
|
||||||
logging.info("Unable to issue reset command")
|
logging.info("Unable to issue reset command")
|
||||||
return
|
return
|
||||||
# Attempt reset via command
|
if self._reset_cmd is None:
|
||||||
|
# Attempt reset via config_reset command
|
||||||
|
logging.info("Attempting a microcontroller config_reset command")
|
||||||
|
self.is_shutdown = True
|
||||||
|
self.force_shutdown()
|
||||||
|
reactor.pause(reactor.monotonic() + 0.015)
|
||||||
|
self.send(self._config_reset_cmd.encode())
|
||||||
|
reactor.pause(reactor.monotonic() + 0.015)
|
||||||
|
self.disconnect()
|
||||||
|
return
|
||||||
|
# Attempt reset via reset command
|
||||||
logging.info("Attempting a microcontroller reset command")
|
logging.info("Attempting a microcontroller reset command")
|
||||||
self.send(self._reset_cmd.encode())
|
self.send(self._reset_cmd.encode())
|
||||||
reactor.pause(reactor.monotonic() + 0.015)
|
reactor.pause(reactor.monotonic() + 0.015)
|
||||||
|
@ -682,6 +693,11 @@ class MCU:
|
||||||
return self.serial.alloc_command_queue()
|
return self.serial.alloc_command_queue()
|
||||||
def lookup_command(self, msgformat):
|
def lookup_command(self, msgformat):
|
||||||
return self.serial.msgparser.lookup_command(msgformat)
|
return self.serial.msgparser.lookup_command(msgformat)
|
||||||
|
def try_lookup_command(self, msgformat):
|
||||||
|
try:
|
||||||
|
return self.serial.msgparser.lookup_command(msgformat)
|
||||||
|
except self.serial.msgparser.error as e:
|
||||||
|
return None
|
||||||
def create_command(self, msg):
|
def create_command(self, msg):
|
||||||
return self.serial.msgparser.create_command(msg)
|
return self.serial.msgparser.create_command(msg)
|
||||||
# Clock syncing
|
# Clock syncing
|
||||||
|
|
|
@ -215,6 +215,25 @@ command_finalize_config(uint32_t *args)
|
||||||
}
|
}
|
||||||
DECL_COMMAND(command_finalize_config, "finalize_config crc=%u");
|
DECL_COMMAND(command_finalize_config, "finalize_config crc=%u");
|
||||||
|
|
||||||
|
// Attempt a full manual reset of the config
|
||||||
|
void
|
||||||
|
config_reset(uint32_t *args)
|
||||||
|
{
|
||||||
|
if (! sched_is_shutdown())
|
||||||
|
shutdown("config_reset only available when shutdown");
|
||||||
|
irq_disable();
|
||||||
|
config_crc = 0;
|
||||||
|
oid_count = 0;
|
||||||
|
oids = NULL;
|
||||||
|
move_free_list = NULL;
|
||||||
|
move_list = NULL;
|
||||||
|
move_count = move_item_size = 0;
|
||||||
|
alloc_init();
|
||||||
|
sched_timer_reset();
|
||||||
|
sched_clear_shutdown();
|
||||||
|
irq_enable();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************
|
/****************************************************************
|
||||||
* Timing and load stats
|
* Timing and load stats
|
||||||
|
|
|
@ -10,6 +10,7 @@ void *oid_lookup(uint8_t oid, void *type);
|
||||||
void *oid_alloc(uint8_t oid, void *type, uint16_t size);
|
void *oid_alloc(uint8_t oid, void *type, uint16_t size);
|
||||||
void *oid_next(uint8_t *i, void *type);
|
void *oid_next(uint8_t *i, void *type);
|
||||||
void stats_update(uint32_t start, uint32_t cur);
|
void stats_update(uint32_t start, uint32_t cur);
|
||||||
|
void config_reset(uint32_t *args);
|
||||||
|
|
||||||
#define foreach_oid(pos,data,oidtype) \
|
#define foreach_oid(pos,data,oidtype) \
|
||||||
for (pos=-1; (data=oid_next(&pos, oidtype)); )
|
for (pos=-1; (data=oid_next(&pos, oidtype)); )
|
||||||
|
|
|
@ -212,6 +212,9 @@ struct my_resource_table {
|
||||||
* Startup
|
* Startup
|
||||||
****************************************************************/
|
****************************************************************/
|
||||||
|
|
||||||
|
// Support config_reset
|
||||||
|
DECL_COMMAND_FLAGS(config_reset, HF_IN_SHUTDOWN, "config_reset");
|
||||||
|
|
||||||
// Main entry point
|
// Main entry point
|
||||||
int
|
int
|
||||||
main(void)
|
main(void)
|
||||||
|
|
|
@ -165,8 +165,8 @@ sched_timer_dispatch(void)
|
||||||
return next_waketime;
|
return next_waketime;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove all user timers on a shutdown
|
// Remove all user timers
|
||||||
static void
|
void
|
||||||
sched_timer_reset(void)
|
sched_timer_reset(void)
|
||||||
{
|
{
|
||||||
timer_list = &deleted_timer;
|
timer_list = &deleted_timer;
|
||||||
|
|
|
@ -29,6 +29,7 @@ struct task_wake {
|
||||||
void sched_add_timer(struct timer*);
|
void sched_add_timer(struct timer*);
|
||||||
void sched_del_timer(struct timer *del);
|
void sched_del_timer(struct timer *del);
|
||||||
unsigned int sched_timer_dispatch(void);
|
unsigned int sched_timer_dispatch(void);
|
||||||
|
void sched_timer_reset(void);
|
||||||
void sched_wake_tasks(void);
|
void sched_wake_tasks(void);
|
||||||
uint8_t sched_tasks_busy(void);
|
uint8_t sched_tasks_busy(void);
|
||||||
void sched_wake_task(struct task_wake *w);
|
void sched_wake_task(struct task_wake *w);
|
||||||
|
|
Loading…
Reference in New Issue