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

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

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

;****************************************************************************
;
;   file:   utilities.asm
;   Description: This file contains miscellaneous protocol procedures
;                   process_rx_int
;                   verify_packet
;                   transmit_sys
;                   transmit_app
;                   set_sys_parity
;                   set_app_parity
;                   set_sys_checksum
;                   set_app_checksum
;                   clear_rx_packet
;                   delay200us
;                   
;
;   Target:  Cypress CY7C63723 Encore Chip
;   $Header:
;   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.
;
;****************************************************************************

;-------------------------------------------------------
;
;   process_rx_int
;
;   Sets the EOF flags if end of frame interrupt is on
;   AND  reads data 
;-------------------------------------------------------
process_rx_int:
    MOV  A, REG_RX_INT_STAT
    MOV  [reg_addr], A  
    CALL SPI_read               
    MOV  A, [reg_data]
    MOV  [radio_int], A

    AND  A, bRX_FULL_A               ; check for data
    JZ   check_eof
    CALL data_read

check_eof:    
    MOV  A, [radio_int]
    AND  A, bRX_EOF_A
    JZ   process_rx_int_complete      ; check for EOF
    MOV  A, [rx_counter]
    AND  A, ffh
    JZ   process_rx_int_complete      ; don't set EOF flag for 0 byte packets    
    MOV  A, bFLAG_EOF
    MOV  [packet_ready], A

process_rx_int_complete:
    RET 

;-------------------------------------------------------
;   data_read
;-------------------------------------------------------
data_read:
    MOV  X, [rx_counter]                    
    MOV  A, [radio_int]
    AND  A, bRX_VALID_A
    JZ   data_read_invalid
    MOV  A, ffh
    MOV  [X+valid_buffer], A
    JMP  data_read_valid

data_read_invalid:
    MOV  A, REG_RX_VALID_A           ; read the rx data valid byte
    MOV  [reg_addr], A               ;
    CALL SPI_read                   ;

    MOV  A, [reg_data]               ; IF only the bottom 2-3 bits are
    CMP  A, 08h                      ; valid, this is probably noise
    JC   reset_byte_counter           ; so throw it away
    MOV  [X+valid_buffer], A         ; store the valid byte (used in error correction)

data_read_valid:
    MOV  A, REG_RX_DATA_A            ; read the rx data byte
    MOV  [reg_addr], A               ;
    CALL SPI_read                   ;
    
    MOV  A, [reg_data]               ; store the data
    MOV  [X+rx_buffer], A            ;   
    INC  [rx_counter]                ; inc the counter for next time
    MOV  A, [rx_counter]             ; RWW 2004.9.10
    CMP  A, RX_BUFFER_LEN+1
    JNC  reset_byte_counter          ; buffer overflow check
    
data_read_complete:    
    MOV  A, 00h                      ; reset the radio timer
    MOV  [timer], A                  ; to prevent reset in mid-packet from RSSI, etc.
    RET      
       
reset_byte_counter: 
    MOV  A, REG_RX_DATA_A            ; do a dummy data read to clear the 
    MOV  [reg_addr], A               ; interrupt flag in the radio.
    CALL SPI_read                   ;
        
    MOV  A, 00h                      ; reset the rx byte counter
    MOV  [rx_counter], A             ; AND  return to polling loop
    
    RET 

;-------------------------------------------------------
;
;   verify_packet
;       
;   parity correction AND  verification,
;   error correction AND  checksum verification, etc.
;
;-------------------------------------------------------
verify_packet:                             
    MOV  A, [rx_counter]
    CMP  A, 1                        ; if empty packet just throw it away... it's just noise
    JC   verify_packet_complete
    
verify_packet_header:
    MOV  A, [valid_buffer]
    CMP  A, ffh
    JNZ  verify_packet_header_failed        ; throw away packets with invalid packet headers

    ; check the parity
    MOV  A, 0
    MOV  [parity], A                 ; "1" bits counter
    MOV  A, 80h
    MOV  [loop_counter], A           ; loop counter

verify_parity_loop:
    MOV  A, [rx_buffer]
    AND  A, [loop_counter]              
    JZ   verify_parity_low_bit
    INC  [parity]                    ; keep track of all "1" bits
    
verify_parity_low_bit:
    MOV  A, [loop_counter]
    ASR 
    AND  A, 7fh                      ; need to clear the top bit, because it doesn't shift in a zero
    JZ   verify_parity_loop_complete
    MOV  [loop_counter], A
    JMP  verify_parity_loop

