Difference Analysis Generated by HtmlDiff on 10/26/2004 1:34 PM  

Base file: C:\CY4632_RDK_1_21\Firmware\Source Code\RDK Bridge\rdk_keyboard.asm

Modified file: C:\CY4632_RDK_1_3\Firmware\Source Code\RDK Bridge\rdk_keyboard.asm

;****************************************************************************
;
;   file:   rdk_keyboard.asm
;   Description: This file contains Keyboard application functionality
;   External Functions:
;                   app_data_received_a
;                   app_idle
;
;   Target:  Cypress CY7C63723 Encore Chip
;   $Header: /WirelessUSB/WUSB Kits/CY4632 LS KBM RDK/DocSrc/CD_Root/Firmware/Source Code/RDK Bridge/rdk_keyboard.asm 12    7/02/04 3:42p13    10/01/04 2:52p Ary $
;   Version:        1.3.0000
;
;****************************************************************************
; Copyright (2003), Cypress Semiconductor Corporation
; This software is owned by Cypress Semiconductor Corporation (Cypress) and  is
; protected by United States copyright laws and international treaty provisions.
; Cypress hereby grants to Licensee a personal, non-exclusive, non-transferable
; license to copy, use, modify, create derivative works of, and compile the
; Cypress Source Code and derivative works for the sole purpose of creating
; custom software in support of Licensee product ("Licensee Product") to be used
; only in conjunction with a Cypress integrated circuit. Any reproduction,
; modification, translation, compilation, or representation of this software
; except as specified above is prohibited without the express written permission
; of Cypress.
; Disclaimer: Cypress makes no warranty of any kind, express or implied, with
; regard to this material, including, but not limited to, the implied warranties
; of merchantability and fitness for a particular purpose. Cypress reserves the
; right to make changes without further notice to the materials described herein.
; Cypress does not assume any liability arising out of the application or use of
; any product or circuit described herein. Cypress’ products described herein are
; not authorized for use as components in life-support devices.
; This software is protected by and subject to worldwide patent coverage,
; including U.S. and foreign patents. Use may be limited by and subject to the
; Cypress Software License Agreement.
;
;****************************************************************************

;****************************************************************************
; Global Variables AND  Frameworks Related Variables
;****************************************************************************
null_packet_data:       equ C0h
byte_len_report:        equ C1h
kb_offset:              equ C2h
kb_temp:                equ C4h
upkey_timer_a:          equ C6h

STD_KEY_STATE:          equ 01h   ; bit position defs for key_down_state
MM_KEY_STATE:           equ 02h
PWR_KEY_STATE:          equ 04h
key_down_state:         equ C7h

UP_KEY_TIMEOUT:         equ 04h
APP_IDLE_TIMEOUT:       equ 30h

IFDEF ENCRYPT_DATA_A
DEFINE ENCRYPT_FILLER
ENDIF ; ENCRYPT_DATA_A
 
