aboutsummaryrefslogtreecommitdiff
path: root/amforth-6.5/avr8/lib/bitnames-code.frt
blob: 897bae3bbcd38c5e51ba34502d76759ed98af3e8 (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
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
\ V 1.3,  02.11.2007
\ V 1.3a, 15.07.2009, assembler version, L.Pekny

\ 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 portpin 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 )

hex

\ At compiletime:
\ Store combination of portaddress and bit number in a cell and give it a name.
\ At runtime:
\ Get pinmask and portaddress on stack.
: portpin: create ( C: "ccc" portadr n -- ) ( R: -- pinmask portadr )
    1 swap lshift
    8 lshift or ,               \ packed value
  does> @i                      \ get packed value
    dup 8 rshift swap ff and    \ 
;

: bitmask: create ( C: "ccc" portadr n -- ) ( R: -- pinmask portadr )
    8 lshift or ,               \ packed value
  does> @i                      \ get packed value
    dup 8 rshift swap ff and    \ 
;


\ 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!
;

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

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

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

\ 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 -- )
  over over pin_high? if
    low
  else
    high
  then
; 


\ ----- assembler version -----
\ assembler library: loadtos, savetos, TOSL,TOSH, readflashcell

\ macros definitions
: loadtos, 16 Y+ ld, 17 Y+ ld, ; \ define macro
: savetos, -Y 17 st, -Y 16 st, ; \ tosl=r22, tosh=r23
: TOSL 16 ;
: TOSH 17 ;

  \ read flash cell to tos
: readflashcell,
    assembler
    ZL lsl,                 \ addr in ZH:ZL
    ZH rol,
    TOSL Z+ lpm_,  
    TOSH Z+ lpm_, ;         \ @i to tos

\ ---------------------------------------------
\ macros definitions

  \ convert mask+addr to port+bit for cbi, sbi,
: ma2pbi ( mask addr -- port bit )
    20 - swap log2 ;


  \ set pin high
: high, ( pinmask portadr -- )
    assembler
    R16 over lds,           \ @portadr
    R16 rot ori,            \ or pinmask
    R16 sts, ;              \ c!


  \ set pin low
: low, ( pinmask portadr -- )
    assembler
    R16 over lds,           \ @portadr
    R16 rot invert andi,    \ and not(pinmask)
    R16 sts, ;              \ c!


  \ c@ and
: is_high?, ( pinmask portadr -- f )
    assembler
    R16 swap lds,           \ @portadr    
    R16 swap andi,          \ c@ and m
    savetos,
    TOSL R16 mov,
    TOSH clr, ;


  \ c@ invert and
: is_low?, ( pinmask portadr -- f )
    assembler
    R16 swap lds,           \ @portadr
    R16 com,                \ invert
    R16 swap andi,          \ and m
    savetos,
    TOSL R16 mov,
    TOSH clr, ;


  \ 1- 1- c@ and
: pin@, ( pinmask portadr -- c )
    1- 1- is_high?, ;

\ macros are for high speed words
\ pin,addr,mask is directly in asm instruction
\ example for use macros
\ PORTB 04 portpin: SPI_SS          \ PB.4 - SPI select
\ : setoutSS SPI_SS pin_output ;
\ code setoutSS SPI_SS 1- high, end-code
\ code setoutSS SPI_SS 1- ma2pbi sbi, end-code
\ : +mmc SPI_SS low ;                      \ forth speed
\ code +mmc  SPI_SS low,         end-code  \ asm speed
\ code +mmc  SPI_SS ma2pbi cbi,  end-code  \ asm high speed
\ code SPI_SS_clk
\    SPI_SS low,
\    SPI_SS high,
\ end-code


\ code definitions
\ pin,addr,mask is read from tos

code (portpin:) ( addr -- pinmask portadr )
    ZL TOSL movw,           \ tos->z, addr @i
    readflashcell,          \ TOSH pinmask, TOSL portadr
    R16 TOSL mov,           \ temp0
    TOSL TOSH mov,
    TOSH clr,
    savetos,                \ -- pinmask
    TOSL R16 mov,           \ -- pinmask portadr
