예제 #1
0
RtStatus_t hw_power_InitPowerSupplies(void)
{
    RtStatus_t Status;

    //----------------------------------------------------------------------
    // Make sure the power supplies are configured for their power sources.
    // This sets the LINREG_OFFSET field correctly for each power supply.
    //---------------------------------------------------------------------

    if(hw_power_Get5vPresentFlag())
    {

        if((Status = hw_power_SetVdddPowerSource(HW_POWER_LINREG_DCDC_READY))
                != SUCCESS)
            return Status;
        if((Status = hw_power_SetVddaPowerSource(HW_POWER_LINREG_DCDC_READY))
                != SUCCESS)
            return Status;
        if((Status = hw_power_SetVddioPowerSource(HW_POWER_LINREG_DCDC_READY))
                != SUCCESS)
            return Status;
    }
    else
    {

        if((Status = hw_power_SetVdddPowerSource(HW_POWER_DCDC_LINREG_READY))
                != SUCCESS)
            return Status;
        if((Status = hw_power_SetVddaPowerSource(HW_POWER_DCDC_LINREG_READY))
                != SUCCESS)
            return Status;
        if((Status = hw_power_SetVddioPowerSource(HW_POWER_DCDC_LINREG_READY))
                != SUCCESS)
            return Status;

        // Need to make sure the DCDC does not run with a bad or broken battery.
        if( hw_power_GetBatteryVoltage() <= 2800 )
        {
            hw_power_PowerDown();
        }
        hw_power_ClearBatteryBrownoutInterrupt();
        hw_power_EnableBatteryBrownoutInterrupt(true);
        hw_power_EnableDcdc(true);
    }

    //--------------------------------------------------------------------------
    // Done.
    //--------------------------------------------------------------------------
    return SUCCESS;
}
예제 #2
0
void hw_power_Init4p2EnabledPowerSupply(void)
{

    if(hw_power_GetBatteryVoltage()>3900)
        HW_POWER_DCDC4P2.B.CMPTRIP = 0;
    else
        HW_POWER_DCDC4P2.B.CMPTRIP = 24;

    HW_POWER_DCDC4P2.B.TRG = 0;
    HW_POWER_5VCTRL.B.HEADROOM_ADJ = 0x4;
    HW_POWER_DCDC4P2.B.DROPOUT_CTRL = 0xA;  //100mV drop before stealing
    // charging current
    HW_POWER_5VCTRL.B.CHARGE_4P2_ILIMIT = 0x3f;
}
예제 #3
0
RtStatus_t hw_power_InitFiq(void)
{
    uint16_t u16SafeBattVolt;
    extern uint8_t g_ddi_power_SafeBatteryVoltageCode;

    //--------------------------------------------------------------------------
    // Clear the brownout interrupts.
    //--------------------------------------------------------------------------

    hw_power_ClearVdddBrownoutInterrupt();
    hw_power_ClearVddaBrownoutInterrupt();
    hw_power_ClearVddioBrownoutInterrupt();

    //--------------------------------------------------------------------------
    // Enable the power supply to assert brownout interrupts.
    //--------------------------------------------------------------------------

    hw_power_EnableVdddBrownoutInterrupt(TRUE);
    hw_power_EnableVddaBrownoutInterrupt(TRUE);
    hw_power_EnableVddioBrownoutInterrupt(TRUE);

    //--------------------------------------------------------------------------
    // Enable the battery brownout interrupt.
    //--------------------------------------------------------------------------

    // Check the battery.  Don't enable the brownout until the battery has at
    // least reached a level where it can do a handoff.
    u16SafeBattVolt = hw_power_ConvertSettingToBattBo(
                          g_ddi_power_SafeBatteryVoltageCode );

    // Check if the battery level is high enough for DCDC to operate.
    if( hw_power_GetBatteryVoltage() > u16SafeBattVolt )
    {
        hw_power_ClearBatteryBrownoutInterrupt();
        hw_power_EnableBatteryBrownoutInterrupt( true );
        hw_power_EnableBattBrownoutPowerdown( false );
    }

    return SUCCESS;

}
////////////////////////////////////////////////////////////////////////////////
//!
//! \brief Determines if the battery is charged enough to power DCDC's after
//! a handoff.
//!
//! \fntype Function
//!
//! \retval true Battery is sufficiently charged to power DCDC.
//! \retval false Battery is not sufficient to power DCDC.
////////////////////////////////////////////////////////////////////////////////
bool ddi_power_IsBattValidForHandoff( void )
{
    uint16_t u16SafeBattVolt;

    // First, check if we have a battery
    if( bBatteryConnected == false )
    {
        return false;
    }

    // Determine the brownout voltage.
    u16SafeBattVolt = hw_power_ConvertSettingToBattBo( g_ddi_power_SafeBatteryVoltageCode);

    // Check if the battery level is high enough for DCDC to operate.
    if( hw_power_GetBatteryVoltage() > u16SafeBattVolt )
        return true;
    else
        return false;


}
////////////////////////////////////////////////////////////////////////////////
//! \brief Enable 5V-to-battery handoff
//!
//! \fntype Function
//!
//! This function prepares the hardware for a 5V-to-battery handoff.  It assumes
//! the current configuration is using 5V as the power source.  The 5V
//! interrupt will be set up for a 5V removal.
//!
////////////////////////////////////////////////////////////////////////////////
void ddi_power_Enable5VoltsToBatteryHandoff(void)
{

    //--------------------------------------------------------------------------
    // Enable detection of 5V removal (unplug)
    //--------------------------------------------------------------------------

    hw_power_Enable5vUnplugDetect(TRUE);


    //hw_power_EnableAutoDcdcTransfer(TRUE) causes strange behavior when 4p2 is enabled.
    if(ddi_power_Is4p2Enabled())
    {
        if( BATT_VOLT__4P2TRG_THRESHOLD < hw_power_GetBatteryVoltage() )
        {
            HW_POWER_DCDC4P2.B.TRG = 0; // 4.2V
        }
        else
        {
            HW_POWER_DCDC4P2.B.TRG = 3; // 3.9V
        }

        hw_power_ClearVdd5vDroopInterrupt();
        hw_power_EnableVdd5vDroopInterrupt( true );
        hw_icoll_EnableVector((ICOLL_IRQ_enums_t)(VECTOR_IRQ_VDD5V_DROOP), true );
        return;
    }


    //--------------------------------------------------------------------------
    // Enable automatic transition to DCDC
    //--------------------------------------------------------------------------
    hw_power_EnableAutoDcdcTransfer(TRUE);

    //--------------------------------------------------------------------------
    // Disable hardware power down when 5V is removed since handoff to DC-DC
    // has been enabled.
    //--------------------------------------------------------------------------
    hw_power_Enable5vBrownoutPowerdown( false );
}
/////////////////////////////////////////////////////////////////////////////////
//! \brief Runs the test to determine if a battery is connected to device.
//!
//! \fntype Function
//!
//! The test will turn on the charger with minimal charge current to determine
//! if a battery is present.  This test should only be run once since subsequent
//! tests may be invalid due to the charge left on the battery pin from
//! capacitance.
//!
//! \retval True Test determined battery is connected.
//! \retval False Test determined battery is not connected.
/////////////////////////////////////////////////////////////////////////////////
bool ddi_power_TestBatteryConnection( void )
{
    //--------------------------------------------------------------------------
    // Check if we've already run the test before.  If so, we need to return
    // the result instead of running the test again.
    //--------------------------------------------------------------------------
    if( DidCurrAppRunBattTest() )
    {
        // This application ran the test once, so the battery connection flag is valid.
        return bBatteryConnected;
    }

    if( DidPrevAppRunBattTest() )
    {
        // If a previous application ran this test, return the result.
        return GetPrevAppTestResult();
    }


    //--------------------------------------------------------------------------
    // Let's make sure we have a stable battery voltage first.
    //--------------------------------------------------------------------------
    {
        uint16_t StartVolt, FirstVolt, SecondVolt;
        bool bVoltageStable = false;
        bool bPrevEnLoad = false;

        // Load the battery pin to drain the voltage if an open circuit.
        bPrevEnLoad = HW_POWER_CHARGE.B.ENABLE_LOAD;
        HW_POWER_CHARGE.B.ENABLE_LOAD = 1;

        StartVolt = hw_power_GetBatteryVoltage();
        while( !bVoltageStable )
        {
            // Take a reading, then wait some time before taking the
            // second reading.
            FirstVolt = hw_power_GetBatteryVoltage();
            hw_digctl_MicrosecondWait( 100000 );
            SecondVolt = hw_power_GetBatteryVoltage();

            // Are the two measurements within the stable margin?
            if( FirstVolt > SecondVolt )
            {
                if( FirstVolt - SecondVolt < 25 )
                    bVoltageStable = true;
            }
            else
            {
                if( SecondVolt - FirstVolt < 25 )
                    bVoltageStable = true;
            }

            // Has the voltage dropped significantly since test started?
            if( StartVolt > SecondVolt )
            {
                if( StartVolt - SecondVolt > 200 )
                {
                    SetPrevAppTestResult( false );
                    bBatteryConnectionTestComplete = true;
                    return false;
                }
            }

            else
            {
                if( SecondVolt - StartVolt > 200 )
                {
                    SetPrevAppTestResult( false );
                    bBatteryConnectionTestComplete = true;
                    return false;
                }
            }
        }

        HW_POWER_CHARGE.B.ENABLE_LOAD = bPrevEnLoad;
    }

    //--------------------------------------------------------------------------
    // Before we turn on the charger, first check if the battery voltage is
    // high enough to indicate a battery is present.
    //--------------------------------------------------------------------------
    if( hw_power_GetBatteryVoltage() > BATT_TEST__MIN_BATT_VOLT )
    {
        // If have any battery voltage at this point, then there is a battery.
        SetPrevAppTestResult( true );
        bBatteryConnectionTestComplete = true;
        return true;
    }


    //--------------------------------------------------------------------------
    // Run the battery detection test.
    //--------------------------------------------------------------------------
    {
        bool bBattCon;

        //----------------------------------------------------------------------
        // Save the previous settings, then initialize the charger for the
        // charger test.
        //----------------------------------------------------------------------
        bool prevBATTCHRG_I = HW_POWER_CHARGE.B.BATTCHRG_I;
        bool prevCHARGE_4P2_ILIMIT = HW_POWER_5VCTRL.B.CHARGE_4P2_ILIMIT;
        bool prevPWD_BATTCHRG = HW_POWER_CHARGE.B.PWD_BATTCHRG;
        bool prevPWD_CHARGE_4P2 = HW_POWER_5VCTRL.B.PWD_CHARGE_4P2;
        bool prevENABLE_4P2 = HW_POWER_DCDC4P2.B.ENABLE_4P2;

        // Set the total 4P2/CHRG current limit to 30mA
        HW_POWER_5VCTRL.B.CHARGE_4P2_ILIMIT = 3;

        // Turn on 4p2 rail and wait a little bit to let it start up.
        HW_POWER_DCDC4P2.B.ENABLE_4P2 = 1;
        HW_POWER_5VCTRL.B.PWD_CHARGE_4P2 = 0;
        hw_digctl_MicrosecondWait( 10 );

        // Turn on the charger with 30mA of charge current
        HW_POWER_CHARGE.B.BATTCHRG_I = 3;
        HW_POWER_CHARGE.B.PWD_BATTCHRG = 0;


        //----------------------------------------------------------------------
        // The battery pin has started charging.  The voltage on the battery pin
        // of an open circuit will jump to about 4.2V.  A real battery will
        // sink the small amount of current and the voltage will stay very low.
        //----------------------------------------------------------------------
        {
            bool bThresholdReached = false;
            bool bTimeoutExpired = false;
            uint32_t StartTime;

            StartTime = hw_digctl_GetCurrentTime();
            while( !bThresholdReached && !bTimeoutExpired )
            {
                // Check voltage threshold.
                if( hw_power_GetBatteryVoltage() > BATT_TEST__MIN_OPEN_CIRC_VOLT )
                {
                    // If the threshold was reached first, then we can
                    // assume we have an open circuit.
                    bThresholdReached = true;
                    bBattCon = false;
                }

                // Check timeout.
                if( ( hw_digctl_GetCurrentTime() - StartTime ) > BATT_TEST__WAIT_TIME_US )
                {
                    // If the timeout expired, then we assume a battery is
                    // present and it sank the current.
                    bTimeoutExpired = true;
                    bBattCon = true;
                }
            }
        }


        //----------------------------------------------------------------------
        // Restore the previous settings and return our result.
        //----------------------------------------------------------------------
        HW_POWER_CHARGE.B.PWD_BATTCHRG = prevPWD_BATTCHRG;
        HW_POWER_CHARGE.B.BATTCHRG_I = prevBATTCHRG_I;
        HW_POWER_5VCTRL.B.CHARGE_4P2_ILIMIT = prevCHARGE_4P2_ILIMIT;
        HW_POWER_5VCTRL.B.PWD_CHARGE_4P2 = prevPWD_CHARGE_4P2;
        HW_POWER_DCDC4P2.B.ENABLE_4P2 = prevENABLE_4P2;

        SetPrevAppTestResult(bBattCon);
        bBatteryConnectionTestComplete = true;
        return bBattCon;
    }

}
예제 #7
0
////////////////////////////////////////////////////////////////////////////////
//!
//! \brief Report the voltage across the battery.
//!
//! \fntype Function
//!
//! This function reports the voltage across the battery.
//!
//! \retval The voltage across the battery, in mV.
//!
////////////////////////////////////////////////////////////////////////////////
uint16_t  ddi_power_GetBattery(void)
{
    // Should return a value in range ~3000 - 4200 mV
    return hw_power_GetBatteryVoltage();
}