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'.
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.
I2CSlave_mod/I2CSlave_mod_NXP.cpp@1:bd94bb3170b6, 2016-04-15 (annotated)
- 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?
User | Revision | Line number | New 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 | } |