////////////////////////////////////////////////////////////////////////////////
//! \brief
//!
//! \return
////////////////////////////////////////////////////////////////////////////////
int PowerPrep_ConfigurePowerSource( void )
{
	int iReturnValue = SUCCESS;

	/* initialize DCDC operating parameters */
	hw_power_Init();

#ifdef  NO_DCDC_BATT_SOURCE

	/* device configured for no source to DCDC_BATT input (5V only power
	 * source).  This boot option doesn't waste time looking for a good
	 *  battery.  Battery powered operation and automatic voltage
	 *  measurements are disabled.
	*/
    // set bit 11 of PERSISTENT1
    HW_RTC_PERSISTENT1_SET(0x800);

    // clear bit 12 PERSISTENT1
    HW_RTC_PERSISTENT1_CLR(0x1000);

	bBatteryReady = false;
	bBatteryGood = false;

	printf("\r\nConfigured for 5v only power source.\
		Battery powered operation disabled.\r\n");


	/* Disable automatic battery voltage measurements which seem unnecessary
	 * for this configuration.
	 */
    BF_SET(POWER_BATTMONITOR,EN_BATADJ);
	BF_CLR(LRADC_CONVERSION, AUTOMATIC);
	BF_WR(POWER_BATTMONITOR, BATT_VAL,525);  //4200/8

	HW_POWER_BATTMONITOR.B.BRWNOUT_LVL = BATTERY_BRWNOUT_BITFIELD_VALUE;

	iReturnValue = PowerPrep_5vBoot();

#ifndef MXS_VBUS_CURRENT_DRAW
	PowerPrep_CPUClock2PLL();
#endif


#elif defined(NO_VDD5V_SOURCE)
	printf("\r\nConfigured for DCDC_BATT only power source.\r\n");

#ifdef mx28
	/* We only care about the DCDC_BATT source in this configuration */
	BF_SET(POWER_BATTMONITOR,PWDN_BATTBRNOUT_5VDETECT_ENABLE);
#endif

    // clear bit 11 PERSISTENT1
    HW_RTC_PERSISTENT1_CLR(0x800);

    // set bit 12 PERSISTENT1
    HW_RTC_PERSISTENT1_SET(0x1000);
	/* since the DCDC_BATT input is our only source, we'll assume
	 * it is good and attempt to boot.  If your device has uses
	 * this configuration but has a external DCDC_BATT source
	 * that takes time to ramp, you could add a voltage check
	 * and wait here until voltage reaches near the final level to
	 * avoid trigger a battery brownout when the voltage is too
	 * low.
	 */
	bBatteryReady = true;

	/* bBatteryGood is not used for this configuration */
	/* bBatteryGood = don't care */

	/*Boot from DCDC_BATT source*/
	iReturnValue = PowerPrep_BattBoot();
	PowerPrep_CPUClock2PLL();

	/* raise battery brownout level to programmed value. */
	PowerPrep_InitBattBo();

	/* Configured to not use a VDD5V source */
	HW_POWER_5VCTRL_SET(BM_POWER_5VCTRL_ILIMIT_EQ_ZERO);




#else

    //clear bit 11 and 12 of PERSISTENT1
    HW_RTC_PERSISTENT1_CLR(0x1800);

	/* check if Battery Voltage is high enough for full
	* power operation.
	*/
	bBatteryReady = PowerPrep_IsBatteryReady();

	if(!IsVdd5vGtVddio())
	{
		/* this option allows for fast booting without
		* the unecessary delay required for proper
		* battery detection when booting from 5v.
		*/

		/* battery voltage is present and 5v is not connected,
		* assume valid battery voltage source is present.  Battery
		* brownout protection will take care of supply protection
		* if battery becomes invalid in the future
		*/
 		bBatteryGood = true;
		printf("\r\nboot from battery. 5v input not detected\r\n");
		/*Boot from battery*/
		iReturnValue = PowerPrep_BattBoot();
		PowerPrep_CPUClock2PLL();
	}
	else
	{
		/* 5v input detected, boot from 5V.
		*/
		bBatteryGood = PowerPrep_IsBatteryGood();
		if(!bBatteryGood) {
				BF_CLR(LRADC_CONVERSION, AUTOMATIC);
				BF_WR(POWER_BATTMONITOR, BATT_VAL,0);
				printf("\r\nNo battery or bad battery\
					detected!!!.Disabling battery\
					voltage measurements./r/n");
		}
		iReturnValue = PowerPrep_5vBoot();


#ifndef MXS_VBUS_CURRENT_DRAW
		PowerPrep_CPUClock2PLL();
#endif /* MXS_VBUS_CURRENT_DRAW */
	}
Exemple #2
0
////////////////////////////////////////////////////////////////////////////////
//! \brief  Prepares the power block for the application.
//!
//! \return SUCCESS(0) Power block ready.
////////////////////////////////////////////////////////////////////////////////
//int PowerPrep( void )
int _start( void )
{
	int iRtn = SUCCESS;
	auart_init();
#ifndef mx28
	HW_DIGCTL_CTRL_SET(BM_DIGCTL_CTRL_USE_SERIAL_JTAG);
#else

#define SSP0_PIN_DRIVE_12mA 0x2
// For EMI 200MHz,must enable SSP0 pin drive to 12mA,or the SD boot will fail.
        HW_PINCTRL_DRIVE8_CLR(
		BM_PINCTRL_DRIVE8_BANK2_PIN07_MA |
		BM_PINCTRL_DRIVE8_BANK2_PIN06_MA |
		BM_PINCTRL_DRIVE8_BANK2_PIN05_MA |
		BM_PINCTRL_DRIVE8_BANK2_PIN04_MA |
		BM_PINCTRL_DRIVE8_BANK2_PIN03_MA |
		BM_PINCTRL_DRIVE8_BANK2_PIN02_MA |
		BM_PINCTRL_DRIVE8_BANK2_PIN01_MA |
		BM_PINCTRL_DRIVE8_BANK2_PIN00_MA);

	HW_PINCTRL_DRIVE9_CLR(
		BM_PINCTRL_DRIVE9_BANK2_PIN10_MA |
		BM_PINCTRL_DRIVE9_BANK2_PIN09_MA |
		BM_PINCTRL_DRIVE9_BANK2_PIN08_MA);

	HW_PINCTRL_DRIVE8_SET(
		(SSP0_PIN_DRIVE_12mA << BP_PINCTRL_DRIVE8_BANK2_PIN07_MA) |
		(SSP0_PIN_DRIVE_12mA << BP_PINCTRL_DRIVE8_BANK2_PIN06_MA) |
		(SSP0_PIN_DRIVE_12mA << BP_PINCTRL_DRIVE8_BANK2_PIN05_MA) |
		(SSP0_PIN_DRIVE_12mA << BP_PINCTRL_DRIVE8_BANK2_PIN04_MA) |
		(SSP0_PIN_DRIVE_12mA << BP_PINCTRL_DRIVE8_BANK2_PIN03_MA) |
		(SSP0_PIN_DRIVE_12mA << BP_PINCTRL_DRIVE8_BANK2_PIN02_MA) |
		(SSP0_PIN_DRIVE_12mA << BP_PINCTRL_DRIVE8_BANK2_PIN01_MA) |
		(SSP0_PIN_DRIVE_12mA << BP_PINCTRL_DRIVE8_BANK2_PIN00_MA));

	HW_PINCTRL_DRIVE9_SET(
		(SSP0_PIN_DRIVE_12mA << BP_PINCTRL_DRIVE9_BANK2_PIN10_MA) |
		(SSP0_PIN_DRIVE_12mA << BP_PINCTRL_DRIVE9_BANK2_PIN09_MA) |
		(SSP0_PIN_DRIVE_12mA << BP_PINCTRL_DRIVE9_BANK2_PIN08_MA));

#endif

	PowerPrep_CPUClock2XTAL();
	PowerPrep_ClearAutoRestart();

	hw_power_SetPowerClkGate( false );

	printf("\r\nPowerPrep start initialize power...\r\n");
	HW_POWER_VDDDCTRL.B.LINREG_OFFSET = HW_POWER_LINREG_OFFSET_STEP_BELOW;
	HW_POWER_VDDACTRL.B.LINREG_OFFSET = HW_POWER_LINREG_OFFSET_STEP_BELOW;
	HW_POWER_VDDIOCTRL.B.LINREG_OFFSET = HW_POWER_LINREG_OFFSET_STEP_BELOW;

	// Ready the power block for 5V detection.
	PowerPrep_Setup5vDetect();
	PowerPrep_SetupBattDetect();

	// Ensure the power source that turned on the device is sufficient to
	// power the device.
	PowerPrep_ConfigurePowerSource();

	PowerPrep_EnableOutputRailProtection();
	/* 3.3V is necessary to achieve best power supply capability
	* and best EMI I/O performance.
	*/
	ddi_power_SetVddio(3300, 3150);

#ifdef mx28
	ddi_power_SetVddd(1350, 1200);
#endif

	HW_POWER_CTRL_CLR(BM_POWER_CTRL_VDDD_BO_IRQ |
	BM_POWER_CTRL_VDDA_BO_IRQ |
	BM_POWER_CTRL_VDDIO_BO_IRQ |
	BM_POWER_CTRL_VDD5V_DROOP_IRQ |
	BM_POWER_CTRL_VBUSVALID_IRQ |
	BM_POWER_CTRL_BATT_BO_IRQ |
	BM_POWER_CTRL_DCDC4P2_BO_IRQ
	);
	/* If Battery not ready,setup the auto power down if we lost 5V.*/
	if (!bBatteryReady)
		HW_POWER_5VCTRL_SET(BM_POWER_5VCTRL_PWDN_5VBRNOUT);
	return iRtn;
}
////////////////////////////////////////////////////////////////////////////////
//! \brief  Prepares the power block for the application.
//!
//! \return SUCCESS(0) Power block ready.
////////////////////////////////////////////////////////////////////////////////
//int PowerPrep( void )
int _start( void )
{
	int iRtn = SUCCESS;
#ifndef mx28
	HW_DIGCTL_CTRL_SET(BM_DIGCTL_CTRL_USE_SERIAL_JTAG);
#else

#define SSP0_PIN_DRIVE_12mA 0x2
// For EMI 200MHz,must enable SSP0 pin drive to 12mA,or the SD boot will fail.
        HW_PINCTRL_DRIVE8_CLR(
		BM_PINCTRL_DRIVE8_BANK2_PIN07_MA |
		BM_PINCTRL_DRIVE8_BANK2_PIN06_MA |
		BM_PINCTRL_DRIVE8_BANK2_PIN05_MA |
		BM_PINCTRL_DRIVE8_BANK2_PIN04_MA |
		BM_PINCTRL_DRIVE8_BANK2_PIN03_MA |
		BM_PINCTRL_DRIVE8_BANK2_PIN02_MA |
		BM_PINCTRL_DRIVE8_BANK2_PIN01_MA |
		BM_PINCTRL_DRIVE8_BANK2_PIN00_MA);

	HW_PINCTRL_DRIVE9_CLR(
		BM_PINCTRL_DRIVE9_BANK2_PIN10_MA |
		BM_PINCTRL_DRIVE9_BANK2_PIN09_MA |
		BM_PINCTRL_DRIVE9_BANK2_PIN08_MA);

	HW_PINCTRL_DRIVE8_SET(
		(SSP0_PIN_DRIVE_12mA << BP_PINCTRL_DRIVE8_BANK2_PIN07_MA) |
		(SSP0_PIN_DRIVE_12mA << BP_PINCTRL_DRIVE8_BANK2_PIN06_MA) |
		(SSP0_PIN_DRIVE_12mA << BP_PINCTRL_DRIVE8_BANK2_PIN05_MA) |
		(SSP0_PIN_DRIVE_12mA << BP_PINCTRL_DRIVE8_BANK2_PIN04_MA) |
		(SSP0_PIN_DRIVE_12mA << BP_PINCTRL_DRIVE8_BANK2_PIN03_MA) |
		(SSP0_PIN_DRIVE_12mA << BP_PINCTRL_DRIVE8_BANK2_PIN02_MA) |
		(SSP0_PIN_DRIVE_12mA << BP_PINCTRL_DRIVE8_BANK2_PIN01_MA) |
		(SSP0_PIN_DRIVE_12mA << BP_PINCTRL_DRIVE8_BANK2_PIN00_MA));

	HW_PINCTRL_DRIVE9_SET(
		(SSP0_PIN_DRIVE_12mA << BP_PINCTRL_DRIVE9_BANK2_PIN10_MA) |
		(SSP0_PIN_DRIVE_12mA << BP_PINCTRL_DRIVE9_BANK2_PIN09_MA) |
		(SSP0_PIN_DRIVE_12mA << BP_PINCTRL_DRIVE9_BANK2_PIN08_MA));

#endif

	PowerPrep_CPUClock2XTAL();
	PowerPrep_ClearAutoRestart();

	hw_power_SetPowerClkGate( false );

	printf("\r\nPowerPrep start initialize power...\r\n");
	HW_POWER_VDDDCTRL.B.LINREG_OFFSET = HW_POWER_LINREG_OFFSET_STEP_BELOW;
	HW_POWER_VDDACTRL.B.LINREG_OFFSET = HW_POWER_LINREG_OFFSET_STEP_BELOW;
	HW_POWER_VDDIOCTRL.B.LINREG_OFFSET = HW_POWER_LINREG_OFFSET_STEP_BELOW;

	// Ready the power block for 5V detection.
	PowerPrep_Setup5vDetect();
	PowerPrep_SetupBattDetect();

	// Ensure the power source that turned on the device is sufficient to
	// power the device.
	PowerPrep_ConfigurePowerSource();

	PowerPrep_EnableOutputRailProtection();
	/* 3.3V is necessary to achieve best power supply capability
	* and best EMI I/O performance.
	*/
	ddi_power_SetVddio(3300, 3150);

	HW_POWER_CTRL_CLR(BM_POWER_CTRL_VDDD_BO_IRQ |
	BM_POWER_CTRL_VDDA_BO_IRQ |
	BM_POWER_CTRL_VDDIO_BO_IRQ |
	BM_POWER_CTRL_VDD5V_DROOP_IRQ |
	BM_POWER_CTRL_VBUSVALID_IRQ |
	BM_POWER_CTRL_BATT_BO_IRQ |
	BM_POWER_CTRL_DCDC4P2_BO_IRQ
	);
	/* If Battery not ready,setup the auto power down if we lost 5V.*/
	if (!bBatteryReady)
	{
		HW_POWER_5VCTRL_SET(BM_POWER_5VCTRL_PWDN_5VBRNOUT);

#if defined(NO_DCDC_BATT_SOURCE) && defined(mx28)
	/* On i.MX28, a new bit has been added to allow automatic hardware
	 * shutdown if VDD4P2 browns out.  If we permanently only have a VDD5V
	 * source, we want to enable this bit.  For devices with dead batteries,
	 * we could also temporarily set this bit until the kernel battery
	 * charger sufficiently charges the battery but we won't do this for
	 * now as the latest release kernel versions aren't aware of  it
	 * and thus don't handle the proper setting/clearing of this bit.
	 */
		HW_POWER_REFCTRL_SET(1<<7);
#endif

	}


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