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; }
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; }