1use crate::chip_specific::flash::FlashChipSpecific as FlashChipSpecificTrait;
37use crate::chip_specific::flash::FlashLatency16;
38use crate::chip_specific::flash::RegisterToFlashLatency;
39
40use kernel::ErrorCode;
41use kernel::debug;
42use kernel::utilities::StaticRef;
43use kernel::utilities::registers::interfaces::{ReadWriteable, Readable};
44use kernel::utilities::registers::{ReadWrite, WriteOnly, register_bitfields};
45
46use core::marker::PhantomData;
47
48#[repr(C)]
49struct FlashRegisters {
50 acr: ReadWrite<u32, ACR::Register>,
52 keyr: WriteOnly<u32>,
54 optkeyr: WriteOnly<u32>,
56 sr: ReadWrite<u32, SR::Register>,
58 cr: ReadWrite<u32, CR::Register>,
60 optcr: ReadWrite<u32, OPTCR::Register>,
62 #[cfg(feature = "stm32f429")]
64 optcr1: ReadWrite<u32, OPTCR1::Register>,
65}
66
67register_bitfields![u32,
68 ACR [
69 LATENCY OFFSET(0) NUMBITS(4) [],
72 PRFTEN OFFSET(8) NUMBITS(1) [],
74 ICEN OFFSET(9) NUMBITS(1) [],
76 DCEN OFFSET(10) NUMBITS(1) [],
78 ICRST OFFSET(11) NUMBITS(1) [],
80 DCRST OFFSET(12) NUMBITS(1) []
82 ],
83 KEYR [
84 KEY OFFSET(0) NUMBITS(32) []
86 ],
87 OPTKEYR [
88 OPTKEY OFFSET(0) NUMBITS(32) []
90 ],
91 SR [
92 EOP OFFSET(0) NUMBITS(1) [],
94 OPERR OFFSET(1) NUMBITS(1) [],
96 WRPERR OFFSET(4) NUMBITS(1) [],
98 PGAERR OFFSET(5) NUMBITS(1) [],
100 PGPERR OFFSET(6) NUMBITS(1) [],
102 PGSERR OFFSET(7) NUMBITS(1) [],
104 RDERR OFFSET(8) NUMBITS(1) [],
107 BSY OFFSET(16) NUMBITS(1) []
109 ],
110 CR [
111 PG OFFSET(0) NUMBITS(1) [],
113 SER OFFSET(1) NUMBITS(1) [],
115 MER OFFSET(2) NUMBITS(1) [],
117 SNB OFFSET(3) NUMBITS(5) [],
120 PSIZE OFFSET(8) NUMBITS(2) [],
122 MER1 OFFSET(15) NUMBITS(1) [],
125 STRT OFFSET(16) NUMBITS(1) [],
127 EOPIE OFFSET(24) NUMBITS(1) [],
129 ERRIE OFFSET(25) NUMBITS(1) [],
131 LOCK OFFSET(31) NUMBITS(1) []
133 ],
134 OPTCR [
135 OPTLOCK OFFSET(0) NUMBITS(1) [],
137 OPTSTRT OFFSET(1) NUMBITS(1) [],
139 BOR_LEV OFFSET(2) NUMBITS(2) [],
141 WDG_SW OFFSET(5) NUMBITS(1) [],
143 nRST_STOP OFFSET(6) NUMBITS(1) [],
145 nRST_STDBY OFFSET(7) NUMBITS(1) [],
147 RDP OFFSET(8) NUMBITS(8) [],
149 nWRP OFFSET(16) NUMBITS(12) []
152 ],
153 OPTCR1 [
154 nWRP OFFSET(16) NUMBITS(12) []
157 ]
158];
159
160const FLASH_BASE: StaticRef<FlashRegisters> =
162 unsafe { StaticRef::new(0x40023C00 as *const FlashRegisters) };
163
164pub struct Flash<FlashChipSpecific> {
166 registers: StaticRef<FlashRegisters>,
167 _marker: PhantomData<FlashChipSpecific>,
168}
169
170impl<FlashChipSpecific: FlashChipSpecificTrait> Flash<FlashChipSpecific> {
171 pub(crate) fn new() -> Self {
173 Self {
174 registers: FLASH_BASE,
175 _marker: PhantomData,
176 }
177 }
178
179 fn read_latency_from_register(&self) -> u32 {
180 self.registers.acr.read(ACR::LATENCY)
181 }
182
183 pub(crate) fn set_latency(&self, sys_clock_frequency: usize) -> Result<(), ErrorCode> {
189 let flash_latency =
190 FlashChipSpecific::get_number_wait_cycles_based_on_frequency(sys_clock_frequency);
191 self.registers
192 .acr
193 .modify(ACR::LATENCY.val(flash_latency.into()));
194
195 for _ in 0..16 {
199 if self.get_latency() == flash_latency {
200 return Ok(());
201 }
202 }
203
204 Err(ErrorCode::BUSY)
209 }
210
211 pub(crate) fn get_latency(&self) -> FlashChipSpecific::FlashLatency {
212 FlashChipSpecific::FlashLatency::convert_register_to_enum(self.read_latency_from_register())
213 }
214}
215
216pub mod tests {
272 use super::{Flash, FlashChipSpecificTrait, FlashLatency16, debug};
273 use crate::clocks::hsi::HSI_FREQUENCY_MHZ;
274
275 const AHB_ETHERNET_MINIMUM_FREQUENCY_MHZ: usize = 25;
276 const APB1_MAX_FREQUENCY_MHZ_1: usize = 42;
278 const APB1_MAX_FREQUENCY_MHZ_2: usize = 45;
279 const APB1_MAX_FREQUENCY_MHZ_3: usize = 50;
280 const APB2_MAX_FREQUENCY_MHZ_1: usize = 84;
282 #[cfg(not(feature = "stm32f401"))] const APB2_MAX_FREQUENCY_MHZ_2: usize = 90;
284 #[cfg(not(feature = "stm32f401"))] const APB2_MAX_FREQUENCY_MHZ_3: usize = 100;
286 #[cfg(not(any(feature = "stm32f401", feature = "stm32f412",)))] const SYS_MAX_FREQUENCY_NO_OVERDRIVE_MHZ: usize = 168;
290 #[cfg(not(any(feature = "stm32f401", feature = "stm32f412",)))] const SYS_MAX_FREQUENCY_OVERDRIVE_MHZ: usize = 180;
292 #[cfg(not(feature = "stm32f401"))] const PLL_FREQUENCY_MHZ: usize = 96;
295
296 pub fn test_get_number_wait_cycles_based_on_frequency<
306 FlashChipSpecific: FlashChipSpecificTrait<FlashLatency = FlashLatency16>,
307 >() {
308 debug!("");
309 debug!("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
310 debug!("Testing number of wait cycles based on the system frequency...");
311
312 assert_eq!(
313 FlashChipSpecific::FlashLatency::Latency0,
314 FlashChipSpecific::get_number_wait_cycles_based_on_frequency(HSI_FREQUENCY_MHZ)
315 );
316
317 assert_eq!(
318 FlashChipSpecific::FlashLatency::Latency0,
319 FlashChipSpecific::get_number_wait_cycles_based_on_frequency(
320 AHB_ETHERNET_MINIMUM_FREQUENCY_MHZ
321 )
322 );
323
324 assert_eq!(
325 FlashChipSpecific::FlashLatency::Latency1,
326 FlashChipSpecific::get_number_wait_cycles_based_on_frequency(APB1_MAX_FREQUENCY_MHZ_1)
327 );
328 assert_eq!(
329 FlashChipSpecific::FlashLatency::Latency1,
330 FlashChipSpecific::get_number_wait_cycles_based_on_frequency(APB1_MAX_FREQUENCY_MHZ_2)
331 );
332 assert_eq!(
333 FlashChipSpecific::FlashLatency::Latency1,
334 FlashChipSpecific::get_number_wait_cycles_based_on_frequency(APB1_MAX_FREQUENCY_MHZ_3)
335 );
336
337 assert_eq!(
338 FlashChipSpecific::FlashLatency::Latency2,
339 FlashChipSpecific::get_number_wait_cycles_based_on_frequency(APB2_MAX_FREQUENCY_MHZ_1)
340 );
341
342 #[cfg(not(feature = "stm32f401"))]
344 {
345 assert_eq!(
346 FlashChipSpecific::FlashLatency::Latency2,
347 FlashChipSpecific::get_number_wait_cycles_based_on_frequency(
348 APB2_MAX_FREQUENCY_MHZ_2
349 )
350 );
351
352 assert_eq!(
353 FlashChipSpecific::FlashLatency::Latency3,
354 FlashChipSpecific::get_number_wait_cycles_based_on_frequency(
355 APB2_MAX_FREQUENCY_MHZ_3
356 )
357 );
358
359 assert_eq!(
360 FlashChipSpecific::FlashLatency::Latency3,
361 FlashChipSpecific::get_number_wait_cycles_based_on_frequency(PLL_FREQUENCY_MHZ)
362 );
363 }
364
365 #[cfg(not(any(feature = "stm32f401", feature = "stm32f412",)))]
366 {
368 assert_eq!(
369 FlashChipSpecific::FlashLatency::Latency5,
370 FlashChipSpecific::get_number_wait_cycles_based_on_frequency(
371 SYS_MAX_FREQUENCY_NO_OVERDRIVE_MHZ
372 )
373 );
374
375 assert_eq!(
376 FlashChipSpecific::FlashLatency::Latency5,
377 FlashChipSpecific::get_number_wait_cycles_based_on_frequency(
378 SYS_MAX_FREQUENCY_OVERDRIVE_MHZ
379 )
380 );
381 }
382
383 debug!(
384 "Finished testing number of wait cycles based on the system clock frequency. Everything is alright!"
385 );
386 debug!("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
387 debug!("");
388 }
389
390 pub fn test_set_flash_latency<
401 FlashChipSpecific: FlashChipSpecificTrait<FlashLatency = FlashLatency16>,
402 >(
403 flash: &Flash<FlashChipSpecific>,
404 ) {
405 debug!("");
406 debug!("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
407 debug!("Testing setting flash latency...");
408
409 assert_eq!(Ok(()), flash.set_latency(HSI_FREQUENCY_MHZ));
410 assert_eq!(
411 FlashChipSpecific::FlashLatency::Latency0,
412 flash.get_latency()
413 );
414
415 assert_eq!(
416 Ok(()),
417 flash.set_latency(AHB_ETHERNET_MINIMUM_FREQUENCY_MHZ)
418 );
419 assert_eq!(
420 FlashChipSpecific::FlashLatency::Latency0,
421 flash.get_latency()
422 );
423
424 assert_eq!(Ok(()), flash.set_latency(APB1_MAX_FREQUENCY_MHZ_1));
425 assert_eq!(
426 FlashChipSpecific::FlashLatency::Latency1,
427 flash.get_latency()
428 );
429
430 assert_eq!(Ok(()), flash.set_latency(APB1_MAX_FREQUENCY_MHZ_2));
431 assert_eq!(
432 FlashChipSpecific::FlashLatency::Latency1,
433 flash.get_latency()
434 );
435
436 assert_eq!(Ok(()), flash.set_latency(APB1_MAX_FREQUENCY_MHZ_3));
437 assert_eq!(
438 FlashChipSpecific::FlashLatency::Latency1,
439 flash.get_latency()
440 );
441
442 assert_eq!(Ok(()), flash.set_latency(APB2_MAX_FREQUENCY_MHZ_1));
443
444 #[cfg(not(feature = "stm32f401"))]
446 {
447 assert_eq!(Ok(()), flash.set_latency(APB2_MAX_FREQUENCY_MHZ_2));
448
449 assert_eq!(Ok(()), flash.set_latency(APB2_MAX_FREQUENCY_MHZ_3));
450 assert_eq!(
451 FlashChipSpecific::FlashLatency::Latency3,
452 flash.get_latency()
453 );
454
455 assert_eq!(Ok(()), flash.set_latency(PLL_FREQUENCY_MHZ));
456 assert_eq!(
457 FlashChipSpecific::FlashLatency::Latency3,
458 flash.get_latency()
459 );
460 }
461
462 #[cfg(not(any(feature = "stm32f401", feature = "stm32f412",)))]
466 {
467 assert_eq!(
468 Ok(()),
469 flash.set_latency(SYS_MAX_FREQUENCY_NO_OVERDRIVE_MHZ)
470 );
471 assert_eq!(
472 FlashChipSpecific::FlashLatency::Latency5,
473 flash.get_latency()
474 );
475
476 assert_eq!(Ok(()), flash.set_latency(SYS_MAX_FREQUENCY_OVERDRIVE_MHZ));
477 assert_eq!(
478 FlashChipSpecific::FlashLatency::Latency5,
479 flash.get_latency()
480 );
481 }
482
483 assert_eq!(Ok(()), flash.set_latency(HSI_FREQUENCY_MHZ));
485 assert_eq!(
486 FlashChipSpecific::FlashLatency::Latency0,
487 flash.get_latency()
488 );
489
490 debug!("Finished testing setting flash latency. Everything is alright!");
491 debug!("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
492 debug!("");
493 }
494
495 pub fn run_all<FlashChipSpecific: FlashChipSpecificTrait<FlashLatency = FlashLatency16>>(
497 flash: &Flash<FlashChipSpecific>,
498 ) {
499 debug!("");
500 debug!("===============================================");
501 debug!("Testing setting flash latency...");
502
503 test_get_number_wait_cycles_based_on_frequency::<FlashChipSpecific>();
504 test_set_flash_latency::<FlashChipSpecific>(flash);
505
506 debug!("Finished testing flash. Everything is alright!");
507 debug!("===============================================");
508 debug!("");
509 }
510}