forked from achamaikin/CCSModuleSW30Web
latest version
This commit is contained in:
185
Core/Src/lock.c
185
Core/Src/lock.c
@@ -5,45 +5,37 @@
|
||||
* Author: colorbass
|
||||
*/
|
||||
#include "lock.h"
|
||||
#include "debug.h"
|
||||
|
||||
uint8_t LOCK_POLARITY = 1;
|
||||
|
||||
uint8_t LOCK_POLARITY = 1; // 1 for v1
|
||||
uint8_t LOCK_MOTOR_POLARITY = 1;
|
||||
uint8_t LOCK_DELAY = 50;
|
||||
uint16_t LOCK_DELAY = 100;
|
||||
|
||||
GBT_LockState_t GBT_LockState;
|
||||
GBT_LockState_t GBT_LockState = {
|
||||
.demand = 0,
|
||||
.error = 0,
|
||||
.action_requested = 255, // нет запрошенного действия
|
||||
.motor_state = 0, // idle
|
||||
.last_action_time = 0,
|
||||
.retry_count = 0,
|
||||
.error_tick = 0
|
||||
};
|
||||
|
||||
|
||||
void GBT_ForceLock(uint8_t state){
|
||||
if(LOCK_MOTOR_POLARITY){
|
||||
if(state){//LOCK
|
||||
HAL_GPIO_WritePin(LOCK_B_GPIO_Port, LOCK_B_Pin, 1);
|
||||
HAL_Delay(LOCK_DELAY);
|
||||
HAL_GPIO_WritePin(LOCK_B_GPIO_Port, LOCK_B_Pin, 0);
|
||||
}else{ //UNLOCK
|
||||
HAL_GPIO_WritePin(LOCK_A_GPIO_Port, LOCK_A_Pin, 1);
|
||||
HAL_Delay(LOCK_DELAY);
|
||||
HAL_GPIO_WritePin(LOCK_A_GPIO_Port, LOCK_A_Pin, 0);
|
||||
}
|
||||
}else{
|
||||
if(state){//LOCK
|
||||
HAL_GPIO_WritePin(LOCK_A_GPIO_Port, LOCK_A_Pin, 1);
|
||||
HAL_Delay(LOCK_DELAY);
|
||||
HAL_GPIO_WritePin(LOCK_A_GPIO_Port, LOCK_A_Pin, 0);
|
||||
}else{ //UNLOCK
|
||||
HAL_GPIO_WritePin(LOCK_B_GPIO_Port, LOCK_B_Pin, 1);
|
||||
HAL_Delay(LOCK_DELAY);
|
||||
HAL_GPIO_WritePin(LOCK_B_GPIO_Port, LOCK_B_Pin, 0);
|
||||
}
|
||||
}
|
||||
// Устанавливаем флаг для выполнения действия
|
||||
GBT_LockState.action_requested = state ? 1 : 0;
|
||||
GBT_LockState.retry_count = 0;
|
||||
}
|
||||
|
||||
uint8_t GBT_LockGetState(){
|
||||
//1 = locked
|
||||
//0 = unlocked
|
||||
if(LOCK_POLARITY){
|
||||
return HAL_GPIO_ReadPin(LOCK_FB_GPIO_Port, LOCK_FB_Pin);
|
||||
return HAL_GPIO_ReadPin(IN0_GPIO_Port, IN0_Pin);
|
||||
}else{
|
||||
return !HAL_GPIO_ReadPin(LOCK_FB_GPIO_Port, LOCK_FB_Pin);
|
||||
return !HAL_GPIO_ReadPin(IN0_GPIO_Port, IN0_Pin);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -52,37 +44,126 @@ void GBT_Lock(uint8_t state){
|
||||
GBT_LockState.demand = state;
|
||||
}
|
||||
|
||||
void GBT_ManageLock(){
|
||||
uint8_t MAX_RETRIES = 5;
|
||||
if (GBT_LockState.error) {
|
||||
return;
|
||||
}
|
||||
void GBT_ManageLockSolenoid(){
|
||||
static uint32_t tick;
|
||||
|
||||
if(HAL_GetTick() - tick < 50) return;
|
||||
tick = HAL_GetTick();
|
||||
|
||||
HAL_GPIO_WritePin(LOCK_B_GPIO_Port, LOCK_B_Pin, GBT_LockState.demand ? 1 : 0);
|
||||
}
|
||||
|
||||
void GBT_ManageLockMotor(){
|
||||
static const uint8_t MAX_RETRIES = 5;
|
||||
uint32_t current_tick = HAL_GetTick();
|
||||
|
||||
// Проверяем таймаут сброса ошибки (до проверки error, чтобы можно было сбросить)
|
||||
GBT_ResetErrorTimeout();
|
||||
|
||||
if (GBT_LockState.error) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Проверяем, нужно ли выполнить действие
|
||||
bool lock_is_open = GBT_LockGetState() == 0;
|
||||
bool lock_should_be_open = GBT_LockState.demand == 0;
|
||||
uint8_t retry_count = 0;
|
||||
|
||||
if (lock_is_open != lock_should_be_open) {
|
||||
while (retry_count < MAX_RETRIES) {
|
||||
if (lock_should_be_open) {
|
||||
GBT_ForceLock(0);
|
||||
} else {
|
||||
GBT_ForceLock(1);
|
||||
}
|
||||
|
||||
lock_is_open = GBT_LockGetState() == 0;
|
||||
|
||||
if (lock_is_open == lock_should_be_open) {
|
||||
break;
|
||||
}
|
||||
|
||||
retry_count++;
|
||||
|
||||
// Если есть запрошенное действие или состояние не соответствует требуемому
|
||||
if (GBT_LockState.action_requested != 255 || (lock_is_open != lock_should_be_open)) {
|
||||
// Если действие еще не запрошено, запрашиваем его
|
||||
if (GBT_LockState.action_requested == 255) {
|
||||
GBT_LockState.action_requested = lock_should_be_open ? 0 : 1;
|
||||
GBT_LockState.retry_count = 0;
|
||||
}
|
||||
|
||||
// Управление мотором через машину состояний
|
||||
switch (GBT_LockState.motor_state) {
|
||||
case 0: // idle - мотор выключен
|
||||
// Определяем, какой пин нужно включить
|
||||
if (LOCK_MOTOR_POLARITY) {
|
||||
if (GBT_LockState.action_requested == 1) { // LOCK
|
||||
HAL_GPIO_WritePin(LOCK_B_GPIO_Port, LOCK_B_Pin, 1);
|
||||
} else { // UNLOCK
|
||||
HAL_GPIO_WritePin(LOCK_A_GPIO_Port, LOCK_A_Pin, 1);
|
||||
}
|
||||
} else {
|
||||
if (GBT_LockState.action_requested == 1) { // LOCK
|
||||
HAL_GPIO_WritePin(LOCK_A_GPIO_Port, LOCK_A_Pin, 1);
|
||||
} else { // UNLOCK
|
||||
HAL_GPIO_WritePin(LOCK_B_GPIO_Port, LOCK_B_Pin, 1);
|
||||
}
|
||||
}
|
||||
GBT_LockState.motor_state = 1; // motor_on
|
||||
GBT_LockState.last_action_time = current_tick;
|
||||
break;
|
||||
|
||||
case 1: // motor_on - мотор включен, ждем LOCK_DELAY
|
||||
if (current_tick - GBT_LockState.last_action_time >= LOCK_DELAY) {
|
||||
// Выключаем оба пина
|
||||
HAL_GPIO_WritePin(LOCK_A_GPIO_Port, LOCK_A_Pin, 0);
|
||||
HAL_GPIO_WritePin(LOCK_B_GPIO_Port, LOCK_B_Pin, 0);
|
||||
GBT_LockState.motor_state = 2; // waiting_off
|
||||
GBT_LockState.last_action_time = current_tick;
|
||||
}
|
||||
break;
|
||||
|
||||
case 2: // waiting_off - ждем немного перед проверкой состояния
|
||||
// Небольшая задержка перед проверкой состояния (например, 50мс)
|
||||
if (current_tick - GBT_LockState.last_action_time >= 50) {
|
||||
// Проверяем, достигнуто ли требуемое состояние
|
||||
lock_is_open = GBT_LockGetState() == 0;
|
||||
bool action_success = (lock_is_open == (GBT_LockState.action_requested == 0));
|
||||
|
||||
if (action_success) {
|
||||
// Действие выполнено успешно
|
||||
GBT_LockState.action_requested = 255; // сбрасываем флаг
|
||||
GBT_LockState.motor_state = 0; // idle
|
||||
GBT_LockState.retry_count = 0;
|
||||
} else {
|
||||
// Действие не выполнено, повторяем попытку
|
||||
GBT_LockState.retry_count++;
|
||||
if (GBT_LockState.retry_count >= MAX_RETRIES) {
|
||||
// Превышено количество попыток
|
||||
GBT_LockState.error = 1;
|
||||
GBT_LockState.error_tick = current_tick; // сохраняем время установки ошибки
|
||||
GBT_LockState.action_requested = 0; // пытаемся разблокировать
|
||||
GBT_LockState.motor_state = 0;
|
||||
GBT_LockState.retry_count = 0;
|
||||
log_printf(LOG_ERR, "Lock error\n");
|
||||
} else {
|
||||
// Повторяем попытку
|
||||
GBT_LockState.motor_state = 0; // возвращаемся к началу
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// Состояние соответствует требуемому, сбрасываем флаги
|
||||
if (GBT_LockState.motor_state != 0) {
|
||||
HAL_GPIO_WritePin(LOCK_A_GPIO_Port, LOCK_A_Pin, 0);
|
||||
HAL_GPIO_WritePin(LOCK_B_GPIO_Port, LOCK_B_Pin, 0);
|
||||
GBT_LockState.motor_state = 0;
|
||||
}
|
||||
GBT_LockState.action_requested = 255;
|
||||
GBT_LockState.retry_count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (retry_count >= MAX_RETRIES) {
|
||||
GBT_LockState.error = 1;
|
||||
GBT_ForceLock(0);
|
||||
printf ("Lock error\n");
|
||||
void GBT_LockResetError(){
|
||||
GBT_LockState.error = 0;
|
||||
GBT_LockState.error_tick = 0;
|
||||
log_printf(LOG_INFO, "Lock error reset\n");
|
||||
}
|
||||
|
||||
void GBT_ResetErrorTimeout(){
|
||||
static const uint32_t ERROR_TIMEOUT_MS = 300000; // 5 минут
|
||||
|
||||
if (GBT_LockState.error && GBT_LockState.error_tick != 0) {
|
||||
|
||||
if ((HAL_GetTick()-GBT_LockState.error_tick) >= ERROR_TIMEOUT_MS) {
|
||||
// Прошло 5 минут, сбрасываем ошибку
|
||||
GBT_LockResetError();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user