verify_parity_loop_complete:
    MOV  A, [parity]
    AND  A, 01h
    JZ   verify_packet_failed         ; if parity is even throw the packet away

    MOV  A, [rx_counter]
    CMP  A, 1                        ; If this is a multi-byte packet we need to check the checksum
    JNZ  check_valid_bytes           ; Otherwise this is a valid 1-byte packet

verify_1_byte_packet_success:
    MOV  A, [packet_ready]           ; set the valid packet flag!
    OR   A, bFLAG_VALID
    MOV  [packet_ready], A
    
    MOV  A, [rx_buffer]              ; store the packet type 
    AND  A, f0h  
    MOV  [packet_type], A      
    RET 


check_valid_bytes:
    MOV  X, [rx_counter]
    DEC  X

    MOV  A, ffh
check_valid_loop:
    AND  A, [X+valid_buffer]         
    DEC  X
    JNC  check_valid_loop
    
    CMP  A, ffh                      ; if all bits in all bytes are valid blunder check the checksum
    JZ   check_csum
    MOV  [invalid_bit], A            ; we have an invalid bit... need to correct the packet
    
    MOV  A, NUM_BITS_CORRECTABLE
    MOV  [corrected_bits], A

    ; if the checksum has invalid bits it could be a bit-shift error so toss the packet
    MOV  X, [rx_counter]
    MOV  A, [X + valid_buffer - 1]
    CMP  A, ffh
    JNZ  fix_valid_failed
    
    ; invalid bits are not in the checksum so we can try to correct them
    MOV  A, 01h
    MOV  [loop_counter], A           ; tracks the bit column we are examining
fix_valid_loop:    
    MOV  A, [invalid_bit]
    AND  A, [loop_counter]           ; check to see if we need to correct this column
    JNZ  fix_valid_next_col
    
    DEC  [corrected_bits]           ; If we have already fixed our maximum number of bits
    JC   fix_valid_failed           ; throw the packet away
    
    MOV  A, [checksum_seed]          ; this column needs fixed
    MOV  [parity], A
    MOV  A, ffh;
    MOV  [ls_temp], A                ; set to invalid to start with to track if multiple bits are bad
    
    MOV  X, [rx_counter]    
    DEC  X
    
fix_col_loop:    
    MOV  A, [X+valid_buffer]
    AND  A, [loop_counter]
    JZ   fix_col_loop_bad_byte
    
    MOV  A, [X+rx_buffer]            ; I only care about one column, but it's faster to XOR  the entire byte
    XOR  A, [parity]
    MOV  [parity], A
    JMP  fix_col_loop_next_byte
        
fix_col_loop_bad_byte:    
    MOV  A, [ls_temp]
    CMP  A, ffh
    JNZ  fix_valid_failed
    MOV  A, X
    MOV  [ls_temp], A                ; track the bad bit

fix_col_loop_next_byte:
    DEC  X
    JNC  fix_col_loop         
    
    MOV  A, [parity]                 ; we finished calculating the 
    AND  A, [loop_counter]           ; parity for this column.. fix the bad bit
    JZ   fix_col_set_bit_low
    
    MOV  X, [ls_temp]
    MOV  A, [X+rx_buffer]
    OR   A, [loop_counter]
    MOV  [X+rx_buffer], A
    JMP  fix_valid_next_col
    
fix_col_set_bit_low:
    MOV  X, [ls_temp]
    MOV  A, [loop_counter]
    CPL 
    AND  A, [X+rx_buffer]
    MOV  [X+rx_buffer], A    

fix_valid_next_col:
    MOV  A, [loop_counter]
    ASL 
    MOV  [loop_counter], A
    JNZ  fix_valid_loop

    JMP  check_csum                  ; we finished fixing the packet

fix_valid_failed:
IFDEF BIND_AUTO
    INC  [corrupt_counter]
ENDIF
    RET 


check_csum:
    MOV  A, [rx_counter]
    SUB  A, 2                        ; don't check the checksum, AND  it's 0-indexed
    MOV  X, A                       

IFDEF BIND_AUTO
    MOV  A, [rx_buffer]
    AND  A, f0h
    CMP  A, PT_BIND_REQ
    JNZ  seed_checksum    

    MOV  A, BIND_CHECKSUM_SEED    
    JMP  csum_loop
ENDIF ; BIND_AUTO
    
seed_checksum:
    MOV  A, [checksum_seed]           
    
