core_gpio.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. /*
  2. * Copyright (c) 2022 OpenLuat & AirM2M
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a copy of
  5. * this software and associated documentation files (the "Software"), to deal in
  6. * the Software without restriction, including without limitation the rights to
  7. * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  8. * the Software, and to permit persons to whom the Software is furnished to do so,
  9. * subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in all
  12. * copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  16. * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  17. * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  18. * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  19. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  20. */
  21. #include "user.h"
  22. typedef struct
  23. {
  24. volatile GPIO_TypeDef *RegBase;
  25. const int32_t IrqLine;
  26. uint16_t ODBitMap;
  27. }GPIO_ResourceStruct;
  28. typedef struct
  29. {
  30. CBFuncEx_t AllCB;
  31. CBFuncEx_t HWTimerCB;
  32. void *pParam;
  33. }GPIO_CtrlStruct;
  34. static GPIO_CtrlStruct prvGPIO;
  35. static GPIO_ResourceStruct prvGPIO_Resource[6] =
  36. {
  37. {
  38. GPIOA,
  39. EXTI0_IRQn,
  40. 0,
  41. },
  42. {
  43. GPIOB,
  44. EXTI1_IRQn,
  45. 0,
  46. },
  47. {
  48. GPIOC,
  49. EXTI2_IRQn,
  50. 0,
  51. },
  52. {
  53. GPIOD,
  54. EXTI3_IRQn,
  55. 0,
  56. },
  57. {
  58. GPIOE,
  59. EXTI4_IRQn,
  60. 0,
  61. },
  62. {
  63. GPIOF,
  64. EXTI5_IRQn,
  65. 0,
  66. },
  67. };
  68. static int32_t GPIO_IrqDummyCB(void *pData, void *pParam)
  69. {
  70. // DBG("%d", pData);
  71. return 0;
  72. }
  73. static void __FUNC_IN_RAM__ GPIO_IrqHandle(int32_t IrqLine, void *pData)
  74. {
  75. volatile uint32_t Port = (uint32_t)pData;
  76. volatile uint32_t Sn, i;
  77. if (GPIO->INTP_TYPE_STA[Port].INTP_STA)
  78. {
  79. Sn = GPIO->INTP_TYPE_STA[Port].INTP_STA;
  80. GPIO->INTP_TYPE_STA[Port].INTP_STA = 0xffff;
  81. prvGPIO.HWTimerCB((Port << 16) | Sn, prvGPIO.pParam);
  82. Port = (Port << 4);
  83. for(i = 0; i < 16; i++)
  84. {
  85. if (Sn & (1 << i))
  86. {
  87. prvGPIO.AllCB((void *)(Port+i), 0);
  88. }
  89. }
  90. }
  91. ISR_Clear(IrqLine);
  92. }
  93. void GPIO_GlobalInit(CBFuncEx_t Fun)
  94. {
  95. uint32_t i;
  96. if (Fun)
  97. {
  98. prvGPIO.AllCB = Fun;
  99. }
  100. else
  101. {
  102. prvGPIO.AllCB = GPIO_IrqDummyCB;
  103. }
  104. prvGPIO.HWTimerCB = GPIO_IrqDummyCB;
  105. for(i = 0; i < 6; i++)
  106. {
  107. GPIO->INTP_TYPE_STA[i].INTP_TYPE = 0;
  108. GPIO->INTP_TYPE_STA[i].INTP_STA = 0xffff;
  109. #ifdef __BUILD_OS__
  110. ISR_SetPriority(prvGPIO_Resource[i].IrqLine, IRQ_MAX_PRIORITY + 1);
  111. #else
  112. ISR_SetPriority(prvGPIO_Resource[i].IrqLine, 3);
  113. #endif
  114. ISR_SetHandler(prvGPIO_Resource[i].IrqLine, GPIO_IrqHandle, (void *)i);
  115. ISR_OnOff(prvGPIO_Resource[i].IrqLine, 1);
  116. }
  117. }
  118. void __FUNC_IN_RAM__ GPIO_Config(uint32_t Pin, uint8_t IsInput, uint8_t InitValue)
  119. {
  120. uint8_t Port = (Pin >> 4);
  121. uint8_t orgPin = Pin;
  122. Pin = 1 << (Pin & 0x0000000f);
  123. GPIO_Iomux(orgPin, 1);
  124. if (IsInput)
  125. {
  126. prvGPIO_Resource[Port].RegBase->OEN |= Pin;
  127. }
  128. else
  129. {
  130. prvGPIO_Resource[Port].RegBase->BSRR |= InitValue?Pin:(Pin << 16);
  131. prvGPIO_Resource[Port].RegBase->OEN &= ~Pin;
  132. }
  133. prvGPIO_Resource[Port].ODBitMap &= ~Pin;
  134. }
  135. void __FUNC_IN_RAM__ GPIO_ODConfig(uint32_t Pin, uint8_t InitValue)
  136. {
  137. uint8_t Port = (Pin >> 4);
  138. uint8_t orgPin = Pin;
  139. Pin = 1 << (Pin & 0x0000000f);
  140. GPIO_Iomux(orgPin, 1);
  141. prvGPIO_Resource[Port].RegBase->OEN |= Pin;
  142. if (InitValue)
  143. {
  144. prvGPIO_Resource[Port].RegBase->PUE |= Pin;
  145. }
  146. else
  147. {
  148. prvGPIO_Resource[Port].RegBase->PUE &= ~Pin;
  149. }
  150. prvGPIO_Resource[Port].ODBitMap |= Pin;
  151. }
  152. void __FUNC_IN_RAM__ GPIO_PullConfig(uint32_t Pin, uint8_t IsPull, uint8_t IsUp)
  153. {
  154. uint8_t Port = (Pin >> 4);
  155. Pin = 1 << (Pin & 0x0000000f);
  156. if (IsPull && IsUp)
  157. {
  158. prvGPIO_Resource[Port].RegBase->PUE |= Pin;
  159. }
  160. else
  161. {
  162. prvGPIO_Resource[Port].RegBase->PUE &= ~Pin;
  163. }
  164. }
  165. void GPIO_ExtiConfig(uint32_t Pin, uint8_t IsLevel, uint8_t IsRiseHigh, uint8_t IsFallLow)
  166. {
  167. uint8_t Port = (Pin >> 4);
  168. uint32_t Type = 0;
  169. uint32_t Mask = ~(0x03 << ((Pin & 0x0000000f) * 2));
  170. if (!IsLevel)
  171. {
  172. if (IsRiseHigh && IsFallLow)
  173. {
  174. Type = 0x03 << ((Pin & 0x0000000f) * 2);
  175. }
  176. else if (IsFallLow)
  177. {
  178. Type = 0x02 << ((Pin & 0x0000000f) * 2);
  179. }
  180. else if (IsRiseHigh)
  181. {
  182. Type = 0x01 << ((Pin & 0x0000000f) * 2);
  183. }
  184. }
  185. GPIO->INTP_TYPE_STA[Port].INTP_TYPE = (GPIO->INTP_TYPE_STA[Port].INTP_TYPE & Mask) | Type;
  186. }
  187. void GPIO_ExtiSetHWTimerCB(CBFuncEx_t CB, void *pParam)
  188. {
  189. if (CB)
  190. {
  191. prvGPIO.HWTimerCB = CB;
  192. }
  193. else
  194. {
  195. prvGPIO.HWTimerCB = GPIO_IrqDummyCB;
  196. }
  197. prvGPIO.pParam = pParam;
  198. }
  199. void __FUNC_IN_RAM__ GPIO_Iomux(uint32_t Pin, uint32_t Function)
  200. {
  201. uint8_t Port = (Pin >> 4);
  202. uint32_t Mask = ~(0x03 << ((Pin & 0x0000000f) * 2));
  203. Function = Function << ((Pin & 0x0000000f) * 2);
  204. GPIO->ALT[Port] = (GPIO->ALT[Port] & Mask) | Function;
  205. }
  206. void __FUNC_IN_RAM__ GPIO_Output(uint32_t Pin, uint8_t Level)
  207. {
  208. uint8_t Port = (Pin >> 4);
  209. Pin = 1 << (Pin & 0x0000000f);
  210. if (prvGPIO_Resource[Port].ODBitMap & Pin)
  211. {
  212. if (Level)
  213. {
  214. prvGPIO_Resource[Port].RegBase->PUE |= Pin;
  215. }
  216. else
  217. {
  218. prvGPIO_Resource[Port].RegBase->PUE &= ~Pin;
  219. }
  220. }
  221. else
  222. {
  223. prvGPIO_Resource[Port].RegBase->BSRR |= Level?Pin:(Pin << 16);
  224. }
  225. // DBG("%d, %x, %x, %x",Port, Pin, prvGPIO_Resource[Port].RegBase, prvGPIO_Resource[Port].RegBase->IODR);
  226. }
  227. uint8_t __FUNC_IN_RAM__ GPIO_Input(uint32_t Pin)
  228. {
  229. uint8_t Port = (Pin >> 4);
  230. Pin = 1 << (Pin & 0x0000000f);
  231. return (prvGPIO_Resource[Port].RegBase->IODR & (Pin << 16))?1:0;
  232. }
  233. void __FUNC_IN_RAM__ GPIO_OutputMulti(uint32_t Port, uint32_t Pins, uint32_t Level)
  234. {
  235. prvGPIO_Resource[Port].RegBase->BSRR |= Level?Pins:(Pins << 16);
  236. }
  237. uint32_t __FUNC_IN_RAM__ GPIO_InputMulti(uint32_t Port)
  238. {
  239. return (prvGPIO_Resource[Port].RegBase->IODR >> 16);
  240. }