end-code

: portpin: create ( C: "ccc" portadr n -- ) ( R: -- pinmask portadr )
    1 swap lshift
    8 lshift or ,                \ packed value
  does> (portpin:)               \ get packed value
  \ @i dup 8 rshift swap ff and  \ replaced by (portpin:)
;


code high ( pinmask portadr -- )
  \ dup c@ rot or swap c!   \ replaced by assembler
    ZL TOSL movw,           \ tos->z
    R16 Z ld,               \ addr c@
    loadtos,                \ delete portadr
    R16 TOSL or,            \ or pinmask
    Z R16 st,               \ c!
    loadtos,                \ delete pinmask
end-code


code low ( pinmask portadr -- )
  \ dup c@ rot invert and swap c! \ replaced by assembler
    ZL TOSL movw,           \ tos->z
    R16 Z ld,               \ addr c@
    loadtos,                \ delete portadr
    TOSL com,               \ not(pinmask)
    R16 TOSL and,           \ and pinmask
    Z R16 st,               \ c!
    loadtos,                \ delete pinmask
end-code


: pin_output ( pinmask portadr -- )
    1- high ;


: pin_input  ( pinmask portadr -- )   
    1- low ;


code pin! ( c pinmask portadr -- )
  \ (c and m) or (@port and not(m))
    ZL TOSL movw,           \ tos->z
    R16 Z ld,               \ addr c@
    loadtos,                \ delete portadr
    R17 TOSL mov,           \ pinmask
    TOSL com,               \ not(pinmask)
    R16 TOSL and,           \ and pinmask
    loadtos,                \ delete pinmask
    R17 TOSL and,           \ m and c
    R16 R17 or,             \ () or ()
    Z R16 st,               \ c!
    loadtos,                \ delete c
end-code


code pin@ ( pinmask portadr -- c )
  \ 1- 1- c@ and
    ZL TOSL movw,           \ tos->z
    ZH:ZL 2 sbiw,           \ 1- 1-
    R16 Z ld,               \ addr c@
    loadtos,                \ delete portadr
    TOSL R16 and,           \ and pinmask
    TOSH clr,
end-code


code is_low? ( pinmask portaddr -- c )
  \ c@ invert and
    ZL TOSL movw,           \ tos->z
    R16 Z ld,               \ addr c@
    R16 com,                \ invert
    loadtos,                \ delete portadr
    TOSL R16 and,           \ and pinmask
    TOSH clr,
end-code


code is_high? ( pinmask portaddr -- c )
  \ c@ and
    ZL TOSL movw,           \ tos->z
    R16 Z ld,               \ addr c@
    loadtos,                \ delete portadr
    TOSL R16 and,           \ and pinmask
    TOSH clr,
end-code


code pin_low? ( pinmask portadr -- c )
  \ 1- 1- c@ invert and
    ZL TOSL movw,           \ tos->z
    ZH:ZL 2 sbiw,           \ 1- 1-
    R16 Z ld,               \ addr c@
    R16 com,                \ invert
    loadtos,                \ delete portadr
    TOSL R16 and,           \ and pinmask
    TOSH clr,
end-code


code pin_high? ( pinmask portadr -- c )
  \ 1- 1- c@ and
    ZL TOSL movw,           \ tos->z
    ZH:ZL 2 sbiw,           \ 1- 1-
    R16 Z ld,               \ addr c@
    loadtos,                \ delete portadr
    TOSL R16 and,           \ and pinmask
    TOSH clr,
end-code


code toggle ( pinmask portaddr -- )
    ZL TOSL movw,           \ tos->z
    R16 Z ld,               \ addr c@
    loadtos,                \ delete portadr
    R16 TOSL eor,           \ xor pinmask
    Z R16 st,               \ c!
    loadtos,                \ delete pinmask
end-code

\ end of file