Merge pull request #214 from ourairquality/i2c-open-drain2

i2c: use open drain for output rather than flipping between input and output.
This commit is contained in:
sheinz 2016-09-05 09:22:19 +03:00 committed by GitHub
commit c342763612

View file

@ -49,48 +49,47 @@ void i2c_init(uint8_t scl_pin, uint8_t sda_pin)
gpio_set_pullup(g_scl_pin, 1, 1); gpio_set_pullup(g_scl_pin, 1, 1);
gpio_set_pullup(g_sda_pin, 1, 1); gpio_set_pullup(g_sda_pin, 1, 1);
// I2C bus idle state. gpio_enable(g_scl_pin, GPIO_OUT_OPEN_DRAIN);
gpio_enable(g_scl_pin, GPIO_INPUT); gpio_enable(g_sda_pin, GPIO_OUT_OPEN_DRAIN);
gpio_enable(g_scl_pin, GPIO_INPUT);
// Set the pins to a low output state for when they are configured // I2C bus idle state.
// as outputs. gpio_write(g_scl_pin, 1);
gpio_write(g_scl_pin, 0); gpio_write(g_sda_pin, 1);
gpio_write(g_sda_pin, 0);
} }
static void i2c_delay(void) static inline void i2c_delay(void)
{ {
sdk_os_delay_us(CLK_HALF_PERIOD_US); sdk_os_delay_us(CLK_HALF_PERIOD_US);
} }
// Set SCL as input, allowing it to float high, and return current // Set SCL as input, allowing it to float high, and return current
// level of line, 0 or 1 // level of line, 0 or 1
static bool read_scl(void) static inline bool read_scl(void)
{ {
gpio_enable(g_scl_pin, GPIO_INPUT); gpio_write(g_scl_pin, 1);
return gpio_read(g_scl_pin); // Clock high, valid ACK return gpio_read(g_scl_pin); // Clock high, valid ACK
} }
// Set SDA as input and return current level of line, 0 or 1 // Set SDA as input, allowing it to float high, and return current
static bool read_sda(void) // level of line, 0 or 1
static inline bool read_sda(void)
{ {
gpio_enable(g_sda_pin, GPIO_INPUT); gpio_write(g_sda_pin, 1);
// TODO: Without this delay we get arbitration lost in i2c_stop // TODO: Without this delay we get arbitration lost in i2c_stop
i2c_delay(); i2c_delay();
return gpio_read(g_sda_pin); // Clock high, valid ACK return gpio_read(g_sda_pin); // Clock high, valid ACK
} }
// Actively drive SCL signal low // Actively drive SCL signal low
static void clear_scl(void) static inline void clear_scl(void)
{ {
gpio_enable(g_scl_pin, GPIO_OUT_OPEN_DRAIN); gpio_write(g_scl_pin, 0);
} }
// Actively drive SDA signal low // Actively drive SDA signal low
static void clear_sda(void) static inline void clear_sda(void)
{ {
gpio_enable(g_sda_pin, GPIO_OUT_OPEN_DRAIN); gpio_write(g_sda_pin, 0);
} }
// Output start condition // Output start condition