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.

409 lines
12 KiB

1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
  1. #include "zgpio.hpp"
  2. #define TAG "GPIO"
  3. namespace iflytop {
  4. /*******************************************************************************
  5. * LISTENER *
  6. *******************************************************************************/
  7. static ZGPIO *s_irqGPIO[20];
  8. int s_irqGPIO_num = 0;
  9. extern "C" {
  10. /**
  11. * @brief This function handles EXTI line3 interrupt.
  12. */
  13. void EXTI0_IRQHandler() { HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0); }
  14. void EXTI1_IRQHandler() { HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_1); }
  15. void EXTI2_IRQHandler() { HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_2); }
  16. void EXTI3_IRQHandler() { HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_3); }
  17. void EXTI4_IRQHandler() { HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_4); }
  18. void EXTI9_5_IRQHandler(void) {
  19. HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_5);
  20. HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_6);
  21. HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_7);
  22. HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_8);
  23. HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_9);
  24. }
  25. void EXTI15_10_IRQHandler(void) {
  26. HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_10);
  27. HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_11);
  28. HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_12);
  29. HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_13);
  30. HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_14);
  31. HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_15);
  32. }
  33. void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
  34. for (int i = 0; i < s_irqGPIO_num; i++) {
  35. s_irqGPIO[i]->tryTriggerIRQ(GPIO_Pin);
  36. }
  37. }
  38. }
  39. void ZGPIO::regListener(onirq_t listener) { m_onirq = listener; }
  40. /*******************************************************************************
  41. * GPIOIMPL *
  42. *******************************************************************************/
  43. /*******************************************************************************
  44. * BASE_FUNC *
  45. *******************************************************************************/
  46. bool ZGPIO::enableClock(GPIO_TypeDef *port) {
  47. #ifdef GPIOA
  48. if (port == GPIOA) {
  49. __HAL_RCC_GPIOA_CLK_ENABLE();
  50. return true;
  51. }
  52. #endif
  53. #ifdef GPIOB
  54. if (port == GPIOB) {
  55. __HAL_RCC_GPIOB_CLK_ENABLE();
  56. return true;
  57. }
  58. #endif
  59. #ifdef GPIOC
  60. if (port == GPIOC) {
  61. __HAL_RCC_GPIOC_CLK_ENABLE();
  62. return true;
  63. }
  64. #endif
  65. #ifdef GPIOD
  66. if (port == GPIOD) {
  67. __HAL_RCC_GPIOD_CLK_ENABLE();
  68. return true;
  69. }
  70. #endif
  71. #ifdef GPIOE
  72. if (port == GPIOE) {
  73. __HAL_RCC_GPIOE_CLK_ENABLE();
  74. return true;
  75. }
  76. #endif
  77. #ifdef GPIOF
  78. if (port == GPIOF) {
  79. __HAL_RCC_GPIOF_CLK_ENABLE();
  80. return true;
  81. }
  82. #endif
  83. #ifdef GPIOG
  84. if (port == GPIOG) {
  85. __HAL_RCC_GPIOG_CLK_ENABLE();
  86. return true;
  87. }
  88. #endif
  89. #ifdef GPIOH
  90. if (port == GPIOH) {
  91. __HAL_RCC_GPIOH_CLK_ENABLE();
  92. return true;
  93. }
  94. #endif
  95. #ifdef GPIOI
  96. if (port == GPIOI) {
  97. __HAL_RCC_GPIOI_CLK_ENABLE();
  98. return true;
  99. }
  100. #endif
  101. #ifdef GPIOJ
  102. if (port == GPIOJ) {
  103. __HAL_RCC_GPIOJ_CLK_ENABLE();
  104. return true;
  105. }
  106. #endif
  107. #ifdef GPIOK
  108. if (port == GPIOK) {
  109. __HAL_RCC_GPIOK_CLK_ENABLE();
  110. return true;
  111. }
  112. #endif
  113. return false;
  114. }
  115. bool ZGPIO::enableClock() { return enableClock(m_gpio); }
  116. void regIRQGPIO(ZGPIO *gpio) {
  117. for (int i = 0; i < s_irqGPIO_num; i++) {
  118. if (s_irqGPIO[i] == gpio) {
  119. return;
  120. }
  121. }
  122. EARLY_ASSERT((s_irqGPIO_num + 1) < (int)ZARRAY_SIZE(s_irqGPIO));
  123. s_irqGPIO[s_irqGPIO_num] = gpio;
  124. s_irqGPIO_num++;
  125. }
  126. bool ZGPIO::isMirror() { return m_mirror; }
  127. void ZGPIO::initAsInput(Pin_t pin, GPIOMode_t mode, GPIOIrqType_t irqtype, bool mirror) {
  128. if (pin == PinNull) return;
  129. m_mirror = mirror;
  130. m_mode = mode;
  131. m_irqtype = irqtype;
  132. m_gpiotype = kType_Input;
  133. m_pin = pin;
  134. m_gpio = chip_get_gpio(pin);
  135. m_pinoff = chip_get_pinoff(pin);
  136. uint32_t pulluptype = 0;
  137. if (mode == kMode_nopull) {
  138. pulluptype = GPIO_NOPULL;
  139. } else if (mode == kMode_pullup) {
  140. pulluptype = GPIO_PULLUP;
  141. } else if (mode == kMode_pulldown) {
  142. pulluptype = GPIO_PULLDOWN;
  143. }
  144. enableClock();
  145. GPIO_InitTypeDef m_GPIO_InitStruct = {0};
  146. if (m_irqtype == kIRQ_noIrq) {
  147. m_GPIO_InitStruct.Pin = m_pinoff;
  148. m_GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  149. m_GPIO_InitStruct.Pull = pulluptype;
  150. m_GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  151. } else if (m_irqtype == kIRQ_risingIrq) {
  152. m_GPIO_InitStruct.Pin = m_pinoff;
  153. m_GPIO_InitStruct.Mode = m_mirror ? GPIO_MODE_IT_FALLING : GPIO_MODE_IT_RISING;
  154. m_GPIO_InitStruct.Pull = pulluptype;
  155. m_GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  156. } else if (m_irqtype == kIRQ_fallingIrq) {
  157. m_GPIO_InitStruct.Pin = m_pinoff;
  158. m_GPIO_InitStruct.Mode = !m_mirror ? GPIO_MODE_IT_FALLING : GPIO_MODE_IT_RISING;
  159. m_GPIO_InitStruct.Pull = pulluptype;
  160. m_GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  161. } else if (m_irqtype == kIRQ_risingAndFallingIrq) {
  162. m_GPIO_InitStruct.Pin = m_pinoff;
  163. m_GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;
  164. m_GPIO_InitStruct.Pull = pulluptype;
  165. m_GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  166. }
  167. HAL_GPIO_Init(m_gpio, &m_GPIO_InitStruct);
  168. if (m_irqtype != kIRQ_noIrq) {
  169. regIRQGPIO(this);
  170. lastLevel = getState();
  171. HAL_NVIC_SetPriority(getEXTIIRQn(), PC_IRQ_PREEMPTPRIORITY_DEFAULT, 0);
  172. HAL_NVIC_EnableIRQ(getEXTIIRQn());
  173. }
  174. m_initflag = true;
  175. return;
  176. }
  177. void ZGPIO::initAsOutputStatic(Pin_t pin, GPIOMode_t mode, bool mirror, bool initLevel) {
  178. if (pin == PinNull) return;
  179. GPIO_TypeDef *m_gpio = chip_get_gpio(pin);
  180. uint16_t m_pinoff = chip_get_pinoff(pin);
  181. enableClock(m_gpio);
  182. GPIO_InitTypeDef m_GPIO_InitStruct = {0};
  183. initLevel = mirror ? !initLevel : initLevel;
  184. GPIO_PinState pinState = initLevel ? GPIO_PIN_SET : GPIO_PIN_RESET;
  185. HAL_GPIO_WritePin(m_gpio, m_pinoff, pinState);
  186. if (mode == kMode_nopull) {
  187. m_GPIO_InitStruct.Pin = m_pinoff;
  188. m_GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  189. m_GPIO_InitStruct.Pull = GPIO_NOPULL;
  190. m_GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  191. } else if (mode == kMode_pullup) {
  192. m_GPIO_InitStruct.Pin = m_pinoff;
  193. m_GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  194. m_GPIO_InitStruct.Pull = GPIO_PULLUP;
  195. m_GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  196. } else if (mode == kMode_pulldown) {
  197. m_GPIO_InitStruct.Pin = m_pinoff;
  198. m_GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  199. m_GPIO_InitStruct.Pull = GPIO_PULLDOWN;
  200. m_GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  201. } else if (mode == kMode_od) {
  202. m_GPIO_InitStruct.Pin = m_pinoff;
  203. m_GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
  204. m_GPIO_InitStruct.Pull = 0;
  205. m_GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  206. }
  207. HAL_GPIO_Init(m_gpio, &m_GPIO_InitStruct);
  208. return;
  209. }
  210. void ZGPIO::initAsOutput(Pin_t pin, GPIOMode_t mode, bool mirror, bool initLevel) {
  211. if (pin == PinNull) return;
  212. m_mirror = mirror;
  213. m_mode = mode;
  214. m_irqtype = kIRQ_noIrq;
  215. m_gpiotype = kType_Output;
  216. m_pin = pin;
  217. m_gpio = chip_get_gpio(pin);
  218. m_pinoff = chip_get_pinoff(pin);
  219. enableClock();
  220. GPIO_InitTypeDef m_GPIO_InitStruct = {0};
  221. initLevel = m_mirror ? !initLevel : initLevel;
  222. GPIO_PinState pinState = initLevel ? GPIO_PIN_SET : GPIO_PIN_RESET;
  223. HAL_GPIO_WritePin(m_gpio, m_pinoff, pinState);
  224. if (m_mode == kMode_nopull) {
  225. m_GPIO_InitStruct.Pin = m_pinoff;
  226. m_GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  227. m_GPIO_InitStruct.Pull = GPIO_NOPULL;
  228. m_GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  229. } else if (m_mode == kMode_pullup) {
  230. m_GPIO_InitStruct.Pin = m_pinoff;
  231. m_GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  232. m_GPIO_InitStruct.Pull = GPIO_PULLUP;
  233. m_GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  234. } else if (m_mode == kMode_pulldown) {
  235. m_GPIO_InitStruct.Pin = m_pinoff;
  236. m_GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  237. m_GPIO_InitStruct.Pull = GPIO_PULLDOWN;
  238. m_GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  239. } else if (m_mode == kMode_od) {
  240. m_GPIO_InitStruct.Pin = m_pinoff;
  241. m_GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
  242. m_GPIO_InitStruct.Pull = 0;
  243. m_GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  244. }
  245. HAL_GPIO_Init(m_gpio, &m_GPIO_InitStruct);
  246. m_initflag = true;
  247. return;
  248. }
  249. bool ZGPIO::isItRisingEXITGPIO() { return m_irqtype == kIRQ_risingIrq; }
  250. bool ZGPIO::isItFallingEXITGPIO() { return m_irqtype == kIRQ_fallingIrq; }
  251. bool ZGPIO::isItRisingAndItFallingEXITGPIO() { return m_irqtype == kIRQ_risingAndFallingIrq; }
  252. /*******************************************************************************
  253. * EXT FUNC *
  254. *******************************************************************************/
  255. /**
  256. * @brief
  257. *
  258. * @param checkloop
  259. * @param GPIO_Pin
  260. * @return true
  261. * @return false
  262. *
  263. * STM32的GPIO中断线是共用的GPIO的即时状态判断是否是这个引脚产生的中??
  264. *
  265. * ??:
  266. * GPIO_MODE_IT_RISING ?? GPIO_MODE_IT_FALLING
  267. * GPIO_MODE_IT_RISING_FALLING true
  268. */
  269. bool ZGPIO::tryTriggerIRQ(uint16_t GPIO_Pin) {
  270. bool ret = false;
  271. bool nostate = false;
  272. if (GPIO_Pin != m_pinoff) return false;
  273. if (!(isItRisingEXITGPIO() || isItFallingEXITGPIO() || isItRisingAndItFallingEXITGPIO())) {
  274. return false;
  275. }
  276. nostate = getState();
  277. if (isItRisingEXITGPIO()) {
  278. if (nostate) {
  279. ret = true;
  280. if (m_onirq) {
  281. m_onirq(this, kRisingIrqEvent);
  282. }
  283. }
  284. } else if (isItFallingEXITGPIO()) {
  285. if (!nostate) {
  286. ret = true;
  287. if (m_onirq) {
  288. m_onirq(this, kFallingIrqEvent);
  289. }
  290. }
  291. } else {
  292. if (lastLevel != nostate) {
  293. ret = true;
  294. if (m_onirq) {
  295. if (lastLevel)
  296. m_onirq(this, kRisingIrqEvent);
  297. else
  298. m_onirq(this, kFallingIrqEvent);
  299. }
  300. }
  301. }
  302. lastLevel = nostate;
  303. return ret;
  304. }
  305. void ZGPIO::toggleState() { HAL_GPIO_TogglePin(m_gpio, m_pinoff); }
  306. uint32_t ZGPIO::getStateUint32() {
  307. if (getState())
  308. return 1;
  309. else
  310. return 0;
  311. }
  312. bool ZGPIO::getState() {
  313. if (m_pin == PinNull) return false;
  314. bool ret = false;
  315. if (HAL_GPIO_ReadPin(m_gpio, m_pinoff) == GPIO_PIN_SET) {
  316. ret = true;
  317. } else {
  318. ret = false;
  319. }
  320. if (m_mirror) ret = !ret;
  321. return ret;
  322. }
  323. bool ZGPIO::setState(bool state) {
  324. if (m_pin == PinNull) return true;
  325. if (m_mirror) state = !state;
  326. if (m_log_when_setstate) ZEARLY_LOGI(TAG, "%s%s set %d", chip_gpio_group_get_name(m_gpio), chip_pinoff_get_name(m_pinoff), state);
  327. if (state) {
  328. HAL_GPIO_WritePin(m_gpio, m_pinoff, GPIO_PIN_SET);
  329. } else {
  330. HAL_GPIO_WritePin(m_gpio, m_pinoff, GPIO_PIN_RESET);
  331. }
  332. return true;
  333. }
  334. IRQn_Type ZGPIO::getEXTIIRQn() {
  335. switch (m_pinoff) {
  336. case GPIO_PIN_0:
  337. return EXTI0_IRQn;
  338. case GPIO_PIN_1:
  339. return EXTI1_IRQn;
  340. case GPIO_PIN_2:
  341. return EXTI2_IRQn;
  342. case GPIO_PIN_3:
  343. return EXTI3_IRQn;
  344. case GPIO_PIN_4:
  345. return EXTI4_IRQn;
  346. case GPIO_PIN_5:
  347. case GPIO_PIN_6:
  348. case GPIO_PIN_7:
  349. case GPIO_PIN_8:
  350. case GPIO_PIN_9:
  351. return EXTI9_5_IRQn;
  352. case GPIO_PIN_10:
  353. case GPIO_PIN_11:
  354. case GPIO_PIN_12:
  355. case GPIO_PIN_13:
  356. case GPIO_PIN_14:
  357. case GPIO_PIN_15:
  358. return EXTI15_10_IRQn;
  359. default:
  360. ZEARLY_ASSERT(0);
  361. }
  362. return EXTI0_IRQn;
  363. }
  364. /**
  365. * @brief GPIO为中断模??
  366. *
  367. * @param pull GPIO_NOPULL, GPIO_PULLUP, GPIO_PULLDOWN
  368. * @param mode GPIO_MODE_IT_RISING, GPIO_MODE_IT_FALLING, GPIO_MODE_IT_RISING_FALLING
  369. * @return true
  370. * @return false
  371. */
  372. } // namespace iflytop