sysctl: debug charger WIP

This commit is contained in:
Lukas F. Hartmann 2023-12-27 13:07:20 +01:00
parent 5776704735
commit 18286f8b7d
No known key found for this signature in database
GPG Key ID: 376511EB67AD7BAF
1 changed files with 120 additions and 65 deletions

View File

@ -168,6 +168,7 @@ float max_word_to_cap(uint16_t w)
float max_word_to_percentage(uint16_t w)
{
// TODO: cap to 100%
float result = ((float)w)*0.00390625;
return result;
}
@ -335,7 +336,9 @@ uint8_t fusb_read_message(union pd_msg *msg)
/* If this isn't an SOP message, return error.
* Because of our configuration, we should be able to assume this means the
* buffer is empty, and not try to read past a non-SOP message. */
if ((fusb_read_byte(FUSB_FIFOS) & FUSB_FIFO_RX_TOKEN_BITS)
uint8_t rxb = fusb_read_byte(FUSB_FIFOS);
if (rxb!=0) printf("[rxb] %x\n", rxb);
if ((rxb & FUSB_FIFO_RX_TOKEN_BITS)
!= FUSB_FIFO_RX_SOP) {
return 1;
}
@ -412,13 +415,21 @@ int print_src_fixed_pdo(uint32_t pdo) {
return voltage;
}
int charger_dump() {
int charger_configure() {
// TODO: check all MP2650 registers, esp. 4, 7, b
// set input current limit to 2000mA
mps_write_byte(0x00, (1<<5)|(1<<3));
// set input voltage limit to 6V (above 5V USB voltage)
mps_write_byte(0x01, (1<<6));
// set charge current limit to 2000mA (1600+400)
mps_write_byte(0x02, (1<<5)|(1<<3));
}
float charger_dump() {
// TODO: if max reports overvoltage (dysbalanced cells),
// can we lower the charging voltage temporarily?
// alternatively, the current
uint8_t status = mps_read_byte(0x13);
uint8_t fault = mps_read_byte(0x14);
@ -439,6 +450,8 @@ int charger_dump() {
uint8_t precharge_c = mps_read_byte(0x03);
uint8_t bat_full_v = mps_read_byte(0x04);
int print_charger_info = 1;
if (print_charger_info) {
printf("[charger info]\n");
printf(" status: %x\n", status);
printf(" fault: %x\n ------------\n", fault);
@ -458,25 +471,32 @@ int charger_dump() {
printf(" charge_c: %x\n", charge_c);
printf(" precharge_c: %x\n", precharge_c);
printf(" bat_full_v: %d\n ============\n", bat_full_v);
if (adc_input_v < 11) {
// renegotiate PD
return 1;
}
return 0;
return adc_input_v;
}
void max_dump() {
// disable write protection (CommStat)
max_write_word(0x61, 0x0000);
max_write_word(0x61, 0x0000);
// set pack cfg: 2 cells (0), 1+1 thermistor, 6v charge pump, 11:thtype=10k, btpken on, no aoldo
max_write_word_100(0xb5, (0<<14)|(1<<13)|(0<<11)|(0<<8)|(2<<2)|0);
// fixme set thermistor config
max_write_word_100(0xca, 0x58ef);
// set pack cfg: 2 cells (0), 1 thermistor, 6v charge pump (?), no aoldo, btpken off (??)
max_write_word_100(0xb5, (1<11)|(0<<8)|(0<<2)|0);
//max_write_word_100(0xca, 0x30fb); // for 100k, beta value 4250
// TODO: need to enable balancing (zener?)
// nBalCfg
max_write_word(0x61, 0x0000);
max_write_word(0x61, 0x0000);
max_write_word_100(0xd4, (1<<13)|(3<<10)|(3<<5));
uint16_t comm_stat = max_read_word(0x61);
uint16_t status = max_read_word(0x00);
uint16_t packcfg = max_read_word_100(0xb5);
uint16_t prot_status = max_read_word(0xd9);
uint16_t prot_alert = max_read_word(0xaf);
uint16_t prot_cfg2 = max_read_word_100(0xf1);
@ -487,6 +507,7 @@ void max_dump() {
float cell2 = max_word_to_mv(max_read_word(0xd7));
float cell3 = max_word_to_mv(max_read_word(0xd6));
float cell4 = max_word_to_mv(max_read_word(0xd5));
// this value looks good (checked with inducing voltages w/ power supply)
float vpack = max_word_to_pack_mv(max_read_word(0xda));
float temp = ((float)((int16_t)max_read_word(0x1b)))*(1.0/256.0);
@ -507,6 +528,7 @@ void max_dump() {
printf(" comm_stat: %04x\n", comm_stat);
printf(" packcfg: %04x\n", packcfg);
printf(" status: %04x\n", status);
if (status & 0x8000) {
printf(" `-- prot alert\n");
@ -845,7 +867,7 @@ void on_uart_rx() {
}
int main() {
set_sys_clock_48mhz();
//set_sys_clock_48mhz();
stdio_init_all();
@ -952,11 +974,11 @@ int main() {
// https://www.reclaimerlabs.com/blog/2017/2/1/usb-c-for-engineers-part-3
sleep_ms(5000);
printf("[pocket-sysctl] entering main loop.\n");
while (true) {
sleep_ms(1);
while (uart_is_readable(UART_ID)) {
handle_commands(uart_getc(UART_ID));
}
@ -964,9 +986,10 @@ int main() {
if (state == 0) {
gpio_put(PIN_LED_R, 0);
power_objects = 0;
request_sent = 0;
// by default, we output 5V on VUSB
gpio_put(PIN_USB_SRC_ENABLE, 1);
gpio_put(PIN_USB_SRC_ENABLE, 1); // FIXME
//printf("[pocket-sysctl] state 0\n");
// probe FUSB302BMPX
@ -974,41 +997,61 @@ int main() {
// 1. set auto GoodCRC
// AUTO_CRC in Switches1
// Address: 03h; Reset Value: 0b0010_0000
// TODO: figure out CC direction?
printf("[pocket-sysctl] FUSB probed.\n");
fusb_write_byte(FUSB_RESET, FUSB_RESET_SW_RES);
sleep_us(10);
// turn on all power
fusb_write_byte(FUSB_POWER, 0x0F);
fusb_write_byte(FUSB_CONTROL3, 0x07);
// automatic retransmission
//fusb_write_byte(FUSB_CONTROL3, 0x07);
// AUTO_HARDRESET | AUTO_SOFTRESET | 3 retries | AUTO_RETRY
fusb_write_byte(FUSB_CONTROL3, (1<<4) | (1<<3) | (3<<1) | 1);
// flush rx buffer
fusb_write_byte(FUSB_CONTROL1, FUSB_CONTROL1_RX_FLUSH);
// pdwn means pulldown. 0 = no pull down
/* Measure CC1 */
fusb_write_byte(FUSB_SWITCHES0, 0x07);
fusb_write_byte(FUSB_SWITCHES0, 4|2|1); // MEAS_CC1|PDWN2 |PDWN1
sleep_us(250);
uint8_t cc1 = fusb_read_byte(FUSB_STATUS0) & FUSB_STATUS0_BC_LVL;
printf("[pocket-sysctl] CC1: %d\n", cc1);
/* Measure CC2 */
fusb_write_byte(FUSB_SWITCHES0, 0x0B);
fusb_write_byte(FUSB_SWITCHES0, 8|2|1); // MEAS_CC2|PDWN2 |PDWN1
sleep_us(250);
uint8_t cc2 = fusb_read_byte(FUSB_STATUS0) & FUSB_STATUS0_BC_LVL;
printf("[pocket-sysctl] CC2: %d\n", cc2);
// cc1: 0, cc2: 3
// detect orientation
if (cc1 > cc2) {
fusb_write_byte(FUSB_SWITCHES1, 0x25);
fusb_write_byte(FUSB_SWITCHES0, 0x07);
fusb_write_byte(FUSB_SWITCHES1, 4|1); // |AUTO_CRC|TXCC1
fusb_write_byte(FUSB_SWITCHES0, 4|2|1); // MEAS_CC1|PDWN2 |PDWN1
} else {
fusb_write_byte(FUSB_SWITCHES1, 0x26);
fusb_write_byte(FUSB_SWITCHES0, 0x0B);
fusb_write_byte(FUSB_SWITCHES1, 4|2); // |AUTO_CRC|TXCC2
fusb_write_byte(FUSB_SWITCHES0, 8|2|1); // MEAS_CC2|PDWN2 |PDWN1
}
printf("[pocket-sysctl] switches set\n");
//fusb_write_byte(FUSB_RESET, FUSB_RESET_PD_RESET);
fusb_write_byte(FUSB_RESET, FUSB_RESET_PD_RESET);
// automatic soft reset
// FIXME
//fusb_write_byte(FUSB_CONTROL3, (1<<6) | (1<<4) | (1<<3) | (3<<1) | 1);
//sleep_ms(1);
//fusb_write_byte(FUSB_CONTROL3, (1<<4) | (1<<3) | (3<<1) | 1);
printf("[pocket-sysctl] auto hard/soft reset and retries set.\n");
t = 0;
state = 1;
} else {
@ -1019,37 +1062,40 @@ int main() {
}
} else if (state == 1) {
//printf("[pocket-sysctl] state 2\n");
//printf("[pocket-sysctl] state 1\n");
if (t>2000) {
printf("[pocket-sysctl] state 2, timeout, sleep\n");
// save power
sleep_ms(100);
t += 100;
// issue hard reset
fusb_write_byte(FUSB_CONTROL3, (1<<6) | 0x07);
sleep_ms(1);
fusb_write_byte(FUSB_CONTROL3, 0x07);
request_sent = 0;
state = 0;
if (t>3000) {
printf("[pocket-sysctl] state 1, timeout\n");
float input_voltage = charger_dump();
max_dump();
t = 0;
// without batteries, the system dies here (brownout?)
// but the charger might have set up the requested voltage anyway
if (input_voltage < 6) {
fusb_write_byte(FUSB_CONTROL3, (1<<6) | (1<<4) | (1<<3) | (3<<1) | 1);
//sleep_ms(1);
fusb_write_byte(FUSB_CONTROL3, (1<<4) | (1<<3) | (3<<1) | 1);
state = 0;
} else {
state = 3;
}
}
int res = fusb_read_message(&rx_msg);
if (!res) {
//printf("[pocket-sysctl] s1: charger responds, turning off USB_SRC\n");
// if a charger is responding, turn off our 5V output
gpio_put(PIN_USB_SRC_ENABLE, 0);
uint8_t msgtype = PD_MSGTYPE_GET(&rx_msg);
uint8_t numobj = PD_NUMOBJ_GET(&rx_msg);
printf(" msg type: %x numobj: %d\n", msgtype, numobj);
if (msgtype == PD_MSGTYPE_SOURCE_CAPABILITIES) {
int max_voltage = 0;
for (int i=0; i<numobj; i++) {
uint32_t pdo = rx_msg.obj[i];
if ((pdo & PD_PDO_TYPE) == PD_PDO_TYPE_FIXED) {
int voltage = print_src_fixed_pdo(pdo);
if (voltage > max_voltage && voltage <= 20) {
@ -1057,7 +1103,7 @@ int main() {
max_voltage = voltage;
}
} else {
printf("not a fixed PDO: %08x\n", pdo);
printf("[pocket-sysctl] s1: not a fixed PDO: %08x\n", pdo);
}
}
if (!request_sent) {
@ -1066,11 +1112,16 @@ int main() {
}
} else if (msgtype == PD_MSGTYPE_PS_RDY) {
// power supply is ready
printf("[pocket-sysctl] power supply ready!\n");
printf("[pocket-sysctl] s1: power supply ready!\n");
request_sent = 0;
t = 0;
state = 3;
} else {
printf("[pocket-sysctl] s1: msg type: %x numobj: %d\n", msgtype, numobj);
}
} else {
//sleep_ms(1);
//printf("[pocket-sysctl] s1: no message\n");
}
} else if (state == 2) {
printf("[pocket-sysctl] state 2, requesting PO %d\n", power_objects);
@ -1088,23 +1139,32 @@ int main() {
fusb_send_message(&tx);
printf("[pocket-sysctl] request sent.\n");
printf("[pocket-sysctl] s2: request sent.\n");
tx_id_count++;
t = 0;
request_sent = 1;
state = 1;
} else if (state == 3) {
gpio_put(PIN_LED_R, 1);
gpio_put(PIN_USB_SRC_ENABLE, 0);
charger_configure();
// charging
sleep_ms(1);
// running
if (t>2000) {
printf("[pocket-sysctl] state 3\n");
//i2c_scan();
int renegotiate = charger_dump();
float input_voltage = charger_dump();
max_dump();
if (renegotiate) {
if (input_voltage < 6) {
printf("[pocket-sysctl] input voltage below 6v, renegotiate\n");
state = 0;
}
@ -1112,11 +1172,6 @@ int main() {
}
}
if (t_report>5000) {
max_dump();
t_report = 0;
}
t++;
t_report++;
}