eeprom support
This commit is contained in:
		
							parent
							
								
									d335e30901
								
							
						
					
					
						commit
						7be84f137c
					
				| @ -11,6 +11,9 @@ use crate::Peri; | |||||||
| use crate::_generated::FLASH_BASE; | use crate::_generated::FLASH_BASE; | ||||||
| use crate::peripherals::FLASH; | use crate::peripherals::FLASH; | ||||||
| 
 | 
 | ||||||
|  | #[cfg(eeprom)] | ||||||
|  | use crate::_generated::{EEPROM_BASE, EEPROM_SIZE}; | ||||||
|  | 
 | ||||||
| /// Internal flash memory driver.
 | /// Internal flash memory driver.
 | ||||||
| pub struct Flash<'d, MODE = Async> { | pub struct Flash<'d, MODE = Async> { | ||||||
|     pub(crate) inner: Peri<'d, FLASH>, |     pub(crate) inner: Peri<'d, FLASH>, | ||||||
| @ -72,6 +75,100 @@ impl<'d, MODE> Flash<'d, MODE> { | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | #[cfg(eeprom)] | ||||||
|  | impl<'d> Flash<'d, Blocking> { | ||||||
|  |     fn eeprom_base(&self) -> u32 { | ||||||
|  |         EEPROM_BASE as u32 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn eeprom_size(&self) -> u32 { | ||||||
|  |         EEPROM_SIZE as u32 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn check_eeprom_offset(&self, offset: u32, size: u32) -> Result<(), Error> { | ||||||
|  |         if offset + size > self.eeprom_size() { | ||||||
|  |             Err(Error::Size) | ||||||
|  |         } else { | ||||||
|  |             Ok(()) | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /// Read a byte (u8) from EEPROM at the given offset.
 | ||||||
|  |     pub fn eeprom_read_u8(&self, offset: u32) -> Result<u8, Error> { | ||||||
|  |         self.check_eeprom_offset(offset, 1)?; | ||||||
|  |         let addr = self.eeprom_base() + offset; | ||||||
|  |         Ok(unsafe { core::ptr::read_volatile(addr as *const u8) }) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /// Read a half-word (u16) from EEPROM at the given offset.
 | ||||||
|  |     pub fn eeprom_read_u16(&self, offset: u32) -> Result<u16, Error> { | ||||||
|  |         if offset % 2 != 0 { | ||||||
|  |             return Err(Error::Unaligned); | ||||||
|  |         } | ||||||
|  |         self.check_eeprom_offset(offset, 2)?; | ||||||
|  |         let addr = self.eeprom_base() + offset; | ||||||
|  |         Ok(unsafe { core::ptr::read_volatile(addr as *const u16) }) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /// Read a word (u32) from EEPROM at the given offset.
 | ||||||
|  |     pub fn eeprom_read_u32(&self, offset: u32) -> Result<u32, Error> { | ||||||
|  |         if offset % 4 != 0 { | ||||||
|  |             return Err(Error::Unaligned); | ||||||
|  |         } | ||||||
|  |         self.check_eeprom_offset(offset, 4)?; | ||||||
|  |         let addr = self.eeprom_base() + offset; | ||||||
|  |         Ok(unsafe { core::ptr::read_volatile(addr as *const u32) }) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /// Write a byte (u8) to EEPROM at the given offset.
 | ||||||
|  |     pub fn eeprom_write_u8(&mut self, offset: u32, value: u8) -> Result<(), Error> { | ||||||
|  |         self.check_eeprom_offset(offset, 1)?; | ||||||
|  |         let addr = self.eeprom_base() + offset; | ||||||
|  |         unsafe { | ||||||
|  |             family::unlock(); | ||||||
|  |             core::ptr::write_volatile(addr as *mut u8, value); | ||||||
|  |             family::wait_ready_blocking()?; | ||||||
|  |             family::clear_all_err(); | ||||||
|  |             family::lock(); | ||||||
|  |         } | ||||||
|  |         Ok(()) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /// Write a half-word (u16) to EEPROM at the given offset.
 | ||||||
|  |     pub fn eeprom_write_u16(&mut self, offset: u32, value: u16) -> Result<(), Error> { | ||||||
|  |         if offset % 2 != 0 { | ||||||
|  |             return Err(Error::Unaligned); | ||||||
|  |         } | ||||||
|  |         self.check_eeprom_offset(offset, 2)?; | ||||||
|  |         let addr = self.eeprom_base() + offset; | ||||||
|  |         unsafe { | ||||||
|  |             family::unlock(); | ||||||
|  |             core::ptr::write_volatile(addr as *mut u16, value); | ||||||
|  |             family::wait_ready_blocking()?; | ||||||
|  |             family::clear_all_err(); | ||||||
|  |             family::lock(); | ||||||
|  |         } | ||||||
|  |         Ok(()) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /// Write a word (u32) to EEPROM at the given offset.
 | ||||||
|  |     pub fn eeprom_write_u32(&mut self, offset: u32, value: u32) -> Result<(), Error> { | ||||||
|  |         if offset % 4 != 0 { | ||||||
|  |             return Err(Error::Unaligned); | ||||||
|  |         } | ||||||
|  |         self.check_eeprom_offset(offset, 4)?; | ||||||
|  |         let addr = self.eeprom_base() + offset; | ||||||
|  |         unsafe { | ||||||
|  |             family::unlock(); | ||||||
|  |             core::ptr::write_volatile(addr as *mut u32, value); | ||||||
|  |             family::wait_ready_blocking()?; | ||||||
|  |             family::clear_all_err(); | ||||||
|  |             family::lock(); | ||||||
|  |         } | ||||||
|  |         Ok(()) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| pub(super) fn blocking_read(base: u32, size: u32, offset: u32, bytes: &mut [u8]) -> Result<(), Error> { | pub(super) fn blocking_read(base: u32, size: u32, offset: u32, bytes: &mut [u8]) -> Result<(), Error> { | ||||||
|     if offset + bytes.len() as u32 > size { |     if offset + bytes.len() as u32 > size { | ||||||
|         return Err(Error::Size); |         return Err(Error::Size); | ||||||
|  | |||||||
| @ -162,7 +162,7 @@ pub(crate) unsafe fn clear_all_err() { | |||||||
|     pac::FLASH.nssr().modify(|_| {}); |     pac::FLASH.nssr().modify(|_| {}); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| unsafe fn wait_ready_blocking() -> Result<(), Error> { | pub(crate) unsafe fn wait_ready_blocking() -> Result<(), Error> { | ||||||
|     loop { |     loop { | ||||||
|         #[cfg(not(flash_l5))] |         #[cfg(not(flash_l5))] | ||||||
|         { |         { | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user