| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326 |
- /*! \file
- * keyboard.c contains the low-level keyboard scan and the
- * interfacing with NutOS (signalling)
- * Copyright STREAMIT, 2010.
- * \version 1.0
- * \date 26 september 2003
- */
- #define LOG_MODULE LOG_KEYBOARD_MODULE
- #include <sys/atom.h>
- #include <sys/event.h>
- //#pragma text:appcode
- #include "log.h"
- #include "keyboard.h"
- #include "portio.h"
- #include "system.h"
- /*-------------------------------------------------------------------------*/
- /* local defines */
- /*-------------------------------------------------------------------------*/
- /*
- * definition of raw keys as found in keyboardscan
- * Note that these 16-bit values are remapped before
- * the application uses them
- */
- #define RAW_KEY_01 0xFFFB
- #define RAW_KEY_02 0xFFFD
- #define RAW_KEY_03 0xFF7F
- #define RAW_KEY_04 0xFFF7
- #define RAW_KEY_05 0xFFFE
- #define RAW_KEY_ALT 0xFFBF
- #define RAW_KEY_ESC 0xFFEF
- #define RAW_KEY_UP 0xF7FF
- #define RAW_KEY_OK 0xFFDF
- #define RAW_KEY_LEFT 0xFEFF
- #define RAW_KEY_DOWN 0xFBFF
- #define RAW_KEY_RIGHT 0xFDFF
- #define RAW_KEY_POWER 0xEFFF
- #define RAW_KEY_SETUP 0xFFCF // combine 'ESCAPE' (0xFFEF') with 'OK' (0xFFDF)
- /*-------------------------------------------------------------------------*/
- /* local variable definitions */
- /*-------------------------------------------------------------------------*/
- static HANDLE hKBEvent;
- static u_short KeyFound; // use short for 4 nibbles (4 colums)
- static u_char KeyBuffer[KB_BUFFER_SIZE];
- static u_short HoldCounter;
- static u_char KbState;
- static u_char KeyRepeatArray[KEY_NROF_KEYS];
- /*-------------------------------------------------------------------------*/
- /* local routines (prototyping) */
- /*-------------------------------------------------------------------------*/
- static void KbClearEvent(HANDLE*);
- static u_char KbRemapKey(u_short LongKey);
- /*!
- * \addtogroup Keyboard
- */
- /*@{*/
- /*-------------------------------------------------------------------------*/
- /* start of code */
- /*-------------------------------------------------------------------------*/
- /* ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ */
- /*!
- * \brief Clear the eventbuffer of this module
- *
- * This routine is called during module initialization.
- *
- * \param *pEvent pointer to the event queue
- */
- /* ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ */
- static void KbClearEvent(HANDLE *pEvent)
- {
- NutEnterCritical();
- *pEvent = 0;
- NutExitCritical();
- }
- /* ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ */
- /*!
- * \brief Low-level keyboard scan
- *
- * KbScan is called each 4.44 msec from MainBeat interrupt
- * Remember: pressed key gives a '0' on KB_IN_READ
- *
- * After each keyboard-scan, check for a valid MMCard
- */
- /* ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ */
- int KbScan()
- {
- u_char KeyNibble0, KeyNibble1, KeyNibble2, KeyNibble3;
- /*
- * we must scan 4 colums, 2 in PORTG and 2 in PORTD
- */
- #ifndef USE_JTAG
- // scan keys in COL 0
- cbi (KB_OUT_WRITE_A, KB_COL_0);
- asm("nop\n\tnop"); // small delay
- KeyNibble0 = inp(KB_IN_READ) & KB_ROW_MASK;
- sbi (KB_OUT_WRITE_A, KB_COL_0);
- // scan keys in COL 1
- cbi (KB_OUT_WRITE_A, KB_COL_1);
- asm("nop\n\tnop"); // small delay
- KeyNibble1 = inp(KB_IN_READ) & KB_ROW_MASK;
- sbi (KB_OUT_WRITE_A, KB_COL_1);
- // scan keys in COL 2
- cbi (KB_OUT_WRITE_B, KB_COL_2);
- asm("nop\n\tnop"); // small delay
- KeyNibble2 = inp(KB_IN_READ) & KB_ROW_MASK;
- sbi (KB_OUT_WRITE_B, KB_COL_2);
- // scan keys in COL 3
- cbi (KB_OUT_WRITE_B, KB_COL_3);
- asm("nop\n\tnop"); // small delay
- KeyNibble3 = inp(KB_IN_READ) & KB_ROW_MASK;
- sbi (KB_OUT_WRITE_B, KB_COL_3);
- /*
- * we want to detect exactly 1 key in exactly 1 colom
- * exception is the combination of VOLMIN & POWER (-> SETUP)
- * meaning: Keynibble0==[0000 1011] (KEY_VOLMIN) & KeyNibble1==[0111 0000] (KEY_POWER)
- */
- /*
- * put all 4 seperate nibbles in place in 'KeyFound'
- *
- * KeyNibble0 on b3...b0 (col 0)
- * KeyNibble1 on b7...b4 (col 1)
- * KeyNibble2 on b11..b8 (col 2)
- * KeyNibble3 on b15..b12 (col 3)
- */
- KeyFound = ((KeyNibble0>>4) & 0x000F); // b7..b4 in 'KeyNibble0' to b3...b0 in 'KeyFound' >> shift 4 right
- KeyFound |= (KeyNibble1 & 0x00F0); // b7..b4 in 'KeyNibble1' to b7...b4 in 'KeyFound' -- do nothing
- KeyFound |= ((KeyNibble2<<4) & 0x0F00); // b7..b4 in 'KeyNibble2' to b11..b8 in 'KeyFound' << shift 4 left
- KeyFound |= ((KeyNibble3<<8) & 0xF000); // b7..b4 in 'KeyNibble3' to b15..b12 in 'KeyFound' << shift 8 left
- return KeyFound;
- #endif // USE_JTAG
- }
- /* ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ */
- /*!
- * \brief Remap the 16-bit value for the active key to an 8-bit value
- *
- */
- /* ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ */
- static u_char KbRemapKey(u_short LongKey)
- {
- switch (LongKey)
- {
- case RAW_KEY_01: return(KEY_01);
- case RAW_KEY_02: return(KEY_02);
- case RAW_KEY_03: return(KEY_03);
- case RAW_KEY_04: return(KEY_04);
- case RAW_KEY_05: return(KEY_05);
- case RAW_KEY_ALT: return(KEY_ALT);
- case RAW_KEY_ESC: return(KEY_ESC);
- case RAW_KEY_UP: return(KEY_UP);
- case RAW_KEY_OK: return(KEY_OK);
- case RAW_KEY_LEFT: return(KEY_LEFT);
- case RAW_KEY_DOWN: return(KEY_DOWN);
- case RAW_KEY_RIGHT: return(KEY_RIGHT);
- case RAW_KEY_POWER: return(KEY_POWER);
- case RAW_KEY_SETUP: return(KEY_SETUP); // combined key
- default: return(KEY_UNDEFINED);
- }
- }
- /* ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ */
- /*!
- * \brief Return the repeating property for this key
- *
- * \return 'TRUE' in case the key was repeating, 'FALSE' if not
- *
- */
- /* ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ */
- static u_char KbKeyIsRepeating(u_short Key)
- {
- return(KeyRepeatArray[KbRemapKey(Key)]==KEY_REPEAT);
- }
- /* ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ */
- /*!
- * \brief set the property of this key to repeating or not-repeating
- *
- */
- /* ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ */
- void KbSetKeyRepeating(u_char Key, u_char Property)
- {
- // check arguments
- if (((Property==KEY_REPEAT) || (Property==KEY_NO_REPEAT)) && (Key < KEY_NROF_KEYS))
- {
- KeyRepeatArray[Key]=Property;
- }
- }
- /* ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ */
- /*!
- * \brief Wait until an event was pushed on the eventqueue for this module
- *
- * This routine provides the event interface for other Luks-modules
- *
- * \param dwTimeout time in milisecs that this routine should wait before
- * it will return with KB_ERROR
- *
- * \return KB_OK in case an event was found
- * \return KB_ERROR in case no event was found (return due to timeout)
- */
- /* ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ */
- int KbWaitForKeyEvent(u_long dwTimeout)
- {
- int nError = KB_OK;
- int nTimeout;
- nTimeout = NutEventWait(&hKBEvent, dwTimeout);
- if (nTimeout == -1)
- {
- nError = KB_ERROR;
- }
- return(nError);
- }
- /* ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ */
- /*!
- * \brief Return the databyte that was receeived in the IR-stream
- *
- * In case a valid key is found in the keyboard scan, the key-code is
- * stored in the keyboardbuffer. This routine returns the first available
- * valid key in this buffer
- * \return the keycode that was found by the keyboard scan
- *
- * \todo implement a key-buffer for this routine
- */
- /* ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ */
- u_char KbGetKey()
- {
- return(KeyBuffer[0]);
- }
- /*!
- * \brief inject a virtual key into the system
- *
- */
- void KbInjectKey(u_char VirtualKey)
- {
- KeyBuffer[0]=VirtualKey;
- NutEventPostFromIrq(&hKBEvent); // 'valid key' detected -> generate Event
- }
- /* ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ */
- /*!
- * \brief Initialise the Keyboard module
- *
- *
- * - initialise the keyboard read- and write port
- * - flush the keyboardbuffer
- * - flush the eventqueue for this module
- *
- * \note PORTF uses internal pull-ups. That's why a '1' is read
- * when no key is pressed. Use negative logic to detect keys.
- * So default state of the colums is '1'
- */
- /* ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ */
- void KbInit()
- {
- u_char i;
- sbi (KB_OUT_WRITE_A, KB_COL_0);
- sbi (KB_OUT_WRITE_A, KB_COL_1);
- sbi (KB_OUT_WRITE_B, KB_COL_2);
- sbi (KB_OUT_WRITE_B, KB_COL_3);
- KbState = KB_IDLE;
- KeyFound = KEY_NO_KEY;
- KbClearEvent(&hKBEvent);
- for (i=0;i<KB_BUFFER_SIZE;++i)
- {
- KeyBuffer[i] = (u_char)KEY_NO_KEY;
- }
- for (i=0; i<KEY_NROF_KEYS; ++i)
- {
- KeyRepeatArray[i]=KEY_NO_REPEAT;
- }
- HoldCounter=0;
- // arrow keys are repeating keys by default
- KbSetKeyRepeating(KEY_UP, KEY_REPEAT);
- KbSetKeyRepeating(KEY_DOWN, KEY_REPEAT);
- KbSetKeyRepeating(KEY_LEFT, KEY_REPEAT);
- KbSetKeyRepeating(KEY_RIGHT, KEY_REPEAT);
- }
- /* ---------- end of module ------------------------------------------------ */
- /*@}*/
|