I2CSlave test program. I2CSlave library has some improper behavior, so this program is able to watch that. The workaround for this behavior, only for NXP device, is wrote in 'I2CSlave_mod_NXP.cpp'.

Dependencies:   mbed

First, write this program to the microcontroller which you want to check. Second, send I2C data to the microcontroller from the other one. Anything is enough for the transmission data, but the data length is made 8, 9, 10 and 11 bytes and confirm each reply.

Committer:
oks486
Date:
Fri Apr 15 08:16:34 2016 +0000
Revision:
1:bd94bb3170b6
Added workaround for NXP device (confirmed only LPC1114)

Who changed what in which revision?

UserRevisionLine numberNew contents of line
oks486 1:bd94bb3170b6 1 #include "I2CSlave_mod_NXP.h"
oks486 1:bd94bb3170b6 2
oks486 1:bd94bb3170b6 3 #define I2C_CONSET(x) (x->i2c->CONSET)
oks486 1:bd94bb3170b6 4 #define I2C_CONCLR(x) (x->i2c->CONCLR)
oks486 1:bd94bb3170b6 5 #define I2C_DAT(x) (x->i2c->DAT)
oks486 1:bd94bb3170b6 6 #define I2C_STAT(x) (x->i2c->STAT)
oks486 1:bd94bb3170b6 7
oks486 1:bd94bb3170b6 8 static inline void i2c_conclr(i2c_t *obj, int start, int stop, int interrupt, int acknowledge) {
oks486 1:bd94bb3170b6 9 I2C_CONCLR(obj) = (start << 5)
oks486 1:bd94bb3170b6 10 | (stop << 4)
oks486 1:bd94bb3170b6 11 | (interrupt << 3)
oks486 1:bd94bb3170b6 12 | (acknowledge << 2);
oks486 1:bd94bb3170b6 13 }
oks486 1:bd94bb3170b6 14
oks486 1:bd94bb3170b6 15 // Clear the Serial Interrupt (SI)
oks486 1:bd94bb3170b6 16 static inline void i2c_clear_SI(i2c_t *obj) {
oks486 1:bd94bb3170b6 17 i2c_conclr(obj, 0, 0, 1, 0);
oks486 1:bd94bb3170b6 18 }
oks486 1:bd94bb3170b6 19
oks486 1:bd94bb3170b6 20 static inline int i2c_status(i2c_t *obj) {
oks486 1:bd94bb3170b6 21 return I2C_STAT(obj);
oks486 1:bd94bb3170b6 22 }
oks486 1:bd94bb3170b6 23
oks486 1:bd94bb3170b6 24 // Wait until the Serial Interrupt (SI) is set
oks486 1:bd94bb3170b6 25 static int i2c_wait_SI(i2c_t *obj) {
oks486 1:bd94bb3170b6 26 int timeout = 0;
oks486 1:bd94bb3170b6 27 while (!(I2C_CONSET(obj) & (1 << 3))) {
oks486 1:bd94bb3170b6 28 timeout++;
oks486 1:bd94bb3170b6 29 if (timeout > 100000) return -1;
oks486 1:bd94bb3170b6 30 }
oks486 1:bd94bb3170b6 31 return 0;
oks486 1:bd94bb3170b6 32 }
oks486 1:bd94bb3170b6 33
oks486 1:bd94bb3170b6 34
oks486 1:bd94bb3170b6 35 I2CSlave_mod::I2CSlave_mod(PinName sda, PinName scl) : I2CSlave(sda, scl) {
oks486 1:bd94bb3170b6 36 }
oks486 1:bd94bb3170b6 37
oks486 1:bd94bb3170b6 38
oks486 1:bd94bb3170b6 39 int I2CSlave_mod::read(char *data, int length) {
oks486 1:bd94bb3170b6 40 return i2c_slave_read_mod(&_i2c, data, length) != length;
oks486 1:bd94bb3170b6 41 }
oks486 1:bd94bb3170b6 42
oks486 1:bd94bb3170b6 43
oks486 1:bd94bb3170b6 44 int I2CSlave_mod::i2c_slave_read_mod(i2c_t *obj, char *data, int length) {
oks486 1:bd94bb3170b6 45 int count = 0;
oks486 1:bd94bb3170b6 46 int status;
oks486 1:bd94bb3170b6 47
oks486 1:bd94bb3170b6 48 do {
oks486 1:bd94bb3170b6 49 if((status == 0x80) || (status == 0x90)) {
oks486 1:bd94bb3170b6 50 data[count] = I2C_DAT(obj) & 0xFF;
oks486 1:bd94bb3170b6 51 count++;
oks486 1:bd94bb3170b6 52 }
oks486 1:bd94bb3170b6 53 i2c_clear_SI(obj);
oks486 1:bd94bb3170b6 54 i2c_wait_SI(obj);
oks486 1:bd94bb3170b6 55 status = i2c_status(obj);
oks486 1:bd94bb3170b6 56 } while (((status == 0x80) || (status == 0x90) ||
oks486 1:bd94bb3170b6 57 (status == 0x060) || (status == 0x70)) && (count < length));
oks486 1:bd94bb3170b6 58
oks486 1:bd94bb3170b6 59 if(status != 0xA0) {
oks486 1:bd94bb3170b6 60 i2c_stop(obj);
oks486 1:bd94bb3170b6 61 }
oks486 1:bd94bb3170b6 62
oks486 1:bd94bb3170b6 63 i2c_clear_SI(obj);
oks486 1:bd94bb3170b6 64
oks486 1:bd94bb3170b6 65 return count;
oks486 1:bd94bb3170b6 66 }