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