Rev Author Line No. Line
3514 miho 1 /* Name: main.c
2 * Project: i2c-tiny-usb
3 * Author: Till Harbaum
4 * Tabsize: 4
5 * Copyright: (c) 2005 by Till Harbaum <till@harbaum.org>
6 * License: GPL
7 * This Revision: $Id: main.c,v 1.9 2007/06/07 13:53:47 harbaum Exp $
8 *
9 * $Log: main.c,v $
10 * Revision 1.9 2007/06/07 13:53:47 harbaum
11 * Version number fixes
12 *
13 * Revision 1.8 2007/05/19 12:30:11 harbaum
14 * Updated USB stacks
15 *
16 * Revision 1.7 2007/04/22 10:34:05 harbaum
17 * *** empty log message ***
18 *
19 * Revision 1.6 2007/01/05 19:30:58 harbaum
20 * i2c clock bug fix
21 *
22 * Revision 1.5 2007/01/03 18:35:07 harbaum
23 * usbtiny fixes and pcb layouts
24 *
25 * Revision 1.4 2006/12/03 21:28:59 harbaum
26 * *** empty log message ***
27 *
28 * Revision 1.3 2006/11/22 19:12:45 harbaum
29 * Added usbtiny support
30 *
31 * Revision 1.2 2006/11/14 19:15:13 harbaum
32 * *** empty log message ***
33 *
34 */
35  
36 #include <stdio.h>
37 #include <ctype.h>
38 #include <string.h>
39  
40 #include <avr/io.h>
41 #include <avr/interrupt.h>
42 #include <avr/pgmspace.h>
43 #include <avr/wdt.h>
44  
45 #include <util/delay.h>
46  
3516 miho 47 #include "config.h"
48  
49 // Include USB library (AVRUSB or USBTINY)
50 // -------------------
51  
3514 miho 52 #ifndef USBTINY
3516 miho 53 // use avrusb library
54 #include "usbdrv.h"
55 #include "oddebug.h"
3514 miho 56 #else
3516 miho 57 // use usbtiny library
58 #include "usb.h"
59 #include "usbtiny.h"
60 typedef byte_t uchar;
61 #define usbInit() usb_init()
62 #define usbPoll() usb_poll()
3514 miho 63 #endif
64  
65 /* commands from USB, must e.g. match command ids in kernel driver */
66 #define CMD_ECHO 0
67 #define CMD_GET_FUNC 1
68 #define CMD_SET_DELAY 2
69 #define CMD_GET_STATUS 3
70  
71 #define CMD_I2C_IO 4
72 #define CMD_I2C_BEGIN 1 // flag fo I2C_IO
73 #define CMD_I2C_END 2 // flag fo I2C_IO
74  
75 /* linux kernel flags */
76 #define I2C_M_TEN 0x10 /* we have a ten bit chip address */
77 #define I2C_M_RD 0x01
78 #define I2C_M_NOSTART 0x4000
79 #define I2C_M_REV_DIR_ADDR 0x2000
80 #define I2C_M_IGNORE_NAK 0x1000
81 #define I2C_M_NO_RD_ACK 0x0800
82  
83 /* To determine what functionality is present */
84 #define I2C_FUNC_I2C 0x00000001
85 #define I2C_FUNC_10BIT_ADDR 0x00000002
86 #define I2C_FUNC_PROTOCOL_MANGLING 0x00000004 /* I2C_M_{REV_DIR_ADDR,NOSTART,..} */
87 #define I2C_FUNC_SMBUS_HWPEC_CALC 0x00000008 /* SMBus 2.0 */
88 #define I2C_FUNC_SMBUS_READ_WORD_DATA_PEC 0x00000800 /* SMBus 2.0 */
89 #define I2C_FUNC_SMBUS_WRITE_WORD_DATA_PEC 0x00001000 /* SMBus 2.0 */
90 #define I2C_FUNC_SMBUS_PROC_CALL_PEC 0x00002000 /* SMBus 2.0 */
91 #define I2C_FUNC_SMBUS_BLOCK_PROC_CALL_PEC 0x00004000 /* SMBus 2.0 */
92 #define I2C_FUNC_SMBUS_BLOCK_PROC_CALL 0x00008000 /* SMBus 2.0 */
93 #define I2C_FUNC_SMBUS_QUICK 0x00010000
94 #define I2C_FUNC_SMBUS_READ_BYTE 0x00020000
95 #define I2C_FUNC_SMBUS_WRITE_BYTE 0x00040000
96 #define I2C_FUNC_SMBUS_READ_BYTE_DATA 0x00080000
97 #define I2C_FUNC_SMBUS_WRITE_BYTE_DATA 0x00100000
98 #define I2C_FUNC_SMBUS_READ_WORD_DATA 0x00200000
99 #define I2C_FUNC_SMBUS_WRITE_WORD_DATA 0x00400000
100 #define I2C_FUNC_SMBUS_PROC_CALL 0x00800000
101 #define I2C_FUNC_SMBUS_READ_BLOCK_DATA 0x01000000
102 #define I2C_FUNC_SMBUS_WRITE_BLOCK_DATA 0x02000000
103 #define I2C_FUNC_SMBUS_READ_I2C_BLOCK 0x04000000 /* I2C-like block xfer */
104 #define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK 0x08000000 /* w/ 1-byte reg. addr. */
105 #define I2C_FUNC_SMBUS_READ_I2C_BLOCK_2 0x10000000 /* I2C-like block xfer */
106 #define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK_2 0x20000000 /* w/ 2-byte reg. addr. */
107 #define I2C_FUNC_SMBUS_READ_BLOCK_DATA_PEC 0x40000000 /* SMBus 2.0 */
108 #define I2C_FUNC_SMBUS_WRITE_BLOCK_DATA_PEC 0x80000000 /* SMBus 2.0 */
109  
110 #define I2C_FUNC_SMBUS_BYTE I2C_FUNC_SMBUS_READ_BYTE | \
111 I2C_FUNC_SMBUS_WRITE_BYTE
112 #define I2C_FUNC_SMBUS_BYTE_DATA I2C_FUNC_SMBUS_READ_BYTE_DATA | \
113 I2C_FUNC_SMBUS_WRITE_BYTE_DATA
114 #define I2C_FUNC_SMBUS_WORD_DATA I2C_FUNC_SMBUS_READ_WORD_DATA | \
115 I2C_FUNC_SMBUS_WRITE_WORD_DATA
116 #define I2C_FUNC_SMBUS_BLOCK_DATA I2C_FUNC_SMBUS_READ_BLOCK_DATA | \
117 I2C_FUNC_SMBUS_WRITE_BLOCK_DATA
118 #define I2C_FUNC_SMBUS_I2C_BLOCK I2C_FUNC_SMBUS_READ_I2C_BLOCK | \
119 I2C_FUNC_SMBUS_WRITE_I2C_BLOCK
120  
121 #define I2C_FUNC_SMBUS_EMUL I2C_FUNC_SMBUS_QUICK | \
122 I2C_FUNC_SMBUS_BYTE | \
123 I2C_FUNC_SMBUS_BYTE_DATA | \
124 I2C_FUNC_SMBUS_WORD_DATA | \
125 I2C_FUNC_SMBUS_PROC_CALL | \
126 I2C_FUNC_SMBUS_WRITE_BLOCK_DATA | \
127 I2C_FUNC_SMBUS_WRITE_BLOCK_DATA_PEC | \
128 I2C_FUNC_SMBUS_I2C_BLOCK
129  
130 /* the currently support capability is quite limited */
131 const unsigned long func PROGMEM = I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
132  
133 #ifdef DEBUG
134 #define DEBUGF(format, args...) printf_P(PSTR(format), ##args)
135  
136 /* ------------------------------------------------------------------------- */
137 static int uart_putchar(char c, FILE *stream) {
138 if (c == '\n')
139 uart_putchar('\r', stream);
140 loop_until_bit_is_set(UCSRA, UDRE);
141 UDR = c;
142 return 0;
143 }
144  
145 static FILE mystdout = FDEV_SETUP_STREAM(uart_putchar, NULL,
146 _FDEV_SETUP_WRITE);
147 #else
148 #define DEBUGF(format, args...)
149 #endif
150  
151 /* ------------------------------------------------------------------------- */
152 #define DEFAULT_DELAY 10 // default 10us (100khz)
153 static unsigned short clock_delay = DEFAULT_DELAY;
154 static unsigned short clock_delay2 = DEFAULT_DELAY/2;
155  
156 static unsigned short expected;
157 static unsigned char saved_cmd;
158  
159 #if! defined (__AVR_ATtiny45__)
160 #define I2C_PORT PORTC
161 #define I2C_PIN PINC
162 #define I2C_DDR DDRC
163 #define I2C_SDA _BV(4)
164 #define I2C_SCL _BV(5)
165 #else
166 #define I2C_PORT PORTB
167 #define I2C_PIN PINB
168 #define I2C_DDR DDRB
169 #define I2C_SDA _BV(1)
170 #define I2C_SCL _BV(5)
171 #endif
172  
173 static void i2c_io_set_sda(uchar hi) {
174 if(hi) {
175 I2C_DDR &= ~I2C_SDA; // high -> input
176 I2C_PORT |= I2C_SDA; // with pullup
177 } else {
178 I2C_DDR |= I2C_SDA; // low -> output
179 I2C_PORT &= ~I2C_SDA; // drive low
180 }
181 }
182  
183 static uchar i2c_io_get_sda(void) {
184 return(I2C_PIN & I2C_SDA);
185 }
186  
187 static void i2c_io_set_scl(uchar hi) {
188 #ifdef ENABLE_SCL_EXPAND
189 _delay_loop_2(clock_delay2);
190 if(hi) {
191 I2C_DDR &= ~I2C_SCL; // port is input
192 I2C_PORT |= I2C_SCL; // enable pullup
193  
194 // wait while pin is pulled low by client
195 while(!(I2C_PIN & I2C_SCL));
196 } else {
197 I2C_DDR |= I2C_SCL; // port is output
198 I2C_PORT &= ~I2C_SCL; // drive it low
199 }
200 _delay_loop_2(clock_delay);
201 #else
202 _delay_loop_2(clock_delay2);
203 if(hi) I2C_PORT |= I2C_SCL; // port is high
204 else I2C_PORT &= ~I2C_SCL; // port is low
205 _delay_loop_2(clock_delay);
206 #endif
207 }
208  
209 static void i2c_init(void) {
210 /* init the sda/scl pins */
211 I2C_DDR &= ~I2C_SDA; // port is input
212 I2C_PORT |= I2C_SDA; // enable pullup
213 #ifdef ENABLE_SCL_EXPAND
214 I2C_DDR &= ~I2C_SCL; // port is input
215 I2C_PORT |= I2C_SCL; // enable pullup
216 #else
217 I2C_DDR |= I2C_SCL; // port is output
218 #endif
219  
220 /* no bytes to be expected */
221 expected = 0;
222 }
223  
224 /* clock HI, delay, then LO */
225 static void i2c_scl_toggle(void) {
226 i2c_io_set_scl(1);
227 i2c_io_set_scl(0);
228 }
229  
230 /* i2c start condition */
231 static void i2c_start(void) {
232 i2c_io_set_sda(0);
233 i2c_io_set_scl(0);
234 }
235  
236 /* i2c repeated start condition */
237 static void i2c_repstart(void)
238 {
239 /* scl, sda may not be high */
240 i2c_io_set_sda(1);
241 i2c_io_set_scl(1);
242  
243 i2c_io_set_sda(0);
244 i2c_io_set_scl(0);
245 }
246  
247 /* i2c stop condition */
248 void i2c_stop(void) {
249 i2c_io_set_sda(0);
250 i2c_io_set_scl(1);
251 i2c_io_set_sda(1);
252 }
253  
254 uchar i2c_put_u08(uchar b) {
255 char i;
256  
257 for (i=7;i>=0;i--) {
258 if ( b & (1<<i) ) i2c_io_set_sda(1);
259 else i2c_io_set_sda(0);
260  
261 i2c_scl_toggle(); // clock HI, delay, then LO
262 }
263  
264 i2c_io_set_sda(1); // leave SDL HI
265 i2c_io_set_scl(1); // clock back up
266  
267 b = i2c_io_get_sda(); // get the ACK bit
268 i2c_io_set_scl(0); // not really ??
269  
270 return(b == 0); // return ACK value
271 }
272  
273 uchar i2c_get_u08(uchar last) {
274 char i;
275 uchar c,b = 0;
276  
277 i2c_io_set_sda(1); // make sure pullups are activated
278 i2c_io_set_scl(0); // clock LOW
279  
280 for(i=7;i>=0;i--) {
281 i2c_io_set_scl(1); // clock HI
282 c = i2c_io_get_sda();
283 b <<= 1;
284 if(c) b |= 1;
285 i2c_io_set_scl(0); // clock LO
286 }
287  
288 if(last) i2c_io_set_sda(1); // set NAK
289 else i2c_io_set_sda(0); // set ACK
290  
291 i2c_scl_toggle(); // clock pulse
292 i2c_io_set_sda(1); // leave with SDL HI
293  
294 return b; // return received byte
295 }
296  
297 #ifdef DEBUG
298 void i2c_scan(void) {
299 uchar i = 0;
300  
301 for(i=0;i<127;i++) {
302 i2c_start(); // do start transition
303 if(i2c_put_u08(i << 1)) // send DEVICE address
304 DEBUGF("I2C device at address 0x%x\n", i);
305  
306 i2c_stop();
307 }
308 }
309 #endif
310  
311 /* ------------------------------------------------------------------------- */
312  
313 struct i2c_cmd {
314 unsigned char type;
315 unsigned char cmd;
316 unsigned short flags;
317 unsigned short addr;
318 unsigned short len;
319 };
320  
321 #define STATUS_IDLE 0
322 #define STATUS_ADDRESS_ACK 1
323 #define STATUS_ADDRESS_NAK 2
324  
325 static uchar status = STATUS_IDLE;
326  
327 static uchar i2c_do(struct i2c_cmd *cmd) {
328 uchar addr;
329  
330 DEBUGF("i2c %s at 0x%02x, len = %d\n",
331 (cmd->flags&I2C_M_RD)?"rd":"wr", cmd->addr, cmd->len);
332  
333 /* normal 7bit address */
334 addr = ( cmd->addr << 1 );
335 if (cmd->flags & I2C_M_RD )
336 addr |= 1;
337  
338 if(cmd->cmd & CMD_I2C_BEGIN)
339 i2c_start();
340 else
341 i2c_repstart();
342  
343 // send DEVICE address
344 if(!i2c_put_u08(addr)) {
345 DEBUGF("I2C read: address error @ %x\n", addr);
346  
347 status = STATUS_ADDRESS_NAK;
348 expected = 0;
349 i2c_stop();
350 } else {
351 status = STATUS_ADDRESS_ACK;
352 expected = cmd->len;
353 saved_cmd = cmd->cmd;
354  
355 /* check if transfer is already done (or failed) */
356 if((cmd->cmd & CMD_I2C_END) && !expected)
357 i2c_stop();
358 }
359  
360 /* more data to be expected? */
361 #ifndef USBTINY
362 return(cmd->len?0xff:0x00);
363 #else
364 return(((cmd->flags & I2C_M_RD) && cmd->len)?0xff:0x00);
365 #endif
366 }
367  
368 #ifndef USBTINY
369 uchar usbFunctionSetup(uchar data[8]) {
370 static uchar replyBuf[4];
371 usbMsgPtr = replyBuf;
372 #else
373 extern byte_t usb_setup ( byte_t data[8] )
374 {
375 byte_t *replyBuf = data;
376 #endif
377  
378 DEBUGF("Setup %x %x %x %x\n", data[0], data[1], data[2], data[3]);
379  
380 switch(data[1]) {
381  
382 case CMD_ECHO: // echo (for transfer reliability testing)
383 replyBuf[0] = data[2];
384 replyBuf[1] = data[3];
385 return 2;
386 break;
387  
388 case CMD_GET_FUNC:
389 memcpy_P(replyBuf, &func, sizeof(func));
390 return sizeof(func);
391 break;
392  
393 case CMD_SET_DELAY:
394 /* The delay function used delays 4 system ticks per cycle. */
395 /* This gives 1/3us at 12Mhz per cycle. The delay function is */
396 /* called twice per clock edge and thus four times per full cycle. */
397 /* Thus it is called one time per edge with the full delay */
398 /* value and one time with the half one. Resulting in */
399 /* 2 * n * 1/3 + 2 * 1/2 n * 1/3 = n us. */
400 clock_delay = *(unsigned short*)(data+2);
401 if(!clock_delay) clock_delay = 1;
402 clock_delay2 = clock_delay/2;
403 if(!clock_delay2) clock_delay2 = 1;
404  
405 DEBUGF("request for delay %dus\n", clock_delay);
406 break;
407  
408 case CMD_I2C_IO:
409 case CMD_I2C_IO + CMD_I2C_BEGIN:
410 case CMD_I2C_IO + CMD_I2C_END:
411 case CMD_I2C_IO + CMD_I2C_BEGIN + CMD_I2C_END:
412 // these are only allowed as class transfers
413  
414 return i2c_do((struct i2c_cmd*)data);
415 break;
416  
417 case CMD_GET_STATUS:
418 replyBuf[0] = status;
419 return 1;
420 break;
421  
422 default:
423 // must not happen ...
424 break;
425 }
426  
427 return 0; // reply len
428 }
429  
430  
431 /*---------------------------------------------------------------------------*/
432 /* usbFunctionRead */
433 /*---------------------------------------------------------------------------*/
434  
435 #ifndef USBTINY
436 uchar usbFunctionRead( uchar *data, uchar len )
437 #else
438 extern byte_t usb_in ( byte_t* data, byte_t len )
439 #endif
440 {
441 uchar i;
442  
443 DEBUGF("read %d bytes, %d exp\n", len, expected);
444  
445 if(status == STATUS_ADDRESS_ACK) {
446 if(len > expected) {
447 DEBUGF("exceeds!\n");
448 len = expected;
449 }
450  
451 // consume bytes
452 for(i=0;i<len;i++) {
453 expected--;
454 *data = i2c_get_u08(expected == 0);
455 DEBUGF("data = %x\n", *data);
456 data++;
457 }
458  
459 // end transfer on last byte
460 if((saved_cmd & CMD_I2C_END) && !expected)
461 i2c_stop();
462  
463 } else {
464 DEBUGF("not in ack state\n");
465 memset(data, 0, len);
466 }
467 return len;
468 }
469  
470 /*---------------------------------------------------------------------------*/
471 /* usbFunctionWrite */
472 /*---------------------------------------------------------------------------*/
473  
474 #ifndef USBTINY
475 uchar usbFunctionWrite( uchar *data, uchar len )
476 #else
477 extern void usb_out ( byte_t* data, byte_t len )
478 #endif
479 {
480 uchar i, err=0;
481  
482 DEBUGF("write %d bytes, %d exp\n", len, expected);
483  
484 if(status == STATUS_ADDRESS_ACK) {
485 if(len > expected) {
486 DEBUGF("exceeds!\n");
487 len = expected;
488 }
489  
490 // consume bytes
491 for(i=0;i<len;i++) {
492 expected--;
493 DEBUGF("data = %x\n", *data);
494 if(!i2c_put_u08(*data++))
495 err = 1;
496 }
497  
498 // end transfer on last byte
499 if((saved_cmd & CMD_I2C_END) && !expected)
500 i2c_stop();
501  
502 if(err) {
503 DEBUGF("write failed\n");
504 //TODO: set status
505 }
506  
507 } else {
508 DEBUGF("not in ack state\n");
509 memset(data, 0, len);
510 }
511  
512 #ifndef USBTINY
513 return len;
514 #endif
515 }
516  
517  
518 /* ------------------------------------------------------------------------- */
519  
520 int main(void) {
521 wdt_enable(WDTO_1S);
522  
523 #if DEBUG_LEVEL > 0
524 /* let debug routines init the uart if they want to */
525 odDebugInit();
526 #else
527 #ifdef DEBUG
528 /* quick'n dirty uart init */
529 UCSRB |= _BV(TXEN);
530 UBRRL = F_CPU / (19200 * 16L) - 1;
531 #endif
532 #endif
533  
534 #ifdef DEBUG
535 stdout = &mystdout;
536 #endif
537  
538 DEBUGF("i2c-tiny-usb - (c) 2006 by Till Harbaum\n");
539  
540 i2c_init();
541  
542 #ifdef DEBUG
543 i2c_scan();
544 #endif
545  
546 /* clear usb ports */
3516 miho 547 PORT(CONFIG_USB_PORT) &= (uchar)~((1<<CONFIG_USB_DMINUS)|(1<<CONFIG_USB_DPLUS));
3514 miho 548  
549 /* make usb data lines outputs */
3516 miho 550 DDR(CONFIG_USB_PORT) |= ((1<<CONFIG_USB_DMINUS)|(1<<CONFIG_USB_DPLUS));
3514 miho 551  
552 /* USB Reset by device only required on Watchdog Reset */
553 _delay_loop_2(40000); // 10ms
554  
555 /* make usb data lines inputs */
3516 miho 556 DDR(CONFIG_USB_PORT) &= ~((1<<CONFIG_USB_DMINUS)|(1<<CONFIG_USB_DPLUS));
3514 miho 557  
558 usbInit();
559  
560 sei();
561 for(;;) { /* main event loop */
562 wdt_reset();
563 usbPoll();
564 }
565  
566 return 0;
567 }
568  
569 /* ------------------------------------------------------------------------- */