Rev Author Line No. Line
3325 kaklik 1 #include "main.h"
2  
3 #define USB_CON_SENSE_PIN PIN_D4
4  
5 #include <pic18_usb.h>
6 #include "usbconfig.h"
7 #include <usb.h>
8  
9 #include <usb.c>
10  
11  
12 /* commands from USB, must e.g. match command ids in kernel driver */
13 #define CMD_ECHO 0
14 #define CMD_GET_FUNC 1
15 #define CMD_SET_DELAY 2
16 #define CMD_GET_STATUS 3
17  
18 #define CMD_I2C_IO 4
19 #define CMD_I2C_BEGIN 1 // flag fo I2C_IO
20 #define CMD_I2C_END 2 // flag fo I2C_IO
21  
22 /* linux kernel flags */
23 #define I2C_M_TEN 0x10 /* we have a ten bit chip address */
24 #define I2C_M_RD 0x01
25 #define I2C_M_NOSTART 0x4000
26 #define I2C_M_REV_DIR_ADDR 0x2000
27 #define I2C_M_IGNORE_NAK 0x1000
28 #define I2C_M_NO_RD_ACK 0x0800
29  
30 /* To determine what functionality is present */
31 #define I2C_FUNC_I2C 0x00000001
32 #define I2C_FUNC_10BIT_ADDR 0x00000002
33 #define I2C_FUNC_PROTOCOL_MANGLING 0x00000004 /* I2C_M_{REV_DIR_ADDR,NOSTART,..} */
34 #define I2C_FUNC_SMBUS_HWPEC_CALC 0x00000008 /* SMBus 2.0 */
35 #define I2C_FUNC_SMBUS_READ_WORD_DATA_PEC 0x00000800 /* SMBus 2.0 */
36 #define I2C_FUNC_SMBUS_WRITE_WORD_DATA_PEC 0x00001000 /* SMBus 2.0 */
37 #define I2C_FUNC_SMBUS_PROC_CALL_PEC 0x00002000 /* SMBus 2.0 */
38 #define I2C_FUNC_SMBUS_BLOCK_PROC_CALL_PEC 0x00004000 /* SMBus 2.0 */
39 #define I2C_FUNC_SMBUS_BLOCK_PROC_CALL 0x00008000 /* SMBus 2.0 */
40 #define I2C_FUNC_SMBUS_QUICK 0x00010000
41 #define I2C_FUNC_SMBUS_READ_BYTE 0x00020000
42 #define I2C_FUNC_SMBUS_WRITE_BYTE 0x00040000
43 #define I2C_FUNC_SMBUS_READ_BYTE_DATA 0x00080000
44 #define I2C_FUNC_SMBUS_WRITE_BYTE_DATA 0x00100000
45 #define I2C_FUNC_SMBUS_READ_WORD_DATA 0x00200000
46 #define I2C_FUNC_SMBUS_WRITE_WORD_DATA 0x00400000
47 #define I2C_FUNC_SMBUS_PROC_CALL 0x00800000
48 #define I2C_FUNC_SMBUS_READ_BLOCK_DATA 0x01000000
49 #define I2C_FUNC_SMBUS_WRITE_BLOCK_DATA 0x02000000
50 #define I2C_FUNC_SMBUS_READ_I2C_BLOCK 0x04000000 /* I2C-like block xfer */
51 #define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK 0x08000000 /* w/ 1-byte reg. addr. */
52 #define I2C_FUNC_SMBUS_READ_I2C_BLOCK_2 0x10000000 /* I2C-like block xfer */
53 #define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK_2 0x20000000 /* w/ 2-byte reg. addr. */
54 #define I2C_FUNC_SMBUS_READ_BLOCK_DATA_PEC 0x40000000 /* SMBus 2.0 */
55 #define I2C_FUNC_SMBUS_WRITE_BLOCK_DATA_PEC 0x80000000 /* SMBus 2.0 */
56  
57 #define I2C_FUNC_SMBUS_BYTE I2C_FUNC_SMBUS_READ_BYTE | \
58 I2C_FUNC_SMBUS_WRITE_BYTE
59 #define I2C_FUNC_SMBUS_BYTE_DATA I2C_FUNC_SMBUS_READ_BYTE_DATA | \
60 I2C_FUNC_SMBUS_WRITE_BYTE_DATA
61 #define I2C_FUNC_SMBUS_WORD_DATA I2C_FUNC_SMBUS_READ_WORD_DATA | \
62 I2C_FUNC_SMBUS_WRITE_WORD_DATA
63 #define I2C_FUNC_SMBUS_BLOCK_DATA I2C_FUNC_SMBUS_READ_BLOCK_DATA | \
64 I2C_FUNC_SMBUS_WRITE_BLOCK_DATA
65 #define I2C_FUNC_SMBUS_I2C_BLOCK I2C_FUNC_SMBUS_READ_I2C_BLOCK | \
66 I2C_FUNC_SMBUS_WRITE_I2C_BLOCK
67  
68 #define I2C_FUNC_SMBUS_EMUL I2C_FUNC_SMBUS_QUICK | \
69 I2C_FUNC_SMBUS_BYTE | \
70 I2C_FUNC_SMBUS_BYTE_DATA | \
71 I2C_FUNC_SMBUS_WORD_DATA | \
72 I2C_FUNC_SMBUS_PROC_CALL | \
73 I2C_FUNC_SMBUS_WRITE_BLOCK_DATA | \
74 I2C_FUNC_SMBUS_WRITE_BLOCK_DATA_PEC | \
75 I2C_FUNC_SMBUS_I2C_BLOCK
76  
77 /* ------------------------------------------------------------------------- */
78 #define DEFAULT_DELAY 10 // default 10us (100khz)
79 static unsigned clock_delay = DEFAULT_DELAY;
80 static unsigned clock_delay2 = DEFAULT_DELAY/2;
81  
82 static unsigned short expected;
83 static unsigned char saved_cmd;
84  
85 unsigned int8 control_data[8];
86  
87 struct i2c_cmd {
88 unsigned char type;
89 unsigned char cmd;
90 unsigned short flags;
91 unsigned short addr;
92 unsigned short len;
93 };
94  
95 #define STATUS_IDLE 0
96 #define STATUS_ADDRESS_ACK 1
97 #define STATUS_ADDRESS_NAK 2
98  
99 unsigned int8 status = STATUS_IDLE;
100  
101 void main()
102 {
103  
104 unsigned int8 replyBuf[4];
105  
106 setup_adc_ports(NO_ANALOGS|VSS_VDD);
107 setup_adc(ADC_CLOCK_DIV_2);
108 setup_psp(PSP_DISABLED);
109 setup_wdt(WDT_OFF);
110 setup_timer_0(RTCC_INTERNAL);
111 setup_timer_1(T1_DISABLED);
112 setup_timer_2(T2_DISABLED,0,1);
113 setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
114 setup_ccp1(CCP_OFF);
115 setup_comparator(NC_NC_NC_NC);
116 setup_vref(FALSE);
117  
118 usb_init();
119  
120  
121  
122 while (TRUE) {
123 if (usb_enumerated())
124 {
125 usb_gets(0,control_data,8,100);
126  
127 switch(control_data[1])
128 {
129 case CMD_ECHO: // echo (for transfer reliability testing)
130 replyBuf[0] = control_data[2];
131 replyBuf[1] = control_data[3];
132 usb_puts(0,replyBuf,2,50);
133 break;
134  
135 case CMD_GET_FUNC:
136 usb_puts(0,(I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL),32,50);
137 break;
138  
139 case CMD_SET_DELAY:
140 /* The delay function used delays 4 system ticks per cycle. */
141 /* This gives 1/3us at 12Mhz per cycle. The delay function is */
142 /* called twice per clock edge and thus four times per full cycle. */
143 /* Thus it is called one time per edge with the full delay */
144 /* value and one time with the half one. Resulting in */
145 /* 2 * n * 1/3 + 2 * 1/2 n * 1/3 = n us. */
146 clock_delay = *(unsigned short*)(control_data+2);
147 if(!clock_delay) clock_delay = 1;
148 clock_delay2 = clock_delay/2;
149 if(!clock_delay2) clock_delay2 = 1;
150 break;
151  
152 case CMD_I2C_IO:
153 case CMD_I2C_IO + CMD_I2C_BEGIN:
154 case CMD_I2C_IO + CMD_I2C_END:
155 case CMD_I2C_IO + CMD_I2C_BEGIN + CMD_I2C_END:
156 // these are only allowed as class transfers
157  
158 // return i2c_do((struct i2c_cmd*)data);
159 break;
160  
161 case CMD_GET_STATUS:
162 replyBuf[0] = status;
163 usb_puts(0,replyBuf,1,50);
164 break;
165  
166 default:
167 // must not happen ...
168 break;
169 }
170  
171 delay_ms(10);
172 }
173 }
174 }