📄 keyboard.c
字号:
case 1: P1.0 = 0; break;
case 2: P1.1 = 0; break;
case 3: P1.2 = 0; break;
case 4: P1.3 = 0; break;
case 5: P1.4 = 0; break;
case 6: P1.5 = 0; break;
case 7: P1.6 = 0; break;
case 8: P1.7 = 0; break;
case 9: P3.6 = 0; break;
case 10: P0.0 = 0; break;
case 11: P0.1 = 0; break;
case 12: P0.2 = 0; break;
case 13: P0.3 = 0; break;
case 14: P0.4 = 0; break;
case 15: P0.5 = 0; break;
case 16: P0.6 = 0; break;
case 17: P0.7 = 0; break;
case 18: P3.7 = 0; break;
// Additional scan lines may be added by adding more case statements
// here and increasing the range of the for() statement above.
default: break;
} // end of switch(scanLine)
// Get the current of the current scanline. We invert it so that any bit that
// is set indicates a key that has been pressed.
keypress = ~P2;
if (keypress == 0x01 || keypress == 0x02 || keypress == 0x04 || keypress == 0x08 ||
keypress == 0x10 || keypress == 0x20 || keypress == 0x40 || keypress == 0x80) {
// We now search the keyDefs[] table starting at the offset that we're at.
// We keep searching until the scanline indicated in the table is less than
// the current scanline, which means there are no more options for the current
// scanline.
while(keyDefs[keyDefOffset].scanLine >= scanLine ) {
// If the scanline of the table at our current offset is equal to our
// current scanline then we can proceed to analyze it.
if(keyDefs[keyDefOffset].scanLine == scanLine) {
// If the detected keypress ANDed with the keypress Mask from the table
// results in a non-zero value, it means the given key has been pressed.
// We also make sure the given keypress is supported in our current
// VID/PID mode.
if( (keypress & keyDefs[keyDefOffset].keyPressMask) && (vidPidMask & keyDefs[keyDefOffset].vidPidMask)) {
// keypressDebounce[keyDefs[keyDefOffset].hidCode]++;
// if(keypressDebounce[keyDefs[keyDefOffset].hidCode] > 5)
// {
// keypressDebounce[keyDefs[keyDefOffset].hidCode] = 6;
// We check to see if the key that has been pressed is one of the
// keys that is sent back in the modifier byte.
if(keyDefs[keyDefOffset].modBit != 0x00 ) {
modifierByte |= keyDefs[keyDefOffset].modBit;
}
else if(strlen(keypressBuffer) < KEYPRESS_BUFFER_SIZE ) {
// If it was not a modifier byte key and there is still room in the
// keypressBuffer, we will add this key to the buffer.
keypressBuffer[strlen(keypressBuffer)] = keyDefs[keyDefOffset].hidCode;
}
//}
// else
// {
// keypressDebounce[keyDefs[keyDefOffset].hidCode] = 0;
// }
} // end of if( (keypress & keyDefs[keyDefOffset].keyPressMask) && (vidPidMask & keyDefs[keyDefOffset].vidPidMask))
} // end of if(keyDefs[keyDefOffset].scanLine == scanLine)
keyDefOffset++;
} // end of while(keyDefs[keyDefOffset].scanLine >= scanLine )
// If we reach the end of the keypress table then there's nothing else we can
// possibly find, so we exit our scanline loop even if we haven't checked every
// scan line. We also exit if the keypress buffer has been completely filled.
// In this case, even if there are more valid keys waiting we won't be able to
// store them anyway, so we exit.
if(keyDefs[keyDefOffset].scanLine == 0 || strlen(keypressBuffer) >= KEYPRESS_BUFFER_SIZE)
break;
} // end of if (keypress == 0x01 ...
} // end of for(scanLine = 18; scanLine > 0; scanLine--)
// Send the current keyboard buffer to IEP1 to be sent to host
UpdateIEP1WithKeypress();
} // end of if(keypressBuffer[0] == 0x00)
} // end of while(1)
}
/***************************************************************************
* Function: ClearKeyBoardBuffer *
* Programmer: Craig Steiner (csteiner@vaultbbs.com) *
* Description: Clears the keyboard's internal keypress buffer. The *
* keypress buffer is 6 bytes which represent a maximum of 6 keypresses *
* that can be returned via USB. Once the keypresses are sent via USB, *
* this routine may be called to clear the buffer. *
***************************************************************************/
void ClearKeyBoardBuffer(void)
{
BYTE bTemp;
for(bTemp = 0; bTemp < KEYPRESS_BUFFER_SIZE; bTemp++)
keypressBuffer[bTemp] = 0x00;
}
/***************************************************************************
* Function: UpdateIEP1WithKeypress *
* Programmer: Craig Steiner (csteiner@vaultbbs.com) *
* Description: Is called by the main() program in order to send the *
* contents of the keypressBuffer[] to the host via USB. The function *
* does the following: *
* *
* 1. Makes sure the current IEP1 Byte Counter is "NAK", which means *
* there is nothing pending to send. Any other value means the last *
* packet sent to the host hasn't been sent yet, so we don't send *
* anything else until the previous packet is sent. *
* 2. If nothing is pending to send, the routine constructs the output *
* data packet in the IEP1 Output buffer, copying the modifier byte, *
* the constant 0x00 byte, and the 6 bytes of keypressBufferp[] data.*
* 3. Compares to see if the current packet that is ready to send is *
* the same as the last packet that was sent. If it is, it exits *
* since only *changes* in the keyboard state need to be reported. *
* 4. If all of the above tests are successful, the routine sets the *
* Byte Counter to 8 which will cause the 8-byte packet to be *
* sent when the next IEP1 poll is received from the host. *
***************************************************************************/
void UpdateIEP1WithKeypress(void)
{
BYTE bTemp;
// We first check to see if the character count is NAK. If it's not
// NAK that means we still have some output pending, so we leave it
// alone for now.
if(bIEPDCTX_1 != EPBCT_NAK)
{
ClearKeyBoardBuffer();
return;
}
// Start by initialization the HID Keyboard report header
iep1Buffer[0] = modifierByte; // Holds shift, alt, etc.
iep1Buffer[1] = 0x00; // Second byte is always 0x00
// We now copy the keypress buffer into the rest of the iep1Buffer.
for(bTemp = 0; bTemp < 6; bTemp++)
iep1Buffer[2 + bTemp] = keypressBuffer[bTemp];
// We now compare the currently prepared IEP1 output buffer with the last
// packet that was sent, which is held in the variable previousIEP1packet.
// If the current packet is the same as the previous packet sent, we
// don't need to do anything since the host will assume the previous state
// is still current until we report a different state.
if( memcmp(iep1Buffer, previousIEP1packet, 8) == 0)
{
ClearKeyBoardBuffer();
return;
}
// We now check to see if the device is currently suspended. If it is,
// the keypress should wake the system up--so we generate a Wakeup
// pulse so things come back to life.
#ifdef XXX
if(bSuspended)
bUSBCTL |= USBCTL_RWUP;
#endif
// We finally the set the CTX_1 to the number of bytes in the IEP1 output
// buffer (8). Thus, the next time the host issues an IN1 poll to the
// TUSB2136, the data will be sent out immediately. We will know that
// the transfer has taken place when the IEP1InterruptHandler() interrupt
// handler is called.
bIEPDCTX_1 = 8;
}
/***************************************************************************
* Function: IEP1InterruptHandler *
* Programmer: Craig Steiner (csteiner@vaultbbs.com) *
* Description: This function is the IEP1 interrupt handler. It is called *
* whenever a packet of data has been transmitted from the device to the*
* host. The routine performs the following tasks: *
* *
* 1. Makes a copy of the data packet that was just sent in the *
* variable previousIEP1packet. This is used by the *
* UpdateIEP1WithKeypress function to determine whether or not there *
* has been a change in the keyboard state. *
* 2. Clears the keypressBuffer to allow the main program loop to *
* scan the keyboard and generate a new packet. *
* *
***************************************************************************/
void IEP1InterruptHandler(void)
{
// This interrupt is triggered when we've finished sending a block of data
// to the host. At that point we copy the current IEP1 buffer to the
// "previousIEP1packet" buffer. This holds a copy of the last data that
// was sent to the host. This is used later to see if a subsequent packet
// is the same as a new packet. If it is, we won't have to resend it.
memcpy(previousIEP1packet, iep1Buffer, 8);
// BYTE str;
//
// for(str = 0; str < 8; str++)
// previousIEP1packet[str] = iep1Buffer[str];
// We clear the keypressBuffer. The keyboard scan process will only begin
// if the keypressBuffer is clear.
ClearKeyBoardBuffer();
}
/***************************************************************************
* Function: OEP0SetLEDs *
* Programmer: Craig Steiner (csteiner@vaultbbs.com) *
* Description: This function is called by the usbReceiveNextPacketOnOEP0 *
* routine when the data packet of a LED SetReport transaction is *
* received. This routine sets/clears the keyboard LEDs based on the *
* data received from the host. *
* *
***************************************************************************/
void OEP0SetLEDs(void)
{
// This code is only enabled if this is a "real" keyboard, not the
// demo version selected by DIPSWITCHES. If it is the demo version,
// changing the values of the P3.2-P3.4 pins seems to cause problems.
if(bLED & BIT_NUMLOCK)
PIN_NUMLOCK = 0;
else
PIN_NUMLOCK = 1;
if(bLED & BIT_CAPSLOCK)
PIN_CAPSLOCK = 0;
else
PIN_CAPSLOCK = 1;
if(bLED & BIT_SCROLLLOCK)
PIN_SCROLLLOCK = 0;
else
PIN_SCROLLLOCK = 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -