Index: firmware/App/Drivers/Battery.c =================================================================== diff -u -rac636de6bf42cc4145cbd14886b616da78b3aaf8 -ra8a0f729b78556c2c58a72bad942d04a9dead3f5 --- firmware/App/Drivers/Battery.c (.../Battery.c) (revision ac636de6bf42cc4145cbd14886b616da78b3aaf8) +++ firmware/App/Drivers/Battery.c (.../Battery.c) (revision a8a0f729b78556c2c58a72bad942d04a9dead3f5) @@ -32,18 +32,20 @@ #define BATTERY_STATUS_AC_PRESENT_MASK 0x8000 ///< Battery status AC present bit mask. #define BATTERY_COMM_TIME_OUT_MS 1 ///< Battery communication time out in ms. #define BATTERY_MONITOR_INTERVAL_MS MS_PER_SECOND ///< Battery monitor interval in ms. + +#define AC_POWER_LOST_PERSISTENT_COUNT 3 ///< AC power lost persistent count before alarming. // ********** private data ********** static U16 batteryStatus = 0; ///< Battery current status. static U32 lastBatteryMonitorTime = 0; ///< Previous battery monitor time. -static BOOL isBatteryStatusReceived = FALSE; ///< Flag indicates battery status received. +static U32 lostACPowerPersistentCount = 0; ///< Persistent count for AC power lost alarm. // ********** private function prototypes ********** static void setupI2CDriver( void ); static BOOL waitForTxReady( void ); -static void getBatteryStatus( void ); +static BOOL getBatteryStatus( void ); /*********************************************************************//** * @brief @@ -69,16 +71,28 @@ { if ( TRUE == didTimeout( lastBatteryMonitorTime, BATTERY_MONITOR_INTERVAL_MS ) ) { - isBatteryStatusReceived = FALSE; lastBatteryMonitorTime = getMSTimerCount(); #ifndef DISABLE_BATT_COMM - getBatteryStatus(); - - if ( ( TRUE == isBatteryStatusReceived ) && ( ( batteryStatus & BATTERY_STATUS_AC_PRESENT_MASK ) == 0 ) ) + if ( TRUE == getBatteryStatus() ) { - SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_AC_POWER_LOST, (U32)batteryStatus ); + if ( ( batteryStatus & BATTERY_STATUS_AC_PRESENT_MASK ) == 0 ) + { + if ( ++lostACPowerPersistentCount > AC_POWER_LOST_PERSISTENT_COUNT ) + { + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_AC_POWER_LOST, (U32)batteryStatus ); + } + } + else + { + lostACPowerPersistentCount = 0; + } } + else + { + // Reset i2c bus if cannot communicate with battery charger + setupI2CDriver(); + } #endif } } @@ -121,14 +135,37 @@ /*********************************************************************//** * @brief + * The waitForRxReady function checks for receive ready status from i2c + * driver with a timeout. + * @details Inputs: none + * @details Outputs: checked i2c receive ready status + * @return TRUE if timeout, otherwise FALSE + *************************************************************************/ +static BOOL waitForRxReady( void ) +{ + U32 const startTime = getMSTimerCount(); + BOOL timeout = FALSE; + + while ( ( 0 == i2cIsRxReady( i2cREG1 ) ) && ( FALSE == timeout ) ) + { + timeout = didTimeout( startTime, BATTERY_COMM_TIME_OUT_MS ); + } + + return timeout; +} + +/*********************************************************************//** + * @brief * The getBatteryStatus function send command to smart battery charger controller * interface to get battery status. * @details Inputs: none * @details Outputs: get the current battery status - * @return none + * @return TRUE if received battery status, otherwise FALSE *************************************************************************/ -static void getBatteryStatus( void ) +static BOOL getBatteryStatus( void ) { + BOOL result = FALSE; + if ( FALSE == i2cIsBusBusy( i2cREG1 ) ) { i2cSetMode( i2cREG1, I2C_MASTER ); @@ -145,18 +182,23 @@ { i2cSetDirection( i2cREG1, I2C_RECEIVER ); i2cSetStart( i2cREG1 ); - batteryStatus = i2cReceiveByte( i2cREG1); - i2cSetStop( i2cREG1 ); - batteryStatus = ( batteryStatus | ( i2cReceiveByte( i2cREG1) << 8 ) ); - isBatteryStatusReceived = TRUE; + if ( FALSE == waitForRxReady() ) + { + // Due to the double buffer, the master must generate the stop condition after the (message size - 1)th data + i2cSetStop( i2cREG1 ); + batteryStatus = i2cReceiveByte( i2cREG1); + + if ( FALSE == waitForRxReady() ) + { + batteryStatus = ( batteryStatus | ( i2cReceiveByte( i2cREG1) << 8 ) ); + result = TRUE; + } + } } - else - { - // Reset i2c bus if comm timeout - setupI2CDriver(); - } } + + return result; } /**@}*/