inline int i2c_start(i2c_t *obj) { int status = 0; int isInterrupted = I2C_CONSET(obj) & (1 << 3); // 8.1 Before master mode can be entered, I2CON must be initialised to: // - I2EN STA STO SI AA - - // - 1 0 0 x x - - // if AA = 0, it can't enter slave mode i2c_conclr(obj, 1, 1, 0, 1); // The master mode may now be entered by setting the STA bit // this will generate a start condition when the bus becomes free i2c_conset(obj, 1, 0, 0, 1); // Clearing SI bit when it wasn't set on entry can jump past state // 0x10 or 0x08 and erroneously send uninitialized slave address. if (isInterrupted) i2c_clear_SI(obj); i2c_wait_SI(obj); status = i2c_status(obj); // Clear start bit now that it's transmitted i2c_conclr(obj, 1, 0, 0, 0); return status; }
// Wait until the Serial Interrupt (SI) is set static int i2c_wait_SI(i2c_t *obj) { int timeout = 0; while (!(I2C_CONSET(obj) & (1 << 3))) { timeout++; if (timeout > 100000) return -1; } return 0; }
inline void i2c_stop(i2c_t *obj) { // write the stop bit i2c_conset(obj, 0, 1, 0, 0); i2c_clear_SI(obj); // wait for STO bit to reset while(I2C_CONSET(obj) & (1 << 4)); }
inline int i2c_stop(i2c_t *obj) { int timeout = 0; // write the stop bit i2c_conset(obj, 0, 1, 0, 0); i2c_clear_SI(obj); // wait for STO bit to reset while(I2C_CONSET(obj) & (1 << 4)) { timeout ++; if (timeout > 100000) return 1; } return 0; }
static inline void i2c_interface_enable(i2c_t *obj) { I2C_CONSET(obj) = 0x40; }
static inline void i2c_conset(i2c_t *obj, int start, int stop, int interrupt, int acknowledge) { I2C_CONSET(obj) = (start << 5) | (stop << 4) | (interrupt << 3) | (acknowledge << 2); }