You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
333 lines
11 KiB
333 lines
11 KiB
//
|
|
// Created by iflyt on 2025/3/2.
|
|
//
|
|
#include "exti_key_manager.h"
|
|
|
|
#include <stm32f4xx_hal.h>
|
|
#include <base/apphardware.hpp>
|
|
#include <base/zbasic.h>
|
|
#include <status/motor_manager.h>
|
|
#include <LED/timer_key_manager.h>
|
|
|
|
#include "led.h"
|
|
|
|
#define TAG "EXTI_KEY"
|
|
|
|
ExtiKeyManager* ExtiKeyManager::s_instance = nullptr;
|
|
|
|
EXITKeyInfo ExtiKeyManager::exit_key_info_ = EXITKeyInfo();
|
|
|
|
const B_PinInfo ExtiKeyManager::pinInfos[EXTI_PIN_COUNT] = {
|
|
{X_PORT, X_ORIGIN_PIN, GPIO_PIN_RESET},
|
|
{X_PORT, X_LIMIT_PIN, GPIO_PIN_RESET},
|
|
{Y_PORT, Y_ORIGIN_PIN, GPIO_PIN_RESET},
|
|
{Y_PORT, Y_LIMIT_PIN, GPIO_PIN_RESET},
|
|
{Z_PORT, Z_ORIGIN_PIN, GPIO_PIN_RESET},
|
|
{Z_PORT, Z_LIMIT_PIN, GPIO_PIN_RESET},
|
|
{SYSTEM_POWER_PORT, SYSTEM_POWER_PIN, GPIO_PIN_SET},
|
|
{E_STOP_PORT, E_STOP_PIN, GPIO_PIN_RESET}
|
|
};
|
|
|
|
|
|
ExtiKeyManager* ExtiKeyManager::ins() {
|
|
if (s_instance == nullptr) {
|
|
s_instance = new ExtiKeyManager();
|
|
}
|
|
return s_instance;
|
|
}
|
|
|
|
ExtiKeyManager::ExtiKeyManager() {
|
|
keyQueue_ = osMessageQueueNew(10, sizeof(EXITKeyInfo), nullptr);
|
|
if (keyQueue_ == nullptr) {
|
|
}
|
|
osThreadNew(ExtiKeyManager::handleKeyInterrupts, this, nullptr);
|
|
}
|
|
|
|
ExtiKeyManager::~ExtiKeyManager() {
|
|
if(keyQueue_ != nullptr) {
|
|
osMessageQueueDelete(keyQueue_);
|
|
}
|
|
}
|
|
|
|
bool ExtiKeyManager::isPinStateTriggered(const uint16_t targetPin, const bool state) {
|
|
for (int i = 0; i < sizeof(pinInfos) / sizeof(B_PinInfo); i++) {
|
|
if (pinInfos[i].pin == targetPin) {
|
|
GPIO_PinState currentLevel = state ? GPIO_PIN_SET : GPIO_PIN_RESET;
|
|
// 检查当前电平是否等于有效电平,并且输入的电平也等于有效电平
|
|
return (currentLevel == pinInfos[i].activeLevel);
|
|
}
|
|
}
|
|
return false; // 如果未找到对应的引脚,返回 false
|
|
}
|
|
|
|
bool ExtiKeyManager::isPinTriggered(uint16_t targetPin) {
|
|
for (int i = 0; i < sizeof(pinInfos) / sizeof(pinInfos[0]); i++) {
|
|
if (pinInfos[i].pin == targetPin) {
|
|
GPIO_PinState currentLevel = HAL_GPIO_ReadPin(pinInfos[i].port, pinInfos[i].pin);
|
|
return (currentLevel == pinInfos[i].activeLevel);
|
|
}
|
|
}
|
|
return false; // 如果未找到对应的引脚,返回 false
|
|
}
|
|
|
|
GPIO_TypeDef* ExtiKeyManager::getPortByPin(uint16_t pin) {
|
|
for(int i = 0; i < EXTI_PIN_COUNT; i++) {
|
|
if(pin == pinInfos[i].pin) {
|
|
return pinInfos[i].port;
|
|
}
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
extern "C" void HAL_GPIO_EXTI_Callback(uint16_t gpio_pin) {
|
|
GPIO_PinState pin_state = GPIO_PIN_RESET;
|
|
GPIO_TypeDef *gpio_port = ExtiKeyManager::getPortByPin(gpio_pin);
|
|
if(gpio_port != nullptr) {
|
|
pin_state = HAL_GPIO_ReadPin(gpio_port, gpio_pin);
|
|
ExtiKeyManager::handleInterrupt(gpio_pin, pin_state);
|
|
}
|
|
}
|
|
|
|
void ExtiKeyManager::handleInterrupt(uint16_t gpio_pin, GPIO_PinState pin_state) {
|
|
if (s_instance && s_instance->keyQueue_) {
|
|
exit_key_info_.gpio_pin = gpio_pin;
|
|
exit_key_info_.pin_state = pin_state;
|
|
osMessageQueuePut(s_instance->keyQueue_, &exit_key_info_, 0, 0);
|
|
}
|
|
}
|
|
|
|
void ExtiKeyManager::handleKeyInterrupts(void* arg) {
|
|
ExtiKeyManager* manager = static_cast<ExtiKeyManager*>(arg);
|
|
EXITKeyInfo exit_key_info = EXITKeyInfo();
|
|
while (true) {
|
|
osStatus os_status = osMessageQueueGet(manager->keyQueue_, &exit_key_info, nullptr, osWaitForever);
|
|
if (os_status == osOK) {
|
|
if(exit_key_info.gpio_pin == SYSTEM_POWER_PIN || exit_key_info.gpio_pin == E_STOP_PIN) {
|
|
osDelay(50);
|
|
GPIO_TypeDef* port = getPortByPin(exit_key_info.gpio_pin);
|
|
GPIO_PinState pin_state = HAL_GPIO_ReadPin(port, exit_key_info.gpio_pin);
|
|
if(pin_state == exit_key_info.pin_state) {
|
|
const bool is_triggerd = manager->isPinStateTriggered(exit_key_info.gpio_pin, exit_key_info.pin_state);
|
|
manager->processKeyEvent(exit_key_info.gpio_pin, is_triggerd);
|
|
}
|
|
}
|
|
else {
|
|
const bool is_triggerd = manager->isPinStateTriggered(exit_key_info.gpio_pin, exit_key_info.pin_state);
|
|
manager->processKeyEvent(exit_key_info.gpio_pin, is_triggerd);
|
|
}
|
|
}
|
|
else {
|
|
ZLOGI(TAG, "key queue get failed error code %d", os_status);
|
|
}
|
|
}
|
|
}
|
|
|
|
void ExtiKeyManager::processKeyEvent(const uint16_t gpio_pin, const bool is_triggerd) {
|
|
switch (gpio_pin) {
|
|
case E_STOP_PIN: {
|
|
// 处理急停按键事件
|
|
if (is_triggerd) {
|
|
ZLOGI(TAG, "E_STOP_PIN Pressed");
|
|
iflytop::AppHardware::ins()->setE_Stop(true);
|
|
iflytop::AppHardware::ins()->SystemPowerOff(true);
|
|
tri_color_light(COLOR_RED); // 开启红灯
|
|
} else {
|
|
ZLOGI(TAG, "E_STOP_PIN Released");
|
|
iflytop::AppHardware::ins()->setE_Stop(false);
|
|
bool isLaunched = iflytop::AppHardware::ins()->isLaunched();
|
|
if(isLaunched) {
|
|
iflytop::AppHardware::ins()->SystemPowerOn();
|
|
}
|
|
else {
|
|
tri_color_light(COLOR_OFF); // 开启绿灯
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case SYSTEM_POWER_PIN: {
|
|
// 处理开解按键事件
|
|
if(is_triggerd) {
|
|
ZLOGI(TAG, "SYSTEM_POWER_PIN Pressed");
|
|
RK3588_POWER_TOGGLE;
|
|
LED_KEY_TOGGLE;
|
|
// bool
|
|
const bool isLaunched = iflytop::AppHardware::ins()->isLaunched();
|
|
if(!isLaunched) {
|
|
iflytop::AppHardware::ins()->SystemPowerOn();
|
|
}
|
|
else {
|
|
iflytop::AppHardware::ins()->SystemPowerOff();
|
|
}
|
|
iflytop::AppHardware::ins()->toggleLaunched();
|
|
}
|
|
else {
|
|
ZLOGI(TAG, "SYSTEM POWER PIN Released");
|
|
}
|
|
|
|
break;
|
|
}
|
|
case X_ORIGIN_PIN: {
|
|
// 处理X轴原点传感器事件
|
|
MotorManager::ins()->motors[0].runZeroLimit(is_triggerd);
|
|
if (is_triggerd) {
|
|
ZLOGI(TAG, "X_ORIGIN_PIN ENTER");
|
|
} else {
|
|
ZLOGI(TAG, "X_ORIGIN_PIN LEAVE");
|
|
}
|
|
break;
|
|
}
|
|
case X_LIMIT_PIN: {
|
|
// 处理X轴限位传感器事件
|
|
MotorManager::ins()->motors[0].runEndLimit(is_triggerd);
|
|
|
|
if (isPinStateTriggered(X_LIMIT_PIN, is_triggerd)) {
|
|
ZLOGI(TAG, "X_LIMIT_PIN ENTER");
|
|
} else {
|
|
ZLOGI(TAG, "X_LIMIT_PIN LEAVE");
|
|
}
|
|
break;
|
|
}
|
|
case Y_ORIGIN_PIN: {
|
|
// 处理Y轴原点传感器事件
|
|
MotorManager::ins()->motors[1].runZeroLimit(is_triggerd);
|
|
|
|
if (is_triggerd) {
|
|
ZLOGI(TAG, "Y_ORIGIN_PIN ENTER");
|
|
|
|
} else {
|
|
ZLOGI(TAG, "Y_ORIGIN_PIN LEAVE");
|
|
}
|
|
break;
|
|
}
|
|
case Y_LIMIT_PIN: {
|
|
// 处理Y轴限位传感器事件
|
|
MotorManager::ins()->motors[1].runEndLimit(is_triggerd);
|
|
|
|
if (is_triggerd) {
|
|
ZLOGI(TAG, "Y_LIMIT_PIN ENTER");
|
|
} else {
|
|
ZLOGI(TAG, "Y_LIMIT_PIN LEAVE");
|
|
}
|
|
break;
|
|
}
|
|
case Z_ORIGIN_PIN: {
|
|
// 处理Z轴原点传感器事件
|
|
MotorManager::ins()->motors[2].runZeroLimit(is_triggerd);
|
|
|
|
if (is_triggerd) {
|
|
ZLOGI(TAG, "Z_ORIGIN_PIN ENTER");
|
|
} else {
|
|
ZLOGI(TAG, "Z_ORIGIN_PIN LEAVE");
|
|
}
|
|
break;
|
|
}
|
|
case Z_LIMIT_PIN: {
|
|
// 处理Z轴限位传感器事件
|
|
MotorManager::ins()->motors[2].runEndLimit(is_triggerd);
|
|
|
|
if (is_triggerd) {
|
|
ZLOGI(TAG, "Z_LIMIT_PIN ENTER");
|
|
|
|
} else {
|
|
ZLOGI(TAG, "Z_LIMIT_PIN LEAVE");
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
// 初始化 GPIO 引脚
|
|
void EX_GPIO_Init(void) {
|
|
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
|
|
|
// 使能 GPIO 时钟
|
|
__HAL_RCC_GPIOA_CLK_ENABLE();
|
|
__HAL_RCC_GPIOB_CLK_ENABLE();
|
|
__HAL_RCC_GPIOF_CLK_ENABLE();
|
|
|
|
// 配置 X 轴传感器引脚
|
|
GPIO_InitStruct.Pin = X_ORIGIN_PIN | X_LIMIT_PIN;
|
|
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;
|
|
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
|
HAL_GPIO_Init(X_PORT, &GPIO_InitStruct);
|
|
|
|
// 配置 Y 轴传感器引脚
|
|
GPIO_InitStruct.Pin = Y_ORIGIN_PIN | Y_LIMIT_PIN;
|
|
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;
|
|
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
|
HAL_GPIO_Init(Y_PORT, &GPIO_InitStruct);
|
|
|
|
// 配置 Z 轴传感器引脚
|
|
GPIO_InitStruct.Pin = Z_ORIGIN_PIN | Z_LIMIT_PIN;
|
|
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;
|
|
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
|
HAL_GPIO_Init(Z_PORT, &GPIO_InitStruct);
|
|
|
|
// 配置 KEY1 引脚
|
|
GPIO_InitStruct.Pin = SYSTEM_POWER_PIN;
|
|
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING; // 上升沿触发中断
|
|
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
|
HAL_GPIO_Init(SYSTEM_POWER_PORT, &GPIO_InitStruct);
|
|
|
|
// 配置 JT 引脚
|
|
GPIO_InitStruct.Pin = E_STOP_PIN;
|
|
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;
|
|
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
|
HAL_GPIO_Init(E_STOP_PORT, &GPIO_InitStruct);
|
|
|
|
// 配置中断优先级
|
|
HAL_NVIC_SetPriority(EXTI9_5_IRQn, 5, 0);
|
|
HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);
|
|
|
|
HAL_NVIC_SetPriority(EXTI15_10_IRQn, 5, 0);
|
|
HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);
|
|
|
|
HAL_NVIC_SetPriority(EXTI0_IRQn, 5, 0);
|
|
HAL_NVIC_EnableIRQ(EXTI0_IRQn);
|
|
|
|
}
|
|
|
|
extern "C" void EXTI0_IRQHandler(void) {
|
|
HAL_GPIO_EXTI_IRQHandler(SYSTEM_POWER_PIN);
|
|
}
|
|
|
|
extern "C" void EXTI9_5_IRQHandler(void) {
|
|
HAL_GPIO_EXTI_IRQHandler(X_ORIGIN_PIN);
|
|
HAL_GPIO_EXTI_IRQHandler(X_LIMIT_PIN);
|
|
HAL_GPIO_EXTI_IRQHandler(Y_ORIGIN_PIN);
|
|
}
|
|
|
|
extern "C" void EXTI15_10_IRQHandler(void) {
|
|
HAL_GPIO_EXTI_IRQHandler(Y_LIMIT_PIN);
|
|
HAL_GPIO_EXTI_IRQHandler(Z_ORIGIN_PIN);
|
|
HAL_GPIO_EXTI_IRQHandler(Z_LIMIT_PIN);
|
|
// HAL_GPIO_EXTI_IRQHandler(E_STOP_PIN);
|
|
}
|
|
|
|
extern "C" uint16_t getORIGINPin(uint32_t motor_index) {
|
|
switch (motor_index) {
|
|
case 0:
|
|
return X_ORIGIN_PIN;
|
|
case 1:
|
|
return Y_ORIGIN_PIN;
|
|
case 2:
|
|
return Z_ORIGIN_PIN;
|
|
default:
|
|
return 0xFFFF;
|
|
}
|
|
}
|
|
|
|
uint16_t getAxisLimitPin(uint32_t motor_index) {
|
|
switch (motor_index) {
|
|
case 0:
|
|
return X_LIMIT_PIN;
|
|
case 1:
|
|
return Y_LIMIT_PIN;
|
|
case 2:
|
|
return Z_LIMIT_PIN;
|
|
default:
|
|
return 0xFFFF;
|
|
}
|
|
}
|