core_gpio.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  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. }GPIO_ResourceStruct;
  27. typedef struct
  28. {
  29. CBFuncEx_t AllCB;
  30. CBFuncEx_t HWTimerCB;
  31. void *pParam;
  32. }GPIO_CtrlStruct;
  33. static GPIO_CtrlStruct prvGPIO;
  34. static const GPIO_ResourceStruct prvGPIO_Resource[6] =
  35. {
  36. {
  37. GPIOA,
  38. EXTI0_IRQn,
  39. },
  40. {
  41. GPIOB,
  42. EXTI1_IRQn,
  43. },
  44. {
  45. GPIOC,
  46. EXTI2_IRQn,
  47. },
  48. {
  49. GPIOD,
  50. EXTI3_IRQn,
  51. },
  52. {
  53. GPIOE,
  54. EXTI4_IRQn,
  55. },
  56. {
  57. GPIOF,
  58. EXTI5_IRQn,
  59. },
  60. };
  61. static int32_t GPIO_IrqDummyCB(void *pData, void *pParam)
  62. {
  63. // DBG("%d", pData);
  64. return 0;
  65. }
  66. static void __FUNC_IN_RAM__ GPIO_IrqHandle(int32_t IrqLine, void *pData)
  67. {
  68. volatile uint32_t Port = (uint32_t)pData;
  69. volatile uint32_t Sn, i;
  70. if (GPIO->INTP_TYPE_STA[Port].INTP_STA)
  71. {
  72. Sn = GPIO->INTP_TYPE_STA[Port].INTP_STA;
  73. GPIO->INTP_TYPE_STA[Port].INTP_STA = 0xffff;
  74. prvGPIO.HWTimerCB((Port << 16) | Sn, prvGPIO.pParam);
  75. Port = (Port << 4);
  76. for(i = 0; i < 16; i++)
  77. {
  78. if (Sn & (1 << i))
  79. {
  80. prvGPIO.AllCB((void *)(Port+i), 0);
  81. }
  82. }
  83. }
  84. ISR_Clear(IrqLine);
  85. }
  86. void GPIO_GlobalInit(CBFuncEx_t Fun)
  87. {
  88. uint32_t i;
  89. if (Fun)
  90. {
  91. prvGPIO.AllCB = Fun;
  92. }
  93. else
  94. {
  95. prvGPIO.AllCB = GPIO_IrqDummyCB;
  96. }
  97. prvGPIO.HWTimerCB = GPIO_IrqDummyCB;
  98. for(i = 0; i < 6; i++)
  99. {
  100. GPIO->INTP_TYPE_STA[i].INTP_TYPE = 0;
  101. GPIO->INTP_TYPE_STA[i].INTP_STA = 0xffff;
  102. #ifdef __BUILD_OS__
  103. ISR_SetPriority(prvGPIO_Resource[i].IrqLine, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY + 1);
  104. #else
  105. ISR_SetPriority(prvGPIO_Resource[i].IrqLine, 3);
  106. #endif
  107. ISR_SetHandler(prvGPIO_Resource[i].IrqLine, GPIO_IrqHandle, (void *)i);
  108. ISR_OnOff(prvGPIO_Resource[i].IrqLine, 1);
  109. }
  110. }
  111. void __FUNC_IN_RAM__ GPIO_Config(uint32_t Pin, uint8_t IsInput, uint8_t InitValue)
  112. {
  113. uint8_t Port = (Pin >> 4);
  114. uint8_t orgPin = Pin;
  115. Pin = 1 << (Pin & 0x0000000f);
  116. GPIO_Iomux(orgPin, 1);
  117. if (IsInput)
  118. {
  119. prvGPIO_Resource[Port].RegBase->OEN |= Pin;
  120. }
  121. else
  122. {
  123. prvGPIO_Resource[Port].RegBase->BSRR |= InitValue?Pin:(Pin << 16);
  124. prvGPIO_Resource[Port].RegBase->OEN &= ~Pin;
  125. }
  126. }
  127. void __FUNC_IN_RAM__ GPIO_PullConfig(uint32_t Pin, uint8_t IsPull, uint8_t IsUp)
  128. {
  129. uint8_t Port = (Pin >> 4);
  130. Pin = 1 << (Pin & 0x0000000f);
  131. if (IsPull && IsUp)
  132. {
  133. prvGPIO_Resource[Port].RegBase->PUE |= Pin;
  134. }
  135. else
  136. {
  137. prvGPIO_Resource[Port].RegBase->PUE &= ~Pin;
  138. }
  139. }
  140. void GPIO_ExtiConfig(uint32_t Pin, uint8_t IsLevel, uint8_t IsRiseHigh, uint8_t IsFallLow)
  141. {
  142. uint8_t Port = (Pin >> 4);
  143. uint32_t Type = 0;
  144. uint32_t Mask = ~(0x03 << ((Pin & 0x0000000f) * 2));
  145. if (!IsLevel)
  146. {
  147. if (IsRiseHigh && IsFallLow)
  148. {
  149. Type = 0x03 << ((Pin & 0x0000000f) * 2);
  150. }
  151. else if (IsFallLow)
  152. {
  153. Type = 0x02 << ((Pin & 0x0000000f) * 2);
  154. }
  155. else if (IsRiseHigh)
  156. {
  157. Type = 0x01 << ((Pin & 0x0000000f) * 2);
  158. }
  159. }
  160. GPIO->INTP_TYPE_STA[Port].INTP_TYPE = (GPIO->INTP_TYPE_STA[Port].INTP_TYPE & Mask) | Type;
  161. }
  162. void GPIO_ExtiSetHWTimerCB(CBFuncEx_t CB, void *pParam)
  163. {
  164. if (CB)
  165. {
  166. prvGPIO.HWTimerCB = CB;
  167. }
  168. else
  169. {
  170. prvGPIO.HWTimerCB = GPIO_IrqDummyCB;
  171. }
  172. prvGPIO.pParam = pParam;
  173. }
  174. void __FUNC_IN_RAM__ GPIO_Iomux(uint32_t Pin, uint32_t Function)
  175. {
  176. uint8_t Port = (Pin >> 4);
  177. uint32_t Mask = ~(0x03 << ((Pin & 0x0000000f) * 2));
  178. Function = Function << ((Pin & 0x0000000f) * 2);
  179. GPIO->ALT[Port] = (GPIO->ALT[Port] & Mask) | Function;
  180. }
  181. void __FUNC_IN_RAM__ GPIO_Output(uint32_t Pin, uint8_t Level)
  182. {
  183. uint8_t Port = (Pin >> 4);
  184. Pin = 1 << (Pin & 0x0000000f);
  185. prvGPIO_Resource[Port].RegBase->BSRR |= Level?Pin:(Pin << 16);
  186. // DBG("%d, %x, %x, %x",Port, Pin, prvGPIO_Resource[Port].RegBase, prvGPIO_Resource[Port].RegBase->IODR);
  187. }
  188. uint8_t __FUNC_IN_RAM__ GPIO_Input(uint32_t Pin)
  189. {
  190. uint8_t Port = (Pin >> 4);
  191. Pin = 1 << (Pin & 0x0000000f);
  192. return (prvGPIO_Resource[Port].RegBase->IODR & (Pin << 16))?1:0;
  193. }
  194. void __FUNC_IN_RAM__ GPIO_OutputMulti(uint32_t Port, uint32_t Pins, uint32_t Level)
  195. {
  196. prvGPIO_Resource[Port].RegBase->BSRR |= Level?Pins:(Pins << 16);
  197. }
  198. uint32_t __FUNC_IN_RAM__ GPIO_InputMulti(uint32_t Port)
  199. {
  200. return (prvGPIO_Resource[Port].RegBase->IODR >> 16);
  201. }