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

Base file: C:\CY4632_RDK_1_21\Firmware\Source Code\RDK Mouse\mouse.c

Modified file: C:\CY4632_RDK_1_3\Firmware\Source Code\RDK Mouse\mouse.c

//--------------------------------------------------------------------------
//
// This module provides the main control for the mouse application.  It also
// implements the two sleep algorithms along with some other housekeeping.
//
//--------------------------------------------------------------------------
// $Archive: /WirelessUSB/WUSB Kits/CY4632 LS KBM RDK/DocSrc/CD_Root/Firmware/Source Code/RDK Mouse/mouse.c $
// $Modtime: 6/16/04 4:38p10/01/04 1:18p $
// $Revision: 910 $
//--------------------------------------------------------------------------
//
// Copyright 2003-2004, Cypress Semiconductor Corporation.
//
// This software is owned by Cypress Semiconductor Corporation (Cypress)
// and is protected by and subject to worldwide patent protection (United
// States and foreign), 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 to be used only in conjunction with a Cypress integrated 
// circuit as specified in the applicable agreement. 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 does not authorize its products for use as critical components in
// life-support systems where a malfunction or failure may reasonably be
// expected to result in significant injury to the user. The inclusion of
// Cypress’ product in a life-support systems application implies that the
// manufacturer assumes all risk of such use and in doing so indemnifies
// Cypress against all charges.
//
// Use may be limited by and subject to the applicable Cypress software
// license agreement.
//
//--------------------------------------------------------------------------


//--------------------------------------
// Included files
//--------------------------------------

#include "psocgpioint.h"
#include "mouse.h"
#include "appconfig.h"
#include PLATFORM_H
#include "timer.h"
#include "protocol.h"
#include "bind.h"
#include "isr.h"
#include "buttons.h"
#include "testmode.h"
#include "battery.h"
#include "ls_config.h"
#include "debug.h"
#include "port.h"
#include "mfgtest.h"


//--------------------------------------
// Global Variable Definitions
//--------------------------------------

BOOL mouse_asleep;
BOOL mouse_auto_bind;


//--------------------------------------
// Local Defines and Types
//--------------------------------------

#ifdef  MOUSE_MOTION_NOT_TIME_SLEEP
#define MOUSE_SLEEP(n)            mouse_sleep(n)
#define MOUSE_WAIT_BUTTON_UP()
#else
#define MOUSE_SLEEP(n)            mouse_progressive_sleep(n)
#define MOUSE_WAIT_BUTTON_UP()    while( !buttons_up() )
#endif

#ifdef TWO_WAY
#define MOUSE_PROTOCOL_BIND()     protocol_bind()
#else
#define MOUSE_PROTOCOL_BIND()
#endif

#ifdef DEBUG
#define DEBUG_INIT()              debug_init()
#else
#define DEBUG_INIT()
#endif

#ifdef MOUSE_BATTERY_STATUS
#define CACHE_BATTERY_STATUS()    mouse_battery_status = battery_status();
#else
#define CACHE_BATTERY_STATUS()
#endif


//--------------------------------------
// Local Function Declarations
//--------------------------------------

static void mouse_init(void);
static BOOL mouse_sleep(TIME_STAMP*);
static void mouse_do_bind(void);
static void mouse_optics_cycle(UINT16 off_ms);

#ifndef  MOUSE_MOTION_NOT_TIME_SLEEP
static BOOL mouse_progressive_sleep(TIME_STAMP*);
#endif


//--------------------------------------
// Local Variable Definitions
//--------------------------------------

static TIME_STAMP sleep_timer;
static BOOL       mouse_asleep;

#ifdef MOUSE_BATTERY_STATUS
static UINT8      mouse_battery_status;
static BOOL       mouse_auto_bind;
#endif


//--------------------------------------------------------------------------
// main
//--------------------------------------------------------------------------

