purpose: Swiss army knife for dealing with the OLPC battery(s) \ Version 0.3.11 [ifdef] forgetme forgetme [then] marker forgetme [ifndef] fileih 0 value fileih [then] [ifndef] bat-b@ : bat-b@ h# f900 + ec@ ; [then] [ifndef] w16>d32 : w16>d32 ( 16bit -- 32bit_sign-extended ) d# 16 << d# 16 >>a ; [then] [ifndef] batman-init \ A few commands for looking at what the EC is doing in \ the battery state machine. \ Unless you are on a serial console with stdout turned off \ (stdout off) this will miss some state changes. \ : next-bstate begin f780 ec@ tuck <> until ; : see-bstate 0 begin next-bstate dup . dup 4 = if cr then key? until ; : next-e1-state begin fae1 ec@ tuck <> until ; : see-e1 0 begin next-e1-state dup . key? until ; \ Turn on the charging mosfet : bat-enable-charge ( -- ) fc21 ec@ 40 or fc21 ec! ; \ Turn off the charging mosfet : bat-disable-charge ( -- ) fc21 ec@ 40 invert and fc21 ec! 03 fc24 ec! ; \ Turn on the trickle charge with max system voltage : bat-enable-trickle ( -- ) fc23 ec@ 1 or fc23 ec! 01 fc24 ec! ; \ Turn off the trickle charger : bat-disable-trickle ( -- ) fc23 ec@ 1 invert and fc23 ec! ; \ Access the 1-wire data line via the EC GPIO ports h# 383 constant dataport h# 382 constant lowadr 4 constant dq-bit 0 value high 0 value low false value 1w-initialized : disable-ec-charging 1 h# fa07 ec! ; : disable-ec-1w 1 h# fa08 ec! ; : enable-ec-charging 0 h# fa07 ec! ; : enable-ec-1w 0 h# fa08 ec! ; : ec-api-ver@ ( -- b ) h# 08 ec-cmd-b@ ; : 1w-init ( -- ) disable-interrupts h# fc24 ec@ dq-bit invert and fc24 ec! h# fc14 ec@ dup dq-bit or to low dq-bit invert and to high high fc14 ec! true to 1w-initialized 1 ms ; \ New ec revs can turn off the battery subsystem without \ putting the ec into reset allowing the user to \ use the XO keyboard. : init-ec-live disable-ec-charging disable-ec-1w 1w-init ; : init-ec-dead kbc-off 1w-init ; : batman-init ec-api-ver@ h# 54 >= if init-ec-live else init-ec-dead then ; : batman-init? 1w-initialized if else batman-init then ; : batman-start batman-init? ; : batman-stop enable-ec-1w enable-ec-charging enable-interrupts false to 1w-initialized ; : bit? ( us -- flag ) \ Test the data after a delay us h# 34 lowadr pc! dataport pc@ dq-bit and 0<> ; : 1w-pulse ( us -- ) \ Pulse the wire low for some duration h# 14 lowadr pc! low dataport pc! us high dataport pc! ; \ Generic 1-wire primitives : 1w-reset ( -- ) d# 480 1w-pulse d# 67 bit? abort" No response from battery" begin 1 bit? until ; : 1w-write-byte ( byte -- ) 8 0 do ( byte ) dup 1 and if ( byte ) 1 1w-pulse d# 60 us ( byte ) else ( byte ) d# 60 1w-pulse ( byte ) then ( byte ) 2/ ( byte' ) loop ( byte ) drop ( ) ; : 1w-read-byte ( -- ) 0 8 0 do 1 1w-pulse \ Shift bits in from the left, little endian d# 10 bit? h# 100 and or 2/ d# 50 us loop ; : 1w-skip-address ( -- ) h# cc 1w-write-byte ; : 1w-cmd ( arg cmd -- ) 1w-reset 1w-skip-address 1w-write-byte 1w-write-byte ; \ Basic commands for the DS2756 chip : 1w-read ( adr len start -- ) h# 69 1w-cmd ( adr len ) bounds ?do 1w-read-byte i c! loop ( ) 1w-reset ; : 1w-write ( adr len start -- ) h# 6c 1w-cmd ( adr len ) bounds ?do i c@ 1w-write-byte loop ( ) 1w-reset ; : 1w-write-start ( start -- ) h# 6c 1w-cmd ; : 1w-copy ( start -- ) h# 48 1w-cmd d# 10 ms ; : 1w-recall ( start -- ) h# b8 1w-cmd ; \ : 1w-lock ( start -- ) h# 6a 1w-cmd ; : 1w-sync ( -- ) 0 h# d2 1w-cmd ; \ Some higher-level commands for accessing battery data \ buffer for reading bank data h# 20 constant /ds-bank \ Bytes per bank in the battery sensor chip h# 60 constant /ds-eeprom \ Bytes in the eeprom h# 01 constant ni-mh h# 02 constant li-fe h# 00 constant ds-regs h# 10 constant ds-acr h# 20 constant ds-bank0 h# 25 constant ds-bat-misc-flag h# 2d constant ds-last-dis-soc h# 2e constant ds-last-dis-acr-msb h# 2f constant ds-last-dis-acr-lsb h# 31 constant ds-pack-default-status h# 5f constant ds-batid h# 60 constant ds_bat_serial_num_1 h# 61 constant ds_bat_serial_num_2 h# 62 constant ds_bat_serial_num_3 h# 63 constant ds_bat_serial_num_4 h# 64 constant ds_bat_serial_num_5 h# 68 constant ds-remain-acr-msb h# 69 constant ds-remain-acr-lsb h# 6a constant ds_bat_charge_msb h# 6b constant ds_bat_charge_lsb h# 6c constant ds_bat_charge_soc h# 6d constant ds_bat_discharge_msb h# 6e constant ds_bat_discharge_lsb h# 6f constant ds_bat_discharge_soc h# 40 constant ds-bank1 h# 60 constant ds-bank2 h# 68 constant ds-remain-acr-msb h# 69 constant ds-remain-acr-lsb h# 5f constant ds-batid h# 01 constant ds-bat-low-volt h# 20 constant ds-bat-full h# 20 buffer: ds-bank-buf : ds-bank$ ( -- adr len ) ds-bank-buf /ds-bank ; : bat-id ( -- id ) ds-bank-buf 1 ds-batid 1w-read ds-bank-buf c@ h# 0f and ; : read-bank ( offset -- ) ds-bank$ rot 1w-read ; : bat-read-eeprom ( -- ) ds-bank-buf /ds-eeprom ds-bank0 1w-read ; : bat-ds-regs@ ( -- ) ds-regs read-bank ; : bat-bank0@ ( -- ) ds-bank0 read-bank ; : bat-bank1@ ( -- ) ds-bank1 read-bank ; : bat-bank2@ ( -- ) ds-bank2 read-bank ; : bat-dump-bank ( -- ) ds-bank$ dump ; : bat-dump-banks ( -- ) batman-init? cr ." Regs" bat-ds-regs@ bat-dump-bank cr cr ." Bank 0" bat-bank0@ bat-dump-bank cr cr ." Bank 1" bat-bank1@ bat-dump-bank cr cr ." Bank 2" bat-bank2@ bat-dump-bank ; : bat-dump-regs ( -- ) bat-ds-regs@ bat-dump-bank ; : bat-save ( -- ) " disk:\battery.dmp" 2dup ['] $delete catch if 2drop then ( name$ ) $create-file to fileih 1w-init h# 80 0 do ds-bank$ i 1w-read ds-bank$ " write" fileih $call-method /ds-bank +loop fileih close-dev ; \ bg-* words access the gauge directly via 1w rather than \ read the value from the ec cache : bg-acr@ ( -- acr ) batman-init? ds-bank-buf 2 h# 10 1w-read ( ) ds-bank-buf c@ 8 << ( msb ) ds-bank-buf 1 + c@ or w16>d32 ( acr ) ; : bg-acr! ( acr -- ) batman-init? wbsplit ds-acr 1w-write-start 1w-write-byte 1w-write-byte 1w-reset ; : bg-last-dis-soc@ ( -- last-dis-soc ) batman-init? ds-bank-buf 1 ds-last-dis-soc 1w-read ds-bank-buf c@ ; : bg-last-dis-soc! ( soc -- ) batman-init? ds-bank0 1w-recall ds-last-dis-soc 1w-write-start 1w-write-byte ds-last-dis-soc 1w-copy 1w-reset ; : bg-last-dis-acr@ ( -- last-dis-acr ) batman-init? ds-bank-buf 2 ds-last-dis-acr-msb 1w-read ( ) ds-bank-buf c@ 8 << ( last-dis-acr-msb ) ds-bank-buf 1 + c@ or w16>d32 ( last-dis-acr ) ; : bg-last-dis-acr! ( last-dis-acr --) batman-init? wbsplit ds-bank0 1w-recall ds-last-dis-acr-msb 1w-write-start 1w-write-byte 1w-write-byte ds-last-dis-acr-msb 1w-copy 1w-reset ; : bg-misc@ ( -- misc-flag ) batman-init? ds-bank-buf 1 ds-bat-misc-flag 1w-read ds-bank-buf c@ ; : bg-set-full-flag ( -- ) bg-misc@ ds-bat-full or ds-bank0 1w-recall ds-bat-misc-flag 1w-write-start 1w-write-byte ds-bat-misc-flag 1w-copy 1w-reset ; : bg-clear-full-flag ( -- ) bg-misc@ ds-bat-full not and ds-bank0 1w-recall ds-bat-misc-flag 1w-write-start 1w-write-byte ds-bat-misc-flag 1w-copy 1w-reset ; : .bg-eeprom base @ >r decimal ." acr: " bg-acr@ . cr ." Last dis soc: " bg-last-dis-soc@ . cr ." Last dis acr: " bg-last-dis-acr@ . cr hex ." Misc flags: " bg-misc@ dup . ." : " dup ds-bat-full and if ." fully charged " then dup ds-bat-low-volt and if ." low voltage " then drop cr r> base ! ; [then] \ batman-init [ifndef] >sd.ddd h# 90 buffer: logstr : >sd <# " " hold$ u#s u#> ; : >sdx <# " " hold$ u#s " 0x" hold$ u#> ; : >sd.ddd ( n -- formatted ) base @ >r decimal dup abs <# u# u# u# [char] . hold u#s rot sign u#> r> base ! ; : >sd.dd ( n -- formatted ) base @ >r decimal dup abs <# u# u# [char] . hold u#s rot sign u#> 8 over - 0 max spaces r> base ! ; h# FA00 constant ec-rambase : ec-ram@ ec-rambase + ec@ ; [then] \ >sd.ddd [ifndef] .sd.ddd : .sd.ddd ( value -- ) >sd.ddd type ; : .sd.dd ( value -- ) >sd.dd type ; [then] \ Default bank 0 values for NiMh battery create ds-NiMh-init \ Bank 0 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 0e c, 1a c, 50 c, 00 c, 37 c, 00 c, 37 c, 00 c, 00 c, 00 c, 00 c, 6a c, 00 c, 00 c, 01 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, \ Bank 1 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 11 c, \ Bank 2 4c c, DB c, 01 c, 21 c, 77 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 55 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, \ Default bank values for LiFe battery create ds-LiFe-init \ Bank 0 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 0a c, f0 c, 50 c, 00 c, 37 c, 00 c, 37 c, 00 c, 00 c, 00 c, 00 c, 6A c, 00 c, 00 c, 01 c, 00 c, 00 c, 00 c, 13 c, 88 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, \ Bank 1 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 22 c, \ Bank 2 4C c, DB c, 01 c, 21 c, 77 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 55 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, : bat-rewrite-NiMh ( -- ) ds-NiMh-init /ds-eeprom ds-bank0 1w-write ds-bank0 1w-copy ds-bank1 1w-copy ds-bank2 1w-copy ; : bat-rewrite-LiFe ( -- ) ds-LiFe-init /ds-eeprom ds-bank0 1w-write ds-bank0 1w-copy ds-bank1 1w-copy ds-bank2 1w-copy ; : bat-init ( -- ) ." Battery EEPROM data corrupted... Fixing." cr bat-id case ni-mh of bat-rewrite-NiMh endof li-fe of bat-rewrite-LiFe endof endcase ; : bat-id-check bat-id case h# 1 of ." Checking NiMH battery" endof h# 2 of ." Checking LiFePO4 battery" endof ." Can't try to auto recover this battery because the battery type is unknown." cr ." Type is set to: " bat-id . cr ." Manual recovery may be needed." cr ." Seek assistance." cr true abort" procedure aborted." endcase ; \ The EC error checking code watches for a series of >= 3 0xff's in a row \ so use that as the method of determining that the battery info has \ been corrupted and reset the EEPROM infomation. : bat-check-and-recover ( -- ) 1w-init bat-id-check cr ." Scaning " cr 0 ds-bank0 bat-read-eeprom ds-bank-buf /ds-eeprom bounds do i c@ h# ff = if 1 + dup 3 >= if bat-init leave then else drop 0 then loop drop ." Done " cr ; \ Restore the bat-id byte to nimh \ Currntly this also sets the mfg to \ goldpeak : bat-set-nimh ( -- ) ds-batid 1w-recall ds-batid h# 6c 1w-cmd h# 11 1w-write-byte ds-batid 1w-copy ; \ Rstore the bat-id byte to Life \ Also sets the mfg to BYD. : bat-set-life-byd ( -- ) ds-batid 1w-recall ds-batid h# 6c 1w-cmd h# 22 1w-write-byte ds-batid 1w-copy ; : bat-set-life-gp ( -- ) ds-batid 1w-recall ds-batid h# 6c 1w-cmd h# 12 1w-write-byte ds-batid 1w-copy ; \ Clears various flags in the eeprom and sets the remaining \ amount of charge to be low. This will reset the SOC so the \ EC thinks the battery has been discharged : bat-set-low ( -- ) ds-bank0 1w-recall ds-bank1 1w-recall ds-bank2 1w-recall h# 25 1w-write-start 00 1w-write-byte h# 2d 1w-write-start 05 1w-write-byte 03 1w-write-byte 35 1w-write-byte ds-bank0 1w-copy ds-remain-acr-msb 1w-write-start 03 1w-write-byte 35 1w-write-byte ds-remain-acr-msb 1w-copy 1w-reset ; [ifndef] ds-default-status h# 31 constant ds-default-status : bat-set-default-status ( val -- ) ds-bank0 1w-recall ds-default-status 1w-write-start 1w-write-byte ds-bank0 1w-copy 1w-reset ; : bat-get-default-status ( -- val ) ds-bank0 1w-recall ds-bank-buf 1 ds-default-status 1w-read ds-bank-buf c@ ( pack info ) ; : bat-fix-error-2 batman-init? bat-get-default-status dup h# 6a = if ." Pack info is already correct" drop else ." Fixing bad pack info: " . h# 6a bat-set-default-status then ; [then] \ Retrieve the key battery stats in bulk and put it on the stack \ sign extending the values that are 2's complement. : bat-charge-info@ ( -- voltage current ACR ) ds-bank-buf 6 h# 0c 1w-read ( ) ds-bank-buf c@ 8 << ( voltage_msb ) ds-bank-buf 1 + c@ or d# 16 << d# 16 >>a ( voltage ) ds-bank-buf 2 + c@ 8 << ( voltage current_msb ) ds-bank-buf 3 + c@ or d# 16 << d# 16 >>a ( voltage current ) ds-bank-buf 4 + c@ 8 << ( voltage current ACR_msb ) ds-bank-buf 5 + c@ or d# 16 << d# 16 >>a ( voltage current ACR ) ; : bat-recover-info@ ( -- voltage ACR current temp ) ds-bank-buf 6 h# 0c 1w-read ( ) ds-bank-buf c@ 8 << ( voltage_msb ) ds-bank-buf 1 + c@ or d# 16 << d# 16 >>a ( voltage ) ds-bank-buf 4 + c@ 8 << ( voltage ACR_msb ) ds-bank-buf 5 + c@ or d# 16 << d# 16 >>a ( voltage ACR ) ds-bank-buf 4 h# 18 1w-read ( voltage ACR ) ds-bank-buf 2 + c@ 8 << ( voltage ACR current_msb ) ds-bank-buf 3 + c@ or d# 16 << d# 16 >>a ( voltage ACR current ) swap ( voltage current ACR ) ds-bank-buf c@ 8 << ( voltage ACR current temp_msb ) ds-bank-buf 1 + c@ or d# 16 << d# 16 >>a ( voltage ACR current temp ) ; : >x ( n -- formatted ) base @ >r hex h# ffff and (.) 4 over - spaces r> base ! ; : .(x) ( value -- ) ." (" >x type ." ) " ; : batgauge-V>V ( raw-value - Volts ) abs d# 488 ( mV ) * 2* d# 100 / 5 >> over 0< if negate then ; : .volt ( raw-volt -- ) dup batgauge-V>V .sd.ddd ." V " .(x) ; : batgauge-I>mA ( raw-value -- I_in_mA ) abs 3 >> d# 15625 ( nV ) * d# 15 ( mOhm ) / d# 10 / over 0< if negate then ; : .current ( raw-value -- ) dup batgauge-I>mA .sd.dd ." mA " .(x) ; : batgauge-avgI>avgImA ( raw-value -- avgI_in_mA ) abs d# 1953 ( nV ) * d# 15 ( mOhm ) / d# 10 / over 0< if negate then ; : .avg-cur ( raw-value -- ) dup batgauge-avgI>avgImA .sd.dd ." mA" .(x) ; : batgauge-acr>mAh ( raw-value -- acr_in_mAh ) abs d# 625 ( mV ) * d# 15 ( mOhm ) / over 0< if negate then ; : .acr ( raw-value -- ) dup batgauge-acr>mAh .sd.dd ." mAh " .(x) ; : batgauge-temp>degc ( raw-value -- temp_in_degc ) abs d# 125 * d# 10 / 5 >> over 0< if negate then ; : .temp ( raw-value -- ) dup batgauge-temp>degc .sd.dd ." C " .(x) ; : .bat-charge-info bat-charge-info@ .acr .current .volt ; : .bat-gauge-acr ( -- ) bg-acr@ . ; : bat-watch-acr ( -- ) cursor-off begin (cr .bat-gauge-acr 100 ms key? until key drop cursor-on ; 0 value last-acr 0 value v_avg : bat-charge ( -- ) bat-enable-charge bg-acr@ begin bat-charge-info@ dup to last-acr .acr .current .volt dup last-acr swap - ." Chg:" .acr cr 500 ms key? until drop bat-disable-charge ; 4 value bon 2 value boff : bat-recover ( -- ) batman-init? bg-acr@ begin bat-enable-charge bon ms bat-disable-charge bat-recover-info@ .temp to last-acr .current v_avg + 2 / dup to v_avg .volt dup last-acr swap - ." Chg:" .acr cr boff ms false until drop bat-disable-charge ; : bat-trickle ( -- ) bat-enable-trickle bg-acr@ begin bat-charge-info@ dup to last-acr .acr .current .volt dup last-acr swap - ." Chg:" .acr cr 500 ms false until drop bat-disable-trickle ; : .bat-info ." BatStatus: " h# a4 ec-ram@ . ." ChgStatus: " h# a5 ec-ram@ . ." BAT_ACR: " h# 04 bat-b@ 8 << h# 05 bat-b@ or . ." Real ACR: " h# 54 bat-b@ 8 << h# 55 bat-b@ or . ." SOC: " h# 10 bat-b@ . ." State: " h# 11 bat-b@ . cr ." Abnormal: " h# 70 bat-b@ . ." Voltage: " h# 00 bat-b@ 8 << h# 01 bat-b@ or . ." Current: " h# 02 bat-b@ 8 << h# 03 bat-b@ or . ." Temp: " h# 06 bat-b@ 8 << h# 07 bat-b@ or . ." ChrgFlw: " h# fbd0 ec@ . ." PBatChg: " h# fbd1 ec@ . ; [ifndef] watch-battery : watch-battery begin h# 00 bat-b@ 8 << h# 01 bat-b@ or w16>d32 .volt h# 02 bat-b@ 8 << h# 03 bat-b@ or w16>d32 \ I .current cr d# 2500 ms key? until drop ; [then] : bat-nimh-rawdata@ ( -- values... number_of_values ) h# 17 bat-b@ 8 << h# 18 bat-b@ or \ Chargetime h# 06 bat-b@ 8 << h# 07 bat-b@ or \ Temp h# 02 bat-b@ 8 << h# 03 bat-b@ or \ I h# 60 bat-b@ 8 << h# 61 bat-b@ or \ V85 h# 00 bat-b@ 8 << h# 01 bat-b@ or \ V h# 54 bat-b@ 8 << h# 55 bat-b@ or \ ACR h# a7 ec-ram@ \ bat misc2 h# a6 ec-ram@ \ bat misc h# a5 ec-ram@ \ chg status h# a4 ec-ram@ \ bat_status h# 10 bat-b@ \ SOC h# e0 ec-ram@ \ C state h# 11 bat-b@ \ bat_state d# 13 \ number of values ; : bat-nimh-dataf@ base @ >r decimal 0 logstr c! h# 11 bat-b@ \ bat_state >sd logstr $cat hex h# e0 ec-ram@ \ C state >sdx logstr $cat decimal h# 10 bat-b@ \ SOC >sd logstr $cat hex h# a4 ec-ram@ \ bat_status >sdx logstr $cat h# a5 ec-ram@ \ chg status >sdx logstr $cat h# a6 ec-ram@ \ bat misc >sdx logstr $cat h# a7 ec-ram@ \ bat misc2 >sdx logstr $cat decimal h# 54 bat-b@ 8 << h# 55 bat-b@ or w16>d32 \ ACR batgauge-acr>mAh >sd.dd logstr $cat " " logstr $cat h# 00 bat-b@ 8 << h# 01 bat-b@ or \ V batgauge-V>V >sd.ddd logstr $cat " " logstr $cat h# 60 bat-b@ 8 << h# 61 bat-b@ or \ V85 batgauge-V>V >sd.ddd logstr $cat " " logstr $cat h# 02 bat-b@ 8 << h# 03 bat-b@ or w16>d32 \ I batgauge-I>mA >sd.dd logstr $cat " " logstr $cat h# 06 bat-b@ 8 << h# 07 bat-b@ or \ Temp batgauge-temp>degc >sd.dd logstr $cat " " logstr $cat h# 3c bat-b@ 8 << h# 3d bat-b@ or w16>d32 d# 0 - \ dRi >sd logstr $cat h# 17 bat-b@ 8 << h# 18 bat-b@ or \ Chargetime >sd logstr $cat now drop <# " :" hold$ u#s u#> logstr $cat <# " " hold$ u#s u#> logstr $cat \ Running time r> base ! ; : bat-see-nimh cursor-off begin bat-nimh-dataf@ logstr count type cr 350 ms key? until key drop cursor-on ; : bat-watch-info cursor-off begin .bat-info cr 200 ms key? until key drop cursor-on ; : bg-ds-serial@ 1w-reset h# 33 1w-write-byte 1w-read-byte 0 7 bounds ?do 1w-read-byte loop ; : read-net-addr ( -- seral_num crc ) 1w-reset h# 33 1w-write-byte 1w-read-byte ." Family: " . cr 0 7 bounds ?do 1w-read-byte loop ." Serial: " 0 6 bounds ?do . loop cr ." CRC: " . cr ; : solar-append ( adr len -- ) " sd:\mylog.txt" $append-open ofd @ fputs ofd @ fclose ; [ifndef] start-acr 0 value start-acr d# 5 value wake-delay : bat-build-chg$ base @ >r decimal 0 logstr c! time&date >unix-seconds >sd logstr $cat " , " logstr $cat soc >sd logstr $cat " , " logstr $cat uvolt@ >sd logstr $cat " , " logstr $cat cur@ >sd logstr $cat " , " logstr $cat bat-temp >sd logstr $cat " , " logstr $cat bat-acr@ w16>d32 bg-acr>mah dup >sd.dd logstr $cat " , " logstr $cat start-acr - batgauge-acr>mAh >sd.dd logstr $cat " , " logstr $cat r> base ! ; : bat-chg-log ( -- ) sci-wakeup bat-acr@ w16>d32 bg-acr>mah to start-acr begin bat-build-chg$ logstr count type cr wake-delay d# 1000 * h# 36 ec-cmd-l! s key? until key drop ; [then] : bat-reset-bank0 batman-init ds-bank0 1w-write-start 20 0 do 0 1w-write-byte loop f0 0a ds-bank0 6 + 1w-write-start 1w-write-byte 1w-write-byte 6a ds-default-status 1w-write-start 1w-write-byte ds-bank0 1w-copy 1w-reset ;