This source file includes following definitions.
- i2c_bitbang_send_start
- i2c_bitbang_send_stop
- i2c_bitbang_initiate_xfer
- i2c_bitbang_read_byte
- i2c_bitbang_write_byte
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 #include <sys/param.h>
44
45 #include <dev/i2c/i2cvar.h>
46 #include <dev/i2c/i2c_bitbang.h>
47
48 #define BB_SET(x) ops->ibo_set_bits(v, (x))
49 #define BB_DIR(x) ops->ibo_set_dir(v, (x))
50 #define BB_READ ops->ibo_read_bits(v)
51
52 #define SDA ops->ibo_bits[I2C_BIT_SDA]
53 #define SCL ops->ibo_bits[I2C_BIT_SCL]
54 #define OUTPUT ops->ibo_bits[I2C_BIT_OUTPUT]
55 #define INPUT ops->ibo_bits[I2C_BIT_INPUT]
56
57
58 int
59 i2c_bitbang_send_start(void *v, int flags, i2c_bitbang_ops_t ops)
60 {
61
62 BB_DIR(OUTPUT);
63
64 BB_SET(SDA | SCL);
65 delay(5);
66 BB_SET( SCL);
67 delay(4);
68 BB_SET( 0);
69 delay(5);
70
71 return (0);
72 }
73
74
75 int
76 i2c_bitbang_send_stop(void *v, int flags, i2c_bitbang_ops_t ops)
77 {
78
79 BB_DIR(OUTPUT);
80
81 BB_SET( SCL);
82 delay(4);
83 BB_SET(SDA | SCL);
84
85 return (0);
86 }
87
88 int
89 i2c_bitbang_initiate_xfer(void *v, i2c_addr_t addr, int flags,
90 i2c_bitbang_ops_t ops)
91 {
92 int i2caddr;
93
94
95 if ((addr & 0x78) == 0x78)
96 return (EINVAL);
97
98 i2caddr = (addr << 1) | ((flags & I2C_F_READ) ? 1 : 0);
99
100 (void) i2c_bitbang_send_start(v, flags, ops);
101 return (i2c_bitbang_write_byte(v, i2caddr, flags & ~I2C_F_STOP, ops));
102 }
103
104 int
105 i2c_bitbang_read_byte(void *v, uint8_t *valp, int flags,
106 i2c_bitbang_ops_t ops)
107 {
108 int i;
109 uint8_t val = 0;
110 uint32_t bit;
111
112 BB_DIR(INPUT);
113 BB_SET(SDA );
114
115 for (i = 0; i < 8; i++) {
116 val <<= 1;
117 BB_SET(SDA | SCL);
118 delay(4);
119 if (BB_READ & SDA)
120 val |= 1;
121 BB_SET(SDA );
122 delay(5);
123 }
124
125 bit = (flags & I2C_F_LAST) ? SDA : 0;
126 BB_DIR(OUTPUT);
127 BB_SET(bit );
128 delay(1);
129 BB_SET(bit | SCL);
130 delay(4);
131 BB_SET(bit );
132 delay(5);
133
134 BB_DIR(INPUT);
135 BB_SET(SDA );
136 delay(5);
137
138 if ((flags & (I2C_F_STOP | I2C_F_LAST)) == (I2C_F_STOP | I2C_F_LAST))
139 (void) i2c_bitbang_send_stop(v, flags, ops);
140
141 *valp = val;
142 return (0);
143 }
144
145 int
146 i2c_bitbang_write_byte(void *v, uint8_t val, int flags,
147 i2c_bitbang_ops_t ops)
148 {
149 uint32_t bit;
150 uint8_t mask;
151 int error;
152
153 BB_DIR(OUTPUT);
154
155 for (mask = 0x80; mask != 0; mask >>= 1) {
156 bit = (val & mask) ? SDA : 0;
157 BB_SET(bit );
158 delay(1);
159 BB_SET(bit | SCL);
160 delay(4);
161 BB_SET(bit );
162 delay(5);
163 }
164
165 BB_DIR(INPUT);
166
167 BB_SET(SDA );
168 delay(5);
169 BB_SET(SDA | SCL);
170 delay(4);
171 error = (BB_READ & SDA) ? EIO : 0;
172 BB_SET(SDA );
173 delay(5);
174
175 if (flags & I2C_F_STOP)
176 (void) i2c_bitbang_send_stop(v, flags, ops);
177
178 return (error);
179 }