//-------------- // funnykbd.c // // The original is "ezcombo.c". // changed by ENDO.Taichi 2006-APL //--------------// #pragma NOIV // Do not generate interrupt vectors //----------------------------------------------------------------------------- // File: periph.c // Contents: Hooks required to implement USB peripheral function. // // Copyright (c) 2001 Cypress Semiconductor, Inc. All rights reserved //----------------------------------------------------------------------------- //#define ALLOCATE_EXTERN #include #include #define min(a,b) (((a)<(b))?(a):(b)) #define GD_HID 0x21 #define GD_REPORT 0x22 #define CR_SET_REPORT 0x09 #define GD_IF0 0x00 #define GD_IF1 0x01 #define HID_OUTPUT_REPORT 2 #define BTN_ADDR 0x41 extern BOOL GotSUD; // Received setup data flag extern BOOL Sleep; WORD pHID1Dscr; WORD pHID1ReportDscr; WORD pHID1ReportDscrEnd; extern code HID1Dscr; extern code HID1ReportDscr; extern code HID1ReportDscrEnd; WORD pHID2Dscr; WORD pHID2ReportDscr; WORD pHID2ReportDscrEnd; extern code HID2Dscr; extern code HID2ReportDscr; extern code HID2ReportDscrEnd; void TD_Poll(void); BYTE Configuration; // Current configuration BYTE AlternateSetting; // Alternate settings BYTE HID1buttons; BYTE HID1oldbuttons; BYTE HID2buttons; BYTE HID2oldbuttons; BYTE read_buttons (void); //----------------------------------------------------------------------------- // Task Dispatcher hooks // The following hooks are called by the task dispatcher. //----------------------------------------------------------------------------- void TD_Init(void) // Called once at startup { // Enable endpoint 2 IN and endpoint 1 IN IN07VAL |= bmEP1 | bmEP2; // Validate all EP's // Setup breakpoint to trigger on TD_Poll() BPADDR = (WORD)TD_Poll; USBBAV |= bmBPEN; // Enable the breakpoint USBBAV &= ~bmBPPULSE; } BYTE read_buttons (void) { BYTE d; while (I2CS & 0x40); //Wait for stop to be done I2CS = 0x80; //Set start condition I2DAT = BTN_ADDR; //Write button address while (!(I2CS & 0x01)); //Wait for done I2CS = 0x20; //Set last read d = I2DAT; //Dummy read while (!(I2CS & 0x01)); //Wait for done I2CS = 0x40; //Set stop bit return(I2DAT); //Read the data } void TD_Poll(void) // Called repeatedly while the device is idle { if( !(EPIO[IN2BUF_ID].cntrl & bmEPBUSY) ) // Is the IN2BUF available, { HID1buttons = read_buttons(); if (HID1buttons == read_buttons()) // Debounce { HID1buttons &= 0x0F; IN2BUF[0] = 0x00; // clear button state as seen by the host if ((HID1oldbuttons - HID1buttons) != 0) //Change in button state { if ( !(HID1buttons & 1) ) // left click { IN2BUF[0] |= 0x01; } if ( !(HID1buttons & 2) ) // right click { IN2BUF[0] |= 0x02; } IN2BUF[1] = 0x00; IN2BUF[2] = 0x00; IN2BC = 3; } HID1oldbuttons = HID1buttons; } } if( !(EPIO[IN1BUF_ID].cntrl & bmEPBUSY) ) // Is the IN1BUF available, { HID2buttons = read_buttons(); if (HID2buttons == read_buttons()) //Debounce { HID2buttons &= 0x0F; if ((HID2oldbuttons - HID2buttons) != 0) //Change in button state { if (HID2buttons & 4) // b IN1BUF[3] = 0x00; else IN1BUF[3] = 0x05; if (HID2buttons & 8) // c IN1BUF[4] = 0x00; else IN1BUF[4] = 0x06; IN1BUF[0] = 0x00; IN1BUF[1] = 0x00; IN1BUF[2] = 0x00; IN1BC = 5; } HID2oldbuttons = HID2buttons; } } } BOOL TD_Suspend(void) // Called before the device goes into suspend mode { // Turn off breakpoint light before entering suspend USBBAV |= bmBREAK; // Clear the breakpoint return(TRUE); } BOOL TD_Resume(void) // Called after the device resumes { return(TRUE); } //----------------------------------------------------------------------------- // Device Request hooks // The following hooks are called by the end point 0 device request parser. //----------------------------------------------------------------------------- BOOL DR_ClassRequest(void) { return(TRUE); } BOOL DR_GetDescriptor(void) { BYTE HID1length,i; BYTE HID2length,j; pHID1Dscr = (WORD)&HID1Dscr; pHID1ReportDscr = (WORD)&HID1ReportDscr; pHID1ReportDscrEnd = (WORD)&HID1ReportDscrEnd; pHID2Dscr = (WORD)&HID2Dscr; pHID2ReportDscr = (WORD)&HID2ReportDscr; pHID2ReportDscrEnd = (WORD)&HID2ReportDscrEnd; switch (SETUPDAT[3]) { case GD_HID: //HID Descriptor switch (SETUPDAT[4]) { case GD_IF0: SUDPTRH = MSB(pHID1Dscr); SUDPTRL = LSB(pHID1Dscr); break; case GD_IF1: SUDPTRH = MSB(pHID2Dscr); SUDPTRL = LSB(pHID2Dscr); break; default: EZUSB_STALL_EP0(); } return (FALSE); break; case GD_REPORT: //Report Descriptor switch (SETUPDAT[4]) { case GD_IF0: HID1length = pHID1ReportDscrEnd - pHID1ReportDscr; while (HID1length) { for(i=0; i