purpose: 1-wire bit banger for EEPROM inside OLPC battery [ifdef] forgetme forgetme [then] marker forgetme \ 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 : 1w-init ( -- ) disable-interrupts kbc-off 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! ; : 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-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# 20 constant ds-bank0 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# 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 ( -- ) 1w-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 ; \ 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, 0e c, 1a c, 50 c, 00 c, F0 c, 00 c, F0 c, 06 c, 11 c, 01 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 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 h# 6c 1w-cmd h# 22 1w-write-byte ds-batid 1w-copy ; : bat-set-life-gp ( -- ) ds-batid h# 6c 1w-cmd h# 12 1w-write-byte ds-batid 1w-copy ; : bat-set-low ( -- ) h# 2d h# 6c 1w-cmd 05 1w-write-byte 03 1w-write-byte 35 1w-write-byte h# 2d 1w-copy ds-remain-acr-msb h# 6c 1w-cmd 03 1w-write-byte 35 1w-write-byte ds-remain-acr-msb 1w-copy 1w-reset ; : bat-guage-acr@ ( -- acr ) ds-bank-buf 2 h# 10 1w-read ( ) ds-bank-buf c@ 8 << ( msb ) ds-bank-buf 1 + c@ or ( acr ) ; : .bat-guage-acr ( -- ) bat-guage-acr@ . ; : bat-watch-acr ( -- ) cursor-off begin (cr .bat-guage-acr 100 ms key? until key drop cursor-on ; \ 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 ; \ Dump out lots of the EC RAM that deal with the battery. h# FA00 constant ec-rambase : ec-ram@ ec-rambase + ec@ ; : .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@ . ; : bat-watch-info cursor-off begin .bat-info cr 200 ms key? until key drop cursor-on ; : 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 ; : 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 ;