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