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