1/*
2 * Copyright 2007, Axel D��rfler, axeld@pinc-software.de. All Rights Reserved.
3 * Copyright 2003, Thomas Kurschel. All Rights Reserved.
4 * Distributed under the terms of the MIT License.
5 */
6
7/*!
8	I2C protocol
9*/
10
11#include "i2c.h"
12
13#include <KernelExport.h>
14#include <OS.h>
15#include <string.h>
16
17
18//#define TRACE_I2C
19#ifdef TRACE_I2C
20#ifdef __cplusplus
21extern "C"
22#endif
23void _sPrintf(const char *format, ...);
24#	define TRACE(x...) _sPrintf("I2C: " x)
25#else
26#	define TRACE(x...) ;
27#endif
28
29
30/*!
31	I2c timings, rounded up (Philips 1995 i2c bus specification, p20)
32*/
33
34//! Timing for standard mode i2c (100kHz max)
35const static i2c_timing kTiming100k = {
36	.buf = 5,
37	.hd_sta = 4,
38	.low = 5,
39	.high = 4,
40	.su_sta = 5,
41	.hd_dat = 1,
42	.su_dat = 2,
43	.r = 2,
44	.f = 2,
45	.su_sto = 4,
46
47	// these are unspecified, use half a clock cycle as a safe guess
48	.start_timeout = 5,
49	.byte_timeout = 5,
50	.bit_timeout = 5,
51	.ack_start_timeout = 5,
52	.ack_timeout = 5
53};
54
55//! Timing for fast mode i2c (400kHz max)
56const static i2c_timing kTiming400k = {
57	.buf = 2,
58	.hd_sta = 1,
59	.low = 2,
60	.high = 1,
61	.su_sta = 1,
62	.hd_dat = 0,
63	.su_dat = 1,
64	.r = 1,
65	.f = 1,
66	.su_sto = 1,
67
68	// these are unspecified, use half a clock cycle as a safe guess
69	.start_timeout = 2,
70	.byte_timeout = 2,
71	.bit_timeout = 2,
72	.ack_start_timeout = 2,
73	.ack_timeout = 2
74};
75
76
77/*!
78	There's no spin in user space, but we need it to wait a couple
79	of microseconds only
80	(in this case, snooze has much too much overhead)
81*/
82void
83spin(bigtime_t delay)
84{
85	bigtime_t startTime = system_time();
86
87	while (system_time() - startTime < delay)
88		;
89}
90
91
92//! Wait until slave releases clock signal ("clock stretching")
93static status_t
94wait_for_clk(const i2c_bus *bus, bigtime_t timeout)
95{
96	bigtime_t startTime;
97
98	// wait for clock signal to raise
99	spin(bus->timing.r);
100
101	startTime = system_time();
102
103	while (true) {
104		int clk, data;
105
106		bus->get_signals(bus->cookie, &clk, &data);
107		if (clk != 0)
108			return B_OK;
109
110		if (system_time() - startTime > timeout) {
111			TRACE("%s: Timeout waiting on clock (r)\n", __func__);
112			return B_TIMEOUT;
113		}
114
115		spin(bus->timing.r);
116	}
117}
118
119
120//!	Send start or repeated start condition
121static status_t
122send_start_condition(const i2c_bus *bus)
123{
124	status_t status;
125
126	bus->set_signals(bus->cookie, 1, 1);
127
128	status = wait_for_clk(bus, bus->timing.start_timeout);
129	if (status != B_OK) {
130		TRACE("%s: Timeout sending start condition\n", __func__);
131		return status;
132	}
133
134	spin(bus->timing.su_sta);
135	bus->set_signals(bus->cookie, 1, 0);
136	spin(bus->timing.hd_sta);
137	bus->set_signals(bus->cookie, 0, 0);
138	spin(bus->timing.f);
139
140	return B_OK;
141}
142
143
144//!	Send stop condition
145static status_t
146send_stop_condition(const i2c_bus *bus)
147{
148	status_t status;
149
150	bus->set_signals(bus->cookie, 0, 0);
151	spin(bus->timing.r);
152	bus->set_signals(bus->cookie, 1, 0);
153
154	// a slave may wait for us, so let elapse the acknowledge timeout
155	// to make the slave release bus control
156	status = wait_for_clk(bus, bus->timing.ack_timeout);
157	if (status != B_OK) {
158		TRACE("%s: Timeout sending stop condition\n", __func__);
159		return status;
160	}
161
162	spin(bus->timing.su_sto);
163	bus->set_signals(bus->cookie, 1, 1);
164	spin(bus->timing.buf);
165
166	return B_OK;
167}
168
169
170//!	Send one bit
171static status_t
172send_bit(const i2c_bus *bus, uint8 bit, int timeout)
173{
174	status_t status;
175
176	//TRACE("send_bit(bit = %d)\n", bit & 1);
177
178	bus->set_signals(bus->cookie, 0, bit & 1);
179	spin(bus->timing.su_dat);
180	bus->set_signals(bus->cookie, 1, bit & 1);
181
182	status = wait_for_clk(bus, timeout);
183	if (status != B_OK) {
184		TRACE("%s: Timeout when sending next bit\n", __func__);
185		return status;
186	}
187
188	spin(bus->timing.high);
189	bus->set_signals(bus->cookie, 0, bit & 1);
190	spin(bus->timing.f + bus->timing.low);
191
192	return B_OK;
193}
194
195
196//!	Send acknowledge and wait for reply
197static status_t
198send_acknowledge(const i2c_bus *bus)
199{
200	status_t status;
201	bigtime_t startTime;
202
203	// release data so slave can modify it
204	bus->set_signals(bus->cookie, 0, 1);
205	spin(bus->timing.su_dat);
206	bus->set_signals(bus->cookie, 1, 1);
207
208	status = wait_for_clk(bus, bus->timing.ack_start_timeout);
209	if (status != B_OK) {
210		TRACE("%s: Timeout when sending acknowledge\n", __func__);
211		return status;
212	}
213
214	// data and clock is high, now wait for slave to pull data low
215	// (according to spec, this can happen any time once clock is high)
216	startTime = system_time();
217
218	while (true) {
219		int clk, data;
220
221		bus->get_signals(bus->cookie, &clk, &data);
222
223		if (data == 0)
224			break;
225
226		if (system_time() - startTime > bus->timing.ack_timeout) {
227			TRACE("%s: slave didn't acknowledge byte within ack_timeout: %ld\n",
228				__func__, bus->timing.ack_timeout);
229			return B_TIMEOUT;
230		}
231
232		spin(bus->timing.r);
233	}
234
235	TRACE("send_acknowledge(): Success!\n");
236
237	// make sure we've waited at least t_high
238	spin(bus->timing.high);
239
240	bus->set_signals(bus->cookie, 0, 1);
241	spin(bus->timing.f + bus->timing.low);
242
243	return B_OK;
244}
245
246
247//!	Send byte and wait for acknowledge if <ackowledge> is true
248static status_t
249send_byte(const i2c_bus *bus, uint8 byte, bool acknowledge)
250{
251	int i;
252
253	//TRACE("%s: (byte = %x)\n", __func__, byte);
254
255	for (i = 7; i >= 0; --i) {
256		status_t status = send_bit(bus, byte >> i,
257			i == 7 ? bus->timing.byte_timeout : bus->timing.bit_timeout);
258		if (status != B_OK)
259			return status;
260	}
261
262	if (acknowledge)
263		return send_acknowledge(bus);
264
265	return B_OK;
266}
267
268
269//!	Send slave address, obeying 10-bit addresses and general call addresses
270static status_t
271send_slave_address(const i2c_bus *bus, uint8 slaveAddress, bool isWrite)
272{
273	status_t status;
274
275	TRACE("%s: 0x%X\n", __func__, slaveAddress);
276	status = send_byte(bus, (slaveAddress & 0xfe) | (isWrite ? 0 : 1), true);
277	if (status != B_OK)
278		return status;
279
280	// there are the following special cases if the first byte looks like:
281	// - 0000 0000 - general call address (second byte with address follows)
282	// - 0000 0001 - start byte
283	// - 0000 001x - CBus address
284	// - 0000 010x - address reserved for different bus format
285	// - 0000 011x |
286	// - 0000 1xxx |-> reserved
287	// - 1111 1xxx |
288	// - 1111 0xxx - 10 bit address  (second byte contains remaining 8 bits)
289
290	// the lsb is 0 for write and 1 for read (except for general call address)
291	if ((slaveAddress & 0xff) != 0 && (slaveAddress & 0xf8) != 0xf0)
292		return B_OK;
293
294	return send_byte(bus, slaveAddress >> 8, true);
295		// send second byte if required
296}
297
298
299//!	Receive one bit
300static status_t
301receive_bit(const i2c_bus *bus, bool *bit, int timeout)
302{
303	status_t status;
304	int clk, data;
305
306	bus->set_signals(bus->cookie, 1, 1);
307		// release clock
308
309	// wait for slave to raise clock
310	status = wait_for_clk(bus, timeout);
311	if (status != B_OK) {
312		TRACE("%s: Timeout waiting for bit sent by slave\n", __func__);
313		return status;
314	}
315
316	bus->get_signals(bus->cookie, &clk, &data);
317		// sample data
318
319	spin(bus->timing.high);
320		// leave clock high for minimal time
321
322	bus->set_signals(bus->cookie, 0, 1);
323		// pull clock low so slave waits for us before next bit
324
325	spin(bus->timing.f + bus->timing.low);
326		// let it settle and leave it low for minimal time
327		// to make sure slave has finished bit transmission too
328
329	*bit = data;
330	return B_OK;
331}
332
333
334/*!
335	Send positive acknowledge afterwards if <acknowledge> is true,
336	else send negative one
337*/
338static status_t
339receive_byte(const i2c_bus *bus, uint8 *resultByte, bool acknowledge)
340{
341	uint8 byte = 0;
342	int i;
343
344	// pull clock low to let slave wait for us
345	bus->set_signals(bus->cookie, 0, 1);
346
347	for (i = 7; i >= 0; i--) {
348		bool bit;
349
350		status_t status = receive_bit(bus, &bit,
351			i == 7 ? bus->timing.byte_timeout : bus->timing.bit_timeout);
352		if (status != B_OK)
353			return status;
354
355		byte = (byte << 1) | bit;
356	}
357
358	//SHOW_FLOW(3, "%x ", byte);
359
360	*resultByte = byte;
361
362	return send_bit(bus, acknowledge ? 0 : 1, bus->timing.bit_timeout);
363}
364
365
366//!	Send multiple bytes
367static status_t
368send_bytes(const i2c_bus *bus, const uint8 *writeBuffer, ssize_t writeLength)
369{
370	TRACE("%s: (length = %ld)\n", __func__, writeLength);
371
372	for (; writeLength > 0; --writeLength, ++writeBuffer) {
373		status_t status = send_byte(bus, *writeBuffer, true);
374		if (status != B_OK)
375			return status;
376	}
377
378	return B_OK;
379}
380
381
382//!	Receive multiple bytes
383static status_t
384receive_bytes(const i2c_bus *bus, uint8 *readBuffer, ssize_t readLength)
385{
386	TRACE("%s: (length = %ld)\n", __func__, readLength);
387
388	for (; readLength > 0; --readLength, ++readBuffer) {
389		status_t status = receive_byte(bus, readBuffer, readLength > 1);
390		if (status != B_OK)
391			return status;
392	}
393
394	return B_OK;
395}
396
397
398//	#pragma mark - exported functions
399
400
401//!	Combined i2c send+receive format
402status_t
403i2c_send_receive_callback(const i2c_bus *bus, uint32 slaveAddress, const uint8 *writeBuffer,
404	size_t writeLength, uint8 *readBuffer, size_t readLength)
405{
406	status_t status;
407
408	// the address is 7-bit
409	slaveAddress <<= 1;
410	if (slaveAddress > 0xff)
411		return B_BAD_VALUE;
412
413	status = send_start_condition(bus);
414	if (status != B_OK)
415		return status;
416
417	status = send_slave_address(bus, slaveAddress, true);
418	if (status != B_OK)
419		goto err;
420
421	status = send_bytes(bus, writeBuffer, writeLength);
422	if (status != B_OK)
423		goto err;
424
425	status = send_start_condition(bus);
426	if (status != B_OK)
427		return status;
428
429	status = send_slave_address(bus, slaveAddress, false);
430	if (status != B_OK)
431		goto err;
432
433	status = receive_bytes(bus, readBuffer, readLength);
434	if (status != B_OK)
435		goto err;
436
437	return send_stop_condition(bus);
438
439err:
440	TRACE("%s: Cancelling transmission\n", __func__);
441	send_stop_condition(bus);
442	return status;
443}
444
445
446void
447i2c_get100k_timing(i2c_timing *timing)
448{
449	// AKA standard i2c mode
450	memcpy(timing, &kTiming100k, sizeof(i2c_timing));
451}
452
453
454void
455i2c_get400k_timing(i2c_timing *timing)
456{
457	// AKA fast i2c mode
458	memcpy(timing, &kTiming400k, sizeof(i2c_timing));
459}
460