📄 keyboard.c
字号:
char endpoint_stall_status; /* zero is not stalled */
/* one is stalled */
char protocol_status; /* zero is boot protocol */
/* one is report protocol */
char far * USB_send_buffer_ptr;
char idle_period;
char prev_idle_period;
char new_idle_period;
char new_idle_flag;
char idle_period_counter;
char four_ms_counter;
char suspend_counter;
/* support the scan matrix */
char data_start;
char data_count;
char byte_count;
char wakeup_counter; /* used to count 10ms wakeup signal */
char wakeup_flag; /* indicates wakeup is in process */
/* application support */
char task; /* # of task to be executed by main. */
/* scheduled by 1 ms timer */
char schedule; /* task schedule counter */
char tx_required; /* indicates a key(s) changed state */
/* therefore a report is required */
/* current keyswitch state in RAM is 46h to 66h (20 columns) */
char image[20];
char changes; /* keypress changes in a column */
char data_ok; /* flag to indicate validity of received data */
char down_up; /* 0x00: key went up, FFh: key went down */
char premature_setup;
char dbfifo[DEB_HI_ADDR]; /* debounce FIFO */
char db_ca[DEB_HI_ADDR];
char report_buffer[8]; /* duplicate input report buffer */
/* last_mod */
/* reserved_byte */
/* last_key1 */
/* last_key2 */
/* last_key3 */
/* last_key4 */
/* last_key5 */
/* last_key6 */
char error_code_buffer[8];
/* error_mod */
/* error_reserved */
/* error_key1 */
/* error_key2 */
/* error_key3 */
/* error_key4 */
/* error_key5 */
/* error_key6 */
char phantom_key_flag; /* flag indicates phantom key situation */
char key_count; /* indicates number of keys pressed */
char kb_error_sent; /* indicates keyboard error sent */
char temp;
char last_mod;
char ep0mode;
unsigned int bit_mask;
#pragma vector RESERVED @ 0x000e;
#pragma vector RESERVED @ 0x0010;
#pragma vector RESERVED @ 0x0012;
#pragma vector RESERVED @ 0x0018;
void RESERVED(void) {}
void MICROSECONDx128_ISR(void)
{
// HALT();
}
void USB_EP2_ISR(void)
{
// HALT();
}
void DAC_ISR(void)
{
// HALT();
}
/* When the part detects a single-ended zero from the upstream port,
* an interrupt occurs that wakes up the CPU from suspend mode and
* transfers control to this interrupt service routine.
*
* clears watchdog timer
* clears USB device address register
*
* The USB Bus Reset interrupt service routine prepares for enumeration.
***/
void USB_BUS_RESET_ISR(void)
{
PUSHA();
PUSHX();
RESET_COP();
PROCESSOR_STATUS.USB_RESET = 0;
GLOBAL_INTERRUPT = MILLISECOND_ENABLE | USB_RESET_ENABLE;
ENDPOINT_INTERRUPT = EPA0_ENABLE; /* enable Endpoint 0 interrupt */
AC = EP_A0_MODE;
EP_A0_MODE = USB_MODE_IGNORE_IN_OUT; /* accept setup */
USB_DEVICE_A=(1<<DEVICE_ADDRESS_ENABLE);
EP_A1_MODE = USB_MODE_DISABLE;
RESET_COP();
USB_init();
RESET_COP();
POPX();
POPA();
}
/* The 1 msec interrupt is used to clear the watchdog timer.
* It implements Suspend / Resume and enables GPIO interrupts
* to support Remote Wakeup.
* It is also responsible for scheduling the Scan Task and updating the
* Debounce FIFO.
***/
void MILLISECOND_ISR(void)
{
PUSHA();
RESET_COP();
if( wakeup_flag == 0x01 )
wakeup_counter++;
else
{
if( --four_ms_counter == 0 )
{
four_ms_counter=4;
if( idle_period_counter != 0xFF)
idle_period_counter++;
}
if( USB_STATUS.BUS_ACTIVITY )
{
USB_STATUS.BUS_ACTIVITY = 0;
suspend_counter = 0;
}
else
{
if(++suspend_counter==0x03)
{
suspend_counter = 0;
GPIO_CONFIG = PORTS_RESISTIVE;
PORT1 = PORT0 = 0;
PORT3 = AC | P3_LED_MASK;
if( remote_wakeup_status == ENABLE_REMOTE_WAKEUP)
{
GLOBAL_INTERRUPT = GPIO_ENABLE;
EI();
if( PORT2 == 0xFF)
{
PROCESSOR_STATUS.SUSPEND = 1;
NOP(); /* execute a nop after resuming */
}
}
else
{
PROCESSOR_STATUS.SUSPEND = 1;
NOP(); /* execute a nop after resuming */
}
DI();
GPIO_CONFIG = NORMAL;
GLOBAL_INTERRUPT = MILLISECOND_ENABLE | USB_RESET_ENABLE;
PORT0 = PORT0_S;
PORT1 = PORT1_S;
PORT3 = PORT3_S;
}
}
if( (++schedule&SCAN_TIME) == 0 && (task == NO_TASK) )
task = SCAN_TASK;
}
POPA();
}
void USB_EP0_ISR(void)
{
PUSHA();
PUSHX();
if ( EP_A0_MODE.SETUP_RECEIVED )
{
if ( ((EP_A0_COUNTER & DATAVALID) == 0) ||
((EP_A0_COUNTER & COUNT_MASK) != 0x0A) ||
((EP_A0_COUNTER & DATATOGGLE) != 0)
)
USB_send_stall();
else
{
AC=EP_A0_MODE;
do
EP_A0_MODE = USB_MODE_NAK_IN_OUT;
while(EP_A0_MODE != USB_MODE_NAK_IN_OUT);
ENDPOINT_INTERRUPT &= ~EPA0_ENABLE;
EI();
USB_stage_one();
if( premature_setup != 0 )
premature_setup = 0;
DI();
ENDPOINT_INTERRUPT |= EPA0_ENABLE;
}
}
POPX();
POPA();
}
/* Endpoint one is used to send keyboard data to the host. This interrupt
* occurs if the USB serial interface engine has transferred a packet
* to the host (including NAKs).
*
* This routine disables another transfer until valid data has been loaded
* into the endpoint. This routine is also responsible for toggling the
* data 0/1 bit for endpoint one after every successful transfer.
***/
void USB_EP1_ISR(void)
{
PUSHA(); /* save accumulator on stack */
if ( EP_A1_MODE.ACKNOWLEDGE )
{
EP_A1_MODE = USB_MODE_NAK_IN;
EP_A1_COUNTER ^= DATATOGGLE;
PUSHX();
IX = 8;
AC = 0;
do
ENDPOINT_A1_FIFO[IX-1] = AC;
while(--IX);
POPX();
}
POPA();
}
/* The GPIO interrupt is used to send the remote wakeup signal to the
* host after we suspended the microcontroller
***/
void GPIO_ISR(void)
{
PUSHA();
RESET_COP();
if(PORT2 != 0xFF)
{
if( !USB_STATUS.BUS_ACTIVITY )
{
wakeup_flag = 1;
wakeup_counter = 0;
GLOBAL_INTERRUPT = MILLISECOND_ENABLE;
EI();
while(wakeup_counter < 0x05);
DI();
wakeup_flag = 0;
if( !USB_STATUS.BUS_ACTIVITY )
{
wakeup_flag = 1;
wakeup_counter = 0;
USB_STATUS = FORCE_J;
NOP();
USB_STATUS = FORCE_K;
GLOBAL_INTERRUPT = MILLISECOND_ENABLE;
EI();
while(wakeup_counter < 0x0A);
DI();
USB_STATUS = NOT_FORCING;
wakeup_flag = 0;
}
}
GLOBAL_INTERRUPT = DISABLE_INTERRUPTS;
}
USB_STATUS.BUS_ACTIVITY = 0;
POPA();
}
void __STARTUP (void)
{
RESET_COP(); /* clear Watchdog timer */
configuration_status = UNCONFIGURED;
if( PROCESSOR_STATUS.POWERON_RESET )
PROCESSOR_STATUS.POWERON_RESET = 0;
if( PROCESSOR_STATUS.WATCHDOG_RESET )
PROCESSOR_STATUS.WATCHDOG_RESET = 0;
GLOBAL_INTERRUPT = USB_RESET_ENABLE;
EI();
}
void USB_init (void)
{
GPIO_CONFIG = NORMAL;
PORT2=0xff;
PORT_WRITE(PORT0,0xff);
PORT_WRITE(PORT1,0xff);
PORT_WRITE(PORT3,0xf0);
PORT2IE = 0xFF; /* enable port interrupts */
PORT3IE = PORT1IE = PORT0IE = 0; /* disable port interrupts */
remote_wakeup_status = ENABLE_REMOTE_WAKEUP;
configuration_status = UNCONFIGURED;
protocol_status = REPORT_PROTOCOL;
endpoint_stall_status = 0;
suspend_counter=0;
wakeup_flag = 0;
wakeup_counter = 0;
task = 0;
schedule = 0;
tx_required = 0;
down_up = 0;
premature_setup = 0;
data_ok = 0;
idle_period = 0;
new_idle_period = 0;
prev_idle_period = 0;
new_idle_flag = 0;
idle_period_counter = 0;
phantom_key_flag = 0;
key_count = 0;
kb_error_sent = 0;
ep0mode = 0;
four_ms_counter = 4;
IX = DEB_HI_ADDR;
do
{
dbfifo[IX-1] = 0xff;
db_ca[IX-1] = 0;
}
while(--IX);
IX = 20;
do
image[IX -1] = 0;
while(--IX);
IX = 8;
do
{
/* clear out duplicate report buffer */
report_buffer[IX-1]=0;
ENDPOINT_A1_FIFO[IX-1] = 0;
error_code_buffer[IX-1]=1;
}
while(--IX);
error_code_buffer[0]=0;
error_code_buffer[1]=0;
}
void main(void)
{
while(1)
{
do
RESET_COP();
while(configuration_status == UNCONFIGURED);
if(task != NO_TASK)
{
if(task == SCAN_TASK)
{
debounce_task();
scan_task();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -