Subversion Repositories Code-Repo

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
155 Kevin 1
#include <xc.h>
2
#include <stdio.h>
3
#include <string.h>
4
#include "defines.h"
158 Kevin 5
#include "base_I2C.h"
6
#include "base_UART.h"
155 Kevin 7
 
8
static I2C_DATA *i2c_data_p;
9
 
158 Kevin 10
// Set up the data structures for the base_I2C.code
155 Kevin 11
// Should be called once before any i2c routines are called
12
void I2C_Init(I2C_DATA *data) {
13
    i2c_data_p = data;
14
 
15
    i2c_data_p->buffer_in_len = 0;
16
    i2c_data_p->buffer_in_len_tmp = 0;
17
    i2c_data_p->buffer_in_read_ind = 0;
18
    i2c_data_p->buffer_in_write_ind = 0;
19
 
20
    i2c_data_p->buffer_out_ind = 0;
21
    i2c_data_p->buffer_out_len = 0;
22
 
23
    i2c_data_p->operating_mode = 0;
24
    i2c_data_p->operating_state = I2C_IDLE;
25
    i2c_data_p->return_status = 0;
26
 
27
    i2c_data_p->slave_in_last_byte = 0;
28
    i2c_data_p->slave_sending_data = 0;
29
 
30
    i2c_data_p->master_dest_addr = 0;
31
    i2c_data_p->master_status = I2C_MASTER_IDLE;
32
 
33
    // Enable I2C interrupt
34
    PIE1bits.SSPIE = 1;
35
}
36
 
37
// Setup the PIC to operate as a master.
38
void I2C_Configure_Master(char speed) {
39
    i2c_data_p->operating_mode = I2C_MODE_MASTER;
40
 
41
    I2C_CLK_TRIS = 1;
42
    I2C_DAT_TRIS = 1;
43
 
44
    SSPSTAT = 0x0;
45
    SSPCON1 = 0x0;
46
    SSPCON2 = 0x0;
47
    SSPCON1bits.SSPM = 0x8; // I2C Master Mode
48
    if (speed) {
49
        SSPADD = 0x74;          // Operate at 100KHz (48MHz)
50
    } else {
51
        SSPADD = 0x1A;          // Operate at 400KHz (48MHz)
52
    }
53
    SSPSTATbits.SMP = 1;    // Disable Slew Rate Control
54
    SSPCON1bits.SSPEN = 1;  // Enable MSSP Module
55
}
56
 
57
// Sends length number of bytes in msg to specified address (no R/W bit)
58
void I2C_Master_Send(char address, char length, char *msg) {
59
    char i;
60
    if (length == 0)
61
        return;
62
 
63
    // Copy message to send into buffer and save length/address
64
    for (i = 0; i < length; i++) {
65
        i2c_data_p->buffer_in[i] = msg[i];
66
    }
67
    i2c_data_p->buffer_in_len = length;
68
    i2c_data_p->master_dest_addr = address;
69
    i2c_data_p->buffer_in_read_ind = 0;
70
    i2c_data_p->buffer_in_write_ind = 0;
71
 
72
    // Change status to 'next' operation
73
    i2c_data_p->operating_state = I2C_SEND_ADDR;
74
    i2c_data_p->master_status = I2C_MASTER_SEND;
75
 
76
    // Generate start condition
77
    SSPCON2bits.SEN = 1;
78
}
79
 
80
// Reads length number of bytes from address (no R/W bit)
81
void I2C_Master_Recv(char address, char length) {
82
    if (length == 0)
83
        return;
84
 
85
    // Save length and address to get data from
86
    i2c_data_p->buffer_in_len = length;
87
    i2c_data_p->master_dest_addr = address;
88
    i2c_data_p->buffer_in_read_ind = 0;
89
    i2c_data_p->buffer_in_write_ind = 0;
90
 
91
    // Change status to 'next' operation
92
    i2c_data_p->operating_state = I2C_SEND_ADDR;
93
    i2c_data_p->master_status = I2C_MASTER_RECV;
94
 
95
    // Generate start condition
96
    SSPCON2bits.SEN = 1;
97
}
98
 
99
// Writes msg to address then reads length number of bytes from address
100
void I2C_Master_Restart(char address, char msg, char length) {
101
    char c;
102
    if (length == 0) {
103
        c = msg;
104
        I2C_Master_Send(address, 1, &c);
105
        return;
106
    }
107
 
108
    // Save length and address to get data from
109
    i2c_data_p->buffer_in[0] = msg;
110
    i2c_data_p->buffer_in_len = length;
111
    i2c_data_p->master_dest_addr = address;
112
    i2c_data_p->buffer_in_read_ind = 0;
113
    i2c_data_p->buffer_in_write_ind = 0;
114
 
115
    // Change status to 'next' operation
116
    i2c_data_p->operating_state = I2C_SEND_ADDR;
117
    i2c_data_p->master_status = I2C_MASTER_RESTART;
118
 
119
    // Generate start condition
120
    SSPCON2bits.SEN = 1;
121
}
122
 
123
// Setup the PIC to operate as a slave. The address must not include the R/W bit
124
void I2C_Configure_Slave(char addr) {
125
    i2c_data_p->operating_mode = I2C_MODE_SLAVE;
126
 
127
    // Ensure the two lines are set for input (we are a slave)
128
    I2C_CLK_TRIS = 1;
129
    I2C_DAT_TRIS = 1;
130
 
131
    SSPADD = addr << 1;     // Set the slave address
132
 
133
    SSPSTAT = 0x0;
134
    SSPCON1 = 0x0;
135
    SSPCON2 = 0x0;
136
    SSPCON1bits.SSPM = 0xE; // Enable Slave 7-bit w/ start/stop interrupts
137
    SSPSTATbits.SMP = 1;    // Slew Off
138
    SSPCON2bits.SEN = 1;    // Enable clock-stretching
139
    SSPCON1bits.SSPEN = 1;  // Enable MSSP Module
140
}
141
 
142
void I2C_Interrupt_Handler() {
143
    // Call interrupt depending on which mode we are operating in
144
    if (i2c_data_p->operating_mode == I2C_MODE_MASTER) {
145
        I2C_Interrupt_Master();
146
    } else if (i2c_data_p->operating_mode == I2C_MODE_SLAVE) {
147
        I2C_Interrupt_Slave();
148
    }
149
}
150
 
