aboutsummaryrefslogtreecommitdiff
path: root/amforth-6.5/avr8/drivers/1wire.asm
blob: ab5c9f409ed52aebb58e4c21a7d582273327822b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
;; AUTHORs
;   B. J. Rodriguez (MSP 430)
;   Matthias Trute (AVR Atmega)
; COPYRIGHT
;   (c) 2012 Bradford J. Rodriguez for the 430 code and API

;  adapted 430 assembly code to AVR
;  wishlist: 
;     use a configurable pin at runtime, compatible with bitnames.frt
;     no external pull up, no external power supply for devices
;     ???
;
;.EQU OW_BIT=4
;.equ OW_PORT=PORTE
.set OW_DDR=(OW_PORT-1)
.set OW_PIN=(OW_DDR-1)

;****f* 1W.RESET
; NAME
;   1W.RESET
; SYNOPSIS
;   1W.RESET ( -- f )  Initialize 1-wire devices; return true if present
; DESCRIPTION
;   This configures the port pin used by the 1-wire interface, and then
;   sends an "initialize" sequence to the 1-wire devices.  If any device
;   is present, it will be detected.
;
;   Timing, per DS18B20 data sheet:
;   a) Output "0" (drive output low) for >480 usec.
;   b) Output "1" (let output float).
;   c) After 15 to 60 usec, device will drive pin low for 60 to 240 usec.
;      So, wait 75 usec and sample input.
;   d) Leave output high (floating) for at least 480 usec.
;******
; ( -- f )
; Hardware
; Initialize 1-wire devices; return true if present
VE_OW_RESET:
    .dw $ff08
    .db "1w.reset"
    .dw VE_HEAD
    .set VE_HEAD = VE_OW_RESET
XT_OW_RESET:
    .dw PFA_OW_RESET
PFA_OW_RESET:
    savetos
    ; setup to output
    sbi OW_DDR, OW_BIT
    ; Pull output low
    cbi OW_PORT, OW_BIT
    ; Delay >480 usec        
    DELAY   480
    ; Critical timing period, disable interrupts.
    in temp1, SREG
    cli
    ; Pull output high
    sbi OW_PORT, OW_BIT
    ; make pin input, sends "1"
    cbi OW_DDR, OW_BIT 
    DELAY   64 ; delayB
    ; Sample input pin, set TOS if input is zero
    in tosl, OW_PIN
    sbrs tosl, OW_BIT
    ser  tosh
    ; End critical timing period, enable interrupts
    out SREG, temp1
    ; release bus
    cbi OW_DDR, OW_BIT
    cbi OW_PORT, OW_BIT

    ; Delay rest of 480 usec 
    DELAY   416
    ; we now have the result flag in TOS        
    mov tosl, tosh
    jmp_ DO_NEXT
    
;****f* 1W.SLOT
; NAME
;   1W.SLOT
; SYNOPSIS
;   1W.SLOT ( c -- c' ) Write and read one bit to/from 1-wire.
; DESCRIPTION
;   The "touch byte" function is described in Dallas App Note 74.
;   It outputs a byte to the 1-wire pin, LSB first, and reads back
;   the state of the 1-wire pin after a suitable delay.
;   To read a byte, output $FF and read the reply data.
;   To write a byte, output that byte and discard the reply.
;
;   This function performs one bit of the "touch" operation --
;   one read/write "slot" in Dallas jargon.  Perform this eight
;   times in a row to get the "touch byte" function.
;
; PARAMETERS
;   The input parameter is xxxxxxxxbbbbbbbo where
;   'xxxxxxxx' are don't cares,
;   'bbbbbbb' are bits to be shifted down, and
;   'o' is the bit to be output in the slot.  This must be 1
;   to create a read slot.
;
;   The returned value is xxxxxxxxibbbbbbb where
;   'xxxxxxxx' are not known (the input shifted down 1 position),
;   'i' is the bit read during the slot.  This has no meaning
;   if it was a write slot.
;   'bbbbbbb' are the 7 input bits, shifted down one position.
;
;   This peculiar parameter usage allows OWTOUCH to be written as
;     OWSLOT OWSLOT OWSLOT OWSLOT OWSLOT OWSLOT OWSLOT OWSLOT 
;
; NOTES 
;   Interrupts are disabled during each bit.

;   Timing, per DS18B20 data sheet:
;   a) Output "0" for start period.  (> 1 us, < 15 us, typ. 6 us*)
;   b) Output data bit (0 or 1), open drain 
;   c) After MS from start of cycle, sample input (15 to 60 us, typ. 25 us*)
;   d) After write-0 period from start of cycle, output "1" (>60 us)
;   e) After recovery period, loop or return. (> 1 us)
;   For writes, DS18B20 samples input 15 to 60 usec from start of cycle.
;   * "Typical" values are per App Note 132 for a 300m cable length.

;   ---------        -------------------------------
;            \      /                        /
;             ------------------------------- 
;            a      b          c             d     e
;            |  6us |   19us   |    35us     | 2us |
;******
; ( c -- c' )
; Hardware
; Write and read one bit to/from 1-wire.
VE_OW_SLOT:
    .dw $ff07
    .db "1w.slot",0
    .dw VE_HEAD
    .set VE_HEAD = VE_OW_SLOT
XT_OW_SLOT:
    .dw PFA_OW_SLOT
PFA_OW_SLOT:
    ; pull low
    cbi OW_PORT, OW_BIT
    sbi OW_DDR, OW_BIT
    ; disable interrupts
    in temp1, SREG
    cli
    DELAY   6 ; DELAY A
    ; check bit
    clc
    ror tosl
    brcc PFA_OW_SLOT0 ; a 0 keeps the bus low
      ; release bus, a 1 is written
      sbi OW_PORT, OW_BIT
      cbi OW_DDR, OW_BIT
PFA_OW_SLOT0:
    ; sample the input (no action required if zero)
    DELAY 9   ; wait DELAY E to sample
    in temp0, OW_PIN
    sbrc temp0, OW_BIT
    ori tosl, $80

    DELAY   51 ; DELAY B
    sbi OW_PORT, OW_BIT ; release bus
    cbi OW_DDR, OW_BIT
    delay 2
    ; re-enable interrupts
    out SREG, temp1
    jmp_ DO_NEXT