1 /**
2 * @file i2c_io
3 * @brief
4 * Details.
5 *
6 * @author Kevin.Zhou
7 * @version 0.0.0.0
8 * @date 2018-10-11
9 * @license
10
11 */
12
13 typedef struct{
14 INT8U slaveaddr;
15 INT16U num1;
16 INT16U num2;
17 INT8U *buf1;
18 INT8U *buf2;
19 INT8U delay;
20 }i2c_message_io_t;
21
22
23
24 INT32S i2c_burst_read_io(volatile tTTLPort *pTTLPort,i2c_message_io_t *i2c_message_io);
25
26 INT32S i2c_burst_write_io(volatile tTTLPort *pTTLPort,i2c_message_io_t *i2c_message_io);
27
28
29
30 static void issue_start_condition(volatile tTTLPort *pTTLPort,INT16U delay_us)
31 {
32 pTTLPort->sda =0xff;
33 pTTLPort->scl =0xff;
34 delay_x1us(delay_us);
35 pTTLPort->sda =0x00;
36 delay_x1us(delay_us);
37 pTTLPort->scl =0x00;
38 delay_x1us(delay_us);
39 }
40
41 static void issue_stop_condition(volatile tTTLPort *pTTLPort,INT16U delay_us)
42 {
43 pTTLPort->sda =0x00;
44 pTTLPort->scl =0xff;
45 delay_x1us(delay_us);
46 pTTLPort->sda =0xff;
47 delay_x1us(delay_us);
48 pTTLPort->scl =0x00;
49 delay_x1us(delay_us);
50 pTTLPort->sda =0x00;
51 }
52
53 static INT32S AckCheck(volatile tTTLPort *pTTLPort,INT16U delay_us)
54 {
55 INT8U ack=0;
56
57 ack = pTTLPort->sda_z;
58 delay_x1us(delay_us);
59 pTTLPort->scl =0xff;
60 delay_x1us(delay_us);
61 ack = pTTLPort->sda_z;
62 pTTLPort->scl =0x00;
63 delay_x1us(delay_us);
64
65 return ack;
66 }
67
68 static INT8U read_Nbit_data(volatile tTTLPort *pTTLPort,INT8U num,INT16U delay_us)
69 {
70 INT8U cnt=num;
71 INT16U recx,ret=0;
72
73 ret = pTTLPort->sda_z;
74
75 delay_x1us(2);
76
77 while(cnt){
78 cnt--;
79 pTTLPort->scl =0xff;
80 delay_x1us(delay_us);
81 recx = pTTLPort->sda_z;
82 delay_x1us(delay_us);
83 pTTLPort->scl =0x00;
84 ret=((ret<<1)|(recx&0x01));
85 delay_x1us(delay_us);
86 }
87
88 return ret;
89 }
90
91 static void send_Nbit_data(volatile tTTLPort *pTTLPort,INT8U num,INT8U data,INT16U delay_us)
92 {
93 INT8U ret;
94 INT8U cnt=num;
95 INT8U ch = data;
96
97 while(cnt--)
98 {
99 pTTLPort->sda = ch&0x80?0xff:0x00;
100 delay_x1us(delay_us);
101 pTTLPort->scl =0xff;
102 delay_x1us(delay_us);
103 pTTLPort->scl =0x00;
104 delay_x1us(delay_us);
105
106 ch = ch<<1;
107 }
108
109 ret = pTTLPort->sda_z;
110 }
111
112 static void slave_ACK(volatile tTTLPort *pTTLPort,INT16U delay_us)
113 {
114 send_Nbit_data(pTTLPort,1,0,delay_us);
115 }
116
117 static void slave_NOACK(volatile tTTLPort *pTTLPort,INT16U delay_us)
118 {
119 send_Nbit_data(pTTLPort,1,0x80,delay_us);
120 }
121
122 static INT32S issue_single_byte(volatile tTTLPort *pTTLPort,INT8U data, INT16U delay_us)
123 {
124 send_Nbit_data(pTTLPort,8,data,delay_us);
125
126 if(0 != AckCheck(pTTLPort,delay_us)) return 1;
127
128 return 0;
129 }
130
131 static INT32S get_single_byte(volatile tTTLPort *pTTLPort,INT8U *data, INT8U state_bit, INT16U delay_us)
132 {
133 INT8U *getdata = data;
134
135 *getdata = read_Nbit_data(pTTLPort,8,delay_us);
136
137 if(0 == (state_bit&0x01)){
138 slave_ACK(pTTLPort,delay_us);
139 }
140 else{
141 slave_NOACK(pTTLPort,delay_us);
142 }
143
144 return 0;
145 }
146
147 static INT32S i2c_read(volatile tTTLPort *pTTLPort,i2c_message_io_t *i2c_message_io)
148 {
149 INT32S i=0;
150 INT8U state_bit=0;
151
152 issue_start_condition(pTTLPort,i2c_message_io->delay);
153
154 if(0 != issue_single_byte(pTTLPort,i2c_message_io->slaveaddr,i2c_message_io->delay)) // address + Write
155 {
156 sys_seterr("send Slave I2C address+W fail");
157 return -1;
158 }
159
160 for(i=0; i<i2c_message_io->num1; i++)
161 {
162 if(0 != issue_single_byte(pTTLPort,i2c_message_io->buf1[i],i2c_message_io->delay))
163 {
164 sys_seterr("write byte_%d err", i);
165 return -1;
166 }
167 }
168
169 issue_start_condition(pTTLPort,i2c_message_io->delay);
170
171 if(0 != issue_single_byte(pTTLPort,i2c_message_io->slaveaddr|0x01,i2c_message_io->delay)){ // address + Read
172 sys_seterr("send Slave I2C address+R fail");
173 return -1;
174 }
175
176 for(i=0; i<i2c_message_io->num2; i++)
177 {
178 state_bit = (i==(i2c_message_io->num2-1))?1:0;
179
180 if(0 != get_single_byte(pTTLPort,i2c_message_io->buf2+i,state_bit,i2c_message_io->delay)){
181 sys_seterr("read byte_%d err", i);
182 return -1;
183 }
184 }
185
186 issue_stop_condition(pTTLPort,i2c_message_io->delay);
187
188 return 0;
189 }
190
191 static INT32S i2c_write(volatile tTTLPort *pTTLPort,i2c_message_io_t *i2c_message_io)
192 {
193 INT32S i=0;
194
195 issue_start_condition(pTTLPort,i2c_message_io->delay);
196
197 if(0 != issue_single_byte(pTTLPort,i2c_message_io->slaveaddr,i2c_message_io->delay)) // address + Write
198 {
199 sys_seterr("send Slave I2C address+W fail");
200 return -1;
201 }
202
203 for(i=0; i<i2c_message_io->num1; i++)
204 {
205 if(0 != issue_single_byte(pTTLPort,i2c_message_io->buf1[i],i2c_message_io->delay))
206 {
207 sys_seterr("write1 byte_%d err", i);
208 return -1;
209 }
210 }
211
212 for(i=0; i<i2c_message_io->num2; i++)
213 {
214 if(0 != issue_single_byte(pTTLPort,i2c_message_io->buf2[i],i2c_message_io->delay))
215 {
216 sys_seterr("write2 byte_%d err", i);
217 return -1;
218 }
219 }
220
221 issue_stop_condition(pTTLPort,i2c_message_io->delay);
222
223 return 0;
224 }
225
226 INT32S i2c_burst_read_io(volatile tTTLPort *pTTLPort,i2c_message_io_t *i2c_message_io)
227 {
228 return i2c_read(pTTLPort,i2c_message_io);
229 }
230
231 INT32S i2c_burst_write_io(volatile tTTLPort *pTTLPort,i2c_message_io_t *i2c_message_io)
232 {
233 return i2c_write(pTTLPort,i2c_message_io);
234 }