raspberrypi / pico-sdk

BSD 3-Clause "New" or "Revised" License
3.62k stars 901 forks source link

i2c_write_raw_blocking needs nostop parameter #812

Open sigmafx opened 2 years ago

sigmafx commented 2 years ago

Whilst writing to an I2C EEPROM it's necessary to write eeprom memory address followed by the data to write without a STOP between the address and the data. A typical write function would accept a memory address and data as separate parameters. This is best written to the EEPROM in 2 API calls: 1st: Sends device address and eeprom memory address 2nd: Sends data, followed by a STOP

The only achievable way is using the following APIs:

        // nostop is true so STOP isn't sent allowing data bytes to follow immediately
        i2c_write_blocking(m_instance, m_devAddr, &address, 1, true);
        i2c_write_raw_blocking(m_instance, &data, sizeof(data));

However, i2c_write_raw_blocking does not write a STOP.

It would be helpful to include the nostop paramter to i2c_write_raw_blocking function:

static inline void i2c_write_raw_blocking(i2c_inst_t *i2c, const uint8_t *src, size_t len, bool nostop) {
    for (size_t i = 0; i < len; ++i) {
        bool last = i == len - 1;

        // TODO NACK or STOP on end?
        while (!i2c_get_write_available(i2c))
            tight_loop_contents();
        i2c_get_hw(i2c)->data_cmd =
            bool_to_bit(last && !nostop) << I2C_IC_DATA_CMD_STOP_LSB |
            *src++;
    }
}

There's already a comment in there about this.

kilograham commented 1 year ago

note #1049 which also deals with I2C functions - perhaps we need an additional config

kaimac1 commented 6 months ago

this is also very useful for driving OLED displays, where the frame data needs to be preceded by a single 0x40 byte.

@sigmafx 's function needs the following after the for loop to wait for the STOP bit to actually be generated:

while (!(i2c->hw->raw_intr_stat & I2C_IC_RAW_INTR_STAT_STOP_DET_BITS)) tight_loop_contents(); 
lurch commented 1 week ago

Does #1495 fix this, or is that a different problem entirely?