fl { PropForth5.2 1-Wire Refered SpinObject "SpinOneWire.spin" 03/09/2012 22:52:48 } hex \ 1-Wire Device family-code 28 wconstant DS18B20 09 wconstant DS2502 \ Pin on 1-Wire Bus 0 wconstant _OW \ FET-sw for strong pull-up 1 wconstant _FET \ 12V for programming DS2502 2 wconstant _PROG \ DS18B20's Command F0 wconstant SEARCH_ROM 33 wconstant READ_ROM 55 wconstant MATCH_ROM CC wconstant SKIP_ROM \ Max devices number to search 8 wconstant maxDevice 100 constant REQUIRED_CRC \ tepm-area stored ROM Code (2Long) \ also used scratch-pad memory(9byte)'s crc8 calculation variable rom 5 allot \ Fault no reply during serching devices wvariable fault \ Set 1 when bitConflict wvariable discrepancy \ Last bitConflict wvariable discrepancyMark \ Set bit when WORD"serch" skip ROM code wvariable locked \ Set family code when serching only family code devices (Default is CRC-valid.) wvariable flag 100 flag W! \ Area to save founded devicecode(64bit) maxDevice=8 variable deviceAddr 3C allot : ow_mask 1 _OW lshift ; : fet_mask 1 _FET lshift ; : prog_mask 1 _PROG lshift ; \ Issue reset pulse to 1_wire bus \ ( -- n ) n:1=device is present 0= not present : reset \ Make sure the line isn't shorted ina COG@ ow_mask and if dira COG@ ow_mask or dira COG! \ Set _OW-pin to Low(output) 1D 0 do 1 1 u* drop loop \ 480usec low dira COG@ ow_mask andn dira COG! \ Set _OW-pin to hi(by pullup resister) 4 0 do 1 1 u* drop loop \ wait 80usec 1 drop 1 drop ina COG@ ow_mask and if 0 else 1 then else \ line is shorted 0 then ; \ write bits on 1-Wire bus \ ( n1 n2 -- ) n1:bit array n2:repeat number : writeBits 0 do dup 1 and if \ Write "1" dira COG@ dup ow_mask or dira COG! \ Set _OW-pin to Low(by outa-register) \ Low about 4.5usec dira COG! 2 0 do 1 1 u* drop loop \ Hi about 43usec else \ Write "0" dira COG@ dup ow_mask or dira COG! 2 0 do 1 1 u* drop loop \ Low about 43usec dira COG! then 1 rshift loop drop ; \ write byte on 1-Wire bus \ ( n -- ) n:byte data : writeByte 8 writeBits ; \ Write ROM Code to 1-Wire bus \ ( n -- ) n:Address stored ROM Code : writeAddress dup L@ 20 writeBits 4+ L@ 20 writeBits ; \ read bits on 1-Wire bus \ ( n1 -- n2 ) n1: repeat number n2:read data : readBits 1 \ mask 0 \ initial read data rot 0 do dira COG@ dup ow_mask or dira COG! \ Set _OW-pin to Low(by outa-register) \ Low about 4.5usec dira COG! 1 drop \ wait \ about 67usec from lineA to lineB ina COG@ ow_mask and \ read 1bit lineA if over or then swap 1 lshift swap \ mask << 1 lineB loop nip ; \ read byte on 1-Wire bus \ ( -- n) n:byte data : readByte 8 readBits ; \ read ROM Code on 1-Wire bus \ ( -- n ) n:ROM Code : readAddress 40 readBits ; \ Convert d64-0 to d31-0 and rom address to 0/+4 \ ( n1 n2 -- n3 n4 ) n1:address of rom n2:bit number(1 to 64) n3:address of rom(+0/+4) n4:bitwise of bit number : convBit32 1- dup 5 rshift 0> \ check if n2-1 is more than d32 if \ n2-1 is more than d32 20 - \ n2-1 --> between 0 to d31 swap 4+ \ rom-addr +4 swap then 1 swap lshift ; \ Get bit-n's data from tepm-area of ROM Code \ { n1 n2 -- n3 } n1:address of rom n2:bit number(1 to 64) n3:0/1 : getBit64 convBit32 swap L@ and if 1 else 0 then ; \ Set n's bit data from tepm-area of ROM Code to 0/1 \ { n1 n2 n3 -- } n1:0/1 n2:address of rom n3:bit number(1 to 64) : setBit64 convBit32 rot \ ( [address of rom] [bitwise of bit number] [0/1]) if over L@ or swap L! else invert over L@ and swap L! then ; \ Calculate the crc8 of ROM code or scrachPad memory \ ( n1 n2 -- n3 ) n1:address of ROM code or scrachPad memory n2:crc's bytes n3:result : crc8 0 \ initial crc swap 0 do over C@ \ Get 1byte 8 0 do 2dup xor 1 and \ (crc ^ byte) & 1 if swap 1 rshift 8C xor \ (crc >> 1) & $8C else swap 1 rshift \ crc >> 1 then swap 1 rshift \ byte >> 1 loop drop \ drop byte swap 1+ swap \ increment address of ROM loop nip \ drop address ; \ Read 2bits on 1-Wire bus \ ( n -- ) n bit number : read2bits 2 readBits \ case 0 0 over = if \ %00 bitConflict \ || \ | -1stbit \ ---second bit(1st bit's complementary) over discrepancy W@ = if over 1 swap rom swap setBit64 else over discrepancy W@ > if over 0 swap rom swap setBit64 over discrepancyMark W! else over rom swap getBit64 0= if over discrepancyMark W! then then then \ case 1 else 1 over = if \ %01 All devices read 1 over 1 swap rom swap setBit64 \ case 2 else 2 over = if \ %10 All devices read 0 over 0 swap rom swap setBit64 \ case other else \ %11 No response from any devices 1 fault W! thens 2drop ; \ search devices on 1-Wire bus \ flag Lower 8bit is zero, all devices are searched \ Lower 8bit include family code, search only devices have family-code \ Max devices Max drvice number to search \ addresPtr Address to store found device's ROM code \ ( n1 n2 -- n3 ) n1:addresPtr n2: Max devices n3:number for founded devices on 1-Wire bus : search 0 rom 4+ L! 0 discrepancy W! 0 locked W! 0 fault W! \ Optionally restrict to a single family flag W@ FF and rom L! rom L@ 0<> if 8 locked W! then 0 swap \ initial device number \ repeat Max devices 0 do reset 0= if maxDevice 1- seti \ Stop search when no device 1 fault W! else SEARCH_ROM writeByte 0 discrepancyMark W! 41 1 do i locked W@ > if i read2bits else \ skip family code 2 readBits drop then \ Reply, selecting only devices that match this bit rom i getBit64 1 writeBits fault W@ if 40 seti then loop fault W@ 0= if flag W@ REQUIRED_CRC and 0> if rom 8 crc8 else 0 then 0= if \ (addrPtr device-number) swap dup dup rom L@ swap L! \ rom L@ --> addrPtr L! rom 4+ L@ swap 4+ L! \ rom 4+ L@ --> addrPtr 4+ L! 8 + \ Increment address swap 1+ \ Incremrnt device number else ." crc error" cr then discrepancyMark W@ discrepancy W! discrepancy W@ 0= if maxDevice 1- seti then else \ Stop search when no device maxDevice 1- seti then then loop nip ; \ Display device-number and Device-Code (defaut:max8pcs) \ Each ROM-Code are stored from deviceAddr \ Each ROM-Code is 2Long(8Byte). \ ( -- ) : devices? \ Set FET-on on out register outa COG@ fet_mask or outa COG! outa COG@ prog_mask or outa COG! cr ." ROM Code" cr deviceAddr 8 search dup 0> if 0 do ." Device No. " i 1+ . ." : " hex deviceAddr i 1+ 8 u* + 4 0 do 2 - dup W@ .word loop \ drop C@ dup 28 = if ." DS18B20 Digital Thermometer" else dup 09 = if ." DS2802 1Kb Add-Only Memory" else ." Unknown device" thens drop cr decimal loop else drop ." No device" cr then cr fault W@ 1 = if ." Sorry, No response from any devices because of any erroor." cr then ; \ Calculate address stored ROM-Code from device number, WORD[devices?] \ ( n -- ) n:device number : calc_ROM_addr 1- 8 u* deviceAddr + \ Get address of ROM Code ; \ Write ROM-Code on 1-Wire bus \ ( n -- ) n:address stored ROM-Code : matchDevice MATCH_ROM writeByte writeAddress ; \ Set family-code \ ( n -- ) n:family code : set_family flag W@ 100 and or flag W! ; \ Serch all devices : all_devices 100 flag W! ; \ Reset crc-check \ ( -- ) : crc_off flag W@ FF and flag W! ; \ Set crc-check \ ( -- ) : crc_on flag W@ 100 or flag W! ; decimal