#include #include #include #include #include #include #include static void write_bit(const struct i2c_bb *i2c, uint8_t bit); static uint8_t read_bit(const struct i2c_bb *i2c); static void start_condition(const struct i2c_bb *i2c); static void stop_condition(const struct i2c_bb *i2c); static bool write_byte(const struct i2c_bb *i2c, uint8_t byte); static uint8_t read_byte(const struct i2c_bb *i2c, bool ack); // cppcheck-suppress unusedFunction int i2c_open(const struct i2c_bb *i2c) { int res = EXIT_SUCCESS; assert(NULL != i2c); res = gpio_open(i2c->sda); res |= gpio_open(i2c->scl); res |= gpio_write(i2c->sda, 1); res |= gpio_write(i2c->scl, 1); return res; } // cppcheck-suppress unusedFunction int i2c_close(const struct i2c_bb *i2c) { int res = EXIT_SUCCESS; assert(NULL != i2c); res = gpio_close(i2c->sda); res |= gpio_close(i2c->scl); return res; } // cppcheck-suppress unusedFunction int i2c_read(const struct i2c_bb *i2c, uint8_t slave_addr, char *buffer, unsigned int len) { unsigned int i; assert(NULL != i2c); if((NULL == buffer) || len == 0) { return 0; } start_condition(i2c); write_byte(i2c, (slave_addr << 1) | 1); for(i = 0; i < len; i++) { buffer[i] = read_byte(i2c, true); } stop_condition(i2c); return (int)i; } // cppcheck-suppress unusedFunction int i2c_write(const struct i2c_bb *i2c, uint8_t slave_addr, const char *buffer, unsigned int len) { unsigned int i; assert(NULL != i2c); if((NULL == buffer) || len == 0) { return 0; } start_condition(i2c); write_byte(i2c, slave_addr << 1); for(i = 0; i < len; i++) { write_byte(i2c, buffer[i]); } stop_condition(i2c); return (int)i; } static void start_condition(const struct i2c_bb *i2c) { assert( NULL != i2c); gpio_write(i2c->scl, 1); gpio_write(i2c->sda, 1); usleep(5); gpio_write(i2c->sda, 0); usleep(5); gpio_write(i2c->scl, 0); usleep(5); } static void stop_condition(const struct i2c_bb *i2c) { assert( NULL != i2c); gpio_write(i2c->sda, 0); usleep(5); gpio_write(i2c->scl, 1); usleep(5); gpio_write(i2c->sda, 1); usleep(5); } static bool write_byte(const struct i2c_bb *i2c, uint8_t byte) { uint8_t ack, i; assert(NULL != i2c); for(i = 0; i < 8; i++) { write_bit(i2c, byte & 0x80); byte <<= 1; } ack = read_bit(i2c); return (bool)(ack & 0x01); } static uint8_t read_byte(const struct i2c_bb *i2c, bool ack) { uint8_t res = 0, i; assert(NULL != i2c); for(i = 0; i < 8; i++) { res <<= 1; res |= read_bit(i2c); } if(ack) { write_bit(i2c, 0); } else { write_bit(i2c, 1); } return res; } static void write_bit(const struct i2c_bb *i2c, uint8_t bit) { assert( NULL != i2c); if(bit > 0) { gpio_write(i2c->sda, 1); } else { gpio_write(i2c->sda, 0); } usleep(5); gpio_write(i2c->scl, 1); usleep(5); gpio_write(i2c->scl, 0); } static uint8_t read_bit(const struct i2c_bb *i2c) { unsigned int res; assert(NULL != i2c); gpio_write(i2c->sda, 1); usleep(5); gpio_write(i2c->scl, 1); usleep(5); gpio_read(i2c->sda, &res); gpio_write(i2c->scl, 0); return (uint8_t) res; }