Merge pull request #1637 from ShakenCodes/main
Ensure I2C master_stop() called after error
This commit is contained in:
		@@ -382,13 +382,18 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
 | 
				
			|||||||
        // I2C start
 | 
					        // I2C start
 | 
				
			||||||
        //
 | 
					        //
 | 
				
			||||||
        // ST SAD+W
 | 
					        // ST SAD+W
 | 
				
			||||||
        Self::master_write(
 | 
					        if let Err(err) = Self::master_write(
 | 
				
			||||||
            address,
 | 
					            address,
 | 
				
			||||||
            write.len().min(255),
 | 
					            write.len().min(255),
 | 
				
			||||||
            Stop::Software,
 | 
					            Stop::Software,
 | 
				
			||||||
            last_chunk_idx != 0,
 | 
					            last_chunk_idx != 0,
 | 
				
			||||||
            &check_timeout,
 | 
					            &check_timeout,
 | 
				
			||||||
        )?;
 | 
					        ) {
 | 
				
			||||||
 | 
					            if send_stop {
 | 
				
			||||||
 | 
					                self.master_stop();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return Err(err);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for (number, chunk) in write.chunks(255).enumerate() {
 | 
					        for (number, chunk) in write.chunks(255).enumerate() {
 | 
				
			||||||
            if number != 0 {
 | 
					            if number != 0 {
 | 
				
			||||||
@@ -399,18 +404,22 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
 | 
				
			|||||||
                // Wait until we are allowed to send data
 | 
					                // Wait until we are allowed to send data
 | 
				
			||||||
                // (START has been ACKed or last byte when
 | 
					                // (START has been ACKed or last byte when
 | 
				
			||||||
                // through)
 | 
					                // through)
 | 
				
			||||||
                self.wait_txe(&check_timeout)?;
 | 
					                if let Err(err) = self.wait_txe(&check_timeout) {
 | 
				
			||||||
 | 
					                    if send_stop {
 | 
				
			||||||
 | 
					                        self.master_stop();
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    return Err(err);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                T::regs().txdr().write(|w| w.set_txdata(*byte));
 | 
					                T::regs().txdr().write(|w| w.set_txdata(*byte));
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        // Wait until the write finishes
 | 
					        // Wait until the write finishes
 | 
				
			||||||
        self.wait_tc(&check_timeout)?;
 | 
					        let result = self.wait_tc(&check_timeout);
 | 
				
			||||||
 | 
					 | 
				
			||||||
        if send_stop {
 | 
					        if send_stop {
 | 
				
			||||||
            self.master_stop();
 | 
					            self.master_stop();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        Ok(())
 | 
					        result
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async fn write_dma_internal(
 | 
					    async fn write_dma_internal(
 | 
				
			||||||
@@ -707,13 +716,16 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
 | 
				
			|||||||
        let first_length = write[0].len();
 | 
					        let first_length = write[0].len();
 | 
				
			||||||
        let last_slice_index = write.len() - 1;
 | 
					        let last_slice_index = write.len() - 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Self::master_write(
 | 
					        if let Err(err) = Self::master_write(
 | 
				
			||||||
            address,
 | 
					            address,
 | 
				
			||||||
            first_length.min(255),
 | 
					            first_length.min(255),
 | 
				
			||||||
            Stop::Software,
 | 
					            Stop::Software,
 | 
				
			||||||
            (first_length > 255) || (last_slice_index != 0),
 | 
					            (first_length > 255) || (last_slice_index != 0),
 | 
				
			||||||
            &check_timeout,
 | 
					            &check_timeout,
 | 
				
			||||||
        )?;
 | 
					        ) {
 | 
				
			||||||
 | 
					            self.master_stop();
 | 
				
			||||||
 | 
					            return Err(err);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for (idx, slice) in write.iter().enumerate() {
 | 
					        for (idx, slice) in write.iter().enumerate() {
 | 
				
			||||||
            let slice_len = slice.len();
 | 
					            let slice_len = slice.len();
 | 
				
			||||||
@@ -726,27 +738,36 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
 | 
				
			|||||||
            let last_chunk_idx = total_chunks.saturating_sub(1);
 | 
					            let last_chunk_idx = total_chunks.saturating_sub(1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if idx != 0 {
 | 
					            if idx != 0 {
 | 
				
			||||||
                Self::master_continue(
 | 
					                if let Err(err) = Self::master_continue(
 | 
				
			||||||
                    slice_len.min(255),
 | 
					                    slice_len.min(255),
 | 
				
			||||||
                    (idx != last_slice_index) || (slice_len > 255),
 | 
					                    (idx != last_slice_index) || (slice_len > 255),
 | 
				
			||||||
                    &check_timeout,
 | 
					                    &check_timeout,
 | 
				
			||||||
                )?;
 | 
					                ) {
 | 
				
			||||||
 | 
					                    self.master_stop();
 | 
				
			||||||
 | 
					                    return Err(err);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            for (number, chunk) in slice.chunks(255).enumerate() {
 | 
					            for (number, chunk) in slice.chunks(255).enumerate() {
 | 
				
			||||||
                if number != 0 {
 | 
					                if number != 0 {
 | 
				
			||||||
                    Self::master_continue(
 | 
					                    if let Err(err) = Self::master_continue(
 | 
				
			||||||
                        chunk.len(),
 | 
					                        chunk.len(),
 | 
				
			||||||
                        (number != last_chunk_idx) || (idx != last_slice_index),
 | 
					                        (number != last_chunk_idx) || (idx != last_slice_index),
 | 
				
			||||||
                        &check_timeout,
 | 
					                        &check_timeout,
 | 
				
			||||||
                    )?;
 | 
					                    ) {
 | 
				
			||||||
 | 
					                        self.master_stop();
 | 
				
			||||||
 | 
					                        return Err(err);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                for byte in chunk {
 | 
					                for byte in chunk {
 | 
				
			||||||
                    // Wait until we are allowed to send data
 | 
					                    // Wait until we are allowed to send data
 | 
				
			||||||
                    // (START has been ACKed or last byte when
 | 
					                    // (START has been ACKed or last byte when
 | 
				
			||||||
                    // through)
 | 
					                    // through)
 | 
				
			||||||
                    self.wait_txe(&check_timeout)?;
 | 
					                    if let Err(err) = self.wait_txe(&check_timeout) {
 | 
				
			||||||
 | 
					                        self.master_stop();
 | 
				
			||||||
 | 
					                        return Err(err);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    // Put byte on the wire
 | 
					                    // Put byte on the wire
 | 
				
			||||||
                    //self.i2c.txdr.write(|w| w.txdata().bits(*byte));
 | 
					                    //self.i2c.txdr.write(|w| w.txdata().bits(*byte));
 | 
				
			||||||
@@ -755,10 +776,9 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        // Wait until the write finishes
 | 
					        // Wait until the write finishes
 | 
				
			||||||
        self.wait_tc(&check_timeout)?;
 | 
					        let result = self.wait_tc(&check_timeout);
 | 
				
			||||||
        self.master_stop();
 | 
					        self.master_stop();
 | 
				
			||||||
 | 
					        result
 | 
				
			||||||
        Ok(())
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn blocking_write_vectored(&mut self, address: u8, write: &[&[u8]]) -> Result<(), Error> {
 | 
					    pub fn blocking_write_vectored(&mut self, address: u8, write: &[&[u8]]) -> Result<(), Error> {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user