keyboard.c 9.6 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 "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. int 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. return 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 Return the repeating property for this key
  161. *
  162. * \return 'TRUE' in case the key was repeating, 'FALSE' if not
  163. *
  164. */
  165. /* ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ */
  166. static u_char KbKeyIsRepeating(u_short Key)
  167. {
  168. return(KeyRepeatArray[KbRemapKey(Key)]==KEY_REPEAT);
  169. }
  170. /* ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ */
  171. /*!
  172. * \brief set the property of this key to repeating or not-repeating
  173. *
  174. */
  175. /* ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ */
  176. void KbSetKeyRepeating(u_char Key, u_char Property)
  177. {
  178. // check arguments
  179. if (((Property==KEY_REPEAT) || (Property==KEY_NO_REPEAT)) && (Key < KEY_NROF_KEYS))
  180. {
  181. KeyRepeatArray[Key]=Property;
  182. }
  183. }
  184. /* ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ */
  185. /*!
  186. * \brief Wait until an event was pushed on the eventqueue for this module
  187. *
  188. * This routine provides the event interface for other Luks-modules
  189. *
  190. * \param dwTimeout time in milisecs that this routine should wait before
  191. * it will return with KB_ERROR
  192. *
  193. * \return KB_OK in case an event was found
  194. * \return KB_ERROR in case no event was found (return due to timeout)
  195. */
  196. /* ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ */
  197. int KbWaitForKeyEvent(u_long dwTimeout)
  198. {
  199. int nError = KB_OK;
  200. int nTimeout;
  201. nTimeout = NutEventWait(&hKBEvent, dwTimeout);
  202. if (nTimeout == -1)
  203. {
  204. nError = KB_ERROR;
  205. }
  206. return(nError);
  207. }
  208. /* ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ */
  209. /*!
  210. * \brief Return the databyte that was receeived in the IR-stream
  211. *
  212. * In case a valid key is found in the keyboard scan, the key-code is
  213. * stored in the keyboardbuffer. This routine returns the first available
  214. * valid key in this buffer
  215. * \return the keycode that was found by the keyboard scan
  216. *
  217. * \todo implement a key-buffer for this routine
  218. */
  219. /* ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ */
  220. u_char KbGetKey()
  221. {
  222. return(KeyBuffer[0]);
  223. }
  224. /*!
  225. * \brief inject a virtual key into the system
  226. *
  227. */
  228. void KbInjectKey(u_char VirtualKey)
  229. {
  230. KeyBuffer[0]=VirtualKey;
  231. NutEventPostFromIrq(&hKBEvent); // 'valid key' detected -> generate Event
  232. }
  233. /* ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ */
  234. /*!
  235. * \brief Initialise the Keyboard module
  236. *
  237. *
  238. * - initialise the keyboard read- and write port
  239. * - flush the keyboardbuffer
  240. * - flush the eventqueue for this module
  241. *
  242. * \note PORTF uses internal pull-ups. That's why a '1' is read
  243. * when no key is pressed. Use negative logic to detect keys.
  244. * So default state of the colums is '1'
  245. */
  246. /* ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ */
  247. void KbInit()
  248. {
  249. u_char i;
  250. sbi (KB_OUT_WRITE_A, KB_COL_0);
  251. sbi (KB_OUT_WRITE_A, KB_COL_1);
  252. sbi (KB_OUT_WRITE_B, KB_COL_2);
  253. sbi (KB_OUT_WRITE_B, KB_COL_3);
  254. KbState = KB_IDLE;
  255. KeyFound = KEY_NO_KEY;
  256. KbClearEvent(&hKBEvent);
  257. for (i=0;i<KB_BUFFER_SIZE;++i)
  258. {
  259. KeyBuffer[i] = (u_char)KEY_NO_KEY;
  260. }
  261. for (i=0; i<KEY_NROF_KEYS; ++i)
  262. {
  263. KeyRepeatArray[i]=KEY_NO_REPEAT;
  264. }
  265. HoldCounter=0;
  266. // arrow keys are repeating keys by default
  267. KbSetKeyRepeating(KEY_UP, KEY_REPEAT);
  268. KbSetKeyRepeating(KEY_DOWN, KEY_REPEAT);
  269. KbSetKeyRepeating(KEY_LEFT, KEY_REPEAT);
  270. KbSetKeyRepeating(KEY_RIGHT, KEY_REPEAT);
  271. }
  272. /* ---------- end of module ------------------------------------------------ */
  273. /*@}*/