;****************************************************************************
; app_data_received_a
; Input:
; X Reg = byte_len_report = Byte length of input report (-2 for hdr, chksum)
; A Reg = null_packet_data = additional info
;         0x00 => UpKey (up_key_standard only)
;         0x02 => KeepAlive
; Keyboard Report bytes in rx_buffer[], app_buffer[]
;
; Background:
; rx_buffer[] contains the input bytes from the radio including the header.
; app_buffer[] points to the first data byte.
; app_buffer is currently 1 byte offset from rx_buffer to skip the 1 byte
; header, but app_buffer[] should be used to allow changes in the length
; of the header (i.e. to allow it to use A two byte header).
;
; Note: hdr=HeaderByte sc=ScanCode  mod=modifier chk=checksum res=reserved
;       ReptType = report type, consumer_keys = Multimedia Keys
;
; Input Examples: (character "A" = "0x04", see Hid Usage Tables)
; rx_buffer[]= 40 04 ; "A"
;     app_buffer[]= 04 ; "A"
;
; More app_buffer examples:
;  ReptType/sc1 ; Scan Code 1 OR   RptType consumer_keys=0xFF power_keys=0xFE
;  |  mod       ; Modifier keys (in StandardKeys reports only)
;  |  |  sc2    ; Scan Code 2 ...
;  |  |  |
; 04            ; "A"
; 04 20         ; "<RightShift>A"
; 04 00 20      ; "A" AND  "3"
; 04 20 20      ; "<RightShift>" AND  "A" AND  "3"
; FF 00 E2      ; consumer_keys "<mute>"
; FE 82         ; power_keys "<sleep>"
; 04 20 05 06 07 08    ; "A" "B" "C" "D" "E"
;
; Note that the second byte, if present is the modifier keys, AND  it always
; gets sent when there is more than A single key in the packet (even if there
; are no modifier keys pressed AND  the value is zero).
; This is based on the assumption that the most common report will contain
; A single key press AND  no modifiers.
; Note that not more than 5 data bytes + modifier should be sent over the air
; since the 6th will not make it to the PC (1 byte is displaced by Report ID)
;
; Processing:
; Forms the USB report (swap modifier, ADD  res byte, ReportID)
; AND  sends data to USB.
;
; Upkey detection - certain values identify Upkeys (don't use header byte)
; if (byte_len_report == 0) AND  (null_packet_data == 0) then up_key_standard
; if (byte_len_report == 1) AND  (RptType == 0xFF) then UpKeyconsumer_keys
; if (byte_len_report == 1) AND  (RptType == 0xFE) then UpKeypower_keys
;
; ReportTypebattery_voltage -
; if (byte_len_report == 2) AND  (RptType == 0xFD) then ReportTypebattery_voltage
;
; So A sequence would be:
; byte_len_report null_packet_data    app_buffer:
;          1               0     04            ; "A"
;          0               0 ; up_key_standard
;          3               0     FF 00 E2      ; consumer_keys "<mute>"
;          1               0     FF            ; UpKeyconsumer_keys
;          3               0     FE 82         ; power_keys "<sleep>"
;          1               0     FE            ; UpKeypower_keys
;
; A KeepAlive sequence would be:
;          1               0     04            ; "A"
;          0               2 ; KeepAlive
;          0               2 ; KeepAlive ...
;          0               0 ; up_key_standard
;
; Output:
; Sends USB packet out EP1.
; ep1_dmabuff = data to USB
;
; Output Examples:
; RptId mod res key
;    01  00  00  04  00 00 00 00  ; "A"
;    01  00  00  00  00 00 00 00  ; up_key_standard
;    01  00  00  59  00 00 00 00  ; "1" (keypad 1)
;    01  00  00  00  00 00 00 00  ; up_key_standard     
;    01  00  00  16  5B 00 00 00  ; "s" AND  "3"
;    01  00  00  00  00 00 00 00  ; up_key_standard
;    01  20  00  04  05 06 07 08  ; "<RightShift>" AND  "A" "B" "C" "D" "E"
;    01  00  00  00  00 00 00 00  ; up_key_standard
;    02  E2 00  ; consumer_keys "<mute>"
;    02  00 00  ; UpKeyconsumer_keys
;    03  82     ; power_keys "<sleep>"
;    03  00     ; UpKeypower_keys
;
;****************************************************************************
app_init_a:
    MOV  A, 00h
    MOV  [battery_a],A
    MOV  [key_down_state],A

    MOV  A, 01h                    ; At startup, request the battery level
    MOV  [batt_report_req_a],A
    RET

app_data_received_a:
    DI                              ; Disable USB Interrupts

    MOV   [null_packet_data],A       ; null_packet_data = AC;
    SWAP  A,X                       ; byte_len_report = IX;
    MOV   [byte_len_report],A     
    SWAP  A,X        
    
    MOV   A,UP_KEY_TIMEOUT          ; Set upkey_timer_a
    MOV   [upkey_timer_a],A     

    MOV   A, [byte_len_report]          ; skip decryption of the packet if it's a NULL packet
    CMP   A, 08h
    JNZ    wait_ep1_clear

IFDEF ENCRYPT_DATA_A
    CALL decrypt_packet
    CALL remove_filler    
    CMP  A, 0
    JZ   ep1_send_end
    MOV  [byte_len_report], A
ENDIF ; ENCRYPT_DATA_A

wait_ep1_clear:                     ; do
    IOWR watchdog                  ; WATCHDOG = AC;
    IORD ep1_mode                   ; If still waiting for USB to ACK last data, fail
    AND  A, 0Fh     
    CMP  A, ACK_IN
    JZ   ep1_send_end                  
                  
init_ep1_out:
    MOV  A,00h                     ; ep1_dmabuff[0] = 0x00;
    MOV  [ep1_dmabuff],A     
    MOV  [ep1_dmabuff+1],A         ; ep1_dmabuff[1] = 0x00;
    MOV  [ep1_dmabuff+2],A         ; ep1_dmabuff[2] = 0x00;
    MOV  [ep1_dmabuff+3],A         ; ep1_dmabuff[3] = 0x00;
    MOV  [ep1_dmabuff+4],A         ; ep1_dmabuff[4] = 0x00;
    MOV  [ep1_dmabuff+5],A         ; ep1_dmabuff[5] = 0x00;
    MOV  [ep1_dmabuff+6],A         ; ep1_dmabuff[6] = 0x00;
    MOV  [ep1_dmabuff+7],A         ; ep1_dmabuff[7] = 0x00;
                  
    MOV  A,[byte_len_report]       ; Check report length
    CMP  A,00h
    JZ   up_key_standard_null

    MOV  A,[app_buffer+0]          ; Check for Multimedia report
    CMP  A,FFh
    JZ   consumer_report

    CMP  A,FEh                     ; Check for Power report
    JZ   power_report

    CMP  A,FDh                     ; Check for Battery report
    JZ   battery_report

    CMP  A,FCh                     ; Check for Keep Alive report
    JZ   ep1_send_end

    CMP  A,00h                     ; Must be Standard 101 key report
    JZ   up_key_standard           ; Check for Standard up key
    MOV  A,STD_KEY_STATE
    OR   [key_down_state],A        ; Must be Standard down key so set appropriate bit
    JMP  standard_keys

up_key_standard_null:
    MOV  A,00h
    MOV  [app_buffer+0],A          ; app_buffer[0] = 0x00;
    INC  A                         ; byte_len_report=1;  ; generate upkey
    MOV  [byte_len_report],A     

up_key_standard:
    MOV  A,~STD_KEY_STATE
    AND  [key_down_state],A        ; Clear appropriate bit
    JMP  standard_keys

consumer_report:
    MOV  A,[pc_has_desc]
    CMP  A,00h
    JZ   ep1_send_end
    MOV  A,[byte_len_report]       ; Check for Multimedia up key
    CMP  A,01h
    JZ   up_key_consumer
    MOV  A,MM_KEY_STATE
    OR   [key_down_state],A        ; Must be Multimedia down key so set appropriate bit
    JMP  consumer_keys

up_key_consumer:
    MOV  A,~MM_KEY_STATE
    AND  [key_down_state],A        ; Clear appropriate bit
    MOV  A,00h                     ; app_buffer[1] = 0x00;
    MOV  [app_buffer+1],A     
    MOV  [app_buffer+2],A          ; app_buffer[2] = 0x00;

consumer_keys:
    MOV  A,02h                     ; ep1_dmabuff[0] = 0x02; ; consumer_keys Report ID
    MOV  [ep1_dmabuff],A     
    MOV  A,[app_buffer+2]          ; ep1_dmabuff[1] = app_buffer[2]; ; Lo byte
    MOV  [ep1_dmabuff+1],A     
    MOV  A,[app_buffer+1]          ; ep1_dmabuff[2] = app_buffer[1]; ; Hi byte
    MOV  [ep1_dmabuff+2],A     
    MOV  A,03h                     ; byte_len_report = 0x03; ; Report Length
    MOV  [byte_len_report],A     
    JMP  ep1_send                  ; else if(app_buffer[0] == 0xFE)

power_report:
    MOV  A,[pc_has_desc]
    CMP  A,00h
    JZ   ep1_send_end
    MOV  A,[byte_len_report]       ; Check for Multimedia up key
    CMP  A,01h
    JZ   up_key_power
    MOV  A,PWR_KEY_STATE
    OR   [key_down_state],A        ; Must be Power down key so set appropriate bit
    JMP  power_keys

up_key_power:
    MOV  A,~PWR_KEY_STATE
    AND  [key_down_state],A        ; Clear appropriate bit
    MOV  A,00h                     ; app_buffer[1] = 0x00;
    MOV  [app_buffer+1],A     

power_keys:
    MOV  A,03h                     ; ep1_dmabuff[0] = 0x03; ; power_keys Report ID
    MOV  [ep1_dmabuff],A     
    MOV  A,[app_buffer+1]          ; ep1_dmabuff[1] = app_buffer[1]; ; Lo byte
    MOV  [ep1_dmabuff+1],A     
    MOV  A,02h                     ; byte_len_report = 0x02; ; Report Length
    MOV  [byte_len_report],A     
    JMP  ep1_send                  ; else if(app_buffer[0] == 0xFD)

battery_report:
    MOV  A,[app_buffer+1]          ; ep1_dmabuff[1] = app_buffer[1] Battery Level
    AND  A, 0fh                    ; mask-off high-order nibble
    MOV  [battery_a],A             ; remember the battery level
    JMP  ep1_send_end  

standard_keys:                     ; kb_offset = (pc_has_desc && protocol); 
                                   ; use ReportID in ReportMode
set_report_id_offset:
    MOV  A,[pc_has_desc]
    CMP  A,00h       
    JZ   set_offset       
    MOV  A,[protocol]     
    CMP  A,00h       
    JZ   set_offset       
    MOV  A,01h       
set_offset:
    MOV  [kb_offset],A     
                  
    CMP  A,00h                     ; if((kb_offset) && (byte_len_report == 7)) 
    JZ   set_standard_keys_report_id                          
    MOV  A,[byte_len_report]     
    CMP  A,07h       
    JNZ  set_standard_keys_report_id       
    DEC  [byte_len_report]         ; throw away 1 key if it is displaced by report ID

set_standard_keys_report_id:
    MOV  A,[kb_offset]             ; if(kb_offset)
    CMP  A,00h                         
    JZ   place_first_byte
    MOV  A,01h                     ; ep1_dmabuff[0] = 0x01; ;  Standard Keys Report ID
    MOV  [ep1_dmabuff],A     
place_first_byte:
    MOV  A,[app_buffer+0]          ; ep1_dmabuff[kb_offset+2] = app_buffer[0]; ; place first byte
    MOV  X,[kb_offset]     
    MOV  [X+ep1_dmabuff+2],A   
                  
    MOV  A,01h                     ; if(byte_len_report>1) 
    CMP  A,[byte_len_report]                           
    JNC  ep1_send       
    MOV  X,[kb_offset]             ; ep1_dmabuff[kb_offset+0] = app_buffer[1]; ; place modifier
    MOV  A,[app_buffer+1]     
    MOV  [X+ep1_dmabuff+0],A   
                                   ; while(byte_len_report>2) 

load_loop_a:
    MOV  A,02h
    CMP  A,[byte_len_report]       ; kb_temp = app_buffer[byte_len_report-1];
    JNC  ep1_send       
    MOV  X,[byte_len_report]     
    MOV  A,[X+rx_buffer+0]   
    MOV  [kb_temp],A     
    MOV  A,[kb_offset]             ; ep1_dmabuff[kb_offset+byte_len_report] = kb_temp;
    ADD  A,[byte_len_report]     
    MOV  X,A         
    MOV  A,[kb_temp]     
    MOV  [X+ep1_dmabuff+0],A   
    DEC  [byte_len_report]         ; byte_len_report--;
    JMP  load_loop_a                              

ep1_send:
    MOV  A,[configuration]         ; if(configuration && (ep1_stall != 0xFF)) 
    CMP  A,00h       
    JZ   ep1_send_end  
                            
    MOV  A,[ep1_stall]     
    INC  A           
    JZ   ep1_send_end

    MOV  A,80h                     ; ep1_data_toggle ^= 0x80;
    XOR  [ep1_data_toggle],A     
    MOV  A,[ep1_data_toggle]       
    OR   A, 08h                    ; the report length

    IOWR ep1_count         
    MOV  A,ACK_IN                  ; EP_A1_MODE = USB_MODE_ACK_IN;
    IOWR ep1_mode

ep1_send_end:
    MOV  A,0h                      ; led_timer = 0x01; ; BLINK_BIND diag LED
    MOV  [led_timer],A     
    MOV  A,[key_down_state]        ; Clear upkey timer if no keys are down
    CMP  A,00h
    JNZ   exit_app_data_received_a
    MOV  [upkey_timer_a],A         ; upkey_timer_a = 0x00; ; Reset upkey_timer_a

exit_app_data_received_a:
    EI
    RET

;-------------------------------------------------------
;   app_verify_packet_a
;
;-------------------------------------------------------
app_verify_packet_a:
    SWAP A, X                   ; A = packet length
IFDEF ENCRYPT_DATA_A
    CMP  A, 09h                 
ELSE
    CMP  A, 07h                 
ENDIF ENCRYPT_DATA_A
    JNC  app_verify_packet_a_failed

    IORD ep1_mode               ; If still waiting for USB to ACK last data, fail
    AND  A, 0Fh     
    CMP  A, ACK_IN
    JZ   app_verify_packet_a_failed                    
    MOV  A, 1
    RET     

app_verify_packet_a_failed:
    MOV A, 0
    RET

                                    

    
;****************************************************************************
; app_idle
;
; Input:
; upkey_timer_a = Count down timer for sending UpKeyKeyboard
; upkey_timer_b = Count down timer for sending UpKeyMouse
;
; Processing:
; upkey_timer_a counts down from UP_KEY_TIMEOUT to 1
; if(upkey_timer_a == 0) timer is idle
; if(upkey_timer_a == 1) timer triggers Upkey to be sent
; if(upkey_timer_a > 1) timer is active (decrement it)
;
; Background:
; app_idle gets called ~= 50ms
; UP_KEY_TIMEOUT == 0x07 per design
; upkey_timer_a set to UP_KEY_TIMEOUT ~= 300ms Upkey timeout period
; upkey_timer_a set to UP_KEY_TIMEOUT when A DownKey is received (elsewhere)
; upkey_timer_a set to UP_KEY_TIMEOUT when A KeepAlive received (elsewhere)
; upkey_timer_a cleared when an UpKey is received (elsewhere)
;
; Output:
; Sends USB packet out EP1.
; ep1_dmabuff = Keyboard data to USB
; ep2_dmabuff = Mouse data to USB
;
; Output Example:
; RptId mod res key
;    01  00  00  00  00 00 00 00  ; up_key_standard
; Button mod res key
;     00  00  00  00  ; UpKeyMouse
;
;****************************************************************************
app_idle_a:

    MOV  A,[pc_has_desc]
    CMP  A,00h
    JNZ  if_up_key_idle

    MOV  A,[upkey_timer_a]
    CMP  A,00h
    JNZ  if_up_key_idle

    IORD ep1_mode
    AND  A, 0Fh     
    CMP  A, ACK_IN
    JZ   if_up_key_idle 

    CALL ep1_send

if_up_key_idle:
    MOV  A,[upkey_timer_a]         ; if((upkey_timer_a == 0)&&(upkey_timer_b == 0)) 
    DEC  A           
    JNC  if_up_key_timer_active       
    RET                            ; return if timers idle

if_up_key_timer_active:
    MOV  A,01h                     ; if(upkey_timer_a > 1) 
    CMP  A,[upkey_timer_a]                         
    JNC  if_up_key_timer_a_timeout       
    DEC  [upkey_timer_a]           ; upkey_timer_a--;

if_up_key_timer_a_timeout:
    MOV  A,[upkey_timer_a]         ; if(upkey_timer_a == 1) 
    DEC  A           
    JNZ  app_idle_ret       

send_up_keys:
    MOV  A,00h                     ; AC = 0x00;
    MOV  [upkey_timer_a],A         ; reset upkey_timer_a

    MOV  [ep1_dmabuff+1],A         ; ep1_dmabuff[1] = 0x00;
    MOV  [ep1_dmabuff+2],A         ; ep1_dmabuff[2] = 0x00;
    MOV  [ep1_dmabuff+3],A         ; ep1_dmabuff[3] = 0x00;
    MOV  [ep1_dmabuff+4],A         ; ep1_dmabuff[4] = 0x00;
    MOV  [ep1_dmabuff+5],A         ; ep1_dmabuff[5] = 0x00;
    MOV  [ep1_dmabuff+6],A         ; ep1_dmabuff[6] = 0x00;
    MOV  [ep1_dmabuff+7],A         ; ep1_dmabuff[7] = 0x00;

    ; Send upkey for appropriate kbd HID report types,

check_standard_up_key:
    MOV  A,STD_KEY_STATE           ; Check for Standard Keys report
    AND  A,[key_down_state]
    CMP  A,00h
    JZ   check_consumer_up_key

    CALL up_key_standard_null
    CALL wait_usb

check_consumer_up_key:
    MOV  A,MM_KEY_STATE            ; Check for Multimedia Keys report
    AND  A,[key_down_state]
    CMP  A,00h
    JZ   check_power_up_key

    MOV  A,02h                     ; Consumer Keys Report ID
    MOV  [ep1_dmabuff],A      
    CALL ep1_send
    CALL wait_usb

check_power_up_key:
    MOV  A,PWR_KEY_STATE           ; Check for Power Keys report
    AND  A,[key_down_state]
    CMP  A,00h
    JZ   reset_key_down_state

    MOV  A,03h                     ; Power Keys Report ID
    MOV  [ep1_dmabuff],A      
    CALL ep1_send
    CALL wait_usb

reset_key_down_state:
    MOV  A,00h
    MOV  [key_down_state],A        ; reset key_down_state

app_idle_ret:                 
    RET

;****************************************************************************
; app_disconnect_a
;****************************************************************************
app_disconnect_a:
    MOV  A,01h                     ; AC = 0x00;
    MOV  [upkey_timer_a],A         ; reset upkey_timer_a
    JMP  app_idle_a

;****************************************************************************
; wait_usb
;****************************************************************************
wait_usb:                       
    IOWR watchdog                   
    IORD ep1_mode                  ; If still waiting for USB to ACK last data, fail
    AND  A, 0Fh     
    CMP  A, ACK_IN
    JZ   wait_usb 
    RET                

;****************************************************************************
;   endfile:       rdk_Keyboard.asm
;****************************************************************************