void main(void)
{
    TIME_STAMP  ts;
    TX_PACKET   pkt;
    TX_PACKET  *radio_pkt;
    

    mouse_init();
     
    protocol_init();
        
    MFG_PIN_CHECK();

    TEST_EXECUTE();

    radio_pkt = (TX_PACKET*)protocol_get_tx_pkt();
    
    while(1) 
    {
        // Check for auto bind request
        if( mouse_auto_bind )
        {
            mouse_do_bind();
        }
        
        // Get poll time stamp
        ts = timer_get_time_stamp();


        // Check for mouse report
        if( mouse_get_report(&pkt) )
        {
            UINT8 pkt_size;
            UINT8 resp = NO_DATA;

            // Send packet
            do
            {
                if( mouse_auto_bind ||
                    timer_time_elapsed( ts, MOUSE_TX_TIMEOUT ) )
                {
                    break;
                }

                radio_pkt->shared.optical.x = pkt.shared.optical.x;
                radio_pkt->shared.optical.y = pkt.shared.optical.y;

                // Compute packet size
                if( pkt.combi != 0 )
                {
                    radio_pkt->combi = pkt.combi;
                    pkt_size = 3;
                }
                else
                {
                    pkt_size = 2;
                }

                resp = protocol_send_packet(pkt_size);
            }
            while( !(resp == DATA_SENT || resp == ACK_DATA) );
            
#ifdef MOUSE_BATTERY_STATUS
            // Send battery level if requested via ACK_DATA
            if( resp == ACK_DATA )
            {
                do
                {
                    if( mouse_auto_bind ||
                        timer_time_elapsed( ts, MOUSE_TX_TIMEOUT ) )
                    {
                        break;
                    }

                    radio_pkt->shared.battery_level = mouse_battery_status;
                    resp = protocol_send_packet(1);
                }
                while( !(resp == DATA_SENT || resp == ACK_DATA) );
            }
#endif
            
            // Update sleep timer
            sleep_timer = timer_get_time_stamp();

            // Delay for remainder of poll period
            timer_delay_incremental( ts, MOUSE_POLL_IN_MS );
        }
        else if( !MOUSE_SLEEP(&sleep_timer) )
        {
            // Delay for remainder of poll period if not sleeping
            timer_delay_incremental( ts, MOUSE_POLL_IN_MS );
        }
    }

}


//--------------------------------------------------------------------------
// mouse_wakeup
//--------------------------------------------------------------------------

void mouse_wakeup(void)
{
    mouse_asleep = FALSE;
}


//--------------------------------------------------------------------------
// mouse_bind
//--------------------------------------------------------------------------

void mouse_bind(void)
{
    mouse_auto_bind = TRUE;

    isr_disable(INT_BIND);
}


//--------------------------------------------------------------------------
// mouse_power_up
//--------------------------------------------------------------------------

void mouse_power_up(void)
{
    MOTION_POWER_UP();

    optical_power_up();
    
    buttons_power_up();

    wheel_power_up();

    bind_button_power_up();
}


//--------------------------------------------------------------------------
// mouse_power_down
//--------------------------------------------------------------------------

void mouse_power_down()
{
    optical_power_down();

    wheel_power_down();
    
    buttons_power_down();
    
    bind_button_power_down();
    
    MOTION_POWER_DOWN();
}


//--------------------------------------------------------------------------
// mouse_get_report
//--------------------------------------------------------------------------

BOOL mouse_get_report(TX_PACKET *packet)
{
    BOOL report_valid = FALSE;
    BUTTON_REPORT  buttons;
    WHEEL_REPORT   wheel;

          
    packet->combi = 0;

    //------------------------------------------------ Buttons

    if( buttons_get_report( &buttons ) )
    {
        packet->combi |= buttons.buttons;
        report_valid = TRUE;
    }


    //------------------------------------------------ Optical
    
    if( optical_get_report( &packet->shared.optical ) )
    {
        packet->combi = buttons.buttons;
        report_valid = TRUE;
    }

    //-------------------------------------------------- Wheel

    if( wheel_get_report( &wheel ) )
    {
        packet->combi |= = (wheel.z & 0x1f) | buttons.buttons;
        report_valid = TRUE;
    }
    
        
    return report_valid;
}


//--------------------------------------------------------------------------
// mouse_init
//--------------------------------------------------------------------------

