aboutsummaryrefslogtreecommitdiff
path: root/amforth-6.5/avr8/lib/bitnames.frt
blob: fdda840a212b04f911c164538adaef9022ebcc92 (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
\ Code: Matthias Trute
\ Text: M.Kalus

\ A named port pin puts a bitmask on stack, wherin the set bit indicates which
\ bit of the port register corresponds to the pin. 
\ And then puts the address of its port on stack too. 

\ Use it this way:
\ PORTD 7 portpin: PD.7  ( define portD pin #7)
\ PD.7 high              ( turn portD pin #7 on, i.e. set it high-level)
\ PD.7 low               ( turn portD pin #7 off, i.e. set it low-level)
\ PD.7 <ms> pulse        ( turn portD pin #7 for <ms> high and low)
\ the following words are for "real" IO pins only
\ PD.7 pin_output        ( set DDRD so that portD pin #7 is output)
\ PD.7 pin_input         ( set DDRD so that portD pin #7 is input)
\ PD.7 pin_high?         ( true if pinD pin #7 is high)
\ PD.7 pin_low?          ( true if pinD pin #7 is low)
\ 
\ multi bit operation
\ PORTD F bitmask: PD.F  ( define the lower nibble of port d )
\ PD.F pin@              ( get the lower nibble bits )
\ 5 PD.F pin!            ( put the lower nibble bits, do not change the others )

\ #require builds.frt

: bitmask: ( C: "ccc" portadr bmask -- ) ( R: -- pinmask portadr )
  <builds
     , ,
  does> 
    dup @i swap i-cell+ @i
;

: portpin: ( C: "ccc" portadr n -- ) ( R: -- pinmask portadr )
    1 over 7 and lshift >r \ bit position
    3 rshift +             \ byte address
    r> bitmask:            \ portaddr may have changed
;



\ Turn a port pin on, dont change the others.
: high ( pinmask portadr -- )
    dup  ( -- pinmask portadr portadr )
    c@   ( -- pinmask portadr value )
    rot  ( -- portadr value pinmask )
    or   ( -- portadr new-value)
    swap ( -- new-value portadr)
    c!
;

\ Turn a port pin off, dont change the others.
: low ( pinmask portadr -- )
    dup  ( -- pinmask portadr portadr )
    c@   ( -- pinmask portadr value )
    rot  ( -- portadr value pinmask )
    invert and ( -- portadr new-value)
    swap ( -- new-value port)
    c!
;


\ synonym off low
\ synonym on  high

\ pulse the pin
: pulse ( pinmask portaddr time -- )
    >r
    2dup high 
    r> 0 ?do 1ms loop 
    low 
;

: is_low? ( pinmask portaddr -- f)
    c@ and 0=
;

: is_high? ( pinmask portaddr -- f)
    c@ over and =
;

: wait_low ( pinmask portaddr -- )
    begin 
      2dup is_low?
    until 2drop
;

: wait_high_all ( pinmask portaddr -- )
    begin 
      2dup is_high?
    until 2drop
;
 
\ write the pins masked as output
\ read the current value, mask all but
\ the desired bits and set the new
\ bits. write back the resulting byte
: pin! ( c pinmask portaddr -- )
    dup ( -- c pm pa pa )
    >r
    c@  ( -- c pm c' )
    over invert and ( -- c pm c'' )
    >r  ( -- c pm )
    and 
    r>  ( -- c c'' )
    or r>
    c!
;


\ Only for PORTx bits, 
\ because address of DDRx is one less than address of PORTx.

\ Set DDRx so its corresponding pin is output.
: pin_output ( pinmask portadr -- )
    1- high
;

\ Set DDRx so its corresponding pin is input.
: pin_input  ( pinmask portadr -- )   
    1- low
;

\ PINx is two less of PORTx
: pin_high? ( pinmask portaddr -- f)
    1- 1- c@ and
;

: pin_low? ( pinmask portaddr -- f)
    1- 1- c@ invert and
;

\ read the pins masked as input
: pin@  ( pinmask portaddr -- c )
    1- 1- c@ and
;

\ toggle the pin
: toggle ( pinmask portaddr -- )
  2dup pin_high? if
    low
  else
    high
  then
; 

\ disable the pull up resistor
: pin_pullup_off ( pinmask portaddr -- )
  2dup pin_input low
;


\ enable the pull up resistor
: pin_pullup_on ( pinmask portaddr -- )
  2dup pin_input high
;