aboutsummaryrefslogtreecommitdiff
path: root/amforth-6.5/common/lib/hardware/i2c.frt
blob: 8941c5f973ccf2f5d040295124febf3a4a4c97ee (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
\ basic I2C operations, uses 7bit bus addresses
\ uses the TWI module of the Atmega's.
\ #require builds.frt
\ #require bitnames.frt

\ low level driver words
\ #require i2c-twi-master.frt

\ provides public commands

\  i2c.begin         -- starts a I2C bus cycle
\  i2c.end           -- ends a I2C bus cycle
\ the following operation use a complete bus cycle
\  i2c.c!            -- send one byte
\  i2c.c@            -- read one byte
\  i2c.n!            -- send n bytes to device
\  i2c.n@            -- read n bytes from device
\  i2c.m!n@          -- first send m bytes, than read n bytes

\ convert the bus address into a sendable byte
\ the address bits are the upper 7 ones,
\ the LSB is the read/write bit.

: i2c.wr 2* ;
: i2c.rd 2* 1+ ;

\ aquire the bus and select a device
\ start a write transaction
: i2c.begin ( hwid -- )
  dup i2c.current !
  i2c.start i2c.wr i2c.tx
;

\ start a read transaction
: i2c.begin-read ( hwid -- )
  dup i2c.current !
  i2c.start i2c.rd i2c.tx
;

\ release the bus and deselect the device
: i2c.end ( -- )
  i2c.stop
  0 i2c.current !
;

\ tranfser data from/to data stack

\ fetch a byte from the device
: i2c.c@ ( hwid -- c )
   i2c.begin-read
     i2c.rxn
   i2c.end
;

\ store a byte to a device
: i2c.c! ( c hwid -- )
   i2c.begin
     i2c.tx
   i2c.end
;

\ send n bytes to device
: i2c.n! ( xn .. x1 N hwid -- )
  i2c.begin
    0 ?do     \ uses N
      i2c.tx  \ send x1 ... xn
    loop
  i2c.end
;

\ get n bytes from device
: i2c.n@ ( n hwid -- x1 .. xn )
  i2c.begin-read
    1- 0 max 0 ?do i2c.rx loop i2c.rxn
  i2c.end
;

\ complex and flexible transaction word
\ send m bytes x1..xm and fetch n bytes y1..yn afterwards
: i2c.m!n@ ( n xm .. x1 m hwid -- x1 .. xn )
  dup >r i2c.begin
    0 ?do i2c.tx loop \ send m bytes
    i2c.restart       \ repeated start
    r> i2c.rd i2c.tx  \ re-send addr, switch to read mode
    1- 0 max 0 ?do i2c.rx loop i2c.rxn \ read x1 .. xn
  i2c.end
;