keyboard.c 11 KB

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