⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 keyboard.c

📁 Cypress公司Cy7c6xxxx芯片的USB键盘及USB鼠标的firmware代码以及一些example代码。
💻 C
📖 第 1 页 / 共 4 页
字号:
            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 + -