csum_loop:                       
    XOR  A, [X + rx_buffer]       
    DEC  X                           
    JNC  csum_loop                 

    SWAP  A, X
    MOV  A, [rx_counter]
    SWAP A, X
    CMP  A, [X + rx_buffer - 1]      ; compare with csum byte
    JNZ  verify_packet_failed        ; if error discard packet        
    
verify_packet_success:
    MOV  A, [packet_ready]           ; set the valid packet flag!
    OR   A, bFLAG_VALID
    MOV  [packet_ready], A
    
    MOV  A, [rx_buffer]              ; store the packet type (I'll need this A LOT)
    AND  A, f0h  
    MOV  [packet_type], A      
    
verify_packet_complete:
    RET                              ; returns to process_packet_a

verify_packet_failed:
IFDEF BIND_AUTO
    INC  [corrupt_counter]
ENDIF
    RET 

packet_header_failed:
    MOV  A, [rx_counter]
    CMP  A, 1
    JNZ  verify_packet_failed           ; ignore 1-byte noise packets
    RET


;-------------------------------------------------------
;
;   transmit_sys
;
;-------------------------------------------------------
transmit_sys:
    MOV  A, 0h
    MOV  [misc_counter1],A

    MOV  X, 00h                  

IFDEF TX_PAUSE
bit_shift_loop:
    IOWR    watchdog

    IORD port0                     
    AND  A, IRQ
    JNZ  bit_shift_stall
    
    MOV  A, REG_TX_INT_STAT
    MOV  [reg_addr], A             
    CALL SPI_read                
        
    JMP  bit_shift_loop
    
bit_shift_stall:    
    CALL delay200us
    CALL delay200us
ENDIF ; TX_PAUSE

    MOV  A, REG_TX_DATA             
    MOV  [reg_addr], A              

tx_sys_stall:
    IOWR    watchdog

    INC  [misc_counter1]             ; If we incremented past 255, bail-out
    JC   tx_sys_finished

    IORD port0
    AND  A, IRQ
    JZ   tx_sys_stall
    
tx_sys_load:
    MOV  A, [X + tx_sys_buffer]       
    MOV  [reg_data], A
    CALL SPI_write

    MOV  A, 0h
    MOV  [misc_counter1],A

    INC  X                           
    MOV  A, X
    SUB  A, [tx_sys_counter]
    JC   tx_sys_stall                 ; wait for a buffer empty interrupt

    MOV  A, REG_TX_INT_EN
    MOV  [reg_addr], A
    MOV  A, bTX_EOF
    MOV  [reg_data], A
    CALL SPI_write

    MOV  A, 0h
    MOV  [misc_counter1],A

tx_sys_wait_finish:
    IOWR watchdog

    INC  [misc_counter1]             ; If we incremented past 255, bail-out
    JC   tx_sys_finished

    IORD port0
    AND  A, IRQ
    JZ   tx_sys_wait_finish
    
    MOV  A, REG_TX_INT_STAT          ; If there is an interrupt we need to read
    MOV  [reg_addr], A               ; the interrupt status register 
    CALL SPI_read                    ; in order to clear the interrupt

tx_sys_finished:
    MOV  A, REG_TX_INT_EN
    MOV  [reg_addr], A
    MOV  A, bTX_EMPTY
    MOV  [reg_data], A
    CALL SPI_write

    CALL radio_idle    
    MOV  A, 0
    MOV  [timer], A                  ; reset the 1 ms timer

    RET  
 


IFDEF  TWO_WAY_DATA
;-------------------------------------------------------
;
;   transmit_app
;
;-------------------------------------------------------
        
transmit_app:
    MOV  X, 0h
    
    copy_loop:                       ; for (X=0; X < tx_app_counter; X++) {
    MOV  A, [X + tx_app_header]       
    MOV  [X + tx_sys_buffer], A      ;    tx_sys_buffer[X] = tx_app_header[X];

    INC  X                           
    MOV  A, X
    SUB  A, [tx_app_counter]
    JNZ  copy_loop                   ; }  // end for loop 

    MOV  A,[tx_app_counter]          ; Move tx_app_counter into tx_sys_counter
    MOV  [tx_sys_counter], A 
       
    CALL transmit_sys                ; Use transmit_sys code to do the transfer
    RET
ENDIF       ; TWO_WAY_DATA

;-------------------------------------------------------
;
;   set_sys_parity
;
;-------------------------------------------------------
set_sys_parity:
    MOV  A, 0
    MOV  [ls_temp], A                ; clear the temp register

    MOV  X, [tx_sys_buffer]
    MOV  A, X
    
sys_parity_loop:
    AND  A, 1
    JZ   sys_parity_end
    
sys_inc_parity:
    INC  [ls_temp]    
    
sys_parity_end:
    MOV  A, X
    ASR 
    AND  A, 7Fh                     ; ASR may not shift in a zero in the top bit 
    MOV  X, A
    AND  A, ffh                      ; once X == 0, either we've shifted the whole byte
    JNZ  sys_parity_loop             ; OR   the rest is 0's so it doesn't matter
    
    MOV  A, [ls_temp]
    AND  A, 01h                      ; IF the lsb is set THEN it's already odd parity, 
    JNZ  sys_parity_complete
    
    MOV  A, [tx_sys_buffer]          ; ELSE set the parity bit
    OR   A, bPARITY
    MOV  [tx_sys_buffer], A    
    
sys_parity_complete:    
    RET 
    
    
IFDEF  TWO_WAY_DATA
;-------------------------------------------------------
;
;   set_app_parity
;
;-------------------------------------------------------
set_app_parity:
    MOV  A,[tx_app_header] 
    MOV  [tx_sys_buffer], A        
    CALL set_sys_parity

    MOV  A,[tx_sys_buffer] 
    MOV  [tx_app_header], A       
    RET
ENDIF    

;-------------------------------------------------------
;
;   set_sys_checksum
;
;-------------------------------------------------------
set_sys_checksum:
IFDEF BIND_AUTO
    MOV  [ls_temp], A
ENDIF ; BIND_AUTO

sys_init_checksum:    
    MOV  A, [tx_sys_counter]
    SUB  A, 2                        ; don't check the checksum, 0 indexed
    MOV  X, A                        
IFDEF BIND_AUTO
    MOV  A, [ls_temp]
ELSE
    MOV  A, [checksum_seed]            
ENDIF ; BIND_AUTO

sys_checksum_loop:                  
    XOR  A, [X + tx_sys_buffer]      ; XOR each byte
    AND  A, ffh                      ; clear carry flag          
    DEC  X                           
    JNC  sys_checksum_loop           

    MOV  [ls_temp], A                
    MOV  X, [tx_sys_counter]
    MOV  A, [ls_temp]
    MOV  [X + tx_sys_buffer - 1], A  ; store the checksum

    RET 


IFDEF  TWO_WAY_DATA
;-------------------------------------------------------
;
;   set_app_checksum
;
;-------------------------------------------------------
set_app_checksum:
    MOV  A, [tx_app_counter]
    SUB  A, 2                        ; don't check the checksum, 0 indexed
    MOV  X, A                        
    MOV  A, [checksum_seed]

app_checksum_loop:                          
    XOR  A, [X + tx_app_header]      ; XOR each byte
    AND  A, ffh                      ; clear carry flag          
    DEC  X                           
    JNC  app_checksum_loop                   

    MOV  [ls_temp], A                ; csum is subtracted from zero to detect shift errors 
    MOV  X, [tx_app_counter]
    MOV  A, [ls_temp]
    MOV  [X + tx_app_header - 1], A  ; store the checksum

    RET 
ENDIF

;-------------------------------------------------------
;
;   clear_rx_packet
;
;-------------------------------------------------------
clear_rx_packet:
    MOV  A, 00h
    MOV  [rx_counter], A
    MOV  [packet_ready], A
    RET



    


;-------------------------------------------------------
;
;   delay10us
;
;   A 10 us delay at 12 MHz requires 120 cycles...
;
;-------------------------------------------------------
delay10us:
    MOV  A, 8                        ; 8 cycles
    

delay10us_loop:                     ; 9 cycles per loop
    DEC  A                           ; 4 cycles
    JNZ  delay10us_loop              ; 5 cycles (4 if not taken)

    RET                              ; 8 cycles


delay50us:
    CALL delay10us
    CALL delay10us
    CALL delay10us
    CALL delay10us
    CALL delay10us
    RET 


;-------------------------------------------------------
;
;   delay200us
;
;-------------------------------------------------------
delay200us:
    CALL delay10us
    CALL delay10us
    CALL delay10us
    CALL delay10us
    CALL delay10us
    CALL delay10us
    CALL delay10us
    CALL delay10us
    CALL delay10us
    CALL delay10us
    CALL delay10us
    CALL delay10us
    CALL delay10us
    CALL delay10us
    CALL delay10us
    CALL delay10us
    CALL delay10us
    CALL delay10us
    CALL delay10us
    CALL delay10us
    RET