基质喷涂
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

  1. //
  2. // Created by iflyt on 2025/3/2.
  3. //
  4. #include "exti_key_manager.h"
  5. #include <stm32f4xx_hal.h>
  6. #include <base/apphardware.hpp>
  7. #include <base/zbasic.h>
  8. #include <status/motor_manager.h>
  9. #include <LED/timer_key_manager.h>
  10. #include "led.h"
  11. #define TAG "EXTI_KEY"
  12. ExtiKeyManager* ExtiKeyManager::s_instance = nullptr;
  13. EXITKeyInfo ExtiKeyManager::exit_key_info_ = EXITKeyInfo();
  14. const B_PinInfo ExtiKeyManager::pinInfos[EXTI_PIN_COUNT] = {
  15. {X_PORT, X_ORIGIN_PIN, GPIO_PIN_RESET},
  16. {X_PORT, X_LIMIT_PIN, GPIO_PIN_RESET},
  17. {Y_PORT, Y_ORIGIN_PIN, GPIO_PIN_RESET},
  18. {Y_PORT, Y_LIMIT_PIN, GPIO_PIN_RESET},
  19. {Z_PORT, Z_ORIGIN_PIN, GPIO_PIN_RESET},
  20. {Z_PORT, Z_LIMIT_PIN, GPIO_PIN_RESET},
  21. {SYSTEM_POWER_PORT, SYSTEM_POWER_PIN, GPIO_PIN_SET},
  22. {E_STOP_PORT, E_STOP_PIN, GPIO_PIN_RESET}
  23. };
  24. ExtiKeyManager* ExtiKeyManager::ins() {
  25. if (s_instance == nullptr) {
  26. s_instance = new ExtiKeyManager();
  27. }
  28. return s_instance;
  29. }
  30. ExtiKeyManager::ExtiKeyManager() {
  31. keyQueue_ = osMessageQueueNew(10, sizeof(EXITKeyInfo), nullptr);
  32. if (keyQueue_ == nullptr) {
  33. }
  34. osThreadNew(ExtiKeyManager::handleKeyInterrupts, this, nullptr);
  35. }
  36. ExtiKeyManager::~ExtiKeyManager() {
  37. if(keyQueue_ != nullptr) {
  38. osMessageQueueDelete(keyQueue_);
  39. }
  40. }
  41. bool ExtiKeyManager::isPinStateTriggered(const uint16_t targetPin, const bool state) {
  42. for (int i = 0; i < sizeof(pinInfos) / sizeof(B_PinInfo); i++) {
  43. if (pinInfos[i].pin == targetPin) {
  44. GPIO_PinState currentLevel = state ? GPIO_PIN_SET : GPIO_PIN_RESET;
  45. // 检查当前电平是否等于有效电平,并且输入的电平也等于有效电平
  46. return (currentLevel == pinInfos[i].activeLevel);
  47. }
  48. }
  49. return false; // 如果未找到对应的引脚,返回 false
  50. }
  51. bool ExtiKeyManager::isPinTriggered(uint16_t targetPin) {
  52. for (int i = 0; i < sizeof(pinInfos) / sizeof(pinInfos[0]); i++) {
  53. if (pinInfos[i].pin == targetPin) {
  54. GPIO_PinState currentLevel = HAL_GPIO_ReadPin(pinInfos[i].port, pinInfos[i].pin);
  55. return (currentLevel == pinInfos[i].activeLevel);
  56. }
  57. }
  58. return false; // 如果未找到对应的引脚,返回 false
  59. }
  60. GPIO_TypeDef* ExtiKeyManager::getPortByPin(uint16_t pin) {
  61. for(int i = 0; i < EXTI_PIN_COUNT; i++) {
  62. if(pin == pinInfos[i].pin) {
  63. return pinInfos[i].port;
  64. }
  65. }
  66. return nullptr;
  67. }
  68. extern "C" void HAL_GPIO_EXTI_Callback(uint16_t gpio_pin) {
  69. GPIO_PinState pin_state = GPIO_PIN_RESET;
  70. GPIO_TypeDef *gpio_port = ExtiKeyManager::getPortByPin(gpio_pin);
  71. if(gpio_port != nullptr) {
  72. pin_state = HAL_GPIO_ReadPin(gpio_port, gpio_pin);
  73. ExtiKeyManager::handleInterrupt(gpio_pin, pin_state);
  74. }
  75. }
  76. void ExtiKeyManager::handleInterrupt(uint16_t gpio_pin, GPIO_PinState pin_state) {
  77. if (s_instance && s_instance->keyQueue_) {
  78. exit_key_info_.gpio_pin = gpio_pin;
  79. exit_key_info_.pin_state = pin_state;
  80. osMessageQueuePut(s_instance->keyQueue_, &exit_key_info_, 0, 0);
  81. }
  82. }
  83. void ExtiKeyManager::handleKeyInterrupts(void* arg) {
  84. ExtiKeyManager* manager = static_cast<ExtiKeyManager*>(arg);
  85. EXITKeyInfo exit_key_info = EXITKeyInfo();
  86. while (true) {
  87. osStatus os_status = osMessageQueueGet(manager->keyQueue_, &exit_key_info, nullptr, osWaitForever);
  88. if (os_status == osOK) {
  89. if(exit_key_info.gpio_pin == SYSTEM_POWER_PIN || exit_key_info.gpio_pin == E_STOP_PIN) {
  90. osDelay(50);
  91. GPIO_TypeDef* port = getPortByPin(exit_key_info.gpio_pin);
  92. GPIO_PinState pin_state = HAL_GPIO_ReadPin(port, exit_key_info.gpio_pin);
  93. if(pin_state == exit_key_info.pin_state) {
  94. const bool is_triggerd = manager->isPinStateTriggered(exit_key_info.gpio_pin, exit_key_info.pin_state);
  95. manager->processKeyEvent(exit_key_info.gpio_pin, is_triggerd);
  96. }
  97. }
  98. else {
  99. const bool is_triggerd = manager->isPinStateTriggered(exit_key_info.gpio_pin, exit_key_info.pin_state);
  100. manager->processKeyEvent(exit_key_info.gpio_pin, is_triggerd);
  101. }
  102. }
  103. else {
  104. ZLOGI(TAG, "key queue get failed error code %d", os_status);
  105. }
  106. }
  107. }
  108. void ExtiKeyManager::processKeyEvent(const uint16_t gpio_pin, const bool is_triggerd) {
  109. switch (gpio_pin) {
  110. case E_STOP_PIN: {
  111. // 处理急停按键事件
  112. if (is_triggerd) {
  113. ZLOGI(TAG, "E_STOP_PIN Pressed");
  114. iflytop::AppHardware::ins()->setE_Stop(true);
  115. iflytop::AppHardware::ins()->SystemPowerOff(true);
  116. tri_color_light(COLOR_RED); // 开启红灯
  117. } else {
  118. ZLOGI(TAG, "E_STOP_PIN Released");
  119. iflytop::AppHardware::ins()->setE_Stop(false);
  120. bool isLaunched = iflytop::AppHardware::ins()->isLaunched();
  121. if(isLaunched) {
  122. iflytop::AppHardware::ins()->SystemPowerOn();
  123. }
  124. else {
  125. tri_color_light(COLOR_OFF); // 开启绿灯
  126. }
  127. }
  128. break;
  129. }
  130. case SYSTEM_POWER_PIN: {
  131. // 处理开解按键事件
  132. if(is_triggerd) {
  133. ZLOGI(TAG, "SYSTEM_POWER_PIN Pressed");
  134. RK3588_POWER_TOGGLE;
  135. LED_KEY_TOGGLE;
  136. // bool
  137. const bool isLaunched = iflytop::AppHardware::ins()->isLaunched();
  138. if(!isLaunched) {
  139. iflytop::AppHardware::ins()->SystemPowerOn();
  140. }
  141. else {
  142. iflytop::AppHardware::ins()->SystemPowerOff();
  143. }
  144. iflytop::AppHardware::ins()->toggleLaunched();
  145. }
  146. else {
  147. ZLOGI(TAG, "SYSTEM POWER PIN Released");
  148. }
  149. break;
  150. }
  151. case X_ORIGIN_PIN: {
  152. // 处理X轴原点传感器事件
  153. MotorManager::ins()->motors[0].runZeroLimit(is_triggerd);
  154. if (is_triggerd) {
  155. ZLOGI(TAG, "X_ORIGIN_PIN ENTER");
  156. } else {
  157. ZLOGI(TAG, "X_ORIGIN_PIN LEAVE");
  158. }
  159. break;
  160. }
  161. case X_LIMIT_PIN: {
  162. // 处理X轴限位传感器事件
  163. MotorManager::ins()->motors[0].runEndLimit(is_triggerd);
  164. if (isPinStateTriggered(X_LIMIT_PIN, is_triggerd)) {
  165. ZLOGI(TAG, "X_LIMIT_PIN ENTER");
  166. } else {
  167. ZLOGI(TAG, "X_LIMIT_PIN LEAVE");
  168. }
  169. break;
  170. }
  171. case Y_ORIGIN_PIN: {
  172. // 处理Y轴原点传感器事件
  173. MotorManager::ins()->motors[1].runZeroLimit(is_triggerd);
  174. if (is_triggerd) {
  175. ZLOGI(TAG, "Y_ORIGIN_PIN ENTER");
  176. } else {
  177. ZLOGI(TAG, "Y_ORIGIN_PIN LEAVE");
  178. }
  179. break;
  180. }
  181. case Y_LIMIT_PIN: {
  182. // 处理Y轴限位传感器事件
  183. MotorManager::ins()->motors[1].runEndLimit(is_triggerd);
  184. if (is_triggerd) {
  185. ZLOGI(TAG, "Y_LIMIT_PIN ENTER");
  186. } else {
  187. ZLOGI(TAG, "Y_LIMIT_PIN LEAVE");
  188. }
  189. break;
  190. }
  191. case Z_ORIGIN_PIN: {
  192. // 处理Z轴原点传感器事件
  193. MotorManager::ins()->motors[2].runZeroLimit(is_triggerd);
  194. if (is_triggerd) {
  195. ZLOGI(TAG, "Z_ORIGIN_PIN ENTER");
  196. } else {
  197. ZLOGI(TAG, "Z_ORIGIN_PIN LEAVE");
  198. }
  199. break;
  200. }
  201. case Z_LIMIT_PIN: {
  202. // 处理Z轴限位传感器事件
  203. MotorManager::ins()->motors[2].runEndLimit(is_triggerd);
  204. if (is_triggerd) {
  205. ZLOGI(TAG, "Z_LIMIT_PIN ENTER");
  206. } else {
  207. ZLOGI(TAG, "Z_LIMIT_PIN LEAVE");
  208. }
  209. break;
  210. }
  211. default:
  212. break;
  213. }
  214. }
  215. // 初始化 GPIO 引脚
  216. void EX_GPIO_Init(void) {
  217. GPIO_InitTypeDef GPIO_InitStruct = {0};
  218. // 使能 GPIO 时钟
  219. __HAL_RCC_GPIOA_CLK_ENABLE();
  220. __HAL_RCC_GPIOB_CLK_ENABLE();
  221. __HAL_RCC_GPIOF_CLK_ENABLE();
  222. // 配置 X 轴传感器引脚
  223. GPIO_InitStruct.Pin = X_ORIGIN_PIN | X_LIMIT_PIN;
  224. GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;
  225. GPIO_InitStruct.Pull = GPIO_NOPULL;
  226. HAL_GPIO_Init(X_PORT, &GPIO_InitStruct);
  227. // 配置 Y 轴传感器引脚
  228. GPIO_InitStruct.Pin = Y_ORIGIN_PIN | Y_LIMIT_PIN;
  229. GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;
  230. GPIO_InitStruct.Pull = GPIO_NOPULL;
  231. HAL_GPIO_Init(Y_PORT, &GPIO_InitStruct);
  232. // 配置 Z 轴传感器引脚
  233. GPIO_InitStruct.Pin = Z_ORIGIN_PIN | Z_LIMIT_PIN;
  234. GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;
  235. GPIO_InitStruct.Pull = GPIO_NOPULL;
  236. HAL_GPIO_Init(Z_PORT, &GPIO_InitStruct);
  237. // 配置 KEY1 引脚
  238. GPIO_InitStruct.Pin = SYSTEM_POWER_PIN;
  239. GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING; // 上升沿触发中断
  240. GPIO_InitStruct.Pull = GPIO_NOPULL;
  241. HAL_GPIO_Init(SYSTEM_POWER_PORT, &GPIO_InitStruct);
  242. // 配置 JT 引脚
  243. GPIO_InitStruct.Pin = E_STOP_PIN;
  244. GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;
  245. GPIO_InitStruct.Pull = GPIO_NOPULL;
  246. HAL_GPIO_Init(E_STOP_PORT, &GPIO_InitStruct);
  247. // 配置中断优先级
  248. HAL_NVIC_SetPriority(EXTI9_5_IRQn, 5, 0);
  249. HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);
  250. HAL_NVIC_SetPriority(EXTI15_10_IRQn, 5, 0);
  251. HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);
  252. HAL_NVIC_SetPriority(EXTI0_IRQn, 5, 0);
  253. HAL_NVIC_EnableIRQ(EXTI0_IRQn);
  254. }
  255. extern "C" void EXTI0_IRQHandler(void) {
  256. HAL_GPIO_EXTI_IRQHandler(SYSTEM_POWER_PIN);
  257. }
  258. extern "C" void EXTI9_5_IRQHandler(void) {
  259. HAL_GPIO_EXTI_IRQHandler(X_ORIGIN_PIN);
  260. HAL_GPIO_EXTI_IRQHandler(X_LIMIT_PIN);
  261. HAL_GPIO_EXTI_IRQHandler(Y_ORIGIN_PIN);
  262. }
  263. extern "C" void EXTI15_10_IRQHandler(void) {
  264. HAL_GPIO_EXTI_IRQHandler(Y_LIMIT_PIN);
  265. HAL_GPIO_EXTI_IRQHandler(Z_ORIGIN_PIN);
  266. HAL_GPIO_EXTI_IRQHandler(Z_LIMIT_PIN);
  267. HAL_GPIO_EXTI_IRQHandler(E_STOP_PIN);
  268. }
  269. extern "C" uint16_t getORIGINPin(uint32_t motor_index) {
  270. switch (motor_index) {
  271. case 0:
  272. return X_ORIGIN_PIN;
  273. case 1:
  274. return Y_ORIGIN_PIN;
  275. case 2:
  276. return Z_ORIGIN_PIN;
  277. default:
  278. return 0xFFFF;
  279. }
  280. }
  281. uint16_t getAxisLimitPin(uint32_t motor_index) {
  282. switch (motor_index) {
  283. case 0:
  284. return X_LIMIT_PIN;
  285. case 1:
  286. return Y_LIMIT_PIN;
  287. case 2:
  288. return Z_LIMIT_PIN;
  289. default:
  290. return 0xFFFF;
  291. }
  292. }