int board_charging(void)
{
	enum charge_level_t charger;
	uint16_t batt_soc = 0;
	int ret;

	charger = charger_detect();

	ret = init_batt();
	
	if (ret && charger == CHARGE_DISABLE) {
		printf("failed to init battery: %d\n", ret);
		return ret;
	}

	ret = max17042_soc(&batt_soc);

	if (ret && charger == CHARGE_DISABLE) {
		printf("failed to read initial SOC: %d\n", ret);
		return ret;
	}

	if (batt_soc < SOC_THRESH_MIN) {
		display_image(IMAGE_CHARGE_NEEDED, batt_soc);
		if (ret) {
			printf("No battery detected, emergency charging!\n");
		}

		charge_loop(&batt_soc, ret ? 1 : 0);

		if (batt_soc < SOC_THRESH_MIN) {
			// Uh-oh, we exited the charge loop
			// before we passed the minimum
			// In this case we should power down
			if (batt_soc >= SOC_THRESH_DISPLAY_MIN) {
				display_image(IMAGE_CHARGE_NEEDED, batt_soc);
				udelay(1000 * 1000 * 2);
			}

			twl6030_power_off();
		}
	}

	/* Reconfigure MPU DPLL clock as it might have been set */
	/* to conservative values in x-loader, only do this in the
	 case where we are actually going to boot */
	set_mpu_dpll_max_opp();

	display_image(IMAGE_BOOT, batt_soc);
	printf("SOC %hu%%, booting.\n", batt_soc);
	return ret;
}
Example #2
0
int main(void)
{
	static unsigned int tmp = 0;
	
	SET_OUTPUT(LED_R);
	SET_OUTPUT(LED_G);
	SET_OUTPUT(LED_B);
	RESET_LED(LED_R);
	RESET_LED(LED_G);
	RESET_LED(LED_B);
	
#ifdef DCDCCTRL
	SET_OUTPUT(DCDCCTRL);
	RESET(DCDCCTRL);
#endif
	
	battery_state = 0;
	
	slave_init();
	//uart_init();
	timer_init();
	mcan_init();
	spi_init();
	spi_adc_init();
	relai_init();
	adc_init();
	 
	sei();
	
	if( (GPIOR0 & (1<<WDRF)) == (1<<WDRF) )
	{
		status("WDTRST  ");
	}
	else if( (GPIOR0 & (1<<BORF)) == (1<<BORF) )
	{
		status("BORRST  ");
	}
	else if( (GPIOR0 & (1<<EXTRF)) == (1<<EXTRF) )
	{
		status("START EX");
	}
	else if( (GPIOR0 & (1<<PORF)) == (1<<PORF) )
	{
		status("START PO");
	}
	else if( (GPIOR0 & (1<<JTRF)) == (1<<JTRF) )
	{
		status("START JT");
	}
	else
	{
		status("START   ");
	}
	
	WDTCR = (1<<WDCE) | (1<<WDE);
	WDTCR = (1<<WDE) | (1<<WDP2) | (1<<WDP1) | (1<<WDP0);
	
	SET_LED(LED_G);
	
	while (1)
	{
		__asm__ __volatile__ ("wdr");
		
		if( battery_state & STATE_INTERMEDIATE )
		{
			intermediate_loop();
		}
		else if( battery_state & STATE_TRACTIVE )
		{
			tractive_loop();
		}
		else if( battery_state & STATE_CHARGING )
		{
			charge_loop();
		}
		else if( battery_state & STATE_BALANCING )
		{
			balancing_loop();
		}
		else
		{
			// standby mode
			if( (tmp = mcan_check()) && !(battery_state & STATE_ERROR) )
			{
				switch(tmp)
				{
					case CAN_TRACTIVE_ENABLE: // CAN_TRACTIVE_ENABLE == 0x2F0
					{
						if( relai_volt < VCC_RELAI_MIN || vcc_volt < VCC_MIN )
						{
							status("NO   VCC");
							break;
						}
						
						// enable hv
						intermediate_init();
						dspace_heartbeat = 0;
						battery_state |= STATE_TRACTIVE;
					}
					break;
					case CAN_CHARGE_ENABLE: // CAN_CHARGE_ENABLE == 0x2FA
					{
						if( relai_volt < VCC_RELAI_MIN || vcc_volt < VCC_MIN )
						{
							status("NO   VCC");
							break;
						}
						
						// start charging
						intermediate_init();
						battery_state |= STATE_CHARGING;
					}
					break;
					case CAN_BALANCING_ENABLE:
					{
						balancing_start();
						battery_state |= STATE_BALANCING;
					}
					break;
				}
			}
		}
		
		slave_loop();
		mcan_send_loop();
		adc_loop();
	}
	return 0;
}