📄 keyboard.c
字号:
/*
* CYC Code Development System
* USB keyboard example
* KEYBOARD.C
* This code may be adapted for any purpose
* when used with the CYC Code Development
* System. No warranty is implied or given
* as to its usability for any purpose.
*
* (c) Copyright 2000 Byte Craft Limited
* 421 King St.N., Waterloo, ON, Canada, N2J 4E4
* VOICE: 1 (519) 888 6911
* FAX : 1 (519) 746 6751
* email: support@bytecraft.com
*
* REVISION HISTORY
* V0.90b AL 99/06 Initial Version.
* V0.91b AL 00/05
* V0.92b SC 03/09 removed ";" from "if( EP_A0_MODE.IN_RECEIVED );"
***/
#pragma option f0
#pragma option REGSAVEOFF
#pragma option CALLMAP
#include <dev\c63512.h>
#include <port.h>
const char Endpoint_Descriptor[] =
{
0x07, /* descriptor length (7 bytes) */
0x05, /* descriptor type (ENDPOINT) */
0x81, /* endpoint address (IN endpoint, endpoint 1) */
0x03, /* endpoint attributes (interrupt) */
0x08, 0x00, /* maximum packet size (8 bytes) */
0x0A /* polling interval (10ms) */
};
const char Class_Descriptor[] =
{
0x09, /* descriptor size (9 bytes) */
0x21, /* descriptor type (HID) */
0x00, 0x01, /* class specification (1.00) */
0x00, /* hardware target country */
0x01, /* number of hid class desriptors to follow (1) */
0x22, /* report descriptor type (2) */
0x3F,
0x00
};
const char Interface_Descriptor[] =
{
0x09, /* length of descriptor (9 bytes) */
0x04, /* descriptor type (INTERFACE) */
0x00, /* interface number (0) */
0x00, /* alternate setting (0) */
0x01, /* number of endpoints (1) */
0x03, /* interface class (3..defined by USB spec) */
0x01, /* interface sub-class (1..defined by USB spec) */
0x01, /* interface protocol (2..defined by USB spec) */
0x05 /* interface string index (not supported) */
};
const char config_desc_table[] =
{
0x09, /* length of descriptor (9 bytes) */
0x02, /* descriptor type (CONFIGURATION) */
0x22, 0x00, /* total length of descriptor (33 bytes) */
0x01, /* number of interfaces to configure (1) */
0x01, /* configuration value (1) */
0x04, /* configuration string index (not supported) */
0xA0, /* configuration attributes (bus powered, remote wakeup) */
0x32 /* maximum power (100mA) */
};
const char device_desc_table[] =
{
0x12, /* size of descriptor (18 bytes) */
0x01, /* descriptor type (device descriptor) */
0x00, 0x01, /* USB spec release (ver 1.0) */
0x00, /* class code (each interface specifies class information) */
0x00, /* device sub-class (must be set to 0 because class code is 0) */
0x00, /* device protocol (no class specific protocol) */
0x08, /* maximum packet size (8 bytes) */
0xB4, 0x04, /* vendor ID (note Cypress vendor ID) */
0x00, 0x01, /* product ID (Cypress USB keyboard product ID) */
0x01, 0x00, /* device release number */
0x01, /* index of manufacturer string (not supported) */
0x02, /* index of product string (not supported) */
0x03, /* index of serial number string (not supported) */
0x01 /* number of configurations (1) */
};
const char hid_report_desc_table[] =
{
0x05, 0x01, /* usage page (generic desktop) */
0x09, 0x06, /* usage (keyboard) */
0xA1, 0x01, /* collection (application) */
0x05, 0x07, /* usage page( key codes) */
0x19, 0xE0, /* usage minimum (234) */
0x29, 0xE7, /* usage maximum (231) */
0x15, 0x00, /* logical minimum (0) */
0x25, 0x01, /* logical maximum (1) */
0x75, 0x01, /* report size (1 bit) */
0x95, 0x08, /* report count (8 bytes) */
0x81, 0x02, /* input (data, variable, absolute) */
0x95, 0x01, /* report count (1 byte) */
0x75, 0x08, /* report size (8 bits) */
0x81, 0x01, /* input (constant) */
0x95, 0x05, /* report count (5) */
0x75, 0x01, /* report size (1) */
0x05, 0x08, /* usage page (LEDs) */
0x19, 0x01, /* usage minimum (1) */
0x29, 0x05, /* usage maximum (5) */
0x91, 0x02, /* output (data, variable, absolute) */
0x95, 0x01, /* report count (1) */
0x75, 0x03, /* report size (3) */
0x91, 0x01, /* output (constant) */
0x95, 0x06, /* report count (6) */
0x75, 0x08, /* report size (8) */
0x15, 0x00, /* logical minimum (0) */
0x25, 0x65, /* logical maximum (101) */
0x05, 0x07, /* usage page (key codes) */
0x19, 0x00, /* usage minimum (0) */
0x29, 0x65, /* usage maximum (101) */
0x81, 0x00, /* input (data, array) */
0xC0 /* end collection */
};
/* These tables are the mechanism used to return status information to the
* host. The status can be either device, interface, or endpoint.
***/
const char get_dev_status_table[] =
{
0x00, 0x00, /* remote wakeup disabled, bus powered */
0x02, 0x00 /* remote wakeup enabled, bus powered */
};
const char get_interface_status_table[] =
{
0x00, 0x00 /* always return both bytes zero */
};
const char get_endpoint_status_table[] =
{
0x00, 0x00, /* not stalled */
0x01, 0x00 /* stalled */
};
/* String Descriptors */
const char USBStringLanguageDescription[] =
{
0x04, /* Length */
0x03, /* Type (3=string) */
0x09, /* Language: English */
0x04 /* Sub-language: Default */
};
const char USBStringDescription1[] =
{
0x10,0x03,'C',0,'y',0,'p',0,'r',0,'e',0,'s',0,'s',0
};
const char USBStringDescription2[] =
{
0x2A, 0x03,
'C',0,'y',0,'p',0,'r',0,'e',0,'s',0,'s',0,' ',0,
'U',0,'S',0,'B',0,' ',0,'K',0,'e',0,'y',0,'b',0,
'o',0,'a',0,'r',0,'d',0
};
const char USBStringDescription3[] =
{
0x10,0x03,'6',0,'5',0,'4',0,'3',0,'2',0,'1',0,'0',0
};
/* is a serial number is used this number must be unique */
/* for every device or else it may not enumerate properly */
const char USBStringDescription4[] =
{
0x1A,
0x03,
'H',0,'I',0,'D',0,' ',0,'K',0,'e',0,'y',0,'b',
0,'o',0,'a',0,'r',0,'d',0
};
const char USBStringDescription5[] =
{
0x28,
0x03,
'E',0,'n',0,'d',0,'P',0,'o',0,'i',0,'n',0,'t',0,'1',0,' ',0,'I',0,
'n',0,'t',0,'e',0,'r',0,'r',0,'u',0,'p',0,'t',0
};
/* The keycode_table currently has a unique location
* number in each column/row intersection. These
* are useful in determining key mappings to the
* scan matrix using a USB bus analyzer such as the
* CATC Inspector. Simply record the Data packets when
* keys are pressed. The number found in the recordedDATA
* packet will be one of the numbers found below.
* The location number can then be replaced with the
* actual usage code for the key pressed.
* The USB keyboard usage codes are defined
* in the HID spec Appendix A.3.
***/
const char keycode_table[] = {
/* c0: ; 1, 39, 17, 18, 40, 60, 76, 104 P0[0] */
0x29,0x2B,0x35,0x1E,0x14,0x04,0x1D,0x64,
/* c1: ; 2, 54, 3, 34, 19, 41, 77, 61 P0[1] */
0x3A,0x4E,0x3B,0x4B,0x1F,0x1A,0x1B,0x16,
/* c2: ; 4, 52, 5, 32, 57, 74, 101, 90 P0[2] */
0x3C,0x4C,0x3D,0x49,0x61,0x5E,0x63,0x5B,
/* c3: ; 20, 42, 25, 47, 67, 62, 83, 78 P0[3] */
0x20,0x08,0x25,0x0C,0x0E,0x07,0x36,0x06,
/* c4: ; 21, 44, 22, 43, 63, 64, 80, 79 P0[4] */
0x21,0x17,0x22,0x15,0x09,0x0A,0x05,0x19,
/* c5: ; 23, 46, 24, 45, 65, 66, 82, 81 P0[5] */
0x23,0x18,0x24,0x1C,0x0B,0x0D,0x10,0x11,
/* c6: ; 6, 31, 7, 29, 51, 30, 71, 97 P0[6] */
0x3E,0x2A,0x3F,0x2E,0x30,0x31,0x28,0x50,
/* c7: ; 8, 28, 9, 26, 48, 50, 84, 68 P0[7] */
0x40,0x2D,0x41,0x26,0x12,0x2F,0x37,0x0F,
/* c8: ; 10, 98, 11, 27, 69, 70, 49, 85 P1[0] */
0x42,0x51,0x43,0x27,0x33,0x34,0x13,0x38,
/* c9: ; 12, 53, 13, 33, 56, 73, 100, 89 P1[1] */
0x44,0x4D,0x45,0x4A,0x60,0x5D,0x62,0x5A,
/* c10: ; 14, 37, 112, 36, 55, 72, 88, 58 P1[2] */
0x46,0x55,0x65,0x54,0x5F,0x5C,0x59,0x57,
/* c11: ; 15, NA, 91, 110, NA, 102, 103, 113 P1[3] */
0x47,0x66,0x58,0xE3,0x01,0x2B,0x32,0x99,
/* c12: ; 16, NA, NA, NA, 75, NA, 86, NA P1[4] */
0x48,0x66,0x66,0x66,0xE1,0x66,0xE5,0x66,
/* c13: ; 38, NA, 35, NA, NA, 93, NA, 95 P1[5] */
0x56,0x66,0x53,0x66,0x66,0xE2,0x66,0xE6,
/* c14: ; 99, 111, 94, 87, NA, NA, NA, NA P1[6] */
0x4F,0xE7,0x2C,0x52,0x66,0x66,0x66,0x66,
/* c15: ; NA, 59, NA, NA, 92, NA, 96, NA P1[7] */
0x66,0x39,0x66,0x66,0xE0,0x66,0xE4,0x66,
/* c16: ; NA, NA, NA, NA, NA, NA , NA, NA P3[4] */
0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,
/* c17: ; NA, NA, NA, NA, NA, NA, NA, NA P3[5] */
0x66,0x66,0x66,0x66,0x66,0x66,0x61,0x66,
/* c18: ; NA, NA, NA, NA, NA, NA, NA, NA P3[6] */
0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,
/* c19: ; NA, NA, NA, NA, NA, NA, NA, NA P3[7] */
0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66
};
/* constant declarationsfrom USB Spec v1.0 from page 175
* standard request codes
***/
#define USB_GET_STATUS 0x00
#define USB_CLEAR_FEATURE 0x01
#define USB_SET_FEATURE 0x03
#define USB_SET_ADDRESS 0x05
#define USB_GET_DESCRIPTOR 0x06
#define USB_SET_DESCRIPTOR 0x07
#define USB_GET_CONFIGURATION 0x08
#define USB_SET_CONFIGURATION 0x09
#define USB_GET_INTERFACE 0x0A
#define USB_SET_INTERFACE 0x0B
#define USB_SYNCH_FRAME 0x0C
#define HOST_TO_DEVICE 0b00000000
#define DEVICE_TO_HOST 0b10000000
#define STANDARD 0b00000000
#define CLASS 0b00100000
#define VENDOR 0b01000000
#define DEVICE 0b00000000
#define INTERFACE 0b00000001
#define ENDPOINT 0b00000010
#define OTHER 0b00000011
/* standard descriptor types */
#define USB_DEVICE 0x01
#define USB_CONFIGURATION 0x02
#define USB_STRING 0x03
#define USB_INTERFACE 0x04
#define USB_ENDPOINT 0x05
/* standard feature selectors */
#define USB_ENDPOINT_STALL 0x00 /* recipient endpoint */
#define USB_DEVICE_REMOTE_WAKEUP 0x01 /* recipient device */
/* from HID Class v1.0 Draft #4
* class specific descriptor types from section 7.1 Standard R ests
***/
#define USB_HID 0x21
#define USB_REPORT 0x22
#define USB_PHYSICAL 0x23
/* class specific request codes from section 7.2 Class Specific R ests */
#define USB_GET_REPORT 0x01
#define USB_GET_IDLE 0x02
#define USB_GET_PROTOCOL 0x03
#define USB_SET_REPORT 0x09
#define USB_SET_IDLE 0x0A
#define USB_SET_PROTOCOL 0x0B
#define DISABLE_REMOTE_WAKEUP 0x00 /* bit[1] = 0 */
#define ENABLE_REMOTE_WAKEUP 0x02 /* bit[1] = 1 */
/* Debounce FIFO
* Size of debounce fifo depends on debounce time of switch
* Each debounce fifo location is updated on a 12 ms interval. This
* example uses 4 bytes for the fifo, making a 48 ms switch debounce time.
***/
#define DEB_LO_ADDR 0x00 /* start of fifo offset */
#define DEB_HI_ADDR 0x06 /* end of fifo + 1 offset for overflow test */
/* Task Scheduler (in One Millisecond interrupt routine) */
#define SCAN_TIME 0x03 /* scan time test value */
#define DEB_TIME 0x0C /* debounce time test value (12 ms) */
#define SCAN_TASK 0x01 /* task 1 is scan keyboard */
#define NO_TASK 0x00 /* task 0 is idle */
#define CONFIGURED 0x01 /* configuration status values */
#define UNCONFIGURED 0x00
#define BOOT_PROTOCOL 0x00 /* protocol status values */
#define REPORT_PROTOCOL 0x01
#define DEBOUNCE_RELEASE_TIME 0x01 /* set debounce time for 1*4ms= 4ms */
#define DEBOUNCE_PRESS_TIME 0x03 /* set debounce time for 3*4ms= 12ms */
#define COUNT_MASK 0x0F /* count[3:0] bits */
#define DATAVALID 0x40 /* data valid (OUT and SETUP) */
#define DATATOGGLE 0x80 /* Data 0/1 bit */
#define NORMAL PORT0_OPEN_IFALL | PORT1_OPEN_IFALL | PORT2_RESISTIVE | PORT3_OPEN_IFALL
#define P3_KEY_MASK 0xF0 /* bits[7:4] */
#define P3_LED_MASK 0x0F /* bits[3:0] */
#define NUM_LOCK_LED 0x01 /* bit[0] */
#define CAPS_LOCK_LED 0x02 /* bit[1] */
#define SCROLL_LOCK_LED 0x04 /* bit[2] */
#define ADDRESS_MASK 0x7F /* 7 bits of device address */
#define ADDRESS_ENABLE_BIT 0x80 /* enable the device address */
#define MOD_LEFT_CTRL 0xE0
#define MOD_LEFT_SFT 0xE1
#define MOD_LEFT_ALT 0xE2
#define MOD_LEFT_GUI 0xE3
#define MOD_RIGHT_CTRL 0xE4
#define MOD_RIGHT_SFT 0xE5
#define MOD_RIGHT_ALT 0xE6
#define MOD_RIGHT_GUI 0xE7
void start_scan(void);
void debounce_keys(unsigned int key);
void debounce_task(void);
void scan_task(void);
void find_key(unsigned int x_index,unsigned int column_loop);
void next_pattern(void);
void send_error_report(void);
void send_keyboard_report(void);
void prepare_error_code(void);
void copy_report_buffer_to_EP1(void);
void enable_EP1_transmission(void);
void USB_init(void);
void USB_no_data_control(void);
void USB_control_read(void);
void USB_control_write(void);
void USB_send_buffer(void);
void USB_set_ep0_mode(char);
void USB_stage_one(void);
void USB_send_stall(void);
void delay_loop(char);
/* Variables to support the USB specification. */
char remote_wakeup_status; /* remote wakeup request */
/* zero is disabled */
/* two is enabled */
char configuration_status; /* configuration status */
/* zero is unconfigured */
/* one is configured */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -