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

252 lines
7.6 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. #define TAG "EXTI_KEY"
  10. ExtiKeyManager* ExtiKeyManager::s_instance = nullptr;
  11. EXITKeyInfo ExtiKeyManager::exit_key_info_ = EXITKeyInfo();
  12. const B_PinInfo ExtiKeyManager::pinInfos[EXTI_PIN_COUNT] = {
  13. {X_PORT, X_ORIGIN_PIN, GPIO_PIN_RESET},
  14. {X_PORT, X_LIMIT_PIN, GPIO_PIN_RESET},
  15. {Y_PORT, Y_ORIGIN_PIN, GPIO_PIN_RESET},
  16. {Y_PORT, Y_LIMIT_PIN, GPIO_PIN_RESET},
  17. {Z_PORT, Z_ORIGIN_PIN, GPIO_PIN_RESET},
  18. {Z_PORT, Z_LIMIT_PIN, GPIO_PIN_RESET}
  19. };
  20. ExtiKeyManager* ExtiKeyManager::ins() {
  21. if (s_instance == nullptr) {
  22. s_instance = new ExtiKeyManager();
  23. }
  24. return s_instance;
  25. }
  26. ExtiKeyManager::ExtiKeyManager() {
  27. keyQueue_ = osMessageQueueNew(10, sizeof(EXITKeyInfo), nullptr);
  28. if (keyQueue_ == nullptr) {
  29. }
  30. osThreadNew(ExtiKeyManager::handleKeyInterrupts, this, nullptr);
  31. }
  32. ExtiKeyManager::~ExtiKeyManager() {
  33. if(keyQueue_ != nullptr) {
  34. osMessageQueueDelete(keyQueue_);
  35. }
  36. }
  37. bool ExtiKeyManager::isPinStateTriggered(const uint16_t targetPin, const bool state) {
  38. for (int i = 0; i < sizeof(pinInfos) / sizeof(B_PinInfo); i++) {
  39. if (pinInfos[i].pin == targetPin) {
  40. GPIO_PinState currentLevel = state ? GPIO_PIN_SET : GPIO_PIN_RESET;
  41. // 检查当前电平是否等于有效电平,并且输入的电平也等于有效电平
  42. return (currentLevel == pinInfos[i].activeLevel);
  43. }
  44. }
  45. return false; // 如果未找到对应的引脚,返回 false
  46. }
  47. bool ExtiKeyManager::isPinTriggered(uint16_t targetPin) {
  48. for (int i = 0; i < sizeof(pinInfos) / sizeof(pinInfos[0]); i++) {
  49. if (pinInfos[i].pin == targetPin) {
  50. GPIO_PinState currentLevel = HAL_GPIO_ReadPin(pinInfos[i].port, pinInfos[i].pin);
  51. return (currentLevel == pinInfos[i].activeLevel);
  52. }
  53. }
  54. return false; // 如果未找到对应的引脚,返回 false
  55. }
  56. GPIO_TypeDef* ExtiKeyManager::getPortByPin(uint16_t pin) {
  57. for(int i = 0; i < EXTI_PIN_COUNT; i++) {
  58. if(pin == pinInfos[i].pin) {
  59. return pinInfos[i].port;
  60. }
  61. }
  62. return nullptr;
  63. }
  64. extern "C" void HAL_GPIO_EXTI_Callback(uint16_t gpio_pin) {
  65. GPIO_PinState pin_state = GPIO_PIN_RESET;
  66. GPIO_TypeDef *gpio_port = ExtiKeyManager::getPortByPin(gpio_pin);
  67. if(gpio_port != nullptr) {
  68. pin_state = HAL_GPIO_ReadPin(gpio_port, gpio_pin);
  69. ExtiKeyManager::handleInterrupt(gpio_pin, pin_state);
  70. }
  71. }
  72. void ExtiKeyManager::handleInterrupt(uint16_t gpio_pin, GPIO_PinState pin_state) {
  73. if (s_instance && s_instance->keyQueue_) {
  74. exit_key_info_.gpio_pin = gpio_pin;
  75. exit_key_info_.pin_state = pin_state;
  76. osMessageQueuePut(s_instance->keyQueue_, &exit_key_info_, 0, 0);
  77. }
  78. }
  79. void ExtiKeyManager::handleKeyInterrupts(void* arg) {
  80. ExtiKeyManager* manager = static_cast<ExtiKeyManager*>(arg);
  81. EXITKeyInfo exit_key_info = EXITKeyInfo();
  82. while (true) {
  83. osStatus os_status = osMessageQueueGet(manager->keyQueue_, &exit_key_info, nullptr, osWaitForever);
  84. if (os_status == osOK) {
  85. const bool is_triggerd = manager->isPinStateTriggered(exit_key_info.gpio_pin, exit_key_info.pin_state);
  86. manager->processKeyEvent(exit_key_info.gpio_pin, is_triggerd);
  87. }
  88. else {
  89. ZLOGI(TAG, "key queue get failed error code %d", os_status);
  90. }
  91. }
  92. }
  93. void ExtiKeyManager::processKeyEvent(const uint16_t gpio_pin, const bool is_triggerd) {
  94. switch (gpio_pin) {
  95. case X_ORIGIN_PIN: {
  96. // 处理X轴原点传感器事件
  97. MotorManager::ins()->motors[0].runZeroLimit(is_triggerd);
  98. if (is_triggerd) {
  99. ZLOGI(TAG, "X_ORIGIN_PIN ENTER");
  100. } else {
  101. ZLOGI(TAG, "X_ORIGIN_PIN LEAVE");
  102. }
  103. break;
  104. }
  105. case X_LIMIT_PIN: {
  106. // 处理X轴限位传感器事件
  107. MotorManager::ins()->motors[0].runEndLimit(is_triggerd);
  108. if (isPinStateTriggered(X_LIMIT_PIN, is_triggerd)) {
  109. ZLOGI(TAG, "X_LIMIT_PIN ENTER");
  110. } else {
  111. ZLOGI(TAG, "X_LIMIT_PIN LEAVE");
  112. }
  113. break;
  114. }
  115. case Y_ORIGIN_PIN: {
  116. // 处理Y轴原点传感器事件
  117. MotorManager::ins()->motors[1].runZeroLimit(is_triggerd);
  118. if (is_triggerd) {
  119. ZLOGI(TAG, "Y_ORIGIN_PIN ENTER");
  120. } else {
  121. ZLOGI(TAG, "Y_ORIGIN_PIN LEAVE");
  122. }
  123. break;
  124. }
  125. case Y_LIMIT_PIN: {
  126. // 处理Y轴限位传感器事件
  127. MotorManager::ins()->motors[1].runEndLimit(is_triggerd);
  128. if (is_triggerd) {
  129. ZLOGI(TAG, "Y_LIMIT_PIN ENTER");
  130. } else {
  131. ZLOGI(TAG, "Y_LIMIT_PIN LEAVE");
  132. }
  133. break;
  134. }
  135. case Z_ORIGIN_PIN: {
  136. // 处理Z轴原点传感器事件
  137. MotorManager::ins()->motors[2].runZeroLimit(is_triggerd);
  138. if (is_triggerd) {
  139. ZLOGI(TAG, "Z_ORIGIN_PIN ENTER");
  140. } else {
  141. ZLOGI(TAG, "Z_ORIGIN_PIN LEAVE");
  142. }
  143. break;
  144. }
  145. case Z_LIMIT_PIN: {
  146. // 处理Z轴限位传感器事件
  147. MotorManager::ins()->motors[2].runEndLimit(is_triggerd);
  148. if (is_triggerd) {
  149. ZLOGI(TAG, "Z_LIMIT_PIN ENTER");
  150. } else {
  151. ZLOGI(TAG, "Z_LIMIT_PIN LEAVE");
  152. }
  153. break;
  154. }
  155. default:
  156. break;
  157. }
  158. }
  159. // 初始化 GPIO 引脚
  160. void EX_GPIO_Init(void) {
  161. GPIO_InitTypeDef GPIO_InitStruct = {0};
  162. // 使能 GPIO 时钟
  163. __HAL_RCC_GPIOB_CLK_ENABLE();
  164. // 配置 X 轴传感器引脚
  165. GPIO_InitStruct.Pin = X_ORIGIN_PIN | X_LIMIT_PIN;
  166. GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;
  167. GPIO_InitStruct.Pull = GPIO_NOPULL;
  168. HAL_GPIO_Init(X_PORT, &GPIO_InitStruct);
  169. // 配置 Y 轴传感器引脚
  170. GPIO_InitStruct.Pin = Y_ORIGIN_PIN | Y_LIMIT_PIN;
  171. GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;
  172. GPIO_InitStruct.Pull = GPIO_NOPULL;
  173. HAL_GPIO_Init(Y_PORT, &GPIO_InitStruct);
  174. // 配置 Z 轴传感器引脚
  175. GPIO_InitStruct.Pin = Z_ORIGIN_PIN | Z_LIMIT_PIN;
  176. GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;
  177. GPIO_InitStruct.Pull = GPIO_NOPULL;
  178. HAL_GPIO_Init(Z_PORT, &GPIO_InitStruct);
  179. // 配置中断优先级
  180. HAL_NVIC_SetPriority(EXTI9_5_IRQn, 5, 0);
  181. HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);
  182. HAL_NVIC_SetPriority(EXTI15_10_IRQn, 5, 0);
  183. HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);
  184. }
  185. extern "C" void EXTI9_5_IRQHandler(void) {
  186. HAL_GPIO_EXTI_IRQHandler(X_ORIGIN_PIN);
  187. HAL_GPIO_EXTI_IRQHandler(X_LIMIT_PIN);
  188. HAL_GPIO_EXTI_IRQHandler(Y_ORIGIN_PIN);
  189. }
  190. extern "C" void EXTI15_10_IRQHandler(void) {
  191. HAL_GPIO_EXTI_IRQHandler(Y_LIMIT_PIN);
  192. HAL_GPIO_EXTI_IRQHandler(Z_ORIGIN_PIN);
  193. HAL_GPIO_EXTI_IRQHandler(Z_LIMIT_PIN);
  194. }
  195. extern "C" uint16_t getORIGINPin(uint32_t motor_index) {
  196. switch (motor_index) {
  197. case 0:
  198. return X_ORIGIN_PIN;
  199. case 1:
  200. return Y_ORIGIN_PIN;
  201. case 2:
  202. return Z_ORIGIN_PIN;
  203. default:
  204. return 0xFFFF;
  205. }
  206. }
  207. uint16_t getAxisLimitPin(uint32_t motor_index) {
  208. switch (motor_index) {
  209. case 0:
  210. return X_LIMIT_PIN;
  211. case 1:
  212. return Y_LIMIT_PIN;
  213. case 2:
  214. return Z_LIMIT_PIN;
  215. default:
  216. return 0xFFFF;
  217. }
  218. }