fl { PropForth5.2 1-Wire Demo Refered SpinObject "SpinOneWire.spin" 25/08/2012 17:10:31 } hex \ Pin on 1-Wire Bus 0 wconstant _OW \ DS18B20's Command F0 wconstant SEARCH_ROM 33 wconstant READ_ROM 55 wconstant MATCH_ROM CC wconstant SKIP_ROM EC wconstant ALARM_SEARCH BE wconstant READ_SCRATCHPAD 44 wconstant CONVERT_T 4E wconstant WRITE_SCRATCHPAD 48 wconstant COPY_SCRATCHPAD B8 wconstant RECALL_EE B4 wconstant READ_POWER_SUPPLY 28 wconstant Family_DS18B20 \ Max devices number to search 8 wconstant maxDevice 100 constant REQUIRED_CRC \ tepm-area stored ROM Code (2Long) variable rom 4 allot wvariable fault \ Set 1 when bitConflict wvariable discrepancy \ Last bitConflict wvariable discrepancyMark \ bit number skipped ROM code wvariable locked wvariable flag \ Area to save founded devicecode(64bit) maxDevice=8 variable deviceAddr 3C allot : ow_mask 1 _OW 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(by outa-register) 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 74usec 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 n's bit data from tepm-area of ROM Code \ { n1 n2 -- n3 } n1:address of rom n2:bit number(1 to 64) n3:0/1 bit number(1 to 64) : 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 crc5 of ROM code or scrachPad memory \ ( n1 -- n2 ) n1:address of ROM code or scrachPad memory n2:result : crc8 0 \ initial crc 8 0 do over C@ \ Get 1byte 8 0 do 2dup xor and 1 \ (crc ^ byte) & 1 swap if 1 rshift 8C xor \ (crc >> 1) & $8C else 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) i 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! \ 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 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 then discrepancyMark W@ discrepancy W! discrepancy W@ 0= if maxDevice 1- seti then \ Stop search when no device else maxDevice 1- seti then then loop nip ; \ Convert Temp(12bit) to degree \ ( n1 -- n2 ) n1:Temp(12bit) n2:degree : conv12_degree 10 u/mod \ quotient . ." ." \ remainder 271 u* . ; \ -------- demo code -------------------------------------------- \ Read temperature \ ( n1 -- n2 ) n:ROM Code(2Longs) n2:temperature : readTemperature dup reset if 1 drop MATCH_ROM writeByte writeAddress CONVERT_T writeByte begin dup begin 1 readBits 0> until reset if 1 drop MATCH_ROM writeByte writeAddress READ_SCRATCHPAD writeByte 10 readBits conv12_degree ." degree" cr then fkey? swap drop until drop then ; \ Display Device's ROM Code : device cr ." ROM Code" cr deviceAddr 2 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 cr decimal loop else ." No device" cr then cr ; \ Display temperature : temp deviceAddr 2 search dup 0> if 0 do deviceAddr i 8 u* + readTemperature loop then ; \ Display ScratchPadMemory : rd_scratch reset if SKIP_ROM writeByte READ_SCRATCHPAD writeByte \ 9 0 do readByte . loop hex ." Temperature LSB: " readByte . cr ." Temperature MSB: " readByte . cr ." TH register : " readByte . cr ." TL register : " readByte . cr ." Configuration : " readByte . cr ." Reserved(FFH) : " readByte . cr ." Reserved : " readByte . cr ." Reserved(10H) : " readByte . cr ." CRC : " readByte . cr then ; \ change configuration : wr_scratch reset if SKIP_ROM writeByte WRITE_SCRATCHPAD writeByte 4B writeByte \ Default 46 writeByte \ Default 5F writeByte \ change 7F(default:12bits) to 5F(11bits) then rd_scratch ; : default_scratch reset if SKIP_ROM writeByte WRITE_SCRATCHPAD writeByte 4B writeByte \ Default 46 writeByte \ Default 7F writeByte \ recovery default 7F then rd_scratch ;