blob: 17ec818db59a5fd3d075e1ec7993f7e3ef29920a [file] [log] [blame]
Jon Medhurst08185642016-08-25 14:06:32 +01001/*
2 * Copyright (c) 2017 Linaro Ltd.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7/**
8 * @file
9 * @brief Software driven 'bit-banging' library for I2C
10 *
11 * This code implements the I2C single master protocol in software by directly
12 * manipulating the levels of the SCL and SDA lines of an I2C bus. It supports
13 * the Standard-mode and Fast-mode speeds and doesn't support optional
14 * protocol feature like 10-bit addresses or clock stretching.
15 *
16 * Timings and protocol are based Rev. 6 of the I2C specification:
17 * http://www.nxp.com/documents/user_manual/UM10204.pdf
18 */
19
20#include <errno.h>
Jon Medhurst08185642016-08-25 14:06:32 +010021#include <kernel.h>
Anas Nashif3b7dd6e2017-10-01 08:36:49 -040022#include <i2c.h>
23#include "i2c_bitbang.h"
Jon Medhurst08185642016-08-25 14:06:32 +010024
25/*
26 * Indexes into delay table for each part of I2C timing waveform we are
27 * interested in. In practice, for Standard and Fast modes, there are only two
28 * different numerical values (T_LOW and T_HIGH) so we alias the others to
29 * these. (Actually, we're simplifying a little, T_SU_STA could be T_HIGH on
30 * Fast mode)
31 */
32#define T_LOW 0
33#define T_HIGH 1
34#define T_SU_STA T_LOW
35#define T_HD_STA T_HIGH
36#define T_SU_STP T_HIGH
37#define T_BUF T_LOW
38
39#define NS_TO_SYS_CLOCK_HW_CYCLES(ns) \
40 ((u64_t)CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC * (ns) / NSEC_PER_SEC + 1)
41
42static const u32_t delays_fast[] = {
43 [T_LOW] = NS_TO_SYS_CLOCK_HW_CYCLES(1300),
44 [T_HIGH] = NS_TO_SYS_CLOCK_HW_CYCLES(600),
45};
46
47static const u32_t delays_standard[] = {
48 [T_LOW] = NS_TO_SYS_CLOCK_HW_CYCLES(4700),
49 [T_HIGH] = NS_TO_SYS_CLOCK_HW_CYCLES(4000),
50};
51
52int i2c_bitbang_configure(struct i2c_bitbang *context, u32_t dev_config)
53{
Jon Medhurst08185642016-08-25 14:06:32 +010054 /* Check for features we don't support */
Kumar Gala83643a22017-09-13 11:31:00 -050055 if (I2C_ADDR_10_BITS & dev_config) {
Jon Medhurst08185642016-08-25 14:06:32 +010056 return -ENOTSUP;
57 }
58
59 /* Setup speed to use */
Kumar Gala83643a22017-09-13 11:31:00 -050060 switch (I2C_SPEED_GET(dev_config)) {
Jon Medhurst08185642016-08-25 14:06:32 +010061 case I2C_SPEED_STANDARD:
62 context->delays = delays_standard;
63 break;
64 case I2C_SPEED_FAST:
65 context->delays = delays_fast;
66 break;
67 default:
68 return -ENOTSUP;
69 }
70
71 return 0;
72}
73
74static void i2c_set_scl(struct i2c_bitbang *context, int state)
75{
76 context->io->set_scl(context->io_context, state);
77}
78
79static void i2c_set_sda(struct i2c_bitbang *context, int state)
80{
81 context->io->set_sda(context->io_context, state);
82}
83
84static int i2c_get_sda(struct i2c_bitbang *context)
85{
86 return context->io->get_sda(context->io_context);
87}
88
89static void i2c_delay(unsigned int cycles_to_wait)
90{
91 u32_t start = k_cycle_get_32();
92
93 /* Wait until the given number of cycles have passed */
94 while (k_cycle_get_32() - start < cycles_to_wait) {
95 }
96}
97
98static void i2c_start(struct i2c_bitbang *context)
99{
100 if (!i2c_get_sda(context)) {
101 /*
102 * SDA is already low, so we need to do something to make it
103 * high. Try pulsing clock low to get slave to release SDA.
104 */
105 i2c_set_scl(context, 0);
106 i2c_delay(context->delays[T_LOW]);
107 i2c_set_scl(context, 1);
108 i2c_delay(context->delays[T_SU_STA]);
109 }
110 i2c_set_sda(context, 0);
111 i2c_delay(context->delays[T_HD_STA]);
112}
113
114static void i2c_repeated_start(struct i2c_bitbang *context)
115{
116 i2c_delay(context->delays[T_SU_STA]);
117 i2c_start(context);
118}
119
120static void i2c_stop(struct i2c_bitbang *context)
121{
122 if (i2c_get_sda(context)) {
123 /*
124 * SDA is already high, so we need to make it low so that
125 * we can create a rising edge. This means we're effectively
126 * doing a START.
127 */
128 i2c_delay(context->delays[T_SU_STA]);
129 i2c_set_sda(context, 0);
130 i2c_delay(context->delays[T_HD_STA]);
131 }
132 i2c_delay(context->delays[T_SU_STP]);
133 i2c_set_sda(context, 1);
134 i2c_delay(context->delays[T_BUF]); /* In case we start again too soon */
135}
136
137static void i2c_write_bit(struct i2c_bitbang *context, int bit)
138{
139 i2c_set_scl(context, 0);
140 /* SDA hold time is zero, so no need for a delay here */
141 i2c_set_sda(context, bit);
142 i2c_delay(context->delays[T_LOW]);
143 i2c_set_scl(context, 1);
144 i2c_delay(context->delays[T_HIGH]);
145}
146
147static bool i2c_read_bit(struct i2c_bitbang *context)
148{
149 bool bit;
150
151 i2c_set_scl(context, 0);
152 /* SDA hold time is zero, so no need for a delay here */
153 i2c_set_sda(context, 1); /* Stop driving low, so slave has control */
154 i2c_delay(context->delays[T_LOW]);
155 bit = i2c_get_sda(context);
156 i2c_set_scl(context, 1);
157 i2c_delay(context->delays[T_HIGH]);
158 return bit;
159}
160
161static bool i2c_write_byte(struct i2c_bitbang *context, u8_t byte)
162{
163 u8_t mask = 1 << 7;
164
165 do {
166 i2c_write_bit(context, byte & mask);
167 } while (mask >>= 1);
168
169 /* Return inverted ACK bit, i.e. 'true' for ACK, 'false' for NACK */
170 return !i2c_read_bit(context);
171}
172
173static u8_t i2c_read_byte(struct i2c_bitbang *context)
174{
175 unsigned int byte = 1;
176
177 do {
178 byte <<= 1;
179 byte |= i2c_read_bit(context);
180 } while (!(byte & (1 << 8)));
181
182 return byte;
183}
184
185int i2c_bitbang_transfer(struct i2c_bitbang *context,
186 struct i2c_msg *msgs, u8_t num_msgs,
187 u16_t slave_address)
188{
189 u8_t *buf, *buf_end;
190 unsigned int flags;
191 int result = -EIO;
192
193 if (!num_msgs) {
194 return 0;
195 }
196
197 /* We want an initial Start condition */
198 flags = I2C_MSG_RESTART;
199
200 /* Make sure we're in a good state so slave recognises the Start */
201 i2c_set_scl(context, 1);
202 flags |= I2C_MSG_STOP;
203
204 do {
205 /* Stop flag from previous message? */
206 if (flags & I2C_MSG_STOP) {
207 i2c_stop(context);
208 }
209
210 /* Forget old flags except start flag */
211 flags &= I2C_MSG_RESTART;
212
213 /* Start condition? */
214 if (flags & I2C_MSG_RESTART) {
215 i2c_start(context);
216 } else if (msgs->flags & I2C_MSG_RESTART) {
217 i2c_repeated_start(context);
218 }
219
220 /* Get flags for new message */
221 flags |= msgs->flags;
222
223 /* Send address after any Start condition */
224 if (flags & I2C_MSG_RESTART) {
225 unsigned int byte0 = slave_address << 1;
226
227 byte0 |= (flags & I2C_MSG_RW_MASK) == I2C_MSG_READ;
228 if (!i2c_write_byte(context, byte0)) {
229 goto finish; /* No ACK received */
230 }
231 flags &= ~I2C_MSG_RESTART;
232 }
233
234 /* Transfer data */
235 buf = msgs->buf;
236 buf_end = buf + msgs->len;
237 if ((flags & I2C_MSG_RW_MASK) == I2C_MSG_READ) {
238 /* Read */
239 while (buf < buf_end) {
240 *buf++ = i2c_read_byte(context);
241 /* ACK the byte, except for the last one */
242 i2c_write_bit(context, buf == buf_end);
243 }
244 } else {
245 /* Write */
246 while (buf < buf_end) {
247 if (!i2c_write_byte(context, *buf++)) {
248 goto finish; /* No ACK received */
249 }
250 }
251 }
252
253 /* Next message */
254 msgs++;
255 num_msgs--;
256 } while (num_msgs);
257
258 /* Complete without error */
259 result = 0;
260finish:
261 i2c_stop(context);
262
263 return result;
264}
265
266void i2c_bitbang_init(struct i2c_bitbang *context,
267 const struct i2c_bitbang_io *io, void *io_context)
268{
Jon Medhurst08185642016-08-25 14:06:32 +0100269 context->io = io;
270 context->io_context = io_context;
Kumar Gala83643a22017-09-13 11:31:00 -0500271 i2c_bitbang_configure(context, I2C_SPEED_STANDARD << I2C_SPEED_SHIFT);
Jon Medhurst08185642016-08-25 14:06:32 +0100272}