keyboard.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. /*! \file
  2. * keyboard.c contains the low-level keyboard scan and the
  3. * interfacing with NutOS (signalling)
  4. * Copyright STREAMIT, 2010.
  5. * \version 1.0
  6. * \date 26 september 2003
  7. */
  8. #define LOG_MODULE LOG_KEYBOARD_MODULE
  9. #include <sys/atom.h>
  10. #include <sys/event.h>
  11. //#pragma text:appcode
  12. #include "keyboard.h"
  13. #include "portio.h"
  14. #include "system.h"
  15. /*-------------------------------------------------------------------------*/
  16. /* local defines */
  17. /*-------------------------------------------------------------------------*/
  18. /*
  19. * definition of raw keys as found in keyboardscan
  20. * Note that these 16-bit values are remapped before
  21. * the application uses them
  22. */
  23. #define RAW_KEY_01 0xFFFB
  24. #define RAW_KEY_02 0xFFFD
  25. #define RAW_KEY_03 0xFF7F
  26. #define RAW_KEY_04 0xFFF7
  27. #define RAW_KEY_05 0xFFFE
  28. #define RAW_KEY_ALT 0xFFBF
  29. #define RAW_KEY_ESC 0xFFEF
  30. #define RAW_KEY_UP 0xF7FF
  31. #define RAW_KEY_OK 0xFFDF
  32. #define RAW_KEY_LEFT 0xFEFF
  33. #define RAW_KEY_DOWN 0xFBFF
  34. #define RAW_KEY_RIGHT 0xFDFF
  35. #define RAW_KEY_POWER 0xEFFF
  36. #define RAW_KEY_SETUP 0xFFCF // combine 'ESCAPE' (0xFFEF') with 'OK' (0xFFDF)
  37. /*-------------------------------------------------------------------------*/
  38. /* local variable definitions */
  39. /*-------------------------------------------------------------------------*/
  40. static HANDLE hKBEvent;
  41. static u_short KeyFound; // use short for 4 nibbles (4 colums)
  42. static u_char KeyBuffer[KB_BUFFER_SIZE];
  43. static u_short HoldCounter;
  44. static u_char KbState;
  45. static u_char KeyRepeatArray[KEY_NROF_KEYS];
  46. /*-------------------------------------------------------------------------*/
  47. /* local routines (prototyping) */
  48. /*-------------------------------------------------------------------------*/
  49. static void KbClearEvent(HANDLE*);
  50. static u_char KbRemapKey(u_short LongKey);
  51. /*!
  52. * \addtogroup Keyboard
  53. */
  54. /*@{*/
  55. /*-------------------------------------------------------------------------*/
  56. /* start of code */
  57. /*-------------------------------------------------------------------------*/
  58. /* ����������������������������������������������������������������������� */
  59. /*!
  60. * \brief Clear the eventbuffer of this module
  61. *
  62. * This routine is called during module initialization.
  63. *
  64. * \param *pEvent pointer to the event queue
  65. */
  66. /* ����������������������������������������������������������������������� */
  67. static void KbClearEvent(HANDLE *pEvent)
  68. {
  69. NutEnterCritical();
  70. *pEvent = 0;
  71. NutExitCritical();
  72. }
  73. /* ����������������������������������������������������������������������� */
  74. /*!
  75. * \brief Low-level keyboard scan
  76. *
  77. * KbScan is called each 4.44 msec from MainBeat interrupt
  78. * Remember: pressed key gives a '0' on KB_IN_READ
  79. *
  80. * After each keyboard-scan, check for a valid MMCard
  81. */
  82. /* ����������������������������������������������������������������������� */
  83. void KbScan()
  84. {
  85. u_char KeyNibble0, KeyNibble1, KeyNibble2, KeyNibble3;
  86. /*
  87. * we must scan 4 colums, 2 in PORTG and 2 in PORTD
  88. */
  89. #ifndef USE_JTAG
  90. // scan keys in COL 0
  91. cbi (KB_OUT_WRITE_A, KB_COL_0);
  92. asm("nop\n\tnop"); // small delay
  93. KeyNibble0 = inp(KB_IN_READ) & KB_ROW_MASK;
  94. sbi (KB_OUT_WRITE_A, KB_COL_0);
  95. // scan keys in COL 1
  96. cbi (KB_OUT_WRITE_A, KB_COL_1);
  97. asm("nop\n\tnop"); // small delay
  98. KeyNibble1 = inp(KB_IN_READ) & KB_ROW_MASK;
  99. sbi (KB_OUT_WRITE_A, KB_COL_1);
  100. // scan keys in COL 2
  101. cbi (KB_OUT_WRITE_B, KB_COL_2);
  102. asm("nop\n\tnop"); // small delay
  103. KeyNibble2 = inp(KB_IN_READ) & KB_ROW_MASK;
  104. sbi (KB_OUT_WRITE_B, KB_COL_2);
  105. // scan keys in COL 3
  106. cbi (KB_OUT_WRITE_B, KB_COL_3);
  107. asm("nop\n\tnop"); // small delay
  108. KeyNibble3 = inp(KB_IN_READ) & KB_ROW_MASK;
  109. sbi (KB_OUT_WRITE_B, KB_COL_3);
  110. /*
  111. * we want to detect exactly 1 key in exactly 1 colom
  112. * exception is the combination of VOLMIN & POWER (-> SETUP)
  113. * meaning: Keynibble0==[0000 1011] (KEY_VOLMIN) & KeyNibble1==[0111 0000] (KEY_POWER)
  114. */
  115. /*
  116. * put all 4 seperate nibbles in place in 'KeyFound'
  117. *
  118. * KeyNibble0 on b3...b0 (col 0)
  119. * KeyNibble1 on b7...b4 (col 1)
  120. * KeyNibble2 on b11..b8 (col 2)
  121. * KeyNibble3 on b15..b12 (col 3)
  122. */
  123. KeyFound = ((KeyNibble0>>4) & 0x000F); // b7..b4 in 'KeyNibble0' to b3...b0 in 'KeyFound' >> shift 4 right
  124. KeyFound |= (KeyNibble1 & 0x00F0); // b7..b4 in 'KeyNibble1' to b7...b4 in 'KeyFound' -- do nothing
  125. KeyFound |= ((KeyNibble2<<4) & 0x0F00); // b7..b4 in 'KeyNibble2' to b11..b8 in 'KeyFound' << shift 4 left
  126. KeyFound |= ((KeyNibble3<<8) & 0xF000); // b7..b4 in 'KeyNibble3' to b15..b12 in 'KeyFound' << shift 8 left
  127. #endif // USE_JTAG
  128. }
  129. /* ����������������������������������������������������������������������� */
  130. /*!
  131. * \brief Remap the 16-bit value for the active key to an 8-bit value
  132. *
  133. */
  134. /* ����������������������������������������������������������������������� */
  135. static u_char KbRemapKey(u_short LongKey)
  136. {
  137. switch (LongKey)
  138. {
  139. case RAW_KEY_01: return(KEY_01);
  140. case RAW_KEY_02: return(KEY_02);
  141. case RAW_KEY_03: return(KEY_03);
  142. case RAW_KEY_04: return(KEY_04);
  143. case RAW_KEY_05: return(KEY_05);
  144. case RAW_KEY_ALT: return(KEY_ALT);
  145. case RAW_KEY_ESC: return(KEY_ESC);
  146. case RAW_KEY_UP: return(KEY_UP);
  147. case RAW_KEY_OK: return(KEY_OK);
  148. case RAW_KEY_LEFT: return(KEY_LEFT);
  149. case RAW_KEY_DOWN: return(KEY_DOWN);
  150. case RAW_KEY_RIGHT: return(KEY_RIGHT);
  151. case RAW_KEY_POWER: return(KEY_POWER);
  152. case RAW_KEY_SETUP: return(KEY_SETUP); // combined key
  153. default: return(KEY_UNDEFINED);
  154. }
  155. }
  156. /* ����������������������������������������������������������������������� */
  157. /*!
  158. * \brief Return the repeating property for this key
  159. *
  160. * \return 'TRUE' in case the key was repeating, 'FALSE' if not
  161. *
  162. */
  163. /* ����������������������������������������������������������������������� */
  164. static u_char KbKeyIsRepeating(u_short Key)
  165. {
  166. return(KeyRepeatArray[KbRemapKey(Key)]==KEY_REPEAT);
  167. }
  168. /* ����������������������������������������������������������������������� */
  169. /*!
  170. * \brief set the property of this key to repeating or not-repeating
  171. *
  172. */
  173. /* ����������������������������������������������������������������������� */
  174. void KbSetKeyRepeating(u_char Key, u_char Property)
  175. {
  176. // check arguments
  177. if (((Property==KEY_REPEAT) || (Property==KEY_NO_REPEAT)) && (Key < KEY_NROF_KEYS))
  178. {
  179. KeyRepeatArray[Key]=Property;
  180. }
  181. }
  182. /* ����������������������������������������������������������������������� */
  183. /*!
  184. * \brief Wait until an event was pushed on the eventqueue for this module
  185. *
  186. * This routine provides the event interface for other Luks-modules
  187. *
  188. * \param dwTimeout time in milisecs that this routine should wait before
  189. * it will return with KB_ERROR
  190. *
  191. * \return KB_OK in case an event was found
  192. * \return KB_ERROR in case no event was found (return due to timeout)
  193. */
  194. /* ����������������������������������������������������������������������� */
  195. int KbWaitForKeyEvent(u_long dwTimeout)
  196. {
  197. int nError = KB_OK;
  198. int nTimeout;
  199. nTimeout = NutEventWait(&hKBEvent, dwTimeout);
  200. if (nTimeout == -1)
  201. {
  202. nError = KB_ERROR;
  203. }
  204. return(nError);
  205. }
  206. /* ����������������������������������������������������������������������� */
  207. /*!
  208. * \brief Return the databyte that was receeived in the IR-stream
  209. *
  210. * In case a valid key is found in the keyboard scan, the key-code is
  211. * stored in the keyboardbuffer. This routine returns the first available
  212. * valid key in this buffer
  213. * \return the keycode that was found by the keyboard scan
  214. *
  215. * \todo implement a key-buffer for this routine
  216. */
  217. /* ����������������������������������������������������������������������� */
  218. u_char KbGetKey()
  219. {
  220. return(KeyBuffer[0]);
  221. }
  222. /*!
  223. * \brief inject a virtual key into the system
  224. *
  225. */
  226. void KbInjectKey(u_char VirtualKey)
  227. {
  228. KeyBuffer[0]=VirtualKey;
  229. NutEventPostFromIrq(&hKBEvent); // 'valid key' detected -> generate Event
  230. }
  231. /* ����������������������������������������������������������������������� */
  232. /*!
  233. * \brief Initialise the Keyboard module
  234. *
  235. *
  236. * - initialise the keyboard read- and write port
  237. * - flush the keyboardbuffer
  238. * - flush the eventqueue for this module
  239. *
  240. * \note PORTF uses internal pull-ups. That's why a '1' is read
  241. * when no key is pressed. Use negative logic to detect keys.
  242. * So default state of the colums is '1'
  243. */
  244. /* ����������������������������������������������������������������������� */
  245. void KbInit()
  246. {
  247. u_char i;
  248. sbi (KB_OUT_WRITE_A, KB_COL_0);
  249. sbi (KB_OUT_WRITE_A, KB_COL_1);
  250. sbi (KB_OUT_WRITE_B, KB_COL_2);
  251. sbi (KB_OUT_WRITE_B, KB_COL_3);
  252. KbState = KB_IDLE;
  253. KeyFound = KEY_NO_KEY;
  254. KbClearEvent(&hKBEvent);
  255. for (i=0;i<KB_BUFFER_SIZE;++i)
  256. {
  257. KeyBuffer[i] = (u_char)KEY_NO_KEY;
  258. }
  259. for (i=0; i<KEY_NROF_KEYS; ++i)
  260. {
  261. KeyRepeatArray[i]=KEY_NO_REPEAT;
  262. }
  263. HoldCounter=0;
  264. // arrow keys are repeating keys by default
  265. KbSetKeyRepeating(KEY_UP, KEY_REPEAT);
  266. KbSetKeyRepeating(KEY_DOWN, KEY_REPEAT);
  267. KbSetKeyRepeating(KEY_LEFT, KEY_REPEAT);
  268. KbSetKeyRepeating(KEY_RIGHT, KEY_REPEAT);
  269. }
  270. /* ---------- end of module ------------------------------------------------ */
  271. /*@}*/