flash.rs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453
  1. //! Flash memory
  2. use crate::pac::{flash, FLASH};
  3. pub const FLASH_START: u32 = 0x0800_0000;
  4. pub const FLASH_END: u32 = 0x080F_FFFF;
  5. const _RDPRT_KEY: u16 = 0x00A5;
  6. const KEY1: u32 = 0x45670123;
  7. const KEY2: u32 = 0xCDEF89AB;
  8. pub const SZ_1K: u16 = 1024;
  9. pub type Result<T> = core::result::Result<T, Error>;
  10. #[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd)]
  11. pub enum Error {
  12. AddressLargerThanFlash,
  13. AddressMisaligned,
  14. LengthNotMultiple2,
  15. LengthTooLong,
  16. EraseError,
  17. ProgrammingError,
  18. WriteError,
  19. VerifyError,
  20. UnlockError,
  21. LockError,
  22. }
  23. #[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd)]
  24. pub enum SectorSize {
  25. Sz1K = 1,
  26. Sz2K = 2,
  27. Sz4K = 4,
  28. }
  29. impl SectorSize {
  30. const fn kbytes(self) -> u16 {
  31. SZ_1K * self as u16
  32. }
  33. }
  34. #[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd)]
  35. pub enum FlashSize {
  36. Sz16K = 16,
  37. Sz32K = 32,
  38. Sz64K = 64,
  39. Sz128K = 128,
  40. Sz256K = 256,
  41. Sz384K = 384,
  42. Sz512K = 512,
  43. Sz768K = 768,
  44. Sz1M = 1024,
  45. }
  46. impl FlashSize {
  47. const fn kbytes(self) -> u32 {
  48. SZ_1K as u32 * self as u32
  49. }
  50. }
  51. pub struct FlashWriter<'a> {
  52. flash: &'a mut Parts,
  53. sector_sz: SectorSize,
  54. flash_sz: FlashSize,
  55. verify: bool,
  56. }
  57. impl<'a> FlashWriter<'a> {
  58. fn unlock(&mut self) -> Result<()> {
  59. // Wait for any ongoing operations
  60. while self.flash.sr.sr().read().bsy().bit_is_set() {}
  61. // NOTE(unsafe) write Keys to the key register. This is safe because the
  62. // only side effect of these writes is to unlock the flash control
  63. // register, which is the intent of this function. Do not rearrange the
  64. // order of these writes or the control register will be permanently
  65. // locked out until reset.
  66. unsafe {
  67. self.flash.keyr.keyr().write(|w| w.key().bits(KEY1));
  68. }
  69. unsafe {
  70. self.flash.keyr.keyr().write(|w| w.key().bits(KEY2));
  71. }
  72. // Verify success
  73. match self.flash.cr.cr().read().lock().bit_is_clear() {
  74. true => Ok(()),
  75. false => Err(Error::UnlockError),
  76. }
  77. }
  78. fn lock(&mut self) -> Result<()> {
  79. //Wait for ongoing flash operations
  80. while self.flash.sr.sr().read().bsy().bit_is_set() {}
  81. // Set lock bit
  82. self.flash.cr.cr().modify(|_, w| w.lock().set_bit());
  83. // Verify success
  84. match self.flash.cr.cr().read().lock().bit_is_set() {
  85. true => Ok(()),
  86. false => Err(Error::LockError),
  87. }
  88. }
  89. fn valid_address(&self, offset: u32) -> Result<()> {
  90. if FLASH_START + offset > FLASH_END {
  91. Err(Error::AddressLargerThanFlash)
  92. } else if offset & 0x1 != 0 {
  93. Err(Error::AddressMisaligned)
  94. } else {
  95. Ok(())
  96. }
  97. }
  98. fn valid_length(&self, offset: u32, length: usize) -> Result<()> {
  99. if offset + length as u32 > self.flash_sz.kbytes() as u32 {
  100. Err(Error::LengthTooLong)
  101. } else if length & 0x1 != 0 {
  102. Err(Error::LengthNotMultiple2)
  103. } else {
  104. Ok(())
  105. }
  106. }
  107. /// Erase sector which contains `start_offset`
  108. pub fn page_erase(&mut self, start_offset: u32) -> Result<()> {
  109. self.valid_address(start_offset)?;
  110. // Unlock Flash
  111. self.unlock()?;
  112. // Set Page Erase
  113. self.flash.cr.cr().modify(|_, w| w.per().set_bit());
  114. // Write address bits
  115. // NOTE(unsafe) This sets the page address in the Address Register.
  116. // The side-effect of this write is that the page will be erased when we
  117. // set the STRT bit in the CR below. The address is validated by the
  118. // call to self.valid_address() above.
  119. unsafe {
  120. self.flash
  121. .ar
  122. .ar()
  123. .write(|w| w.far().bits(FLASH_START + start_offset));
  124. }
  125. // Start Operation
  126. self.flash.cr.cr().modify(|_, w| w.strt().set_bit());
  127. // Wait for operation to finish
  128. while self.flash.sr.sr().read().bsy().bit_is_set() {}
  129. // Check for errors
  130. let sr = self.flash.sr.sr().read();
  131. // Remove Page Erase Operation bit
  132. self.flash.cr.cr().modify(|_, w| w.per().clear_bit());
  133. // Re-lock flash
  134. self.lock()?;
  135. if sr.wrprterr().bit_is_set() {
  136. self.flash.sr.sr().modify(|_, w| w.wrprterr().clear_bit());
  137. Err(Error::EraseError)
  138. } else {
  139. if self.verify {
  140. // By subtracting 1 from the sector size and masking with
  141. // start_offset, we make 'start' point to the beginning of the
  142. // page. We do this because the entire page should have been
  143. // erased, regardless of where in the page the given
  144. // 'start_offset' was.
  145. let size = self.sector_sz.kbytes() as u32;
  146. let start = start_offset & !(size - 1);
  147. for idx in start..start + size {
  148. let write_address = (FLASH_START + idx as u32) as *const u16;
  149. let verify: u16 = unsafe { core::ptr::read_volatile(write_address) };
  150. if verify != 0xFFFF {
  151. return Err(Error::VerifyError);
  152. }
  153. }
  154. }
  155. Ok(())
  156. }
  157. }
  158. /// Erase the Flash Sectors from `FLASH_START + start_offset` to `length`
  159. pub fn erase(&mut self, start_offset: u32, length: usize) -> Result<()> {
  160. self.valid_length(start_offset, length)?;
  161. // Erase every sector touched by start_offset + length
  162. for offset in
  163. (start_offset..start_offset + length as u32).step_by(self.sector_sz.kbytes() as usize)
  164. {
  165. self.page_erase(offset)?;
  166. }
  167. // Report Success
  168. Ok(())
  169. }
  170. /// Retrieve a slice of data from `FLASH_START + offset`
  171. pub fn read(&self, offset: u32, length: usize) -> Result<&[u8]> {
  172. self.valid_address(offset)?;
  173. if offset + length as u32 > self.flash_sz.kbytes() as u32 {
  174. return Err(Error::LengthTooLong);
  175. }
  176. let address = (FLASH_START + offset) as *const _;
  177. Ok(
  178. // NOTE(unsafe) read with no side effects. The data returned will
  179. // remain valid for its lifetime because we take an immutable
  180. // reference to this FlashWriter, and any operation that would
  181. // invalidate the data returned would first require taking a mutable
  182. // reference to this FlashWriter.
  183. unsafe { core::slice::from_raw_parts(address, length) },
  184. )
  185. }
  186. /// Write data to `FLASH_START + offset`
  187. pub fn write(&mut self, offset: u32, data: &[u8]) -> Result<()> {
  188. self.valid_length(offset, data.len())?;
  189. // Unlock Flash
  190. self.unlock()?;
  191. for idx in (0..data.len()).step_by(2) {
  192. self.valid_address(offset + idx as u32)?;
  193. let write_address = (FLASH_START + offset + idx as u32) as *mut u16;
  194. // Set Page Programming to 1
  195. self.flash.cr.cr().modify(|_, w| w.pg().set_bit());
  196. while self.flash.sr.sr().read().bsy().bit_is_set() {}
  197. // Flash is written 16 bits at a time, so combine two bytes to get a
  198. // half-word
  199. let hword: u16 = (data[idx] as u16) | (data[idx + 1] as u16) << 8;
  200. // NOTE(unsafe) Write to FLASH area with no side effects
  201. unsafe { core::ptr::write_volatile(write_address, hword) };
  202. // Wait for write
  203. while self.flash.sr.sr().read().bsy().bit_is_set() {}
  204. // Set Page Programming to 0
  205. self.flash.cr.cr().modify(|_, w| w.pg().clear_bit());
  206. // Check for errors
  207. if self.flash.sr.sr().read().pgerr().bit_is_set() {
  208. self.flash.sr.sr().modify(|_, w| w.pgerr().clear_bit());
  209. self.lock()?;
  210. return Err(Error::ProgrammingError);
  211. } else if self.flash.sr.sr().read().wrprterr().bit_is_set() {
  212. self.flash.sr.sr().modify(|_, w| w.wrprterr().clear_bit());
  213. self.lock()?;
  214. return Err(Error::WriteError);
  215. } else if self.verify {
  216. // Verify written WORD
  217. // NOTE(unsafe) read with no side effects within FLASH area
  218. let verify: u16 = unsafe { core::ptr::read_volatile(write_address) };
  219. if verify != hword {
  220. self.lock()?;
  221. return Err(Error::VerifyError);
  222. }
  223. }
  224. }
  225. // Lock Flash and report success
  226. self.lock()?;
  227. Ok(())
  228. }
  229. /// Enable/disable verifying that each erase or write operation completed
  230. /// successfuly.
  231. ///
  232. /// When enabled, after each erase operation every address is read to make
  233. /// sure it contains the erase value of 0xFFFF. After each write operation,
  234. /// every address written is read and compared to the value that should have
  235. /// been written. If any address does not contain the expected value, the
  236. /// function will return Err.
  237. /// When disabled, no verification is performed, erase/write operations are
  238. /// assumed to have succeeded.
  239. pub fn change_verification(&mut self, verify: bool) {
  240. self.verify = verify;
  241. }
  242. }
  243. /// Extension trait to constrain the FLASH peripheral
  244. pub trait FlashExt {
  245. /// Constrains the FLASH peripheral to play nicely with the other abstractions
  246. fn constrain(self) -> Parts;
  247. }
  248. impl FlashExt for FLASH {
  249. fn constrain(self) -> Parts {
  250. Parts {
  251. acr: ACR { _0: () },
  252. ar: AR { _0: () },
  253. cr: CR { _0: () },
  254. keyr: KEYR { _0: () },
  255. _obr: OBR { _0: () },
  256. _optkeyr: OPTKEYR { _0: () },
  257. sr: SR { _0: () },
  258. _wrpr: WRPR { _0: () },
  259. }
  260. }
  261. }
  262. /// Constrained FLASH peripheral
  263. pub struct Parts {
  264. /// Opaque ACR register
  265. pub acr: ACR,
  266. /// Opaque AR register
  267. pub(crate) ar: AR,
  268. /// Opaque CR register
  269. pub(crate) cr: CR,
  270. /// Opaque KEYR register
  271. pub(crate) keyr: KEYR,
  272. /// Opaque OBR register
  273. pub(crate) _obr: OBR,
  274. /// Opaque OPTKEYR register
  275. pub(crate) _optkeyr: OPTKEYR,
  276. /// Opaque SR register
  277. pub(crate) sr: SR,
  278. /// Opaque WRPR register
  279. pub(crate) _wrpr: WRPR,
  280. }
  281. impl Parts {
  282. pub fn writer(&mut self, sector_sz: SectorSize, flash_sz: FlashSize) -> FlashWriter {
  283. FlashWriter {
  284. flash: self,
  285. sector_sz,
  286. flash_sz,
  287. verify: true,
  288. }
  289. }
  290. }
  291. /// Opaque ACR register
  292. pub struct ACR {
  293. _0: (),
  294. }
  295. #[allow(dead_code)]
  296. impl ACR {
  297. pub(crate) fn acr(&mut self) -> &flash::ACR {
  298. // NOTE(unsafe) this proxy grants exclusive access to this register
  299. unsafe { &(*FLASH::ptr()).acr }
  300. }
  301. }
  302. /// Opaque AR register
  303. pub struct AR {
  304. _0: (),
  305. }
  306. #[allow(dead_code)]
  307. impl AR {
  308. pub(crate) fn ar(&mut self) -> &flash::AR {
  309. // NOTE(unsafe) this proxy grants exclusive access to this register
  310. unsafe { &(*FLASH::ptr()).ar }
  311. }
  312. }
  313. /// Opaque CR register
  314. pub struct CR {
  315. _0: (),
  316. }
  317. #[allow(dead_code)]
  318. impl CR {
  319. pub(crate) fn cr(&mut self) -> &flash::CR {
  320. // NOTE(unsafe) this proxy grants exclusive access to this register
  321. unsafe { &(*FLASH::ptr()).cr }
  322. }
  323. }
  324. /// Opaque KEYR register
  325. pub struct KEYR {
  326. _0: (),
  327. }
  328. #[allow(dead_code)]
  329. impl KEYR {
  330. pub(crate) fn keyr(&mut self) -> &flash::KEYR {
  331. // NOTE(unsafe) this proxy grants exclusive access to this register
  332. unsafe { &(*FLASH::ptr()).keyr }
  333. }
  334. }
  335. /// Opaque OBR register
  336. pub struct OBR {
  337. _0: (),
  338. }
  339. #[allow(dead_code)]
  340. impl OBR {
  341. pub(crate) fn obr(&mut self) -> &flash::OBR {
  342. // NOTE(unsafe) this proxy grants exclusive access to this register
  343. unsafe { &(*FLASH::ptr()).obr }
  344. }
  345. }
  346. /// Opaque OPTKEYR register
  347. pub struct OPTKEYR {
  348. _0: (),
  349. }
  350. #[allow(dead_code)]
  351. impl OPTKEYR {
  352. pub(crate) fn optkeyr(&mut self) -> &flash::OPTKEYR {
  353. // NOTE(unsafe) this proxy grants exclusive access to this register
  354. unsafe { &(*FLASH::ptr()).optkeyr }
  355. }
  356. }
  357. /// Opaque SR register
  358. pub struct SR {
  359. _0: (),
  360. }
  361. #[allow(dead_code)]
  362. impl SR {
  363. pub(crate) fn sr(&mut self) -> &flash::SR {
  364. // NOTE(unsafe) this proxy grants exclusive access to this register
  365. unsafe { &(*FLASH::ptr()).sr }
  366. }
  367. }
  368. /// Opaque WRPR register
  369. pub struct WRPR {
  370. _0: (),
  371. }
  372. #[allow(dead_code)]
  373. impl WRPR {
  374. pub(crate) fn wrpr(&mut self) -> &flash::WRPR {
  375. // NOTE(unsafe) this proxy grants exclusive access to this register
  376. unsafe { &(*FLASH::ptr()).wrpr }
  377. }
  378. }