bldc/shutdown.c

159 lines
4.2 KiB
C
Raw Normal View History

/*
Copyright 2019 Benjamin Vedder benjamin@vedder.se
This file is part of the VESC firmware.
The VESC firmware is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
The VESC firmware is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "shutdown.h"
#include "app.h"
#ifdef HW_SHUTDOWN_HOLD_ON
// Private variables
bool volatile m_button_pressed = false;
static volatile float m_inactivity_time = 0.0;
static THD_WORKING_AREA(shutdown_thread_wa, 128);
static mutex_t m_sample_mutex;
static volatile bool m_init_done = false;
static volatile bool m_sampling_disabled = false;
// Private functions
static THD_FUNCTION(shutdown_thread, arg);
void shutdown_init(void) {
chMtxObjectInit(&m_sample_mutex);
chThdCreateStatic(shutdown_thread_wa, sizeof(shutdown_thread_wa), NORMALPRIO, shutdown_thread, NULL);
m_init_done = true;
}
void shutdown_reset_timer(void) {
m_inactivity_time = 0.0;
}
bool shutdown_button_pressed(void) {
return m_button_pressed;
}
float shutdown_get_inactivity_time(void) {
return m_inactivity_time;
}
void shutdown_set_sampling_disabled(bool disabled) {
if (!m_init_done) {
return;
}
chMtxLock(&m_sample_mutex);
m_sampling_disabled = disabled;
chMtxUnlock(&m_sample_mutex);
}
static THD_FUNCTION(shutdown_thread, arg) {
(void)arg;
chRegSetThreadName("Shutdown");
bool gates_disabled_here = false;
float gate_disable_time = 0.0;
systime_t last_iteration_time = chVTGetSystemTimeX();
for(;;) {
float dt = (float)chVTTimeElapsedSinceX(last_iteration_time) / (float)CH_CFG_ST_FREQUENCY;
last_iteration_time = chVTGetSystemTimeX();
chMtxLock(&m_sample_mutex);
if (m_sampling_disabled) {
chMtxUnlock(&m_sample_mutex);
chThdSleepMilliseconds(10);
continue;
}
bool sample = HW_SAMPLE_SHUTDOWN();
chMtxUnlock(&m_sample_mutex);
bool clicked = m_button_pressed && !sample;
m_button_pressed = sample;
const app_configuration *conf = app_get_configuration();
// Note: When the gates are enabled, the push to start function
// will prevent the regulator from shutting down. Therefore, the
// gate driver has to be disabled.
switch (conf->shutdown_mode) {
case SHUTDOWN_MODE_ALWAYS_OFF:
if (m_button_pressed) {
DISABLE_GATE();
gates_disabled_here = true;
HW_SHUTDOWN_HOLD_OFF();
}
break;
case SHUTDOWN_MODE_ALWAYS_ON:
HW_SHUTDOWN_HOLD_ON();
break;
default:
if (clicked) {
DISABLE_GATE();
gates_disabled_here = true;
HW_SHUTDOWN_HOLD_OFF();
}
break;
}
// If disabling the gates did not shut the VESC down within
// 2 seconds, enable the gates again.
if (gates_disabled_here && m_button_pressed) {
gate_disable_time += dt;
if (gate_disable_time > 2.0) {
ENABLE_GATE();
gates_disabled_here = false;
gate_disable_time = 0.0;
}
}
if (conf->shutdown_mode >= SHUTDOWN_MODE_OFF_AFTER_10S) {
m_inactivity_time += dt;
float shutdown_timeout = 0.0;
switch (conf->shutdown_mode) {
case SHUTDOWN_MODE_OFF_AFTER_10S: shutdown_timeout = 10.0; break;
case SHUTDOWN_MODE_OFF_AFTER_1M: shutdown_timeout = 60.0; break;
case SHUTDOWN_MODE_OFF_AFTER_5M: shutdown_timeout = 60.0 * 5.0; break;
case SHUTDOWN_MODE_OFF_AFTER_10M: shutdown_timeout = 60.0 * 10.0; break;
case SHUTDOWN_MODE_OFF_AFTER_30M: shutdown_timeout = 60.0 * 30.0; break;
case SHUTDOWN_MODE_OFF_AFTER_1H: shutdown_timeout = 60.0 * 60.0; break;
case SHUTDOWN_MODE_OFF_AFTER_5H: shutdown_timeout = 60.0 * 60.0 * 5.0; break;
default: break;
}
if (m_inactivity_time >= shutdown_timeout && m_button_pressed) {
DISABLE_GATE();
gates_disabled_here = true;
HW_SHUTDOWN_HOLD_OFF();
}
} else {
m_inactivity_time = 0.0;
}
chThdSleepMilliseconds(10);
}
}
#endif