@@ -313,6 +313,8 @@ mod app {
313313 bq25713 : Option < Bq25713 < I2c2Master > > ,
314314 /// Latest power supply report.
315315 power_supply : Option < PowerSupply > ,
316+ /// Connect USB data lines of supply?
317+ power_supply_connect_data : bool ,
316318 /// Latest battery report.
317319 battery : Option < Battery > ,
318320 /// Undervoltage power off in progress?
@@ -748,6 +750,7 @@ mod app {
748750 max14636,
749751 bq25713,
750752 power_supply : None ,
753+ power_supply_connect_data : false ,
751754 battery : None ,
752755 undervoltage_power_off : false ,
753756 bootloader_crc32,
@@ -955,7 +958,7 @@ mod app {
955958
956959 /// Updates the power supply status.
957960 #[ task(
958- shared = [ i2c2, stusb4500, max14636, bq25713, power_supply, irq, board, & power_mode] ,
961+ shared = [ i2c2, stusb4500, max14636, bq25713, power_supply, power_supply_connect_data , irq, board, & power_mode] ,
959962 local = [
960963 first: Option <Instant > = None ,
961964 last_change: Option <Instant > = None ,
@@ -974,84 +977,94 @@ mod app {
974977 cx. shared . max14636 ,
975978 cx. shared . bq25713 ,
976979 cx. shared . power_supply ,
980+ cx. shared . power_supply_connect_data ,
977981 cx. shared . irq ,
978982 cx. shared . board ,
979983 )
980- . lock ( |i2c2, stusb4500, max14636, bq25713, power_supply, irq, board| {
981- // Merge power supply reports.
982- let mut report = PowerSupply :: default ( ) ;
983- if let Some ( stusb4500) = stusb4500 {
984- let stusb4500_report = stusb4500. report ( ) ;
985- defmt:: trace!( "STUSB4500 power supply report: {:?}" , & stusb4500_report) ;
986- report = report. merge ( stusb4500. report ( ) ) ;
987- }
988- if let Some ( max14636) = max14636 {
989- let max14636_report = max14636. report ( ) ;
990- defmt:: trace!( "MAX14636 power supply report: {:?}" , & max14636_report) ;
991- report = report. merge ( & max14636_report) ;
992- }
984+ . lock (
985+ |i2c2, stusb4500, max14636, bq25713, power_supply, power_supply_connect_data, irq, board| {
986+ // Set USB data connection.
987+ if let Some ( max14636) = max14636 {
988+ if max14636. good_battery ( ) != * power_supply_connect_data {
989+ max14636. set_good_battery ( * power_supply_connect_data) ;
990+ }
991+ }
993992
994- // Update power supply status.
995- if Some ( & report) != power_supply. as_ref ( ) {
996- defmt:: info!( "Power supply: {:?}" , report) ;
993+ // Merge power supply reports.
994+ let mut report = PowerSupply :: default ( ) ;
995+ if let Some ( stusb4500) = stusb4500 {
996+ let stusb4500_report = stusb4500. report ( ) ;
997+ defmt:: trace!( "STUSB4500 power supply report: {:?}" , & stusb4500_report) ;
998+ report = report. merge ( stusb4500. report ( ) ) ;
999+ }
1000+ if let Some ( max14636) = max14636 {
1001+ let max14636_report = max14636. report ( ) ;
1002+ defmt:: trace!( "MAX14636 power supply report: {:?}" , & max14636_report) ;
1003+ report = report. merge ( & max14636_report) ;
1004+ }
9971005
998- // Store report and notify host.
999- irq. pend_soft ( IrqState :: SUPPLY | IrqState :: BATTERY ) ;
1000- * power_supply = Some ( report. clone ( ) ) ;
1001- * last_change = monotonics:: now ( ) ;
1002- }
1006+ // Update power supply status.
1007+ if Some ( & report) != power_supply. as_ref ( ) {
1008+ defmt:: info!( "Power supply: {:?}" , report) ;
10031009
1004- // Check for power on and shutdown in charging mode.
1005- if * cx. shared . power_mode == PowerMode :: Charging {
1006- if board. check_power_on_requested ( ) {
1007- defmt:: info!( "Power on requested" ) ;
1008- let _ = power_restart:: spawn ( BootReason :: Restart ) ;
1010+ // Store report and notify host.
1011+ irq. pend_soft ( IrqState :: SUPPLY | IrqState :: BATTERY ) ;
1012+ * power_supply = Some ( report. clone ( ) ) ;
1013+ * last_change = monotonics:: now ( ) ;
10091014 }
10101015
1011- if !report. is_connected ( ) && monotonics:: now ( ) - * first > grace_period {
1012- defmt:: info!( "Shutdown because power supply disconnected" ) ;
1013- let _ = power_off:: spawn ( ) ;
1016+ // Check for power on and shutdown in charging mode.
1017+ if * cx. shared . power_mode == PowerMode :: Charging {
1018+ if board. check_power_on_requested ( ) {
1019+ defmt:: info!( "Power on requested" ) ;
1020+ let _ = power_restart:: spawn ( BootReason :: Restart ) ;
1021+ }
1022+
1023+ if !report. is_connected ( ) && monotonics:: now ( ) - * first > grace_period {
1024+ defmt:: info!( "Shutdown because power supply disconnected" ) ;
1025+ let _ = power_off:: spawn ( ) ;
1026+ }
10141027 }
1015- }
10161028
1017- // Calculate input current limit.
1018- let limit_opt = if report. is_unknown ( ) {
1019- None
1020- } else {
1021- Some ( board. input_current_limit ( & report, monotonics:: now ( ) - * last_change) )
1022- } ;
1029+ // Calculate input current limit.
1030+ let limit_opt = if report. is_unknown ( ) {
1031+ None
1032+ } else {
1033+ Some ( board. input_current_limit ( & report, monotonics:: now ( ) - * last_change) )
1034+ } ;
1035+
1036+ // Configure battery charger.
1037+ match & limit_opt {
1038+ _ if limit_opt == * cx. local . limit_opt => ( ) ,
1039+ Some ( limit) => match ( i2c2, bq25713) {
1040+ ( Some ( i2c2) , Some ( bq25713) ) => {
1041+ defmt:: info!(
1042+ "Setting BQ25713 maximum input current to {} mA and ICO to {}" ,
1043+ limit. max_input_current_ma,
1044+ limit. ico
1045+ ) ;
10231046
1024- // Configure battery charger.
1025- match & limit_opt {
1026- _ if limit_opt == * cx. local . limit_opt => ( ) ,
1027- Some ( limit) => match ( i2c2, bq25713) {
1028- ( Some ( i2c2) , Some ( bq25713) ) => {
1029- defmt:: info!(
1030- "Setting BQ25713 maximum input current to {} mA and ICO to {}" ,
1031- limit. max_input_current_ma,
1032- limit. ico
1033- ) ;
1034-
1035- let res = bq25713. set_input_current_limit ( i2c2, limit) . and_then ( |_| {
1036- if limit. max_input_current_ma > 0 && !bq25713. is_charge_enabled ( ) {
1037- bq25713. set_charge_enable ( i2c2, true ) ?;
1038- } else if limit. max_input_current_ma == 0 && bq25713. is_charge_enabled ( ) {
1039- bq25713. set_charge_enable ( i2c2, false ) ?;
1047+ let res = bq25713. set_input_current_limit ( i2c2, limit) . and_then ( |_| {
1048+ if limit. max_input_current_ma > 0 && !bq25713. is_charge_enabled ( ) {
1049+ bq25713. set_charge_enable ( i2c2, true ) ?;
1050+ } else if limit. max_input_current_ma == 0 && bq25713. is_charge_enabled ( ) {
1051+ bq25713. set_charge_enable ( i2c2, false ) ?;
1052+ }
1053+ Ok ( ( ) )
1054+ } ) ;
1055+ match res {
1056+ Ok ( ( ) ) => * cx. local . limit_opt = limit_opt,
1057+ Err ( err) => defmt:: error!( "Cannot configure BQ25713 charging: {}" , err) ,
10401058 }
1041- Ok ( ( ) )
1042- } ) ;
1043- match res {
1044- Ok ( ( ) ) => * cx. local . limit_opt = limit_opt,
1045- Err ( err) => defmt:: error!( "Cannot configure BQ25713 charging: {}" , err) ,
10461059 }
1047- }
1048- _ => {
1049- * cx . local . limit_opt = limit_opt ;
1050- }
1051- } ,
1052- None => * cx . local . limit_opt = limit_opt ,
1053- }
1054- } ) ;
1060+ _ => {
1061+ * cx . local . limit_opt = limit_opt ;
1062+ }
1063+ } ,
1064+ None => * cx . local . limit_opt = limit_opt ,
1065+ }
1066+ } ,
1067+ ) ;
10551068
10561069 defmt:: unwrap!( power_supply_update:: spawn_after( 500u64 . millis( ) ) ) ;
10571070 }
@@ -1475,6 +1488,7 @@ mod app {
14751488 adc_buf,
14761489 board,
14771490 power_supply,
1491+ power_supply_connect_data,
14781492 battery,
14791493 flash,
14801494 crc,
@@ -1886,6 +1900,12 @@ mod app {
18861900 }
18871901 } ) ;
18881902 }
1903+ Event :: Read { reg : reg:: SUPPLY_CONNECT_DATA } => {
1904+ cx. shared . power_supply_connect_data . lock ( |& mut connect| respond_u8 ( connect. into ( ) ) ) ;
1905+ }
1906+ Event :: Write { reg : reg:: SUPPLY_CONNECT_DATA , value } => {
1907+ cx. shared . power_supply_connect_data . lock ( |connect| * connect = value. as_u8 ( ) != 0 ) ;
1908+ }
18891909 Event :: Read { reg : reg:: BOARD_IO } => {
18901910 cx. shared . board . lock ( |board| {
18911911 let data = board. io_read ( ) ;
0 commit comments