static void mouse_init(void)
{
    mouse_asleep = FALSE;
#ifdef MOUSE_POWER_ON_BIND
    SYS_PARAMETERS systmp;


    mouse_auto_bind = FALSE;
    
    NVRAM_READ( &systmp, sizeof(SYS_PARAMETERS) );

    if (systmp.networkId.signature != SIGNATURE_BYTE) 
    {
        mouse_auto_bind = TRUE;
    }
#else
    mouse_auto_bind = FALSE;
#endif

    mouse_asleep = FALSE;

    port_init();

    isr_init();

    timer_init();
    
    timer_delay_msec(600);  // Wait for battery level detect to stabalize

    mouse_battery_status = battery_status();
    CACHE_BATTERY_STATUS();
    
    optical_init();

    debounce_init();

    buttons_init();

    wheel_init();
    
    bind_button_init();

    MOTION_INIT();

    DEBUG_INIT();
    
    sleep_timer = timer_get_time_stamp();
}


//--------------------------------------------------------------------------
// mouse_sleep
//--------------------------------------------------------------------------

static BOOL mouse_sleep(TIME_STAMP *sleep_ts)
{

    if( timer_time_elapsed(*sleep_ts, MOUSE_OPTIC_OFF_TIME_MS) && 
        buttons_up() )
    {
        mouse_power_down();

        mouse_battery_status = battery_status();
        CACHE_BATTERY_STATUS();
            
        mouse_asleep = TRUE;
            
        timer_timer_off();
            
        while( mouse_asleep )
        {
            // The next instruction after the M8C_Sleep is prefetched.
            // We insert two NOPs so the compare for the loop isn't
            // prefetched.  This will use the latest value of mouse_asleep
            // which can be modified by the interrupt that woke us up.

            M8C_Sleep;
            asm("nop");
            asm("nop");
        }
        
        timer_timer_on();
            
        mouse_power_up();
            
        TIMER_CALIBRATE_TIMER(TRUE);  
        
        MOUSE_WAIT_BUTTON_UP();   // Ignore button in time-sleep algorithm
            
        *sleep_ts = timer_get_time_stamp();

        return TRUE;
    }

    return FALSE;
}

#ifndef  MOUSE_MOTION_NOT_TIME_SLEEP

//--------------------------------------------------------------------------
// mouse_progressive_sleep
//--------------------------------------------------------------------------

#define MOUSE_STEP1        600000               // 10 min
#define MOUSE_STEP1_ON        500               // in mS

#define MOUSE_STEP2       1800000               // 30 min
#define MOUSE_STEP2_ON       1000               // in mS

static BOOL mouse_progressive_sleep(TIME_STAMP *sleep_ts)
{
    TIME_STAMP  delta = timer_get_time_stamp() - *sleep_ts;

    if( delta < MS_TO_TICK(MOUSE_OPTIC_OFF_TIME_MS) )
    {
        return FALSE;
    }
    else if( delta < MS_TO_TICK(MOUSE_STEP1) )
    {
        mouse_optics_cycle( MOUSE_STEP1_ON );
        return TRUE;
    }
    else if( delta < MS_TO_TICK(MOUSE_STEP2) )
    {
        mouse_optics_cycle( MOUSE_STEP2_ON );
        return TRUE;
    }
    else
    {
        return mouse_sleep(sleep_ts);
    }
}


//--------------------------------------------------------------------------
// mouse_optics_cycle
//--------------------------------------------------------------------------

#define MOUSE_OPTICS_RECOVERY_MS  100

static void mouse_optics_cycle(UINT16 off_ms)
{
    optical_power_down();
    timer_delay_msec( off_ms );
    optical_power_up();
    timer_delay_msec( MOUSE_OPTICS_RECOVERY_MS );
}

#endif    // MOUSE_MOTION_NOT_TIME_SLEEP


//--------------------------------------------------------------------------
// mouse_do_bind
//--------------------------------------------------------------------------

static void mouse_do_bind(void)
{
    // wait for button up
    while( (MOUSE_BIND_PORT & MOUSE_BUTTON_BIND) == 0);
    
    isr_disable(INT_ZWHEEL);
    ISR_DISABLE(GPIO_ISR_ZWHEEL_IE_PORT, GPIO_ISR_ZWHEEL_INT);
            
    MOUSE_PROTOCOL_BIND();
    
    isr_enable(INT_ZWHEEL);
    ISR_ENABLE(GPIO_ISR_ZWHEEL_IE_PORT, GPIO_ISR_ZWHEEL_INT);
            
    mouse_auto_bind = FALSE;
    
    isr_enable(INT_BIND);
    ISR_ENABLE(GPIO_ISR_BIND_IE_PORT, GPIO_ISR_BIND_INT);
}