Change TWIM methods to copy slice if required and add non-copying variants
This commit is contained in:
		
							parent
							
								
									2c402ecf16
								
							
						
					
					
						commit
						3f2d9cfe0a
					
				| @ -287,7 +287,12 @@ impl<'d, T: Instance> Twim<'d, T> { | |||||||
|         }) |         }) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fn setup_write(&mut self, address: u8, buffer: &[u8], inten: bool) -> Result<(), Error> { |     fn setup_write_from_ram( | ||||||
|  |         &mut self, | ||||||
|  |         address: u8, | ||||||
|  |         buffer: &[u8], | ||||||
|  |         inten: bool, | ||||||
|  |     ) -> Result<(), Error> { | ||||||
|         let r = T::regs(); |         let r = T::regs(); | ||||||
| 
 | 
 | ||||||
|         compiler_fence(SeqCst); |         compiler_fence(SeqCst); | ||||||
| @ -342,7 +347,7 @@ impl<'d, T: Instance> Twim<'d, T> { | |||||||
|         Ok(()) |         Ok(()) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fn setup_write_read( |     fn setup_write_read_from_ram( | ||||||
|         &mut self, |         &mut self, | ||||||
|         address: u8, |         address: u8, | ||||||
|         wr_buffer: &[u8], |         wr_buffer: &[u8], | ||||||
| @ -382,6 +387,43 @@ impl<'d, T: Instance> Twim<'d, T> { | |||||||
|         Ok(()) |         Ok(()) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     fn setup_write_read( | ||||||
|  |         &mut self, | ||||||
|  |         address: u8, | ||||||
|  |         wr_buffer: &[u8], | ||||||
|  |         rd_buffer: &mut [u8], | ||||||
|  |         inten: bool, | ||||||
|  |     ) -> Result<(), Error> { | ||||||
|  |         match self.setup_write_read_from_ram(address, wr_buffer, rd_buffer, inten) { | ||||||
|  |             Ok(_) => Ok(()), | ||||||
|  |             Err(Error::DMABufferNotInDataMemory) => { | ||||||
|  |                 trace!("Copying TWIM tx buffer into RAM for DMA"); | ||||||
|  |                 let mut tx_buf = [0u8; FORCE_COPY_BUFFER_SIZE]; | ||||||
|  |                 tx_buf[..wr_buffer.len()].copy_from_slice(wr_buffer); | ||||||
|  |                 self.setup_write_read_from_ram( | ||||||
|  |                     address, | ||||||
|  |                     &tx_buf[..wr_buffer.len()], | ||||||
|  |                     rd_buffer, | ||||||
|  |                     inten, | ||||||
|  |                 ) | ||||||
|  |             } | ||||||
|  |             Err(error) => Err(error), | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn setup_write(&mut self, address: u8, wr_buffer: &[u8], inten: bool) -> Result<(), Error> { | ||||||
|  |         match self.setup_write_from_ram(address, wr_buffer, inten) { | ||||||
|  |             Ok(_) => Ok(()), | ||||||
|  |             Err(Error::DMABufferNotInDataMemory) => { | ||||||
|  |                 trace!("Copying TWIM tx buffer into RAM for DMA"); | ||||||
|  |                 let mut tx_buf = [0u8; FORCE_COPY_BUFFER_SIZE]; | ||||||
|  |                 tx_buf[..wr_buffer.len()].copy_from_slice(wr_buffer); | ||||||
|  |                 self.setup_write_from_ram(address, &tx_buf[..wr_buffer.len()], inten) | ||||||
|  |             } | ||||||
|  |             Err(error) => Err(error), | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     /// Write to an I2C slave.
 |     /// Write to an I2C slave.
 | ||||||
|     ///
 |     ///
 | ||||||
|     /// The buffer must have a length of at most 255 bytes on the nRF52832
 |     /// The buffer must have a length of at most 255 bytes on the nRF52832
 | ||||||
| @ -395,6 +437,15 @@ impl<'d, T: Instance> Twim<'d, T> { | |||||||
|         Ok(()) |         Ok(()) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     pub fn blocking_write_from_ram(&mut self, address: u8, buffer: &[u8]) -> Result<(), Error> { | ||||||
|  |         self.setup_write_from_ram(address, buffer, false)?; | ||||||
|  |         self.blocking_wait(); | ||||||
|  |         compiler_fence(SeqCst); | ||||||
|  |         self.check_errorsrc()?; | ||||||
|  |         self.check_tx(buffer.len())?; | ||||||
|  |         Ok(()) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     /// Read from an I2C slave.
 |     /// Read from an I2C slave.
 | ||||||
|     ///
 |     ///
 | ||||||
|     /// The buffer must have a length of at most 255 bytes on the nRF52832
 |     /// The buffer must have a length of at most 255 bytes on the nRF52832
 | ||||||
| @ -428,45 +479,19 @@ impl<'d, T: Instance> Twim<'d, T> { | |||||||
|         Ok(()) |         Ok(()) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /// Copy data into RAM and write to an I2C slave.
 |     pub fn blocking_write_read_from_ram( | ||||||
|     ///
 |  | ||||||
|     /// The write buffer must have a length of at most 255 bytes on the nRF52832
 |  | ||||||
|     /// and at most 1024 bytes on the nRF52840.
 |  | ||||||
|     pub fn blocking_copy_write(&mut self, address: u8, wr_buffer: &[u8]) -> Result<(), Error> { |  | ||||||
|         if wr_buffer.len() > FORCE_COPY_BUFFER_SIZE { |  | ||||||
|             return Err(Error::TxBufferTooLong); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         // Copy to RAM
 |  | ||||||
|         let wr_ram_buffer = &mut [0; FORCE_COPY_BUFFER_SIZE][..wr_buffer.len()]; |  | ||||||
|         wr_ram_buffer.copy_from_slice(wr_buffer); |  | ||||||
| 
 |  | ||||||
|         self.blocking_write(address, wr_ram_buffer) |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /// Copy data into RAM and write to an I2C slave, then read data from the slave without
 |  | ||||||
|     /// triggering a stop condition between the two.
 |  | ||||||
|     ///
 |  | ||||||
|     /// The write buffer must have a length of at most 255 bytes on the nRF52832
 |  | ||||||
|     /// and at most 1024 bytes on the nRF52840.
 |  | ||||||
|     ///
 |  | ||||||
|     /// The read buffer must have a length of at most 255 bytes on the nRF52832
 |  | ||||||
|     /// and at most 65535 bytes on the nRF52840.
 |  | ||||||
|     pub fn blocking_copy_write_read( |  | ||||||
|         &mut self, |         &mut self, | ||||||
|         address: u8, |         address: u8, | ||||||
|         wr_buffer: &[u8], |         wr_buffer: &[u8], | ||||||
|         rd_buffer: &mut [u8], |         rd_buffer: &mut [u8], | ||||||
|     ) -> Result<(), Error> { |     ) -> Result<(), Error> { | ||||||
|         if wr_buffer.len() > FORCE_COPY_BUFFER_SIZE { |         self.setup_write_read_from_ram(address, wr_buffer, rd_buffer, false)?; | ||||||
|             return Err(Error::TxBufferTooLong); |         self.blocking_wait(); | ||||||
|         } |         compiler_fence(SeqCst); | ||||||
| 
 |         self.check_errorsrc()?; | ||||||
|         // Copy to RAM
 |         self.check_tx(wr_buffer.len())?; | ||||||
|         let wr_ram_buffer = &mut [0; FORCE_COPY_BUFFER_SIZE][..wr_buffer.len()]; |         self.check_rx(rd_buffer.len())?; | ||||||
|         wr_ram_buffer.copy_from_slice(wr_buffer); |         Ok(()) | ||||||
| 
 |  | ||||||
|         self.blocking_write_read(address, wr_ram_buffer, rd_buffer) |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     pub async fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Error> { |     pub async fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Error> { | ||||||
| @ -487,6 +512,15 @@ impl<'d, T: Instance> Twim<'d, T> { | |||||||
|         Ok(()) |         Ok(()) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     pub async fn write_from_ram(&mut self, address: u8, buffer: &[u8]) -> Result<(), Error> { | ||||||
|  |         self.setup_write_from_ram(address, buffer, true)?; | ||||||
|  |         self.async_wait().await; | ||||||
|  |         compiler_fence(SeqCst); | ||||||
|  |         self.check_errorsrc()?; | ||||||
|  |         self.check_tx(buffer.len())?; | ||||||
|  |         Ok(()) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     pub async fn write_read( |     pub async fn write_read( | ||||||
|         &mut self, |         &mut self, | ||||||
|         address: u8, |         address: u8, | ||||||
| @ -501,6 +535,21 @@ impl<'d, T: Instance> Twim<'d, T> { | |||||||
|         self.check_rx(rd_buffer.len())?; |         self.check_rx(rd_buffer.len())?; | ||||||
|         Ok(()) |         Ok(()) | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     pub async fn write_read_from_ram( | ||||||
|  |         &mut self, | ||||||
|  |         address: u8, | ||||||
|  |         wr_buffer: &[u8], | ||||||
|  |         rd_buffer: &mut [u8], | ||||||
|  |     ) -> Result<(), Error> { | ||||||
|  |         self.setup_write_read_from_ram(address, wr_buffer, rd_buffer, true)?; | ||||||
|  |         self.async_wait().await; | ||||||
|  |         compiler_fence(SeqCst); | ||||||
|  |         self.check_errorsrc()?; | ||||||
|  |         self.check_tx(wr_buffer.len())?; | ||||||
|  |         self.check_rx(rd_buffer.len())?; | ||||||
|  |         Ok(()) | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl<'a, T: Instance> Drop for Twim<'a, T> { | impl<'a, T: Instance> Drop for Twim<'a, T> { | ||||||
| @ -601,11 +650,7 @@ mod eh02 { | |||||||
|             bytes: &'w [u8], |             bytes: &'w [u8], | ||||||
|             buffer: &'w mut [u8], |             buffer: &'w mut [u8], | ||||||
|         ) -> Result<(), Error> { |         ) -> Result<(), Error> { | ||||||
|             if slice_in_ram(bytes) { |             self.blocking_write_read(addr, bytes, buffer) | ||||||
|                 self.blocking_write_read(addr, bytes, buffer) |  | ||||||
|             } else { |  | ||||||
|                 self.blocking_copy_write_read(addr, bytes, buffer) |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user