/* * Physical detection of battery. */ enum battery_present battery_is_present(void) { enum battery_present batt_pres; int batt_status, rv; /* Get the physical hardware status */ batt_pres = battery_hw_present(); /* * Make sure battery status is implemented, I2C transactions are * success & the battery status is Initialized to find out if it * is a working battery and it is not in the cut-off mode. * * If battery I2C fails but VBATT is high, battery is booting from * cut-off mode. * * FETs are turned off after Power Shutdown time. * The device will wake up when a voltage is applied to PACK. * Battery status will be inactive until it is initialized. */ if (batt_pres == BP_YES && batt_pres_prev != batt_pres && !battery_is_cut_off()) { rv = battery_status(&batt_status); if ((rv && bd9995x_get_battery_voltage() >= info.voltage_min) || (!rv && !(batt_status & STATUS_INITIALIZED))) batt_pres = BP_NO; } batt_pres_prev = batt_pres; return batt_pres; }
uint8_t battery_read() // Returns 0-100 // { uint16_t raw = battery_read_raw(); uint16_t high, low, percent; char status = battery_status(); if(status == 0) { eeprom_read_block((void *) &low, &battery_low, sizeof(uint16_t)); if(raw < low) eeprom_write_block((const void *) &raw, &battery_low, sizeof(uint16_t)); eeprom_read_block((void *) &high, &battery_high, sizeof(uint16_t)); if(high == 0xFFFF) high = 0; if(raw > high) eeprom_write_block((const void *) &raw, &battery_high, sizeof(uint16_t)); percent = ((raw - low) * 100) / (high - low); } else { eeprom_read_block((void *) &low, &battery_low_charging, sizeof(uint16_t)); if(raw < low) eeprom_write_block((const void *) &raw, &battery_low, sizeof(uint16_t)); eeprom_read_block((void *) &high, &battery_high_charging, sizeof(uint16_t)); if(raw > high) eeprom_write_block((const void *) &raw, &battery_high, sizeof(uint16_t)); percent = ((raw - low) * 100) / (high - low); if(status == 1 && percent > 99) percent = 99; if(status == 2) percent = 100; } return percent; }
static void update_battery_led(void) { int alarm; int led_on = 0; if(extpower_is_present()){ battery_status(&alarm); if((alarm & ALARM_CHARGED) && !gpio_get_level(GPIO_CHARGER_EN)) led_on = 1; } gpio_set_level(GPIO_CHARGING_LED, led_on); }
void chargingScreen(void) { char first = 1; menu.push(); while(button.get() != FL_KEY && battery_status() > 0) { wdt_reset(); batteryStatus(0, first); first = 0; } menu.back(); }
char* getChargingStatus() { switch(battery_status()) { case 1: return TEXT("Charging"); case 2: return TEXT("Charged"); case 0: return TEXT("Unplugged"); } return TEXT("ERROR"); }
void hardware_off(void) { if(battery_status() == 0) { // If USB is used, detach from the bus USB_Detach(); // Disable all interrupts cli(); // Shutdown setHigh(POWER_HOLD_PIN); for(;;); } else // Plugged in { // Charging screen // chargingScreen(); } }
void hardware_off(void) { hardware_flashlight(0); if(battery_status() == 0) { //if(timer.cableIsConnected()) //{ // menu.message(STR("Error: Cable")); //} //else //{ shutter_off(); // Save the current time-lapse settings to nv-mem timer.saveCurrent(); // If USB is used, detach from the bus USB_Detach(); // Shutdown bluetooth bt.disconnect(); bt.sleep(); // Disable all interrupts cli(); // Shutdown setHigh(POWER_HOLD_PIN); FOREVER; //} } else // Plugged in { // Charging screen // clock.sleeping = 1; menu.spawn((void *) batteryStatus); } }
main() { char current_time[50]; char hostname[10]; char battery_remain[4]; char status_string[100]; launch_statusbar(); for (;;sleep(1)) { host(hostname); datetime(current_time); battery_status(battery_remain); status(status_string, hostname, battery_remain, current_time); statusbar(status_string); } close_statusbar(); return 0; }
static int calc_next_state(int state) { struct batt_params batt; int alarm; battery_get_params_and_save_a_copy(&batt); switch (state) { case ST_IDLE0: case ST_BAD_COND: case ST_IDLE: /* Check AC and chiset state */ if (!extpower_is_present()) { if (chipset_in_state(CHIPSET_STATE_ON)) return ST_DISCHARGING; return ST_IDLE; } /* Stay in idle mode if charger overtemp */ if (pmu_is_charger_alarm()) return ST_BAD_COND; /* Enable charging when battery doesn't respond */ if (!(batt.flags & BATT_FLAG_RESPONSIVE)) return ST_PRE_CHARGING; /* Turn off charger when battery temperature is out * of the start charging range. */ if (!battery_start_charging_range(batt.temperature)) return ST_BAD_COND; /* Turn off charger on battery over temperature alarm */ if (battery_status(&alarm) || (alarm & ALARM_OVER_TEMP)) return ST_BAD_COND; /* Stop charging if the battery says it's charged */ if (alarm & ALARM_CHARGED) return ST_IDLE; /* Start charging only when battery charge lower than 100% */ if (!(batt.flags & BATT_FLAG_BAD_STATE_OF_CHARGE)) { if (batt.state_of_charge < 100) return ST_CHARGING; } return ST_IDLE; case ST_PRE_CHARGING: if (!extpower_is_present()) return ST_IDLE0; /* * If the battery goes online after enabling the charger, go * into charging state. */ if (batt.flags & BATT_FLAG_RESPONSIVE) { if (!battery_start_charging_range(batt.temperature)) return ST_IDLE0; if (!(batt.flags & BATT_FLAG_BAD_STATE_OF_CHARGE)) { if (batt.state_of_charge >= 100) return ST_IDLE0; } return ST_CHARGING; } return ST_PRE_CHARGING; case ST_CHARGING: /* Go back to idle state when AC is unplugged */ if (!extpower_is_present()) return ST_IDLE0; /* * Disable charging on battery access error, or charging * temperature out of range. */ if (!(batt.flags & BATT_FLAG_RESPONSIVE)) { CPRINTS("pmu charging: unable to get battery " "temperature"); return ST_IDLE0; } else if (!battery_charging_range(batt.temperature)) { CPRINTS("pmu charging: temperature out of range " "%dC", DECI_KELVIN_TO_CELSIUS(batt.temperature)); return ST_CHARGING_ERROR; } /* * Disable charging on battery alarm events or access error: * - over temperature * - over current */ if (battery_status(&alarm)) return ST_IDLE0; if (alarm & ALARM_OVER_TEMP) { CPRINTS("pmu charging: battery over temp"); return ST_CHARGING_ERROR; } /* Go to idle state if battery is fully charged */ if (alarm & ALARM_CHARGED) return ST_IDLE; /* * Disable charging on charger alarm events: * - charger over current * - charger over temperature */ if (pmu_is_charger_alarm()) { CPRINTS("pmu charging: charger alarm"); return ST_IDLE0; } return ST_CHARGING; case ST_CHARGING_ERROR: /* * This state indicates AC is plugged but the battery is not * charging. The conditions to exit this state: * - battery detected * - battery temperature is in start charging range * - no battery alarm */ if (extpower_is_present()) { if (battery_status(&alarm)) return ST_CHARGING_ERROR; if (alarm & ALARM_OVER_TEMP) return ST_CHARGING_ERROR; if (!(batt.flags & BATT_FLAG_RESPONSIVE)) return ST_CHARGING_ERROR; if (!battery_charging_range(batt.temperature)) return ST_CHARGING_ERROR; return ST_CHARGING; } return ST_IDLE0; case ST_DISCHARGING: /* Go back to idle state when AC is plugged */ if (extpower_is_present()) return ST_IDLE0; /* Prepare EC sleep after system stopped discharging */ if (chipset_in_state(CHIPSET_STATE_ANY_OFF)) return ST_IDLE0; /* Check battery discharging temperature range */ if (batt.flags & BATT_FLAG_RESPONSIVE) { if (!battery_discharging_range(batt.temperature)) { CPRINTS("pmu discharging: temperature out of " "range %dC", DECI_KELVIN_TO_CELSIUS( batt.temperature)); return system_off(); } } /* Check discharging alarm */ if (!battery_status(&alarm) && (alarm & ALARM_DISCHARGING)) { CPRINTS("pmu discharging: battery alarm %016b", alarm); return system_off(); } /* Check remaining charge % */ if (!(batt.flags & BATT_FLAG_BAD_STATE_OF_CHARGE)) { /* * Shutdown AP when state of charge < 1.5%. * Moving average is rounded to integer. */ if (rsoc_moving_average(batt.state_of_charge) < 2) return system_off(); else if (batt.state_of_charge < 4) notify_battery_low(); } return ST_DISCHARGING; } return ST_IDLE0; }
void rn42_task(void) { int16_t c; // Raw mode: interpret output report of LED state while ((c = rn42_getc()) != -1) { // LED Out report: 0xFE, 0x02, 0x01, <leds> // To get the report over UART set bit3 with SH, command. static enum {LED_INIT, LED_FE, LED_02, LED_01} state = LED_INIT; switch (state) { case LED_INIT: if (c == 0xFE) state = LED_FE; else { if (0x0 <= c && c <= 0x7f) xprintf("%c", c); else xprintf(" %02X", c); } break; case LED_FE: if (c == 0x02) state = LED_02; else state = LED_INIT; break; case LED_02: if (c == 0x01) state = LED_01; else state = LED_INIT; break; case LED_01: dprintf("LED status: %02X\n", c); rn42_set_leds(c); state = LED_INIT; break; default: state = LED_INIT; } } static uint16_t prev_timer = 0; uint16_t e = timer_elapsed(prev_timer); if (e > 1000) { /* every second */ prev_timer += e/1000*1000; /* Low voltage alert */ uint8_t bs = battery_status(); if (bs == LOW_VOLTAGE) { battery_led(LED_ON); } else { battery_led(LED_CHARGER); } /* every minute */ uint32_t t = timer_read32()/1000; if (t%60 == 0) { uint16_t v = battery_voltage(); uint8_t h = t/3600; uint8_t m = t%3600/60; uint8_t s = t%60; dprintf("%02u:%02u:%02u\t%umV\n", h, m, s, v); } } /* Connection monitor */ if (!rn42_rts() && rn42_linked()) { status_led(true); } else { status_led(false); } }
bool command_extra(uint8_t code) { uint32_t t; uint16_t b; switch (code) { case KC_H: case KC_SLASH: /* ? */ print("\n\n----- Bluetooth RN-42 Help -----\n"); print("i: RN-42 info\n"); print("b: battery voltage\n"); print("Del: enter/exit RN-42 config mode\n"); print("Slck: RN-42 initialize\n"); print("1-4: restore link\n"); print("F1-F4: store link\n"); print("p: pairing\n"); if (config_mode) { return true; } else { print("u: toggle Force USB mode\n"); return false; // to display default command help } case KC_P: pairing(); return true; /* Store link address to EEPROM */ case KC_F1: store_link(RN42_LINK0); return true; case KC_F2: store_link(RN42_LINK1); return true; case KC_F3: store_link(RN42_LINK2); return true; case KC_F4: store_link(RN42_LINK3); return true; /* Restore link address to EEPROM */ case KC_1: restore_link(RN42_LINK0); return true; case KC_2: restore_link(RN42_LINK1); return true; case KC_3: restore_link(RN42_LINK2); return true; case KC_4: restore_link(RN42_LINK3); return true; case KC_5: xprintf("blah! \n"); //rn42_cts_hi(); if (stay_connected == 1){ dprintf("Disconnect after 5 min.\n"); stay_connected = !stay_connected; }else{ dprintf("Stay connected.\n"); stay_connected = 1; //last_press_timer = timer_read32(); } return true; case KC_6: clear_keyboard(); host_set_driver(&rn42_config_driver); // null driver; not to send a key to host rn42_disconnect(); return true; case KC_I: print("\n----- RN-42 info -----\n"); xprintf("protocol: %s\n", (host_get_driver() == &rn42_driver) ? "RN-42" : "LUFA"); xprintf("force_usb: %X\n", force_usb); xprintf("rn42: %s\n", rn42_rts() ? "OFF" : (rn42_linked() ? "CONN" : "ON")); xprintf("rn42_autoconnecting(): %X\n", rn42_autoconnecting()); xprintf("config_mode: %X\n", config_mode); xprintf("USB State: %s\n", (USB_DeviceState == DEVICE_STATE_Unattached) ? "Unattached" : (USB_DeviceState == DEVICE_STATE_Powered) ? "Powered" : (USB_DeviceState == DEVICE_STATE_Default) ? "Default" : (USB_DeviceState == DEVICE_STATE_Addressed) ? "Addressed" : (USB_DeviceState == DEVICE_STATE_Configured) ? "Configured" : (USB_DeviceState == DEVICE_STATE_Suspended) ? "Suspended" : "?"); xprintf("battery: "); switch (battery_status()) { case FULL_CHARGED: xprintf("FULL"); break; case CHARGING: xprintf("CHARG"); break; case DISCHARGING: xprintf("DISCHG"); break; case LOW_VOLTAGE: xprintf("LOW"); break; default: xprintf("?"); break; }; xprintf("\n"); xprintf("RemoteWakeupEnabled: %X\n", USB_Device_RemoteWakeupEnabled); xprintf("VBUS: %X\n", USBSTA&(1<<VBUS)); t = timer_read32()/1000; uint8_t d = t/3600/24; uint8_t h = t/3600; uint8_t m = t%3600/60; uint8_t s = t%60; xprintf("uptime: %02u %02u:%02u:%02u\n", d, h, m, s); xprintf("LINK0: %s\r\n", get_link(RN42_LINK0)); xprintf("LINK1: %s\r\n", get_link(RN42_LINK1)); xprintf("LINK2: %s\r\n", get_link(RN42_LINK2)); xprintf("LINK3: %s\r\n", get_link(RN42_LINK3)); return true; case KC_B: // battery monitor t = timer_read32()/1000; b = battery_voltage(); xprintf("BAT: %umV\t", b); xprintf("%02u:", t/3600); xprintf("%02u:", t%3600/60); xprintf("%02u\n", t%60); return true; case KC_U: if (config_mode) return false; if (force_usb) { print("Auto mode\n"); force_usb = false; } else { print("USB mode\n"); clear_keyboard(); host_set_driver(&rn42_driver); } return true; case KC_DELETE: /* RN-42 Command mode */ if (rn42_autoconnecting()) { enter_command_mode(); command_state = CONSOLE; config_mode = true; } else { exit_command_mode(); command_state = ONESHOT; config_mode = false; } return true; case KC_SCROLLLOCK: init_rn42(); return true; default: if (config_mode) return true; else return false; // yield to default command } return true; }
volatile char batteryStatus(char key, char first) { // uint16_t batt_high = 645; // uint16_t batt_low = 540; static uint8_t charging; char stat = battery_status(); if(first) { charging = (stat > 0); } // unsigned int batt_level = battery_read_raw(); #define BATT_LINES 36 // uint8_t lines = ((batt_level - batt_low) * BATT_LINES) / (batt_high - batt_low); uint8_t lines = (uint8_t)((uint16_t)battery_percent * BATT_LINES / 100); if(lines > BATT_LINES - 1 && stat == 1) lines = BATT_LINES - 1; if(lines > BATT_LINES || stat == 2) lines = BATT_LINES; lcd.cls(); char* text; text = getChargingStatus(); char l = lcd.measureStringTiny(text) / 2; if(battery_status()) lcd.writeStringTiny(41 - l, 31, text); // Draw Battery Outline // lcd.drawLine(20, 15, 60, 15); lcd.drawLine(20, 16, 20, 27); lcd.drawLine(21, 27, 60, 27); lcd.drawLine(60, 16, 60, 19); lcd.drawLine(60, 23, 60, 26); lcd.drawLine(61, 19, 61, 23); // Draw Battery Charge // for(uint8_t i = 0; i <= lines; i++) { lcd.drawLine(22 + i, 17, 22 + i, 25); } menu.setTitle(TEXT("Battery Status")); menu.setBar(TEXT("RETURN"), BLANK_STR); lcd.update(); if(stat == 0 && charging) { clock.awake(); return FN_CANCEL; // unplugged } if(key == FL_KEY) return FN_CANCEL; return FN_CONTINUE; }
int log_energymap(call_t *c) { struct entitydata *entitydata = get_entity_private_data(c); int i = get_node_count(); FILE *file = NULL; char file_map[100]; double time = get_time() * 0.000001; /* create file */ sprintf(file_map, "%s/%s.%.0lf.data", entitydata->directory, entitydata->map_prefix, time); if ((file = fopen(file_map, "w+")) == NULL) { fprintf(stderr, "My monitor: can not open file %s in monitor_event()\n", file_map); return -1; } /* log energy map */ while (i--) { call_t c0 = {-1, i, -1}; position_t *position = get_node_position(c0.node); fprintf(file, "%d %lf %lf %lf %lf\n", c0.node, position->x, position->y, position->z, battery_status(&c0)); } /* log virtual nodes for the 4 area corners */ fprintf(file, "%d %lf %lf %lf %lf\n", -1, 0.0, 0.0, 0.0, 1.0); fprintf(file, "%d %lf %lf %lf %lf\n", -1, get_topology_area()->x, 0.0, 0.0, 1.0); fprintf(file, "%d %lf %lf %lf %lf\n", -1, 0.0, get_topology_area()->y, 0.0, 1.0); fprintf(file, "%d %lf %lf %lf %lf\n", -1, get_topology_area()->x, get_topology_area()->y, 0.0, 1.0); fclose(file); return 0; }