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

📄 keyboard.c

📁 Cypress公司Cy7c6xxxx芯片的USB键盘及USB鼠标的firmware代码以及一些example代码。
💻 C
📖 第 1 页 / 共 4 页
字号:

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 + -