📄 ambakbd.c
字号:
return (status);
}
/*******************************************************************************
*
* kbdWriteData - write data to device
*
* This routine the write function from the I/O subsystem.
*
* RETURNS:
*/
LOCAL int kbdWriteData
(
KBD_DEVICE * pKbdDv /* device to control */
)
{
return (0);
}
/*******************************************************************************
*
* kbdHwInit - initialize the Keyboard
*
* This routine is called to do the keyboard initialization from an external
* routine
*
* RETURNS: N/A
*
* NOMANUAL
*/
LOCAL void kbdHwInit (void)
{
UCHAR reply;
int timeout = 3;
kbdWdid = wdCreate ();
/* disable everything */
KBD_OUT (COMMAND_AMBA_KB, 0);
do
{
/* Clock divisor */
KBD_OUT (KEYB_CLK, KMI_DIVISOR);
/* Enable keyboard but not interrupts */
KBD_OUT (COMMAND_AMBA_KB, KMI_CR_KMIEN);
KBD_OUT (DATA_AMBA_KB, 0xFF);
if (ambaKBRead(&reply) != OK)
continue;
if (reply != 0xfa && reply != 0xaa)
continue;
if (ambaKBRead(&reply) != OK)
continue;
if (reply != 0xfa && reply != 0xaa)
continue;
/* mode 1 produces XT scan codes */
KBD_OUT (DATA_AMBA_KB, 0xF0);
if (ambaKBRead(&reply) != OK)
continue;
KBD_OUT (DATA_AMBA_KB, 0x01);
if (ambaKBRead(&reply) != OK)
continue;
/* enable */
KBD_OUT (DATA_AMBA_KB, 0xF4);
if (ambaKBRead(&reply) != OK)
continue;
/* repeat rate */
KBD_OUT (DATA_AMBA_KB, 0xf3);
if (ambaKBRead(&reply) != OK)
continue;
/* .25 sec delay, 30/sec */
KBD_OUT (DATA_AMBA_KB, 0x00);
if (ambaKBRead(&reply) != OK)
continue;
/* Enable interrupts */
KBD_OUT (COMMAND_AMBA_KB, KMI_CR_RXIEN | KMI_CR_KMIEN);
break;
} while (timeout--);
kbdStatInit ();
}
/*******************************************************************************
*
* kbdStatInit - initialize the Keyboard state
*
* This routine initializes the keyboard descriptor in the virtual consoles.
* The same keyboard descriptor is used for all the virtual consoles.
*
* RETURNS: N/A
*/
LOCAL void kbdStatInit (void)
{
UCHAR stat, reply;
int timeout = 3;
pKbdDevice->kbdFlags = NUM; /* Numeric mode on */
stat = (UCHAR) (pKbdDevice->kbdFlags & 0x07);
if (oldLedStat == stat)
return;
oldLedStat = stat;
do
{
if (ambaKBWrite (0xed) == ERROR)
continue;
if (ambaKBRead(&reply) == ERROR)
continue;
if (ambaKBWrite (stat) == ERROR)
continue;
if (ambaKBRead(&reply) == ERROR)
continue;
break;
} while (--timeout);
}
/*******************************************************************************
*
* kbdIntr - interrupt level processing
*
* This routine handles the keyboard interrupts
*
* RETURNS: N/A
*
* NOMANUAL
*/
LOCAL void kbdIntr (void)
{
FAST UCHAR scanCode; /* to hold the scanCode */
UCHAR stat = KBD_IN (STATUS_AMBA_KB);
kbdIntCnt++;
if (stat & KMI_RXFULL)
{
int par, temp, n;
temp = scanCode = KBD_IN (DATA_AMBA_KB);
/* check parity */
par = (KBD_IN (STATUS_AMBA_KB) & KMI_PARITY) ? 1 : 0;
for (n = 8; n > 0; n--)
{
par ^= (temp & 0x01);
temp = temp >> 1;
}
if (!par)
{
/* parity failed - request retransmission */
if (!(KBD_IN (STATUS_AMBA_KB) & KMI_TXBUSY))
{
/* send a retransmit command if we can */
KBD_OUT (DATA_AMBA_KB, 0xFE);
}
return;
}
/* keyboard acknowledge to any valid input, so just return */
if (scanCode == 0xfa)
{
kbdAcknowledge = TRUE;
return;
}
tyIRd (&(pKbdDevice->tyDev), scanCode);
}
}
/******************************************************************************
*
* kbdLedSet - Keybord LED Set
*
* This routine Keyboad LED control on kbdConDv.kbdFlags numeric, caps and
* stps
*
* RETURNS: N/A
*/
LOCAL void kbdLedSet (void)
{
UCHAR stat = 0;
int timeout;
UCHAR reply;
/* bits 0 1 2 for scroll numlock & capslock */
stat = (UCHAR) (pKbdDevice->kbdFlags & 0x07);
if (oldLedStat == stat)
return;
oldLedStat = stat;
timeout = 3;
do
{
kbdDelay();
kbdIntDisable();
ambaKBWrite(0xed); /* SET LEDS command */
if (ambaKBRead(&reply) != OK)
continue;
ambaKBWrite(stat); /* set LEDs */
if (ambaKBRead(&reply) == OK)
break;
} while (--timeout >= 0);
kbdIntEnable();
}
/******************************************************************************
*
* ambaKBRead - read data from the keyboard.
*
* Read data from the keyboard.
*
* RETURNS: OK or ERROR if timed out
*/
STATUS ambaKBRead
(
UCHAR *pData
)
{
kbdTimeout = FALSE;
wdStart (kbdWdid, (sysClkRateGet() * kbdWdsec), (FUNCPTR)kbdWdog, 0);
while (((KBD_IN (STATUS_AMBA_KB) & KMI_RXFULL) == 0) && !kbdTimeout)
;
wdCancel (kbdWdid);
kbdDelay();
*pData = KBD_IN (DATA_AMBA_KB);
return (kbdTimeout ? ERROR : OK);
}
/******************************************************************************
*
* ambaKBWrite - write data to the keyboard.
*
* Write data to the keyboard.
*
* RETURNS: OK or ERROR if timed out
*/
STATUS ambaKBWrite
(
UCHAR data
)
{
kbdTimeout = FALSE;
wdStart (kbdWdid, (sysClkRateGet() * kbdWdsec), (FUNCPTR)kbdWdog, 0);
while ((KBD_IN (STATUS_AMBA_KB) & KMI_TXBUSY) && !kbdTimeout)
;
wdCancel (kbdWdid);
KBD_OUT (DATA_AMBA_KB, data);
return (kbdTimeout ? ERROR : OK);
}
/******************************************************************************
*
* ambaKBCommand - write command to the keyboard.
*
* Write command to the keyboard.
*
* RETURNS: OK or ERROR if timed out
*/
STATUS ambaKBCommand
(
UCHAR command
)
{
KBD_OUT (COMMAND_AMBA_KB, command);
return (OK);
}
/******************************************************************************
*
* kbdWdog - KBD driver watchdog handler.
*
* KBD driver watchdog handler.
*
* RETURNS: N/A
*/
LOCAL void kbdWdog
(
void
)
{
kbdTimeout = TRUE;
kbdTimeoutCnt++;
}
/*******************************************************************************
*
* kbdDelay - pause
*
* This routine is called to introduce some delay
*
* RETURNS: N/A
*
* NOMANUAL
*/
LOCAL void kbdDelay(void)
{
taskDelay (sysClkRateGet () >> 3);
}
/*******************************************************************************
*
* kbdIntDisable - disable keyboard interrupts
*
* This routine disables interrupts from being generated by the keyboard controller
*
* RETURNS: N/A
*
* NOMANUAL
*/
LOCAL void kbdIntDisable (void)
{
/* Disable interrupts */
KBD_OUT (COMMAND_AMBA_KB, KMI_CR_KMIEN);
}
/*******************************************************************************
*
* kbdIntEable - enable keyboard interrupts
*
* This routine re-enables Rx interrupts to be generated by the keyboard controller
*
* RETURNS: N/A
*
* NOMANUAL
*/
LOCAL void kbdIntEnable (void)
{
/* Enable interrupts */
KBD_OUT (COMMAND_AMBA_KB, KMI_CR_RXIEN | KMI_CR_KMIEN);
}
#endif /* COMMAND_AMBA_KB */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -