Commit 3bd50103 authored by minute's avatar minute
Browse files

lpc: sleep in 3 states; next_state; missing cells only between 1 to 7 cells;...

lpc: sleep in 3 states; next_state; missing cells only between 1 to 7 cells; force sleep mode for testing
parent 67abe92a
......@@ -39,9 +39,10 @@
// don't forget to set this to the correct rev for your motherboard!
#define REFORM_MOTHERBOARD_REV REFORM_MBREV_R3
//#define REF2_DEBUG 1
#define FW_REV "MREF2LPC R2 20210906"
#define FW_REV "MREF2LPC R3 20210924"
#define POWERSAVE_SLEEP_SECONDS 1
#define POWERSAVE_HOLDOFF_CYCLES 30
#define INA260_ADDRESS 0x4e
#define LTC4162F_ADDRESS 0x68
......@@ -146,7 +147,7 @@ int cycles_in_state = 0;
int charge_current = 1;
uint32_t cur_second = 0;
uint32_t last_second = 0;
int powersave_holdoff_cycles = 10;
int powersave_holdoff_cycles = POWERSAVE_HOLDOFF_CYCLES;
// 1.8A x 3600 seconds/hour
#define MAX_CAPACITY (1.8)*3600.0
......@@ -531,10 +532,14 @@ uint8_t remote_arg = 0;
unsigned char cmd_state = ST_EXPECT_DIGIT_0;
unsigned int cmd_number = 0;
int cmd_echo = 0;
int force_sleep = 0;
void handle_commands() {
if (!uartRxBufferDataPending()) return;
// reset sleep counter on any interaction
powersave_holdoff_cycles = POWERSAVE_HOLDOFF_CYCLES;
char chr = uartRxBufferRead();
if (cmd_echo) {
......@@ -624,6 +629,12 @@ void handle_commands() {
uartSend((uint8_t*)uartBuffer, strlen(uartBuffer));
}
}
else if (remote_cmd == 'x') {
// test sleep
force_sleep = cmd_number;
sprintf(uartBuffer,"sleep: %d\r\n", force_sleep);
uartSend((uint8_t*)uartBuffer, strlen(uartBuffer));
}
else if (remote_cmd == 'a') {
// get system current (mA)
sprintf(uartBuffer,"%d\r\n",(int)(current*1000.0));
......@@ -655,10 +666,11 @@ void handle_commands() {
} else if (state == ST_FULLY_CHARGED) {
sprintf(uartBuffer,FW_REV"full charge,%d,%d,%d\r",cycles_in_state,min_mah,acc_mah);
} else if (state == ST_POWERSAVE) {
sprintf(uartBuffer,FW_REV"pwrsv,%d,%lu\r",cycles_in_state,LPC_WWDT->TV);
sprintf(uartBuffer,FW_REV"pwrsv,%d,%x\r",cycles_in_state,LPC_WWDT->TV);
} else {
sprintf(uartBuffer,FW_REV"unknown:%d,%d,%d,%d\r",state,cycles_in_state,min_mah,acc_mah);
}
uartSend((uint8_t*)uartBuffer, strlen(uartBuffer));
}
else if (remote_cmd == 'u') {
......@@ -857,6 +869,8 @@ int main(void)
last_second = delayGetSecondsActive();
int next_state = state;
while (1)
{
// algorithm idea:
......@@ -871,8 +885,6 @@ int main(void)
// charge current 2: ~0.2A
//watchdog_feed();
measure_and_accumulate_current();
measure_cell_voltages_and_control_discharge();
calculate_capacity_percentage();
......@@ -880,23 +892,29 @@ int main(void)
if (state == ST_CHARGE) {
reset_discharge_bits();
if (num_missing_cells > 0) {
if (force_sleep) {
// debug sleeping
if (powersave_holdoff_cycles <= 0) {
next_state = ST_POWERSAVE;
cycles_in_state = 0;
}
} else if ((num_missing_cells >= 1) && (num_missing_cells <= 7)) {
missing_reason = missing_bits;
// if cells were unplugged, we don't know the capacity anymore.
reached_full_charge = 0;
state = ST_MISSING;
next_state = ST_MISSING;
cycles_in_state = 0;
}
else if (num_undervolted_cells > 0) {
else if (current >= 0 && num_undervolted_cells > 0) {
// when transitioning to undervoltage, we assume we reached the bottom
// of usable capacity, so record it
// but only if we reached top charge once, or our counter will
// be off.
if (cycles_in_state > 5) {
if (cycles_in_state > 2) {
if (reached_full_charge > 0) {
capacity_min_ampsecs = capacity_accu_ampsecs;
}
state = ST_UNDERVOLTED;
next_state = ST_UNDERVOLTED;
cycles_in_state = 0;
}
}
......@@ -904,7 +922,7 @@ int main(void)
if (cycles_in_state > 5) {
// when transitioning to fully charged, we assume that we're at max capacity
capacity_accu_ampsecs = capacity_max_ampsecs;
state = ST_FULLY_CHARGED;
next_state = ST_FULLY_CHARGED;
reached_full_charge = 1;
cycles_in_state = 0;
}
......@@ -912,21 +930,21 @@ int main(void)
else if (num_overvolted_cells > 0) {
if (cycles_in_state > 5) {
// some cool-off time
state = ST_OVERVOLTED;
next_state = ST_OVERVOLTED;
cycles_in_state = 0;
}
}
else if (current < 0.05 && current >= 0) {
// if not charging and the system is off, we can sleep regularly to save power
if (cycles_in_state > 0 && powersave_holdoff_cycles <= 0) {
state = ST_POWERSAVE;
if (powersave_holdoff_cycles <= 0) {
next_state = ST_POWERSAVE;
cycles_in_state = 0;
}
}
}
else if (state == ST_UNDERVOLTED) {
// TODO: issue alert -- switch off system if critical
reset_discharge_bits();
deep_sleep_seconds(POWERSAVE_SLEEP_SECONDS);
if (cycles_in_state > 1) {
// TODO: find safe heuristic. here we turn off if half
......@@ -935,10 +953,8 @@ int main(void)
turn_som_power_off();
}
if (current >= 0 && powersave_holdoff_cycles <= 0) {
state = ST_POWERSAVE;
cycles_in_state = 0;
}
next_state = ST_CHARGE;
cycles_in_state = 0;
}
}
else if (state == ST_OVERVOLTED) {
......@@ -946,7 +962,7 @@ int main(void)
missing_reason = missing_bits;
// if cells were unplugged, we don't know the capacity anymore.
reached_full_charge = 0;
state = ST_MISSING;
next_state = ST_MISSING;
cycles_in_state = 0;
} else {
discharge_overvolted_cells();
......@@ -955,17 +971,18 @@ int main(void)
if (cycles_in_state > 1 && (num_overvolted_cells==0 || num_undervolted_cells>0)) {
reset_discharge_bits();
state = ST_CHARGE;
next_state = ST_CHARGE;
cycles_in_state = 0;
}
}
}
else if (state == ST_MISSING) {
reset_discharge_bits();
deep_sleep_seconds(POWERSAVE_SLEEP_SECONDS);
if (cycles_in_state > 5) {
if (num_missing_cells < 1) {
state = ST_CHARGE;
if (cycles_in_state > 1) {
if (num_missing_cells == 0 || num_missing_cells == 8) {
next_state = ST_CHARGE;
cycles_in_state = 0;
}
}
......@@ -976,31 +993,27 @@ int main(void)
if (cycles_in_state > 5) {
// if none of the cells are fully charged anymore, allow charging again
if (num_fully_charged_cells < 1) {
state = ST_CHARGE;
next_state = ST_CHARGE;
cycles_in_state = 0;
}
else if (num_overvolted_cells > 0) {
state = ST_OVERVOLTED;
next_state = ST_OVERVOLTED;
cycles_in_state = 0;
}
}
}
else if (state == ST_POWERSAVE) {
deep_sleep_seconds(POWERSAVE_SLEEP_SECONDS);
state = ST_CHARGE;
next_state = ST_CHARGE;
cycles_in_state = 0;
}
// handle keyboard commands
if (uartRxBufferDataPending()) {
// don't go to powersave if keyboard wants to communicate
powersave_holdoff_cycles = 5;
}
// this also resets powersave holdoff counter
handle_commands();
if (state == ST_POWERSAVE) {
cur_second+=POWERSAVE_SLEEP_SECONDS;
if (state == ST_POWERSAVE || state == ST_MISSING || state == ST_UNDERVOLTED) {
cur_second += POWERSAVE_SLEEP_SECONDS;
} else {
cur_second = delayGetSecondsActive();
}
......@@ -1016,10 +1029,13 @@ int main(void)
}
last_second = cur_second;
if (powersave_holdoff_cycles>=0) {
if (powersave_holdoff_cycles > 0) {
powersave_holdoff_cycles--;
}
}
state = next_state;
}
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment