📄 keyboard.c
字号:
else
{
/* other tasks */
}
}
}
}
void delay_loop (registera time) /* delay for A units */
{
while(--time);
}
void get_key(void)
{
unsigned int column_loop=20;
unsigned int x_index=0;
do
{
delay_loop(0x20);
changes = ~PORT2; /* save the port 2 data */
delay_loop(0x20);
changes = changes & ~PORT2;
changes ^= image[column_loop - 1];
if(changes != 0)
find_key(x_index,column_loop);
CC.C = 1;
AC = PORT0_S;
RLC();
PORT_WRITE(PORT0,AC);
/* load c[15:8] data */
/* rotate left */
AC = PORT1_S; /* update memory copy */
RLC();
PORT_WRITE(PORT1,AC);
AC = PORT3_S;
if (CC.C == 1)
AC |= 0x08;
else
AC &= 0xF7;
RLC();
AC &= P3_KEY_MASK;
PUSHA();
PORT_WRITE(PORT3,PORT3_S & P3_LED_MASK);
POPA();
AC |= PORT3_S;
PORT_WRITE(PORT3,AC);
x_index++;
}
while(--column_loop);
}
void scan_task(void)
{
phantom_key_flag = 0;
PORT_WRITE(PORT0,0b11111110); /* write ones to c[7:1] */
PORT_WRITE(PORT1,0xff); /* write all ones to c[15:8] */
PORT_WRITE(PORT3,PORT3_S|P3_KEY_MASK);
get_key();
if( kb_error_sent != 0 )
{
if( (phantom_key_flag == 0) && (key_count < 7) && (tx_required != 0) )
send_keyboard_report();
else
{
if( (idle_period != 0) && ( idle_period_counter > idle_period ) )
{
if( new_idle_flag != 0 )
{
idle_period = new_idle_period;
new_idle_flag = 0;
}
if( kb_error_sent == 0 )
send_keyboard_report();
else
send_error_report();
}
}
}
else
{
if( (phantom_key_flag != 0) && (key_count < 7) )
{
kb_error_sent=0;
tx_required = 0xFF;
}
send_error_report();
}
task = NO_TASK;
}
/* We have a key identified by an x_index and a y_index. Combine the two
* into a single index and lookup the keycode, check if up or down change.
***/
void find_key(unsigned int x_index,unsigned int column_loop)
{
unsigned int matrix_addr;
unsigned int y_index = 0;
unsigned int row = 1;
do
{
if( (changes&row) != 0)
{
if( (row&image[column_loop-1]) != 0 )
down_up = 0; /* clear flag */
else
{
down_up = 0xFF; /* key went down set flag */
IX=20;
do
{
if((IX==column_loop) && (row&image[IX-1]) && ((~row)&image[IX-1]))
{
phantom_key_flag = 1;
return;
}
}
while(--IX != 0 );
}
AC = (x_index << 3); /* multiply by eight */
AC += y_index; /* add in the row index */
IX = DEB_HI_ADDR;
do
if( dbfifo[IX-1] == AC )
return;
while(--IX);
matrix_addr = AC;
image[column_loop-1] ^= row;
debounce_keys(matrix_addr);
matrix_addr = keycode_table[matrix_addr];
switch(matrix_addr)
{
case MOD_LEFT_CTRL .. MOD_RIGHT_GUI :
AC=(1<<(matrix_addr-MOD_LEFT_CTRL));
break;
default:
tx_required = 0xFF;
if (down_up == 0)
{
if (key_count != 0)
key_count--;
IX = 2;
do
{
if( matrix_addr == report_buffer[IX] )
{
report_buffer[IX] = 0;
break;
}
}
while( ++IX < 8);
}
else
{
if (key_count != 0xFF)
key_count++;
IX = 2;
do
{
if(report_buffer[IX] == 0)
break;
}
while(++IX<8);
report_buffer[IX]=matrix_addr;
}
return;
}
matrix_addr=AC;
if( down_up == 0 )
{
report_buffer[0] &= ~matrix_addr;
}
else
report_buffer[0] |= matrix_addr;
tx_required = 0xFF; /* depending on if key went */
}
++y_index;
}
while( row <<= 1 );
}
void debounce_keys(unsigned int key)
{
IX = DEB_HI_ADDR; /* point to the last location id the array */
do
{
AC=dbfifo[IX-1];
if ( AC == 0xFF)
{
dbfifo[IX-1] = key; /* store the key in the array */
if (down_up != 0) /* check if key went up or down */
db_ca[IX -1] = DEBOUNCE_PRESS_TIME; /* key press debounce is loaded */
else
{
AC = DEBOUNCE_RELEASE_TIME; /* the time constant for key release debounce */
db_ca[IX-1] = AC; /* is loaded */
}
break;
}
}
while(--IX != 0);
}
/* debounce_task function declaration- M(August 12, 1998)-4
* Decrement the time constant in the counter ARRAY
***/
void debounce_task (void)
{
registerx index;
index = DEB_HI_ADDR-1;
do
{
if( dbfifo[index] != 0xFF )
{
db_ca[index]=db_ca[index]-1;
if(db_ca[index] == 0)
dbfifo[index]=0xff;
}
}
while(--index);
}
void send_keyboard_report (void)
{
if ((EP_A1_MODE & USB_MODE_MASK) != USB_MODE_ACK_IN )
{
copy_report_buffer_to_EP1();
enable_EP1_transmission();
idle_period_counter = 0;
tx_required = 0;
}
}
void send_error_report (void)
{
if ((EP_A1_MODE & USB_MODE_MASK) != USB_MODE_ACK_IN )
{
prepare_error_code();
enable_EP1_transmission();
idle_period_counter = 0;
tx_required = 0;
kb_error_sent = 1;
}
}
void copy_report_buffer_to_EP1 (void)
{
IX =7;
do
ENDPOINT_A1_FIFO[IX] = report_buffer[IX];
while(IX-- != 0 );
}
void prepare_error_code (void)
{
tx_required = 0xFF;
IX = 7;
do
ENDPOINT_A1_FIFO[IX] = error_code_buffer[IX];
while(IX-- != 0);
}
void enable_EP1_transmission (void)
{
EP_A1_COUNTER = (EP_A1_COUNTER & DATATOGGLE) | 0x08;
EP_A1_MODE = USB_MODE_ACK_IN;
}
/* function: USB_set_ep0_mode
* purpose: Writes the mode stored in the accumulator into the EPO
* mode register. Takes care of unlocking the register
***/
void USB_set_ep0_mode (ep0mode)
{
do
{
EP_A0_MODE = ep0mode;
if(EP_A0_MODE == ep0mode)
return;
}
while( ( AC & (1<<SETUP_RECEIVED) )==0 );
premature_setup=1;
}
/* function: USB_no_data_control
* purpose: performs the no-data control operation
* as defined by the USB specifications
***/
void USB_no_data_control(void)
{
USB_set_ep0_mode(USB_MODE_STATUS_ONLY);
if (premature_setup == 0)
{
do
{
if( EP_A0_MODE.SETUP_RECEIVED )
{
premature_setup = 1;
return;
}
}
while( !EP_A0_MODE.ACKNOWLEDGE );
USB_set_ep0_mode(USB_MODE_IGNORE_IN_OUT); /* accept setup */
}
}
/* function: USB_control_write
* purpose: peform the control_write operation
* as defined by the USB specification for 1 OUT byte:
* SETUP - OUT - IN
* this routine does not acknowledge the Status IN packet from the host.
* The USB_no_data_control routine will do this.
* data_ok is set to 1 (true) if valid data is received,
* otherwise it is set to 0 (false)
* premature_setup is set to 1 (true) if a SETUP is received during
* the routine, otherwise it is set to 0 (false)
***/
void USB_control_write(void)
{
USB_set_ep0_mode(USB_MODE_ACK_OUT_STATUS_IN);
if(!premature_setup)
{
while( !EP_A0_MODE.OUT_RECEIVED )
{
if( EP_A0_MODE.SETUP_RECEIVED )
{
premature_setup = 1;
return;
}
}
if( !(EP_A0_COUNTER&DATAVALID) ) /* DATAVALID */
goto USB_control_write;
if( (EP_A0_COUNTER&COUNT_MASK)!=0x03 )
{
data_ok = 0;
USB_send_stall();
return;
}
USB_set_ep0_mode(USB_MODE_NAK_IN_OUT);
if( premature_setup )
return;
do
{
if( EP_A0_MODE.OUT_RECEIVED )
goto USB_control_write;
if( EP_A0_MODE.IN_RECEIVED )
{
data_ok = 1;
return;
}
}
while( !EP_A0_MODE.SETUP_RECEIVED );
premature_setup = 1;
return;
}
}
/* This subroutine copies 8 bytes of ROM data from ROM into the endpoint
* zero fifo.
***/
void USB_send_buffer(void)
{
USB_set_ep0_mode(USB_MODE_NAK_IN_OUT);
if(premature_setup == 0)
{
PUSHX();
byte_count = 0;
while((data_count!=0) && (byte_count < 8))
{
data_count--;
ENDPOINT_A0_FIFO[byte_count++] = *USB_send_buffer_ptr;
USB_send_buffer_ptr++;
}
POPX();
}
}
void USB_control_read(void)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -