void INT_VDD5V(void)
{
#ifdef USE_VBUSVALID
    if(BF_RD(POWER_CTRL, VBUSVALID_IRQ))
    {
        if(BF_RD(POWER_STS, VBUSVALID))
            usb_insert_int();
        else
            usb_remove_int();
        /* reverse polarity */
        BF_WR(POWER_CTRL_TOG, POLARITY_VBUSVALID(1));
        /* clear int */
        BF_CLR(POWER_CTRL, VBUSVALID_IRQ);
    }
#else
    if(BF_RD(POWER_CTRL, VDD5V_GT_VDDIO_IRQ))
    {
        if(BF_RD(POWER_STS, VDD5V_GT_VDDIO))
            usb_insert_int();
        else
            usb_remove_int();
        /* reverse polarity */
        BF_WR(POWER_CTRL_TOG, POLARITY_VDD5V_GT_VDDIO(1));
        /* clear int */
        BF_CLR(POWER_CTRL, VDD5V_GT_VDDIO_IRQ);
    }
#endif
}
void imx233_power_set_stop_current(unsigned current)
{
#if IMX233_SUBTARGET >= 3700
    BF_CLR(POWER_CHARGE, STOP_ILIMIT);
#else
    BF_CLR(POWER_BATTCHRG, STOP_ILIMIT);
#endif
    /* find closest current GREATHER THAN OR EQUAL TO the expected current */
    unsigned sum = 0;
    for(unsigned i = 0; i < ARRAYLEN(g_charger_stop_current_bits); i++)
        sum += g_charger_stop_current_bits[i].current;
    for(unsigned i = 0; i < ARRAYLEN(g_charger_stop_current_bits); i++)
    {
        sum -= g_charger_stop_current_bits[i].current;
        if(current > sum)
        {
            current -= g_charger_stop_current_bits[i].current;
#if IMX233_SUBTARGET >= 3700
            BF_WR(POWER_CHARGE_SET, STOP_ILIMIT(g_charger_stop_current_bits[i].bit));
#else
            BF_WR(POWER_BATTCHRG_SET, STOP_ILIMIT(g_charger_stop_current_bits[i].bit));
#endif
        }
    }
}
Exemplo n.º 3
0
void imx233_lcdif_set_data_swizzle(unsigned swizzle)
{
#if IMX233_SUBTARGET >= 3780
    BF_WR(LCDIF_CTRL, INPUT_DATA_SWIZZLE, swizzle);
#else
    BF_WR(LCDIF_CTRL, DATA_SWIZZLE, swizzle);
#endif
}
Exemplo n.º 4
0
////////////////////////////////////////////////////////////////////////////////
//! See hw_lradc.h for details.
////////////////////////////////////////////////////////////////////////////////
void hw_lradc_AssignChannel( hw_lradc_Channel_t eVirtualChannel,
                             hw_lradc_Channel_t ePhysicalChannel )
{
    // Maps the physical channel to virtual channel
    switch ( eVirtualChannel )
    {
        case LRADC_CH0:
            BF_WR( LRADC_CTRL4, LRADC0SELECT, ePhysicalChannel );
            break;
        case LRADC_CH1:
            BF_WR( LRADC_CTRL4, LRADC1SELECT, ePhysicalChannel );
            break;
        case LRADC_CH2:
            BF_WR( LRADC_CTRL4, LRADC2SELECT, ePhysicalChannel );
            break;
        case LRADC_CH3:
            BF_WR( LRADC_CTRL4, LRADC3SELECT, ePhysicalChannel );
            break;
        case LRADC_CH4:
            BF_WR( LRADC_CTRL4, LRADC4SELECT, ePhysicalChannel );
            break;
        case LRADC_CH5:
            BF_WR( LRADC_CTRL4, LRADC5SELECT, ePhysicalChannel );
            break;
        case LRADC_CH6:
            BF_WR( LRADC_CTRL4, LRADC6SELECT, ePhysicalChannel );
            break;
        case LRADC_CH7:
            BF_WR( LRADC_CTRL4, LRADC7SELECT, ePhysicalChannel );
            break;
        default:
            break;
    }
}
Exemplo n.º 5
0
void imx233_audioout_preinit(void)
{

    /* Enable AUDIOOUT block */
    imx233_reset_block(&HW_AUDIOOUT_CTRL);
    /* Enable digital filter clock */
    imx233_clkctrl_enable(CLK_FILT, true);
    /* Enable DAC */
    BF_CLR(AUDIOOUT_ANACLKCTRL, CLKGATE);
    /* Set capless mode */
#if IMX233_AUDIO_COUPLING_MODE == ACM_CAP
    BF_SET(AUDIOOUT_PWRDN, CAPLESS);
#else
    BF_CLR(AUDIOOUT_PWRDN, CAPLESS);
#endif
    /* Set word-length to 16-bit */
    BF_SET(AUDIOOUT_CTRL, WORD_LENGTH);
    /* Power up DAC */
    BF_CLR(AUDIOOUT_PWRDN, DAC);
    /* Hold HP to ground to avoid pop, then release and power up HP */
    BF_SET(AUDIOOUT_ANACTRL, HP_HOLD_GND);
    BF_CLR(AUDIOOUT_PWRDN, HEADPHONE);
    /* Set HP mode to AB */
    BF_SET(AUDIOOUT_ANACTRL, HP_CLASSAB);
    /* change bias to -50% */
    BF_WR(AUDIOOUT_TEST, HP_I1_ADJ, 1);
    BF_WR(AUDIOOUT_REFCTRL, BIAS_CTRL, 1);
#if IMX233_SUBTARGET >= 3700
    BF_SET(AUDIOOUT_REFCTRL, RAISE_REF);
#endif
    BF_SET(AUDIOOUT_REFCTRL, XTAL_BGR_BIAS);
    /* Stop holding to ground */
    BF_CLR(AUDIOOUT_ANACTRL, HP_HOLD_GND);
    /* Set dmawait count to 31 (see errata, workaround random stop) */
    BF_WR(AUDIOOUT_CTRL, DMAWAIT_COUNT, 31);
    /* start converting audio */
    BF_SET(AUDIOOUT_CTRL, RUN);
    /* unmute DAC */
    HW_AUDIOOUT_DACVOLUME_CLR = BM_OR2(AUDIOOUT_DACVOLUME, MUTE_LEFT, MUTE_RIGHT);
    /* send a few samples to avoid pop */
    HW_AUDIOOUT_DATA = 0;
    HW_AUDIOOUT_DATA = 0;
    HW_AUDIOOUT_DATA = 0;
    HW_AUDIOOUT_DATA = 0;
}
Exemplo n.º 6
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;
}
Exemplo n.º 7
0
////////////////////////////////////////////////////////////////////////////////
//! See hw_power.h for details.
////////////////////////////////////////////////////////////////////////////////
void hw_power_SetBatteryMonitorVoltage(uint16_t u16BattVolt)
{
    uint16_t u16BattValue;

    // Adjust for 8-mV LSB resolution
    u16BattValue = u16BattVolt/BATT_VAL_FIELD_RESOL;

    // Write to register
    BF_WR(POWER_BATTMONITOR, BATT_VAL, u16BattValue);
}
void imx233_power_set_charge_current(unsigned current)
{
#if IMX233_SUBTARGET >= 3700
    BF_CLR(POWER_CHARGE, BATTCHRG_I);
#else
    BF_CLR(POWER_BATTCHRG, BATTCHRG_I);
#endif
    /* find closest current LOWER THAN OR EQUAL TO the expected current */
    for(unsigned i = 0; i < ARRAYLEN(g_charger_current_bits); i++)
        if(current >= g_charger_current_bits[i].current)
        {
            current -= g_charger_current_bits[i].current;
#if IMX233_SUBTARGET >= 3700
            BF_WR(POWER_CHARGE_SET, BATTCHRG_I(g_charger_current_bits[i].bit));
#else
            BF_WR(POWER_BATTCHRG_SET, BATTCHRG_I(g_charger_current_bits[i].bit));
#endif
        }
}
Exemplo n.º 9
0
void imx233_powermgmt_init(void)
{
    imx233_power_set_charge_current(IMX233_CHARGE_CURRENT);
    imx233_power_set_stop_current(IMX233_STOP_CURRENT);
#if IMX233_SUBTARGET >= 3700
    /* assume that adc_init was called and battery monitoring via LRADC setup */
    BF_WR(POWER_BATTMONITOR, EN_BATADJ(1));
    /* setup linear regulator offsets to 25 mV below to prevent contention between
     * linear regulators and DCDC */
    BF_WR(POWER_VDDDCTRL, LINREG_OFFSET(2));
    BF_WR(POWER_VDDACTRL, LINREG_OFFSET(2));
    BF_WR(POWER_VDDIOCTRL, LINREG_OFFSET(2));
    /* enable a few bits controlling the DC-DC as recommended by Freescale */
    BF_SET(POWER_LOOPCTRL, TOGGLE_DIF);
    BF_SET(POWER_LOOPCTRL, EN_CM_HYST);
    BF_CS(POWER_LOOPCTRL, EN_RCSCALE(1));
#else
    BF_SET(POWER_5VCTRL, LINREG_OFFSET);
#endif
}
Exemplo n.º 10
0
////////////////////////////////////////////////////////////////////////////////
//! See hw_lradc.h for details.
////////////////////////////////////////////////////////////////////////////////
void hw_lradc_Init(bool bEnableOnChipGroundRef,  hw_lradc_ClockFreq_t eFreq)
{
    if( bHwLradcInitialized == true )
    {
        return;
    }

    // Clear the Soft Reset for normal operation
    BF_CLR(LRADC_CTRL0, SFTRST);

    // Clear the Clock Gate for normal operation
    BF_CLR(LRADC_CTRL0, CLKGATE);      // use bitfield clear macro

    // Set on-chip ground ref
    if(bEnableOnChipGroundRef)
    {
        // Enable the onchip ground ref of LRADC conversions
        BF_SET( LRADC_CTRL0, ONCHIP_GROUNDREF);
    }
    else
    {
        // Disable the onchip ground ref of LRADC conversions
        BF_CLR( LRADC_CTRL0, ONCHIP_GROUNDREF);
    }

    // Set LRADC conversion clock frequency
    BF_WR(LRADC_CTRL3, CYCLE_TIME, eFreq);

    // Make sure the LRADC channel-6 selected for VDDIO
    BF_WR(LRADC_CTRL4, LRADC6SELECT, VDDIO_VOLTAGE_CH);

    // Make sure the LRADC channel-7 selected for Battery
    BF_WR(LRADC_CTRL4, LRADC7SELECT, BATTERY_VOLTAGE_CH);

    bHwLradcInitialized = true;
}
Exemplo n.º 11
0
// bbp = bytes per pixel
static void pio_send(unsigned len, unsigned bpp, uint8_t *buf)
{
    /* WARNING: the imx233 has a limitation on count wrt to byte packing, the
     * count must be a multiple of 2 with maximum packing when word-length is
     * 16-bit!
     * On the other hand, 8-bit word length doesn't seem to have any limitations,
     * for example one can send 3 bytes with a packing format of 0xf
     * WARNING for this function to work properly with any swizzle, we have to
     * make sure we pack as many 32-bits as possible even when the data is not
     * word-aligned */
    imx233_lcdif_set_byte_packing_format(0xf);
    /* compute shift between buf and next word-aligned pointer */
    int shift = 0;
    uint32_t temp_buf = 0;
    int count = len * bpp; // number of bytes
    while(0x3 & (intptr_t)buf)
    {
        temp_buf = temp_buf | *buf++ << shift;
        shift += 8;
        count--;
    }
    /* starting from now, all read are 32-bit */
    uint32_t *wbuf = (void *)buf;
#if IMX233_SUBTARGET >= 3780
    HW_LCDIF_TRANSFER_COUNT = BF_OR2(LCDIF_TRANSFER_COUNT, V_COUNT(1), H_COUNT(len));
#else
    BF_WR(LCDIF_CTRL, COUNT, len);
#endif
    BF_SET(LCDIF_CTRL, RUN);
    while(count > 0)
    {
        uint32_t val = *wbuf++;
        imx233_lcdif_wait_fifo();
        HW_LCDIF_DATA = temp_buf | val << shift;
        if(shift != 0)
            temp_buf = val >> (32 - shift);
        count -= 4;
    }
    /* send remaining bytes if any */
    if(shift != 0)
    {
        imx233_lcdif_wait_fifo();
        HW_LCDIF_DATA = temp_buf;
    }
    imx233_lcdif_wait_ready();
}
Exemplo n.º 12
0
void imx233_powermgmt_init(void)
{
    imx233_power_set_charge_current(IMX233_CHARGE_CURRENT);
    imx233_power_set_stop_current(IMX233_STOP_CURRENT);
    /* assume that adc_init was called and battery monitoring via LRADC setup */
    BF_WR(POWER_BATTMONITOR, EN_BATADJ, 1);
#if IMX233_SUBTARGET >= 3700
    /* setup linear regulator offsets to 25 mV below to prevent contention between
     * linear regulators and DCDC */
    BF_WR(POWER_VDDDCTRL, LINREG_OFFSET, 2);
    BF_WR(POWER_VDDACTRL, LINREG_OFFSET, 2);
    BF_WR(POWER_VDDIOCTRL, LINREG_OFFSET, 2);
    /* enable DCDC (more efficient) */
    BF_SET(POWER_5VCTRL, ENABLE_DCDC);
    BF_CLR(POWER_5VCTRL, DCDC_XFER);
#else
    BF_SET(POWER_5VCTRL, LINREG_OFFSET);
    BF_SET(POWER_5VCTRL, EN_DCDC1);
    BF_SET(POWER_5VCTRL, EN_DCDC2);
#endif

#if IMX233_SUBTARGET >= 3780
    /* enable a few bits controlling the DC-DC as recommended by Freescale */
    BF_SET(POWER_LOOPCTRL, TOGGLE_DIF);
    BF_SET(POWER_LOOPCTRL, EN_CM_HYST);
    BF_CLR(POWER_LOOPCTRL, EN_RCSCALE);
    BF_SETV(POWER_LOOPCTRL, EN_RCSCALE, 1);
    /* adjust arbitration between 4.2 and battery */
    BF_WR(POWER_DCDC4P2, CMPTRIP, 0); /* 85% */
    BF_WR(POWER_DCDC4P2, DROPOUT_CTRL, 0xe); /* select greater, 200 mV drop */
    /* make sure we are in a known state: disable charger and 4p2 */
    BF_SET(POWER_CHARGE, PWD_BATTCHRG);
    BF_WR(POWER_DCDC4P2, ENABLE_DCDC, 0);
    BF_WR(POWER_DCDC4P2, ENABLE_4P2, 0);
    BF_SET(POWER_5VCTRL, PWD_CHARGE_4P2);
#endif
}
Exemplo n.º 13
0
////////////////////////////////////////////////////////////////////////////////
//! \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 */
	}
Exemplo n.º 14
0
////////////////////////////////////////////////////////////////////////////////
//! \brief
//!
//! \return
////////////////////////////////////////////////////////////////////////////////
int PowerPrep_ConfigurePowerSource( void )
{
	int iReturnValue = SUCCESS;

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

#ifdef  NO_BATTERY_VOLTAGE_SOURCE

	/* device configured for "no battery" operation (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.
	*/

	bBatteryReady = false;
	bBatteryGood = false;

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

	/* disable automatic battery voltage measurements */
	BF_CLR(LRADC_CONVERSION, AUTOMATIC);
	BF_WR(POWER_BATTMONITOR, BATT_VAL,0);

	iReturnValue = PowerPrep_5vBoot();

#ifndef MXS_VBUS_CURRENT_DRAW
	PowerPrep_CPUClock2PLL();
#endif
#else
	/* 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.  Now we need to determine if a
		* valid battery source is present to decide which
		* power source to use during bootup.
		*/
		bBatteryGood = PowerPrep_IsBatteryGood();
		if(!bBatteryReady)
		{
			if(bBatteryGood)
				/* control arrives here if the battery voltage source
				* appears to be chargeable but the voltage is current
				* too low to use as a reliable battery voltage source.
				*/
				printf("\r\nChargeable battery detected but\
					the voltage is too low for battery\
					powered operation.Booting from 5V\
					power source.\r\n");
			else {
				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 */
		}
		else
		{
			printf("\r\n5v source detected.Valid battery\
				voltage detected.Booting from battery\
				voltage source.\r\n");
			/*Boot from battery*/
			iReturnValue = PowerPrep_BattBoot();
			PowerPrep_CPUClock2PLL();

		}
	}
Exemplo n.º 15
0
void charging_algorithm_step(void)
{
#if IMX233_SUBTARGET >= 3700
    bool is_5v_present = usb_detect() == USB_INSERTED;

    /* initial state & 5v -> battery transition */
    if(!is_5v_present && charge_state != DISCHARGING)
    {
        logf("pwrmgmt: * -> discharging");
        logf("pwrmgmt: disable charger and 4p2"); 
        charge_state = DISCHARGING;
        /* 5V has been lost: disable 4p2 power rail */
        BF_SET(POWER_CHARGE, PWD_BATTCHRG);
#if IMX233_SUBTARGET >= 3780
        BF_WR(POWER_DCDC4P2, ENABLE_DCDC(0));
        BF_WR(POWER_DCDC4P2, ENABLE_4P2(0));
        BF_WR(POWER_5VCTRL, CHARGE_4P2_ILIMIT(0));
        BF_SET(POWER_5VCTRL, PWD_CHARGE_4P2);
#endif
    }
    /* battery -> 5v transition */
    else if(is_5v_present && charge_state == DISCHARGING)
    {
        logf("pwrmgmt: discharging -> trickle");
        logf("pwrmgmt: begin charging 4p2");
#if IMX233_SUBTARGET >= 3780
        /* 5V has been detected: prepare 4.2V power rail for activation
         * WARNING we can reach this situation when starting after Freescale bootloader
         * or after RoLo in a state where the DCDC is running. In this case,
         * we must *NOT* disable it or this will shutdown the device. This procedure
         * is safe: it will never disable the DCDC and will not reduce the charge
         * limit on the 4P2 rail. */
        BF_WR(POWER_DCDC4P2, ENABLE_4P2(1));
        BF_SET(POWER_CHARGE, ENABLE_LOAD);
        BF_WR(POWER_5VCTRL, CHARGE_4P2_ILIMIT(0)); /* start by drawing 0mA */
        BF_CLR(POWER_5VCTRL, PWD_CHARGE_4P2);// FIXME: manual error ?
        BF_WR(POWER_DCDC4P2, ENABLE_DCDC(1));
        /* the tick task will take care of slowly ramping up the current in the rail
         * every 10ms (since it runs at HZ and HZ=100) */
#endif
        charge_state = TRICKLE;
    }
    /* trickle -> charging transition */
    else if(charge_state == TRICKLE)
    {
#if IMX233_SUBTARGET >= 3780
        /* If 4.2V current limit has not reached 780mA, don't do anything, the
         * DPC is still running */
        /* If we've reached the maximum, take action */
        if(BF_RD(POWER_5VCTRL, CHARGE_4P2_ILIMIT) == MAX_4P2_ILIMIT)
#endif
        {
            logf("pwrmgmt: enable dcdc and charger");
            logf("pwrmgmt: trickle -> charging");
#if IMX233_SUBTARGET >= 3780
            /* adjust arbitration between 4.2 and battery */
            BF_WR(POWER_DCDC4P2, CMPTRIP(0)); /* 85% */
            BF_WR(POWER_DCDC4P2, DROPOUT_CTRL(0xe)); /* select greater, 200 mV drop */
#endif
            /* switch to DCDC */
            BF_CLR(POWER_5VCTRL, DCDC_XFER);
            BF_SET(POWER_5VCTRL, ENABLE_DCDC);
            /* enable battery charging */
            BF_CLR(POWER_CHARGE, PWD_BATTCHRG);
            charge_state = CHARGING;
            timeout_charging = current_tick + IMX233_CHARGING_TIMEOUT;
        }
    }
    /* charging -> error transition */
    else if(charge_state == CHARGING && TIME_AFTER(current_tick, timeout_charging))
    {
        /* we have charged for a too long time, declare charger broken */
        logf("pwrmgmt: charging timeout exceeded!");
        logf("pwrmgmt: charging -> error");
        /* stop charging, note that we leave the 4.2 rail active so that the DCDC
         * keep drawing current from the 4.2 only and leave the battery untouched */
        BF_SET(POWER_CHARGE, PWD_BATTCHRG);
        /* goto error state */
        charge_state = CHARGE_STATE_ERROR;
    }
    /* charging -> topoff transition */
    else if(charge_state == CHARGING && !BF_RD(POWER_STS, CHRGSTS))
    {
        logf("pwrmgmt: topping off");
        logf("pwrmgmt: charging -> topoff");
        charge_state = TOPOFF;
        timeout_topping_off = current_tick + IMX233_TOPOFF_TIMEOUT;
    }
    /* topoff -> disabled transition */
    else if(charge_state == TOPOFF && TIME_AFTER(current_tick, timeout_topping_off))
    {
        logf("pwrmgmt: charging finished");
        logf("pwrmgmt: topoff -> disabled");
        /* stop charging, note that we leave the 4.2 rail active so that the DCDC
         * keep drawing current from the 4.2 only and leave the battery untouched */
        BF_SET(POWER_CHARGE, PWD_BATTCHRG);
        charge_state = CHARGE_STATE_DISABLED;
    }
#endif
}
Exemplo n.º 16
0
void imx233_lcdif_enable_sync_signals(bool en)
{
    BF_WR(LCDIF_VDCTRL3, SYNC_SIGNALS_ON, en);
}
Exemplo n.º 17
0
void imx233_lcdif_set_byte_packing_format(unsigned byte_packing)
{
    BF_WR(LCDIF_CTRL1, BYTE_PACKING_FORMAT, byte_packing);
}
Exemplo n.º 18
0
////////////////////////////////////////////////////////////////////////////////
//! See hw_power.h for details.
////////////////////////////////////////////////////////////////////////////////
void hw_power_SetBatteryBrownoutCode( uint16_t BoRegCode )
{
    BF_WR(POWER_BATTMONITOR, BRWNOUT_LVL, BoRegCode );
}
Exemplo n.º 19
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;
}
Exemplo n.º 20
0
void charging_algorithm_step(void)
{
#if IMX233_SUBTARGET >= 3780
    bool is_5v_present = usb_detect() == USB_INSERTED;

    /* initial state & 5v -> battery transition */
    if(!is_5v_present && charge_state != DISCHARGING)
    {
        logf("pwrmgmt: * -> discharging");
        logf("pwrmgmt: disable charger and 4p2"); 
        /* 5V has been lost: disable 4p2 power rail */
        BF_SET(POWER_CHARGE, PWD_BATTCHRG);
        BF_WR(POWER_DCDC4P2, ENABLE_DCDC, 0);
        BF_WR(POWER_DCDC4P2, ENABLE_4P2, 0);
        BF_SET(POWER_5VCTRL, PWD_CHARGE_4P2);
        charge_state = DISCHARGING;
    }
    /* battery -> 5v transition */
    else if(is_5v_present && charge_state == DISCHARGING)
    {
        logf("pwrmgmt: discharging -> trickle");
        logf("pwrmgmt: begin charging 4p2");
        /* 5V has been detected: prepare 4.2V power rail for activation */
        BF_WR(POWER_DCDC4P2, ENABLE_4P2, 1);
        BF_SET(POWER_CHARGE, ENABLE_LOAD);
        BF_WR(POWER_5VCTRL, CHARGE_4P2_ILIMIT, 1);
        BF_CLR(POWER_5VCTRL, PWD_CHARGE_4P2);// FIXME: manual error ?
        BF_WR(POWER_DCDC4P2, ENABLE_DCDC, 1);
        timeout_4p2_ilimit_increase = current_tick + HZ / 100;
        charge_state = TRICKLE;
    }
    else if(charge_state == TRICKLE && TIME_AFTER(current_tick, timeout_4p2_ilimit_increase))
    {
        /* if 4.2V current limit has not reached 780mA, increase it slowly to
         * charge the 4.2V capacitance */
        if(BF_RD(POWER_5VCTRL, CHARGE_4P2_ILIMIT) != 0x3f)
        {
            //logf("pwrmgmt: incr 4.2 ilimit");
            HW_POWER_5VCTRL += BF_POWER_5VCTRL_CHARGE_4P2_ILIMIT(1);
            timeout_4p2_ilimit_increase = current_tick + HZ / 100;
        }
        /* we've reached the maximum, take action */
        else
        {
            logf("pwrmgmt: enable dcdc and charger");
            logf("pwrmgmt: trickle -> charging");
            BF_CLR(POWER_5VCTRL, DCDC_XFER);
            BF_SET(POWER_5VCTRL, ENABLE_DCDC);
            /* enable battery charging */
            BF_CLR(POWER_CHARGE, PWD_BATTCHRG);
            charge_state = CHARGING;
            timeout_charging = current_tick + IMX233_CHARGING_TIMEOUT;
        }
    }
    else if(charge_state == CHARGING && TIME_AFTER(current_tick, timeout_charging))
    {
        /* we have charged for a too long time, declare charger broken */
        logf("pwrmgmt: charging timeout exceeded!");
        logf("pwrmgmt: charging -> error");
        /* stop charging */
        BF_SET(POWER_5VCTRL, PWD_CHARGE_4P2);
        /* goto error state */
        charge_state = CHARGE_STATE_ERROR;
    }
    else if(charge_state == CHARGING && !BF_RD(POWER_STS, CHRGSTS))
    {
        logf("pwrmgmt: topping off");
        logf("pwrmgmt: charging -> topoff");
        charge_state = TOPOFF;
        timeout_topping_off = current_tick + IMX233_TOPOFF_TIMEOUT;
    }
    else if(charge_state == TOPOFF && TIME_AFTER(current_tick, timeout_topping_off))
    {
        logf("pwrmgmt: charging finished");
        logf("pwrmgmt: topoff -> disabled");
        /* stop charging */
        BF_SET(POWER_CHARGE, PWD_BATTCHRG);
        charge_state = CHARGE_STATE_DISABLED;
    }
#endif
}