151
// An internal subroutine used in the master version of the i2c_interrupt_handler
152
void I2C_Interrupt_Master() {
153
    // If we are in the middle of sending data
154
    if (i2c_data_p->master_status == I2C_MASTER_SEND) {
155
        switch (i2c_data_p->operating_state) {
156
            case I2C_IDLE:
157
                break;
158
            case I2C_SEND_ADDR:
159
                // Send the address with read bit set
160
                i2c_data_p->operating_state = I2C_CHECK_ACK_SEND;
161
                SSPBUF = (i2c_data_p->master_dest_addr << 1) | 0x0;
162
                break;
163
            case I2C_CHECK_ACK_SEND:
164
                // Check if ACK is received or not
165
                if (!SSPCON2bits.ACKSTAT) {
166
                    // If an ACK is received, send next byte of data
167
                    if (i2c_data_p->buffer_in_read_ind < i2c_data_p->buffer_in_len) {
168
                        SSPBUF = i2c_data_p->buffer_in[i2c_data_p->buffer_in_read_ind];
169
                        i2c_data_p->buffer_in_read_ind++;
170
                    } else {
171
                        // If no more data is to be sent, send stop bit
172
                        i2c_data_p->operating_state = I2C_IDLE;
173
                        SSPCON2bits.PEN = 1;
174
                        i2c_data_p->master_status = I2C_MASTER_IDLE;
175
                        i2c_data_p->return_status = I2C_SEND_OK;
176
                    }
177
                } else {
178
                    // If a NACK is received, stop transmission and send error
179
                    i2c_data_p->operating_state = I2C_IDLE;
180
                    SSPCON2bits.PEN = 1;
181
                    i2c_data_p->master_status = I2C_MASTER_IDLE;
182
                    i2c_data_p->return_status = I2C_SEND_FAIL;
183
                }
184
                break;
185
        }
186
    // If we are in the middle of receiving data
187
    } else if (i2c_data_p->master_status == I2C_MASTER_RECV) {
188
        switch (i2c_data_p->operating_state) {
189
            case I2C_IDLE:
190
                break;
191
            case I2C_SEND_ADDR:
192
                // Send address with write bit set
193
                i2c_data_p->operating_state = I2C_CHECK_ACK_RECV;
194
                SSPBUF = (i2c_data_p->master_dest_addr << 1) | 0x1;
195
                break;
196
            case I2C_CHECK_ACK_RECV:
197
                // Check if ACK is received
198
                if (!SSPCON2bits.ACKSTAT) {
199
                    // If an ACK is received, set module to receive 1 byte of data
200
                    i2c_data_p->operating_state = I2C_RCV_DATA;
201
                    SSPCON2bits.RCEN = 1;
202
                } else {
203
                    // If a NACK is received, stop transmission and send error
204
                    i2c_data_p->operating_state = I2C_IDLE;
205
                    SSPCON2bits.PEN = 1;
206
                    i2c_data_p->master_status = I2C_MASTER_IDLE;
207
                    i2c_data_p->return_status = I2C_RECV_FAIL;
208
                }
209
                break;
210
            case I2C_RCV_DATA:
211
                // On receive, save byte into buffer
157 Kevin 212
                // TODO: Handle I2C buffer overflow
155 Kevin 213
                i2c_data_p->buffer_in[i2c_data_p->buffer_in_write_ind] = SSPBUF;
214
                i2c_data_p->buffer_in_write_ind++;
215
                if (i2c_data_p->buffer_in_write_ind < i2c_data_p->buffer_in_len) {
216
                    // If we still need to read, send an ACK to the slave
217
                    i2c_data_p->operating_state = I2C_REQ_DATA;
218
                    SSPCON2bits.ACKDT = 0;  // ACK
219
                    SSPCON2bits.ACKEN = 1;
220
                } else {
221
                    // If we are done reading, send an NACK to the slave
222
                    i2c_data_p->operating_state = I2C_SEND_STOP;
223
                    SSPCON2bits.ACKDT = 1;  // NACK
224
                    SSPCON2bits.ACKEN = 1;
225
                }
226
                break;
227
            case I2C_REQ_DATA:
228
                // Set module to receive one byte of data
229
                i2c_data_p->operating_state = I2C_RCV_DATA;
230
                SSPCON2bits.RCEN = 1;
231
                break;
232
            case I2C_SEND_STOP:
233
                // Send the stop bit and copy message to send to Main()
234
                i2c_data_p->operating_state = I2C_IDLE;
235
                SSPCON2bits.PEN = 1;
236
                i2c_data_p->master_status = I2C_MASTER_IDLE;
237
                i2c_data_p->return_status = I2C_RECV_OK;
238
                break;
239
        }
240
    } else if (i2c_data_p->master_status == I2C_MASTER_RESTART) {
241
        switch (i2c_data_p->operating_state) {
242
            case I2C_IDLE:
243
                break;
244
            case I2C_SEND_ADDR:
245
                // Send the address with read bit set
246
                i2c_data_p->operating_state = I2C_CHECK_ACK_SEND;
247
                SSPBUF = (i2c_data_p->master_dest_addr << 1) | 0x0;
248
                break;
249
            case I2C_CHECK_ACK_SEND:
250
                // Check if ACK is received or not
251
                if (!SSPCON2bits.ACKSTAT) {
252
                    // If an ACK is received, send first byte of data
253
                    SSPBUF = i2c_data_p->buffer_in[0];
254
                    i2c_data_p->operating_state = I2C_CHECK_ACK_RESTART;
255
                } else {
256
                    // If a NACK is received, stop transmission and send error
257
                    i2c_data_p->operating_state = I2C_IDLE;
258
                    SSPCON2bits.PEN = 1;
259
                    i2c_data_p->master_status = I2C_MASTER_IDLE;
260
                    i2c_data_p->return_status = I2C_SEND_FAIL;
261
                }
262
                break;
263
            case I2C_CHECK_ACK_RESTART:
264
                if (!SSPCON2bits.ACKSTAT) {
265
                    SSPCON2bits.RSEN = 1;
266
                    i2c_data_p->operating_state = I2C_SEND_ADDR_2;
267
                } else {
268
                    // If a NACK is received, stop transmission and send error
269
                    i2c_data_p->operating_state = I2C_IDLE;
270
                    SSPCON2bits.PEN = 1;
271
                    i2c_data_p->master_status = I2C_MASTER_IDLE;
272
                    i2c_data_p->return_status = I2C_SEND_FAIL;
273
                }
274
                break;
275
            case I2C_SEND_ADDR_2:
276
                // Send the address with read bit set
277
                i2c_data_p->operating_state = I2C_CHECK_ACK_RECV;
278
                SSPBUF = (i2c_data_p->master_dest_addr << 1) | 0x1;
279
                break;
280
            case I2C_CHECK_ACK_RECV:
281
                // Check if ACK is received
282
                if (!SSPCON2bits.ACKSTAT) {
283
                    // If an ACK is received, set module to receive 1 byte of data
284
                    i2c_data_p->operating_state = I2C_RCV_DATA;
285
                    SSPCON2bits.RCEN = 1;
286
                } else {
287
                    // If a NACK is received, stop transmission and send error
288
                    i2c_data_p->operating_state = I2C_IDLE;
289
                    SSPCON2bits.PEN = 1;
290
                    i2c_data_p->master_status = I2C_MASTER_IDLE;
291
                    i2c_data_p->return_status = I2C_RECV_FAIL;
292
                }
293
                break;
294
            case I2C_RCV_DATA:
295
                // On receive, save byte into buffer
157 Kevin 296
                // TODO: Handle I2C buffer overflow
155 Kevin 297
                i2c_data_p->buffer_in[i2c_data_p->buffer_in_write_ind] = SSPBUF;
298
                i2c_data_p->buffer_in_write_ind++;
299
                if (i2c_data_p->buffer_in_write_ind < i2c_data_p->buffer_in_len) {
300
                    // If we still need to read, send an ACK to the slave
301
                    i2c_data_p->operating_state = I2C_REQ_DATA;
302
                    SSPCON2bits.ACKDT = 0;  // ACK
303
                    SSPCON2bits.ACKEN = 1;
304
                } else {
305
                    // If we are done reading, send an NACK to the slave
306
                    i2c_data_p->operating_state = I2C_SEND_STOP;
307
                    SSPCON2bits.ACKDT = 1;  // NACK
308
                    SSPCON2bits.ACKEN = 1;
309
                }
310
                break;
311
            case I2C_REQ_DATA:
312
                // Set module to receive one byte of data
313
                i2c_data_p->operating_state = I2C_RCV_DATA;
314
                SSPCON2bits.RCEN = 1;
315
                break;
316
            case I2C_SEND_STOP:
317
                // Send the stop bit and copy message to send to Main()
318
                i2c_data_p->operating_state = I2C_IDLE;
319
                SSPCON2bits.PEN = 1;
320
                i2c_data_p->master_status = I2C_MASTER_IDLE;
321
                i2c_data_p->return_status = I2C_RECV_OK;
322
                break;
323
        }
324
    }
325
}
326
 
327
void I2C_Interrupt_Slave() {
328
    char received_data;
329
    char data_read_from_buffer = 0;
330
    char data_written_to_buffer = 0;
331
    char overrun_error = 0;
332
    char output[64];
333
 
334
    // Clear SSPOV (overflow bit)
335
    if (SSPCON1bits.SSPOV == 1) {
336
        sprintf(output, "I2C: (ERROR) overflow detectedr\r\n");
337
        DBG_PRINT_I2C(output, strlen(output));
338
        SSPCON1bits.SSPOV = 0;
339
        // We failed to read the buffer in time, so we know we
340
        //  can't properly receive this message, just put us in the
341
        //  a state where we are looking for a new message
342
        i2c_data_p->operating_state = I2C_IDLE;
343
        overrun_error = 1;
344
        i2c_data_p->return_status = I2C_ERR_OVERRUN;
345
    }
346
 
347
    // Read SPPxBUF if it is full
348
    if (SSPSTATbits.BF == 1) {
349
        received_data = SSPBUF;
350
//        DBG_PRINT_I2C("I2C: data read from buffer: %x\r\n", SSPBUF);
351
        data_read_from_buffer = 1;
352
    }
353
 
354
    if (!overrun_error) {
355
        switch (i2c_data_p->operating_state) {
356
            case I2C_IDLE:
357
            {
358
                // Ignore anything except a start
359
                if (SSPSTATbits.S == 1) {
360
                    i2c_data_p->buffer_in_len_tmp = 0;
361
                    i2c_data_p->operating_state = I2C_STARTED;
362
//                    if (data_read_from_buffer) {
363
//                        if (SSPSTATbits.D_A == 1) {
364
//                            DBG_PRINT_I2C("I2C Start: (ERROR) no address recieved\r\n");
365
//                            // This is bad because we got data and we wanted an address
366
//                            i2c_data_p->operating_state = I2C_IDLE;
367
//                            i2c_data_p->return_status = I2C_ERR_NOADDR;
368
//                        } else {
369
//                            // Determine if we are sending or receiving data
370
//                            if (SSPSTATbits.R_W == 1) {
371
//                                i2c_data_p->operating_state = I2C_SEND_DATA;
372
//                            } else {
373
//                                i2c_data_p->operating_state = I2C_RCV_DATA;
374
//                            }
375
//                        }
376
//                    } else {
377
//                        i2c_data_p->operating_state = I2C_STARTED;
378
//                    }
379
                }
380
                break;
381
            }
382
            case I2C_STARTED:
383
            {
384
                // In this case, we expect either an address or a stop bit
385
                if (SSPSTATbits.P == 1) {
386
                    // Return to idle mode
387
                    i2c_data_p->operating_state = I2C_IDLE;
388
                } else if (data_read_from_buffer) {
389
                    if (SSPSTATbits.D_A == 0) {
390
                        // Address received
391
                        if (SSPSTATbits.R_W == 0) {
392
                            // Slave write mode
393
                            i2c_data_p->operating_state = I2C_RCV_DATA;
394
                        } else {
395
                            // Slave read mode
396
                            i2c_data_p->operating_state = I2C_SEND_DATA;
397
                            // Process the first byte immediatly if sending data
398
                            goto send;
399
                        }
400
                    } else {
401
                        sprintf(output, "I2C: (ERROR) no data recieved\r\n");
402
                        DBG_PRINT_I2C(output, strlen(output));
403
                        i2c_data_p->operating_state = I2C_IDLE;
404
                        i2c_data_p->return_status = I2C_ERR_NODATA;
405
                    }
406
                }
407
                break;
408
            }
409
            send:
410
            case I2C_SEND_DATA:
411
            {
412
                if (!i2c_data_p->slave_sending_data) {
413
                    // If we are not currently sending data, figure out what to reply with
414
                    if (I2C_Process_Send(i2c_data_p->slave_in_last_byte)) {
415
                        // Data exists to be returned, send first byte
416
                        SSPBUF = i2c_data_p->buffer_out[0];
417
                        i2c_data_p->buffer_out_ind = 1;
418
                        i2c_data_p->slave_sending_data = 1;
419
                        data_written_to_buffer = 1;
420
                    } else {
421
                        // Unknown request
422
                        i2c_data_p->slave_sending_data = 0;
423
                        i2c_data_p->operating_state = I2C_IDLE;
424
                    }
425
                } else {
426
                    // Sending remaining data back to master
427
                    if (i2c_data_p->buffer_out_ind < i2c_data_p->buffer_out_len) {
428
                        SSPBUF = i2c_data_p->buffer_out[i2c_data_p->buffer_out_ind];
429
                        i2c_data_p->buffer_out_ind++;
430
                        data_written_to_buffer = 1;
431
                    } else {
432
                        // Nothing left to send
433
                        i2c_data_p->slave_sending_data = 0;
434
                        i2c_data_p->operating_state = I2C_IDLE;
435
                    }
436
                }
437
                break;
438
            }
439
            case I2C_RCV_DATA:
440
            {
441
                // We expect either data or a stop bit or a (if a restart, an addr)
442
                if (SSPSTATbits.P == 1) {
443
                    // Stop bit detected, we need to check to see if we also read data
444
                    if (data_read_from_buffer) {
445
                        if (SSPSTATbits.D_A == 1) {
446
                            // Data received with stop bit
157 Kevin 447
                            // TODO: Handle I2C buffer overflow
155 Kevin 448
                            i2c_data_p->buffer_in[i2c_data_p->buffer_in_write_ind] = received_data;
449
                            if (i2c_data_p->buffer_in_write_ind == MAXI2CBUF-1) {
450
                                i2c_data_p->buffer_in_write_ind = 0;
451
                            } else {
452
                                i2c_data_p->buffer_in_write_ind++;
453
                            }
454
                            i2c_data_p->buffer_in_len_tmp++;
455
                            // Save the last byte received
456
                            i2c_data_p->slave_in_last_byte = received_data;
457
                            i2c_data_p->return_status = I2C_DATA_AVAL;
458
                        } else {
459
                            sprintf(output, "I2C: (ERROR) no data recieved\r\n");
460
                            DBG_PRINT_I2C(output, strlen(output));
461
                            i2c_data_p->operating_state = I2C_IDLE;
462
                            i2c_data_p->return_status = I2C_ERR_NODATA;
463
                        }
464
                    }
465
                    i2c_data_p->buffer_in_len += i2c_data_p->buffer_in_len_tmp;
466
                    i2c_data_p->operating_state = I2C_IDLE;
467
                } else if (data_read_from_buffer) {
468
                    if (SSPSTATbits.D_A == 1) {
469
                        // Data received
470
                        i2c_data_p->buffer_in[i2c_data_p->buffer_in_write_ind] = received_data;
471
                        if (i2c_data_p->buffer_in_write_ind == MAXI2CBUF-1) {
472
                            i2c_data_p->buffer_in_write_ind = 0;
473
                        } else {
474
                            i2c_data_p->buffer_in_write_ind++;
475
                        }
476
                        i2c_data_p->buffer_in_len_tmp++;
477
                        // Save the last byte received
478
                        i2c_data_p->slave_in_last_byte = received_data;
479
                        i2c_data_p->return_status = I2C_DATA_AVAL;
480
                    } else {
481
                        // Restart bit detected
482
                        if (SSPSTATbits.R_W == 1) {
483
                            i2c_data_p->buffer_in_len += i2c_data_p->buffer_in_len_tmp;
484
                            i2c_data_p->operating_state = I2C_SEND_DATA;
485
                            // Process the first byte immediatly if sending data
486
                            goto send;
487
                        } else {
488
                            // Bad to recv an address again, we aren't ready
489
                            sprintf(output, "I2C: (ERROR) no data recieved\r\n");
490
                            DBG_PRINT_I2C(output, strlen(output));
491
                            i2c_data_p->operating_state = I2C_IDLE;
492
                            i2c_data_p->return_status = I2C_ERR_NODATA;
493
                        }
494
                    }
495
                }
496
                break;
497
            }
498
        }
499
    }
500
 
501
    // Release the clock stretching bit (if we should)
502
    if (data_read_from_buffer || data_written_to_buffer) {
503
        // Release the clock
504
        if (SSPCON1bits.CKP == 0) {
505
            SSPCON1bits.CKP = 1;
506
        }
507
    }
508
}
509
 
