core_soft_keyboard.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. #include "user.h"
  2. typedef struct
  3. {
  4. CBFuncEx_t CB;
  5. void *pParam;
  6. Timer_t *ScanTimer;
  7. uint32_t ScanPeriod; //扫描周期,US
  8. uint8_t ScanTimes; //一次判决所需周期
  9. uint8_t PressConfirmTimes; //判决按下所需周期
  10. uint8_t InIO[16];
  11. uint8_t OutIO[16];
  12. uint8_t InIONum;
  13. uint8_t OutIONum;
  14. uint8_t PressKeyIOLevel;
  15. uint8_t IrqMode;
  16. uint8_t IsScan;
  17. uint8_t IsEnable;
  18. uint8_t Init;
  19. uint8_t ScanCnt;
  20. uint8_t KeyPress[256];
  21. uint8_t KeyState[32];
  22. }SoftKB_CtrlStruct;
  23. static SoftKB_CtrlStruct prvSoftKB;
  24. static int32_t prvSoftKB_DummyCB(void *pData, void *pParam)
  25. {
  26. DBG("%x", pData);
  27. return 0;
  28. }
  29. static int32_t prvSoftKB_IOIrqCB(void *pData, void *pParam)
  30. {
  31. int i;
  32. for(i = 0; i < prvSoftKB.InIONum; i++)
  33. {
  34. GPIO_ExtiConfig(prvSoftKB.InIO[i], 0, 0, 0);
  35. }
  36. for(i = 0; i < prvSoftKB.OutIONum; i++)
  37. {
  38. GPIO_ODConfig(prvSoftKB.OutIO[i], !prvSoftKB.PressKeyIOLevel);
  39. }
  40. if (prvSoftKB.IsEnable)
  41. {
  42. Timer_StartUS(prvSoftKB.ScanTimer, prvSoftKB.ScanPeriod, 1);
  43. prvSoftKB.IsScan = 1;
  44. prvSoftKB.ScanCnt = 0;
  45. }
  46. return 0;
  47. }
  48. static int32_t prvSoftKB_TimerIrqCB(void *pData, void *pParam)
  49. {
  50. if (!prvSoftKB.IsScan || !prvSoftKB.IsEnable)
  51. {
  52. Timer_Stop(prvSoftKB.ScanTimer);
  53. return -1;
  54. }
  55. #ifdef __BUILD_OS__
  56. if (prvSoftKB.IrqMode)
  57. {
  58. #endif
  59. SoftKB_ScanOnce();
  60. #ifdef __BUILD_OS__
  61. }
  62. else
  63. {
  64. Core_ScanKeyBoard();
  65. }
  66. #endif
  67. return 0;
  68. }
  69. void SoftKB_Setup(uint32_t ScanPeriodUS, uint8_t ScanTimes, uint8_t PressConfirmTimes, uint8_t IsIrqMode, CBFuncEx_t CB, void *pParam)
  70. {
  71. prvSoftKB.ScanPeriod = ScanPeriodUS;
  72. prvSoftKB.ScanTimes = ScanTimes;
  73. prvSoftKB.PressConfirmTimes = PressConfirmTimes;
  74. if (CB)
  75. {
  76. prvSoftKB.CB = CB;
  77. }
  78. else
  79. {
  80. prvSoftKB.CB = prvSoftKB_DummyCB;
  81. }
  82. prvSoftKB.pParam = pParam;
  83. prvSoftKB.Init |= 0xf0;
  84. prvSoftKB.IrqMode = IsIrqMode;
  85. }
  86. void SoftKB_IOConfig(const uint8_t *InIO, uint8_t InIONum, const uint8_t *OutIO, uint8_t OutIONum, uint8_t PressKeyIOLevel)
  87. {
  88. if (InIONum > 16 || OutIONum > 16) return;
  89. if (InIO)
  90. {
  91. memset(prvSoftKB.InIO, 0xff, sizeof(prvSoftKB.InIO));
  92. memcpy(prvSoftKB.InIO, InIO, InIONum);
  93. prvSoftKB.InIONum = InIONum;
  94. prvSoftKB.Init |= 0x03;
  95. }
  96. if (OutIO)
  97. {
  98. memset(prvSoftKB.OutIO, 0xff, sizeof(prvSoftKB.OutIO));
  99. memcpy(prvSoftKB.OutIO, OutIO, OutIONum);
  100. prvSoftKB.OutIONum = OutIONum;
  101. prvSoftKB.Init |= 0x0c;
  102. }
  103. prvSoftKB.PressKeyIOLevel = PressKeyIOLevel;
  104. }
  105. void SoftKB_Start(void)
  106. {
  107. int i;
  108. if (!prvSoftKB.ScanTimer)
  109. {
  110. prvSoftKB.ScanTimer = Timer_Create(prvSoftKB_TimerIrqCB, NULL, NULL);
  111. }
  112. if (prvSoftKB.Init != 0xff)
  113. {
  114. return;
  115. }
  116. memset(prvSoftKB.KeyPress, 0, sizeof(prvSoftKB.KeyPress));
  117. memset(prvSoftKB.KeyState, 0, sizeof(prvSoftKB.KeyState));
  118. prvSoftKB.IsScan = 0;
  119. prvSoftKB.ScanCnt = 0;
  120. for(i = 0; i < prvSoftKB.OutIONum; i++)
  121. {
  122. GPIO_ODConfig(prvSoftKB.OutIO[i], prvSoftKB.PressKeyIOLevel);
  123. }
  124. for(i = 0; i < prvSoftKB.InIONum; i++)
  125. {
  126. GPIO_Config(prvSoftKB.InIO[i], 1, 0);
  127. GPIO_PullConfig(prvSoftKB.InIO[i], 1, !prvSoftKB.PressKeyIOLevel);
  128. if (GPIO_Input(prvSoftKB.InIO[i]) == prvSoftKB.PressKeyIOLevel)
  129. {
  130. prvSoftKB.IsScan = 1;
  131. }
  132. GPIO_ExtiSetCB(prvSoftKB.InIO[i], prvSoftKB_IOIrqCB, NULL);
  133. }
  134. if (prvSoftKB.IsScan)
  135. {
  136. Timer_StartUS(prvSoftKB.ScanTimer, prvSoftKB.ScanPeriod, 1);
  137. }
  138. else
  139. {
  140. for(i = 0; i < prvSoftKB.InIONum; i++)
  141. {
  142. GPIO_ExtiConfig(prvSoftKB.InIO[i], 0, prvSoftKB.PressKeyIOLevel, !prvSoftKB.PressKeyIOLevel);
  143. }
  144. }
  145. prvSoftKB.IsEnable = 1;
  146. }
  147. void SoftKB_Stop(void)
  148. {
  149. int i;
  150. if (!prvSoftKB.ScanTimer)
  151. {
  152. prvSoftKB.ScanTimer = Timer_Create(prvSoftKB_TimerIrqCB, NULL, NULL);
  153. }
  154. else
  155. {
  156. Timer_Stop(prvSoftKB.ScanTimer);
  157. }
  158. for(i = 0; i < prvSoftKB.InIONum; i++)
  159. {
  160. GPIO_ExtiConfig(prvSoftKB.InIO[i], 0, 0, 0);
  161. GPIO_ExtiSetCB(prvSoftKB.InIO[i], NULL, NULL);
  162. }
  163. for(i = 0; i < prvSoftKB.OutIONum; i++)
  164. {
  165. GPIO_Output(prvSoftKB.OutIO[i], prvSoftKB.PressKeyIOLevel);
  166. }
  167. prvSoftKB.IsEnable = 0;
  168. }
  169. void SoftKB_ScanOnce(void)
  170. {
  171. int i, j;
  172. uint32_t KeySn;
  173. if (!prvSoftKB.IsEnable || !prvSoftKB.IsScan)
  174. {
  175. return;
  176. }
  177. for(i = 0; i < prvSoftKB.OutIONum; i++)
  178. {
  179. GPIO_Output(prvSoftKB.OutIO[i], prvSoftKB.PressKeyIOLevel);
  180. for(j = 0; j < prvSoftKB.InIONum; j++)
  181. {
  182. //DBG("%d,%d,%d", i, j, GPIO_Input(prvSoftKB.InIO[j]));
  183. prvSoftKB.KeyPress[(i << 4) + j] += (GPIO_Input(prvSoftKB.InIO[j]) == prvSoftKB.PressKeyIOLevel);
  184. }
  185. GPIO_Output(prvSoftKB.OutIO[i], !prvSoftKB.PressKeyIOLevel);
  186. }
  187. prvSoftKB.ScanCnt++;
  188. if (prvSoftKB.ScanCnt >= prvSoftKB.ScanTimes)
  189. {
  190. prvSoftKB.ScanCnt = 0;
  191. for(i = 0; i < prvSoftKB.OutIONum; i++)
  192. {
  193. for(j = 0; j < prvSoftKB.InIONum; j++)
  194. {
  195. KeySn = (i << 4) + j;
  196. if (prvSoftKB.KeyPress[KeySn] >= prvSoftKB.PressConfirmTimes)
  197. {
  198. if (!BSP_TestBit(prvSoftKB.KeyState, KeySn))
  199. {
  200. BSP_SetBit(prvSoftKB.KeyState, KeySn, 1);
  201. prvSoftKB.CB(KeySn|(1 << 16), prvSoftKB.pParam);
  202. }
  203. }
  204. else
  205. {
  206. if (BSP_TestBit(prvSoftKB.KeyState, KeySn))
  207. {
  208. BSP_SetBit(prvSoftKB.KeyState, KeySn, 0);
  209. prvSoftKB.CB(KeySn, prvSoftKB.pParam);
  210. }
  211. }
  212. }
  213. }
  214. memset(prvSoftKB.KeyPress, 0, sizeof(prvSoftKB.KeyPress));
  215. for(i = 0; i < sizeof(prvSoftKB.KeyState); i++)
  216. {
  217. if (prvSoftKB.KeyState[i])
  218. {
  219. return;
  220. }
  221. }
  222. Timer_Stop(prvSoftKB.ScanTimer);
  223. prvSoftKB.IsScan = 0;
  224. for(i = 0; i < prvSoftKB.OutIONum; i++)
  225. {
  226. GPIO_Output(prvSoftKB.OutIO[i], prvSoftKB.PressKeyIOLevel);
  227. }
  228. for(i = 0; i < prvSoftKB.InIONum; i++)
  229. {
  230. GPIO_ExtiConfig(prvSoftKB.InIO[i], 0, prvSoftKB.PressKeyIOLevel, !prvSoftKB.PressKeyIOLevel);
  231. }
  232. }
  233. }
  234. void SoftKB_SetCB(CBFuncEx_t CB, void *pParam)
  235. {
  236. if (CB)
  237. {
  238. prvSoftKB.CB = CB;
  239. }
  240. else
  241. {
  242. prvSoftKB.CB = prvSoftKB_DummyCB;
  243. }
  244. prvSoftKB.pParam = pParam;
  245. }
  246. void SoftKB_Test(void)
  247. {
  248. uint8_t In[4] = {GPIOD_10, GPIOE_00, GPIOE_01, GPIOE_02};
  249. uint8_t Out[4] = {GPIOD_12, GPIOD_13, GPIOD_14, GPIOD_15};
  250. SoftKB_Setup(6250, 4, 2, 0, NULL, NULL);
  251. SoftKB_IOConfig(In, 4, Out, 4, 0);
  252. SoftKB_Start();
  253. }
  254. //INIT_TASK_EXPORT(SoftKB_Test, "3");