mirror of https://github.com/rusefi/bldc.git
Thor300: robust shutdown implementation, remove AO variant
shutdown can now only be triggered by a long-press -500ms of button press triggers shutdown provided erpm < 100 -above 100 erpm the button must be held for 3 seconds to force shutdown Actual shutdown happens on release of the button Signed-off-by: Dado Mista <dadomista@gmail.com>
This commit is contained in:
parent
898ec45cfc
commit
02c5944309
|
@ -1,29 +0,0 @@
|
|||
/*
|
||||
Copyright 2022 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/>.
|
||||
*/
|
||||
|
||||
#ifndef HW_Thor300_AO_H_
|
||||
#define HW_Thor300_AO_H_
|
||||
|
||||
#define HW_NAME "Thor300_AO"
|
||||
|
||||
#include "hw_Thor300_core.h"
|
||||
|
||||
#define ALWAYS_ON 1
|
||||
|
||||
#endif
|
|
@ -23,13 +23,19 @@
|
|||
#include "stm32f4xx_conf.h"
|
||||
#include "utils_math.h"
|
||||
#include <math.h>
|
||||
#include "terminal.h"
|
||||
#include "commands.h"
|
||||
#include "mc_interface.h"
|
||||
|
||||
// Variables
|
||||
static volatile bool i2c_running = false;
|
||||
static mutex_t shutdown_mutex;
|
||||
static float bt_diff = 0.0;
|
||||
static int pressed_time = 0;
|
||||
static float bt_lastval = 0.0;
|
||||
static float bt_unpressed = 0.0;
|
||||
static bool will_poweroff = false;
|
||||
static bool force_poweroff = false;
|
||||
static unsigned int bt_hold_counter = 0;
|
||||
|
||||
// I2C configuration
|
||||
static const I2CConfig i2cfg = {
|
||||
|
@ -38,10 +44,13 @@ static const I2CConfig i2cfg = {
|
|||
STD_DUTY_CYCLE
|
||||
};
|
||||
|
||||
// Private functions
|
||||
static void terminal_button_test(int argc, const char **argv);
|
||||
|
||||
void hw_init_gpio(void) {
|
||||
|
||||
chMtxObjectInit(&shutdown_mutex);
|
||||
|
||||
// GPIO clock enable
|
||||
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
|
||||
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
|
||||
|
@ -109,7 +118,14 @@ void hw_init_gpio(void) {
|
|||
palSetPadMode(GPIOC, 3, PAL_MODE_INPUT_ANALOG);
|
||||
palSetPadMode(GPIOC, 4, PAL_MODE_INPUT_ANALOG);
|
||||
palSetPadMode(GPIOC, 5, PAL_MODE_INPUT_ANALOG);
|
||||
|
||||
terminal_register_command_callback(
|
||||
"test_button",
|
||||
"Try sampling the shutdown button",
|
||||
0,
|
||||
terminal_button_test);
|
||||
}
|
||||
|
||||
void hw_setup_adc_channels(void) {
|
||||
// ADC1 regular channels
|
||||
ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_15Cycles);
|
||||
|
@ -241,38 +257,113 @@ void hw_try_restore_i2c(void) {
|
|||
}
|
||||
}
|
||||
|
||||
#define RISING_EDGE_THRESHOLD 0.09
|
||||
#define TIME_500MS 50
|
||||
#define TIME_3S 300
|
||||
#define ERPM_THRESHOLD 100
|
||||
|
||||
/**
|
||||
* hw_sample_shutdown_button - return false if shutdown is requested, true otherwise
|
||||
*
|
||||
* Behavior: after determining the unpressed level, look for rising edges or values
|
||||
* that are clearly above the unpressed level (2 x Threshold higher), triggering a counter.
|
||||
*
|
||||
* Once triggered, the counter keeps incrementing as long as the level is 2 x Threshold higher
|
||||
* than the normal/unpressed value, otherwise it gets reset to zero.
|
||||
*
|
||||
* Once the counter reaches the threshold the button is considered pressed, provided that
|
||||
* the erpm is below 100.
|
||||
* Shutdown actually happens on the falling edge when the press is over.
|
||||
*
|
||||
* If the motor is spinning faster, then a 3s press is required.
|
||||
* Again, shutdown happens on the falling edge.
|
||||
*
|
||||
* Normal shutdown time: 0.5s
|
||||
* Emergency shutdown time: 3.0s
|
||||
*/
|
||||
|
||||
bool hw_sample_shutdown_button(void) {
|
||||
|
||||
#ifdef ALWAYS_ON
|
||||
return true;
|
||||
#endif
|
||||
|
||||
chMtxLock(&shutdown_mutex);
|
||||
bt_diff = (ADC_VOLTS(ADC_IND_SHUTDOWN));
|
||||
bt_diff = (bt_diff + ADC_VOLTS(ADC_IND_SHUTDOWN))/2;
|
||||
chThdSleep(1);
|
||||
bt_diff = (bt_diff + ADC_VOLTS(ADC_IND_SHUTDOWN))/2;
|
||||
chThdSleep(1);
|
||||
bt_diff = (bt_diff + ADC_VOLTS(ADC_IND_SHUTDOWN))/2;
|
||||
float newval = ADC_VOLTS(ADC_IND_SHUTDOWN);
|
||||
chMtxUnlock(&shutdown_mutex);
|
||||
|
||||
if(bt_diff > 2.25){
|
||||
pressed_time += 12;
|
||||
if (bt_lastval == 0) {
|
||||
bt_lastval = newval;
|
||||
return true;
|
||||
}else{
|
||||
if(pressed_time > 1000){
|
||||
pressed_time = 0;
|
||||
}
|
||||
bt_diff = (newval - bt_lastval);
|
||||
|
||||
bool is_steady = fabsf(bt_diff) < 0.02; // filter out noise above 20mV
|
||||
bool is_rising_edge = (bt_diff > RISING_EDGE_THRESHOLD);
|
||||
|
||||
bt_lastval = newval;
|
||||
|
||||
if (bt_unpressed == 0.0) {
|
||||
// initializing bt_unpressed
|
||||
if (is_steady) {
|
||||
bt_unpressed = newval;
|
||||
}
|
||||
// return true regardless (this happens only after boot)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (will_poweroff) {
|
||||
if (!force_poweroff && (fabsf(mc_interface_get_rpm()) > ERPM_THRESHOLD)) {
|
||||
will_poweroff = false;
|
||||
bt_hold_counter = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Now we look for a falling edge to shut down
|
||||
if ((bt_diff < -RISING_EDGE_THRESHOLD) || (newval < bt_unpressed + RISING_EDGE_THRESHOLD / 2)) {
|
||||
bt_hold_counter++;
|
||||
return false;
|
||||
}else{
|
||||
pressed_time = 0;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (bt_hold_counter == 0) {
|
||||
if (is_rising_edge) {
|
||||
// trigger by edge and by level!
|
||||
bt_hold_counter = 1;
|
||||
}
|
||||
else {
|
||||
if (is_steady && (newval < bt_unpressed + RISING_EDGE_THRESHOLD / 2)) {
|
||||
// pickup drifts due to temperature
|
||||
bt_unpressed = bt_unpressed * 0.9 + newval * 0.1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// we've had a rising edge and are now checking for a steady hold
|
||||
if (newval > bt_unpressed + RISING_EDGE_THRESHOLD * 1.5) {
|
||||
bt_hold_counter++;
|
||||
|
||||
return pressed_time < 1000 ;
|
||||
if (bt_hold_counter > TIME_500MS) {
|
||||
if (fabsf(mc_interface_get_rpm()) < ERPM_THRESHOLD) {
|
||||
// after 150ms, power-down is triggered by the falling edge (releasing the button)
|
||||
will_poweroff = true;
|
||||
bt_hold_counter = 0;
|
||||
}
|
||||
else {
|
||||
if (bt_hold_counter > TIME_3S) {
|
||||
// Emergency Power-Down
|
||||
will_poweroff = true;
|
||||
force_poweroff = true;
|
||||
bt_hold_counter = 0;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// press is too short, abort
|
||||
bt_hold_counter = 0;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
float hw_Thor_get_temp(void) {
|
||||
float t1 = (1.0 / ((logf(NTC_RES(ADC_Value[ADC_IND_TEMP_MOS]) / 10000.0) / 3380.0) + (1.0 / 298.15)) - 273.15);
|
||||
float t3 = (1.0 / ((logf(NTC_RES(ADC_Value[ADC_IND_TEMP_MOS_3]) / 10000.0) / 3380.0) + (1.0 / 298.15)) - 273.15);
|
||||
|
@ -286,5 +377,13 @@ float hw_Thor_get_temp(void) {
|
|||
return res;
|
||||
}
|
||||
|
||||
static void terminal_button_test(int argc, const char **argv) {
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
|
||||
|
||||
for (int i = 0;i < 40;i++) {
|
||||
commands_printf("BT: %d:%d [%.2fV], %.2fV, %.2fV, OFF=%d", HW_SAMPLE_SHUTDOWN(), bt_hold_counter,
|
||||
(double)bt_diff, (double)bt_unpressed, (double)bt_lastval, (int)will_poweroff);
|
||||
chThdSleepMilliseconds(100);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue