fn setup_read<'a, I>(
        &self,
        addr: I2cAddress,
        buffer: &mut [u8],
        start: bool,
        will_continue: bool,
        cmd_iterator: &mut I,
    ) -> Result<(), Error>
    where
        I: Iterator<Item = &'a COMD>,
    {
        if buffer.is_empty() {
            return Err(Error::ZeroLengthInvalid);
        }
        let (max_len, initial_len) = if will_continue {
            (I2C_CHUNK_SIZE + 1, buffer.len())
        } else {
            (I2C_CHUNK_SIZE, buffer.len() - 1)
        };
        if buffer.len() > max_len {
            return Err(Error::FifoExceeded);
        }

        if start {
            add_cmd(cmd_iterator, Command::Start)?;
            // WRITE command
            add_cmd(
                cmd_iterator,
                Command::Write {
                    ack_exp: Ack::Ack,
                    ack_check_en: true,
                    length: 1,
                },
            )?;
        }

        if initial_len > 0 {
            if cfg!(any(esp32, esp32s2)) {
                // try to place END at the same index
                if initial_len < 2 || start {
                    add_cmd(
                        cmd_iterator,
                        Command::Read {
                            ack_value: Ack::Ack,
                            length: initial_len as u8,
                        },
                    )?;
                } else if !will_continue {
                    add_cmd(
                        cmd_iterator,
                        Command::Read {
                            ack_value: Ack::Ack,
                            length: (initial_len as u8) - 1,
                        },
                    )?;
                    add_cmd(
                        cmd_iterator,
                        Command::Read {
                            ack_value: Ack::Ack,
                            length: 1,
                        },
                    )?;
                } else {
                    add_cmd(
                        cmd_iterator,
                        Command::Read {
                            ack_value: Ack::Ack,
                            length: (initial_len as u8) - 2,
                        },
                    )?;
                    add_cmd(
                        cmd_iterator,
                        Command::Read {
                            ack_value: Ack::Ack,
                            length: 1,
                        },
                    )?;
                    add_cmd(
                        cmd_iterator,
                        Command::Read {
                            ack_value: Ack::Ack,
                            length: 1,
                        },
                    )?;
                }
            } else {
                add_cmd(
                    cmd_iterator,
                    Command::Read {
                        ack_value: Ack::Ack,
                        length: initial_len as u8,
                    },
                )?;
            }
        }

        if !will_continue {
            // this is the last read so we need to nack the last byte
            // READ w/o ACK
            add_cmd(
                cmd_iterator,
                Command::Read {
                    ack_value: Ack::Nack,
                    length: 1,
                },
            )?;
        }

        self.update_registers();

        if start {
            // Load address and R/W bit into FIFO
            match addr {
                I2cAddress::SevenBit(addr) => {
                    write_fifo(self.regs(), (addr << 1) | OperationType::Read as u8);
                }
            }
        }
        Ok(())
    }
Configures the I2C peripheral for a read operation.
- `addr` is the address of the slave device.
- `buffer` is the buffer to store the read data.
- `start` indicates whether the operation should start by a START
condition and sending the address.
- `will_continue` indicates whether there is another read operation
following this one and we should not nack the last byte.
- `cmd_iterator` is an iterator over the command registers.
esp-hal/src/i2c/master/mod.rs