//-------------------------------------------------------------------------- // // Battery Voltage Level Detection routine(s) // //-------------------------------------------------------------------------- // $Archive: /WirelessUSB/WUSB Kits/CY4632 LS KBM RDK/DocSrc/CD_Root/Firmware/Source Code/RDK Keyboard/battery.c $ // $Modtime: 4/20/04 1:40p9/29/04 2:19p $ // $Revision: 67 $ //-------------------------------------------------------------------------- // // 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. // //-------------------------------------------------------------------------- #include "globalparams.h" #include "ls_config.h" #include "tick.h" #ifdef KEYBOARD_BATTERY_VOLTAGE_SUPPORT //-------------------------------------- // Local Function Declarations //-------------------------------------- //-------------------------------------- // Local Definitions //-------------------------------------- #define CHARGE_TIME 1 // in milliseconds #define KEYBOARD_BATT_LEV_10 0x4A #define KEYBOARD_BATT_LEV_9 0x49 #define KEYBOARD_BATT_LEV_8 0x47 #define KEYBOARD_BATT_LEV_7 0x45 #define KEYBOARD_BATT_LEV_6 0x42 #define KEYBOARD_BATT_LEV_5 0x40 #define KEYBOARD_BATT_LEV_4 0x36 #define KEYBOARD_BATT_LEV_3 0x30 #define KEYBOARD_BATT_LEV_2 0x20 #define KEYBOARD_BATT_LEV_1 0x00 // Transitions used to compute battery level static const UINT8 level_threshold[] = { KEYBOARD_BATT_LEV_1, KEYBOARD_BATT_LEV_2, KEYBOARD_BATT_LEV_3, KEYBOARD_BATT_LEV_4, KEYBOARD_BATT_LEV_5, KEYBOARD_BATT_LEV_6, KEYBOARD_BATT_LEV_7, KEYBOARD_BATT_LEV_8, KEYBOARD_BATT_LEV_9, KEYBOARD_BATT_LEV_10 }; //-------------------------------------------------------------------------- // battery_status //-------------------------------------------------------------------------- // // This algorithm requires that both BATT_LEVx pins are initialized with // high-z drives and that the battery circuit has had time to stabalize // before reading the level. // // This algorithm does a read modify write on the port which may destroy // port data settings, i.e. pins that read a different an opposite value // of what should be in the data register. UINT8 battery_status(void) { INT8 i; UINT16 batt_count = 0; UINT16 ref_count = 0; //-------------------------------------- // Measure battery voltage //-------------------------------------- // Disable Tick interrupt Tick_DisableInt(); // Set the BATT_LEV pins BATT_LEV_PORT |= BATT_LEV1_MASK; BATT_LEV_PORT &= ~BATT_LEV2_MASK; // Set strong drive on BATT_LEV2 pin, transition thru pull-down BATT_LEV_DM1 = BATT_LEV_PRT_DRV1 & ~BATT_LEV2_MASK; BATT_LEV_DM0 = BATT_LEV_PRT_DRV0 | BATT_LEV2_MASK; // Count battery decay while( BATT_LEV_PORT & BATT_LEV1_MASK ) { batt_count++; if( batt_count == 65535 ) { break; } } // Enable Tick interrupt Tick_EnableInt(); //-------------------------------------- // Measure reference voltage //-------------------------------------- // Set both port to high BATT_LEV_PORT |= BATT_LEV1_MASK | BATT_LEV2_MASK; // Set strong drive on BATT_LEV1 pin, transition thru pull-up BATT_LEV_DM0 = BATT_LEV_PRT_DRV0 | BATT_LEV1_MASK | BATT_LEV2_MASK; BATT_LEV_DM1 = BATT_LEV_PRT_DRV1 & ~(BATT_LEV1_MASK | BATT_LEV2_MASK); // Wait for steady state timer_delay_msec( CHARGE_TIME ); // Disable Tick interrupt Tick_DisableInt(); // Set high-z on BATT_LEV pins (default) BATT_LEV_DM1 = BATT_LEV_PRT_DRV1; BATT_LEV_DM0 = BATT_LEV_PRT_DRV0; // Set BATT_LEV2 low BATT_LEV_PORT &= ~BATT_LEV2_MASK; // Set strong drive on BATT_LEV2 pin, transition thru pull-down BATT_LEV_DM1 = BATT_LEV_PRT_DRV1 & ~BATT_LEV2_MASK; BATT_LEV_DM0 = BATT_LEV_PRT_DRV0 | BATT_LEV2_MASK; // Count vcc reference decay while( BATT_LEV_PORT & BATT_LEV1_MASK ) { ref_count++; if( ref_count == 65535 ) { break; } } // Enable Tick interrupt Tick_EnableInt(); // Set high-z on BATT_LEV2 pins (default) BATT_LEV_DM1 = BATT_LEV_PRT_DRV1; BATT_LEV_DM0 = BATT_LEV_PRT_DRV0; //-------------------------------------- // Compute battery level //-------------------------------------- if (ref_count < batt_count) if( ref_count < batt_count ) { batt_count = batt_count - ref_count; // Determine Battery Level if (KEYBOARD_BATT_LEV_10 < batt_count) { return 10; } else if (KEYBOARD_BATT_LEV_9 < batt_count) { return 9; } else if (KEYBOARD_BATT_LEV_8 < batt_count) { return 8; } else if (KEYBOARD_BATT_LEV_7 < batt_count) { return 7; } else if (KEYBOARD_BATT_LEV_6 < batt_count) { return 6; } else if (KEYBOARD_BATT_LEV_5 < batt_count) for(i=sizeof(level_threshold)-1; i>=0; i--) { return 5; } else if (KEYBOARD_BATT_LEV_4 < batt_count) if( level_threshold[i] < (UINT8)batt_count ) { return 4; return (i+1); } else if (KEYBOARD_BATT_LEV_3 < batt_count) { return 3; } else if (KEYBOARD_BATT_LEV_2 < batt_count) { return 2; } else { return 1; } } else { return 1; } } #endif