510
/* Returns 0 if I2C module is currently busy, otherwise returns status code */
511
char I2C_Get_Status() {
512
    if (i2c_data_p->operating_mode == I2C_MODE_MASTER) {
513
        if (i2c_data_p->master_status != I2C_MASTER_IDLE || i2c_data_p->buffer_in_len == 0) {
514
            return 0;
515
        } else {
516
            return i2c_data_p->return_status;
517
        }
518
    } else {
519
        if (i2c_data_p->operating_state != I2C_IDLE || i2c_data_p->buffer_in_len == 0) {
520
            return 0;
521
        } else {
522
            return i2c_data_p->return_status;
523
        }
524
    }
525
}
526
 
527
char I2C_Buffer_Len() {
528
    return i2c_data_p->buffer_in_len;
529
}
530
 
531
/* Returns 0 if I2C module is currently busy, otherwise returns buffer length */
532
char I2C_Read_Buffer(char *buffer) {
533
    char i = 0;
534
    while (i2c_data_p->buffer_in_len != 0) {
535
        buffer[i] = i2c_data_p->buffer_in[i2c_data_p->buffer_in_read_ind];
536
        i++;
537
        if (i2c_data_p->buffer_in_read_ind == MAXI2CBUF-1) {
538
            i2c_data_p->buffer_in_read_ind = 0;
539
        } else {
540
            i2c_data_p->buffer_in_read_ind++;
541
        }
542
        i2c_data_p->buffer_in_len--;
543
    }
544
    return i;
545
}
546
 
547
/* Put data to be returned here */
548
char I2C_Process_Send(char c) {
549
    char ret = 0;
550
    switch (c) {
551
        case 0xAA:
552
            i2c_data_p->buffer_out[0] = 'A';
553
            i2c_data_p->buffer_out_len = 1;
554
            ret = 1;
555
            break;
556
        case 0xBB:
557
            i2c_data_p->buffer_out[0] = '1';
558
            i2c_data_p->buffer_out[1] = '2';
559
            i2c_data_p->buffer_out_len = 2;
560
            ret = 1;
561
            break;
562
    }
563
    return ret;
564
}