Example #1
0
////////////////////////////////////////////////////////////////////////////////
//! See hw_lradc.h for details.
////////////////////////////////////////////////////////////////////////////////
RtStatus_t hw_lradc_EnableBatteryMeasurement( hw_lradc_DelayTrigger_t eTrigger,
                                              uint16_t u16SamplingInterval)
{
    hw_lradc_Channel_t       eChannel = BATTERY_VOLTAGE_CH;

    //
    // Check if the lradc channel is present in this product
    //
    if( hw_lradc_GetChannelPresent(eChannel) == 0 )
        return (ERROR_HW_LRADC_CH_NOT_PRESENT);

    // Disable the channel interrupt
    hw_lradc_EnableInterrupt(eChannel, FALSE);

    hw_lradc_ClearInterruptFlag(eChannel);

    // Configure the battery conversion register
    BF_WR(LRADC_CONVERSION, SCALE_FACTOR, 2);


    // Enable the automatic update mode of BATT_VALUE field in HW_POWER_MONITOR
    BF_SET(LRADC_CONVERSION, AUTOMATIC);

    hw_lradc_ConfigureChannel(  eChannel,   //Lradc channel
                                    FALSE,      //DIVIDE_BY_TWO
                                    FALSE,      //ACCUMULATE
                                    0);         //NUM_SAMPLES

    // schedule a conversion before the setting up of the delay channel
    // so the user can have a good value right after the function returns
    hw_lradc_ScheduleChannel(eChannel);

    // Setup the trigger loop forever,
    hw_lradc_SetDelayTrigger( eTrigger,         // Trigger Index
                              (1 << eChannel),  // Lradc channels
                              (1 << eTrigger),  // Restart the triggers
                              0,                // No loop count
                              u16SamplingInterval); // 0.5*N msec on 2khz

    // Clear the accumulator & NUM_SAMPLES
    HW_LRADC_CHn_CLR(eChannel, 0xFFFFFFFF);

    // Kick off the LRADC battery measurement
    hw_lradc_SetDelayTriggerKick(eTrigger, TRUE);


    /* Wait for first measurement of battery.  Should occur in 13 LRADC clock
     * cycles from the time of channel kickoff.  Also add some wait time for
     * copy to the power supply BATT_VAL field to occur.
     */
    hw_digctl_MicrosecondWait(10);



    return SUCCESS;
}
Example #2
0
RtStatus_t hw_power_InitBatteryMonitor(hw_lradc_DelayTrigger_t eTrigger,
                                       uint32_t u32SamplingInterval)
{
    RtStatus_t rtn;


    //----------------------------------------------------------------------
    // Start up the battery measurements
    //----------------------------------------------------------------------
    rtn = hw_lradc_EnableBatteryMeasurement(eTrigger,
                                            u32SamplingInterval);


    // wait to make sure first automatic conversion and copy is complete
    // Todo: replace this with a manual first conversion and write to
    // BATT_VAL field.
    hw_digctl_MicrosecondWait(30);



    return rtn;
}
/////////////////////////////////////////////////////////////////////////////////
//! \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;
    }

}
Example #4
0
////////////////////////////////////////////////////////////////////////////////
//! See hw_power.h for details.
////////////////////////////////////////////////////////////////////////////////
RtStatus_t hw_power_Init(void)
{
    RtStatus_t rtn = SUCCESS;

    //--------------------------------------------------------------------------
    // Make the clock registers accessible by ungating power block
    //--------------------------------------------------------------------------
    BF_CLR(POWER_CTRL, CLKGATE);

    //--------------------------------------------------------------------------
    // Improve efficieny and reduce transient ripple
    //--------------------------------------------------------------------------

    {
        //----------------------------------------------------------------------
        // Change stepping voltage only after the diff control loop
        // has toggled as well.
        //----------------------------------------------------------------------
        BF_SET(POWER_LOOPCTRL, TOGGLE_DIF);

        //----------------------------------------------------------------------
        // Enable the commom mode and differential mode hysterisis
        //----------------------------------------------------------------------
        BF_SET(POWER_LOOPCTRL, EN_CM_HYST);
        BF_SET(POWER_LOOPCTRL, EN_DF_HYST);



        //----------------------------------------------------------------------
        // To run with a lower battery voltage, adjust the duty
        // cycle positive limit
        //----------------------------------------------------------------------
        BF_WR(POWER_DCLIMITS, POSLIMIT_BUCK, 0x30);



    }

    //--------------------------------------------------------------------------
    // Finally enable the battery adjust
    //--------------------------------------------------------------------------
    BF_SET(POWER_BATTMONITOR,EN_BATADJ);

    //----------------------------------------------------------------------
    // Increase the RCSCALE_THRESHOLD
    //----------------------------------------------------------------------
    BF_SET(POWER_LOOPCTRL, RCSCALE_THRESH);

    //----------------------------------------------------------------------
    // Increase the RCSCALE level for quick DCDC response to dynamic load
    //----------------------------------------------------------------------
    hw_power_EnableRcScale(HW_POWER_RCSCALE_8X_INCR);

    hw_power_EnableHalfFets(FALSE);
    hw_power_EnableDoubleFets(TRUE);
    //--------------------------------------------------------------------------
    // Initialize the variables we use in hw_power driver.
    //--------------------------------------------------------------------------
    if( bMasterFlagsInitialized == false )
    {
        // Initialize the brownout variables and synchronize these with the
        // master brownout register.
        bEnableMaster5vBrownout = HW_POWER_5VCTRL.B.PWDN_5VBRNOUT;
        bEnableMasterBattBrownout = HW_POWER_BATTMONITOR.B.PWDN_BATTBRNOUT;

        // Initialize the 4p2 and charger variables.  Both the local and the
        // master have to be true for the variable to be true.

        bEnableMaster4p2 = HW_POWER_DCDC4P2.B.ENABLE_4P2 &&
                           !HW_POWER_5VCTRL.B.PWD_CHARGE_4P2;
        bEnableMasterCharge = !HW_POWER_CHARGE.B.PWD_BATTCHRG &&
                              !HW_POWER_5VCTRL.B.PWD_CHARGE_4P2;


        bMasterFlagsInitialized = true;
    }

    /* Enable 5V to battery source handoff on detection of 5V
     * disconnection.  Get the DCDC control loop ready for
     * action.  Leaving DCDC_XFER set causes problems with 4p2
     * operation and has other issues so we only leave
     * it on long enough to prepare the DCDC control loop
     */
    HW_POWER_5VCTRL_SET(BM_POWER_5VCTRL_DCDC_XFER);
    hw_digctl_MicrosecondWait(30);
    HW_POWER_5VCTRL_CLR(BM_POWER_5VCTRL_DCDC_XFER);


    return rtn;
}