1use core::cell::Cell;
17use core::ops::{Index, IndexMut};
18use kernel::deferred_call::{DeferredCall, DeferredCallClient};
19use kernel::hil;
20use kernel::utilities::cells::OptionalCell;
21use kernel::utilities::cells::TakeCell;
22use kernel::utilities::cells::VolatileCell;
23use kernel::utilities::registers::interfaces::{ReadWriteable, Readable, Writeable};
24use kernel::utilities::registers::register_bitfields;
25use kernel::utilities::registers::{ReadOnly, ReadWrite, WriteOnly};
26use kernel::utilities::StaticRef;
27use kernel::ErrorCode;
28
29const FLASH_BASE: StaticRef<FlashRegisters> =
30 unsafe { StaticRef::new(0x40022000 as *const FlashRegisters) };
31
32#[repr(C)]
33struct FlashRegisters {
34 pub acr: ReadWrite<u32, AccessControl::Register>,
37 pub kr: WriteOnly<u32, Key::Register>,
40 pub okr: WriteOnly<u32, Key::Register>,
43 pub sr: ReadWrite<u32, Status::Register>,
46 pub cr: ReadWrite<u32, Control::Register>,
49 pub ar: WriteOnly<u32, Address::Register>,
52 _reserved: u32,
54 pub obr: ReadOnly<u32, OptionByte::Register>,
57 pub wrpr: ReadOnly<u32, WriteProtect::Register>,
60}
61
62register_bitfields! [u32,
63 AccessControl [
64 PRFTBS OFFSET(5) NUMBITS(1) [],
66 PRFTBE OFFSET(4) NUMBITS(1) [],
68 HLFCYA OFFSET(3) NUMBITS(1) [],
70 LATENCY OFFSET(0) NUMBITS(3) [
72 ZeroWaitState = 0,
74 OneWaitState = 1,
76 TwoWaitState = 2
78 ]
79 ],
80 Key [
81 KEYR OFFSET(0) NUMBITS(32) []
85 ],
86 Status [
87 EOP OFFSET(5) NUMBITS(1) [],
91 WRPRTERR OFFSET(4) NUMBITS(1) [],
95 PGERR OFFSET(2) NUMBITS(1) [],
101 BSY OFFSET(0) NUMBITS(1) []
106 ],
107 Control [
108 OBLLAUNCH OFFSET(13) NUMBITS(1) [],
112 EOPIE OFFSET(12) NUMBITS(1) [],
116 ERRIE OFFSET(10) NUMBITS(1) [],
120 OPTWRE OFFSET(9) NUMBITS(1) [],
124 LOCK OFFSET(7) NUMBITS(1) [],
127 STRT OFFSET(6) NUMBITS(1) [],
130 OPTER OFFSET(5) NUMBITS(1) [],
132 OPTPG OFFSET(4) NUMBITS(1) [],
134 MER OFFSET(2) NUMBITS(1) [],
136 PER OFFSET(1) NUMBITS(1) [],
138 PG OFFSET(0) NUMBITS(1) []
140 ],
141 Address [
142 FAR OFFSET(0) NUMBITS(32) []
148 ],
149 OptionByte [
150 DATA1 OFFSET(24) NUMBITS(8) [],
151 DATA0 OFFSET(16) NUMBITS(8) [],
152 SRAMPE OFFSET(14) NUMBITS(1) [
155 ENABLED = 0,
157 DISABLED = 1
159 ],
160 VDDAMONITOR OFFSET(13) NUMBITS(1) [
162 DISABLED = 0,
164 ENABLED = 1
166 ],
167 NBOOT1 OFFSET(12) NUMBITS(1) [],
170 NRSTSTDBY OFFSET(10) NUMBITS(1) [
171 RST = 0,
173 NRST = 1
175 ],
176 NRSTSTOP OFFSET(9) NUMBITS(1) [
177 RST = 0,
179 NRST = 1
181 ],
182 WDGSW OFFSET(8) NUMBITS(1) [
184 HARDWARE = 0,
186 SOFTWARE = 1
188 ],
189 RDPRT OFFSET(1) NUMBITS(2) [
191 LVL0 = 0,
193 LVL1 = 1,
195 LVL2 = 3
197 ],
198 OPTERR OFFSET(1) NUMBITS(1) []
203 ],
204 WriteProtect [
205 WRP OFFSET(0) NUMBITS(32) []
209 ]
210];
211
212const PAGE_SIZE: usize = 2048;
213
214const PAGE_START: usize = 0x08000000;
216
217const OPT_START: usize = 0x1FFFF800;
219
220const KEY1: u32 = 0x45670123;
222const KEY2: u32 = 0xCDEF89AB;
223
224pub struct StmF303Page(pub [u8; PAGE_SIZE]);
238
239impl Default for StmF303Page {
240 fn default() -> Self {
241 Self([0; PAGE_SIZE])
242 }
243}
244
245impl StmF303Page {
246 fn len(&self) -> usize {
247 self.0.len()
248 }
249}
250
251impl Index<usize> for StmF303Page {
252 type Output = u8;
253
254 fn index(&self, idx: usize) -> &u8 {
255 &self.0[idx]
256 }
257}
258
259impl IndexMut<usize> for StmF303Page {
260 fn index_mut(&mut self, idx: usize) -> &mut u8 {
261 &mut self.0[idx]
262 }
263}
264
265impl AsMut<[u8]> for StmF303Page {
266 fn as_mut(&mut self) -> &mut [u8] {
267 &mut self.0
268 }
269}
270
271#[derive(Clone, Copy, PartialEq)]
272pub enum FlashState {
273 Ready, Read, Write, Erase, WriteOption, EraseOption, }
280
281pub struct Flash {
282 registers: StaticRef<FlashRegisters>,
283 client: OptionalCell<&'static dyn hil::flash::Client<Flash>>,
284 buffer: TakeCell<'static, StmF303Page>,
285 state: Cell<FlashState>,
286 write_counter: Cell<usize>,
287 page_number: Cell<usize>,
288 deferred_call: DeferredCall,
289}
290
291impl Flash {
292 pub fn new() -> Flash {
293 Flash {
294 registers: FLASH_BASE,
295 client: OptionalCell::empty(),
296 buffer: TakeCell::empty(),
297 state: Cell::new(FlashState::Ready),
298 write_counter: Cell::new(0),
299 page_number: Cell::new(0),
300 deferred_call: DeferredCall::new(),
301 }
302 }
303
304 pub fn enable(&self) {
306 self.registers.cr.modify(Control::EOPIE::SET);
307 self.registers.cr.modify(Control::ERRIE::SET);
308 }
309
310 pub fn is_locked(&self) -> bool {
311 self.registers.cr.is_set(Control::LOCK)
312 }
313
314 pub fn unlock(&self) {
315 self.registers.kr.write(Key::KEYR.val(KEY1));
316 self.registers.kr.write(Key::KEYR.val(KEY2));
317 }
318
319 pub fn lock(&self) {
320 self.registers.cr.modify(Control::LOCK::SET);
321 }
322
323 pub fn unlock_option(&self) {
324 self.registers.okr.write(Key::KEYR.val(KEY1));
325 self.registers.okr.write(Key::KEYR.val(KEY2));
326 }
327
328 pub fn lock_option(&self) {
329 self.registers.cr.modify(Control::OPTWRE::CLEAR);
330 }
331
332 pub fn load_option(&self) {
334 self.registers.cr.modify(Control::OBLLAUNCH::SET);
335 }
336
337 pub fn handle_interrupt(&self) {
338 if self.registers.sr.is_set(Status::EOP) {
339 self.registers.sr.modify(Status::EOP::SET);
341
342 match self.state.get() {
343 FlashState::Write => {
344 self.write_counter.set(self.write_counter.get() + 2);
345
346 if self.write_counter.get() == PAGE_SIZE {
347 self.registers.cr.modify(Control::PG::CLEAR);
348 self.state.set(FlashState::Ready);
349 self.write_counter.set(0);
350
351 self.client.map(|client| {
352 self.buffer.take().map(|buffer| {
353 client.write_complete(buffer, Ok(()));
354 });
355 });
356 } else {
357 self.program_halfword();
358 }
359 }
360 FlashState::Erase => {
361 if self.registers.cr.is_set(Control::PER) {
362 self.registers.cr.modify(Control::PER::CLEAR);
363 }
364
365 if self.registers.cr.is_set(Control::MER) {
366 self.registers.cr.modify(Control::MER::CLEAR);
367 }
368
369 self.state.set(FlashState::Ready);
370 self.client.map(|client| {
371 client.erase_complete(Ok(()));
372 });
373 }
374 FlashState::WriteOption => {
375 self.registers.cr.modify(Control::OPTPG::CLEAR);
376 self.state.set(FlashState::Ready);
377
378 self.client.map(|client| {
379 self.buffer.take().map(|buffer| {
380 client.write_complete(buffer, Ok(()));
381 });
382 });
383 }
384 FlashState::EraseOption => {
385 self.registers.cr.modify(Control::OPTER::CLEAR);
386 self.state.set(FlashState::Ready);
387
388 self.client.map(|client| {
389 client.erase_complete(Ok(()));
390 });
391 }
392 _ => {}
393 }
394 }
395
396 if self.state.get() == FlashState::Read {
397 self.state.set(FlashState::Ready);
398 self.client.map(|client| {
399 self.buffer.take().map(|buffer| {
400 client.read_complete(buffer, Ok(()));
401 });
402 });
403 }
404
405 if self.registers.sr.is_set(Status::WRPRTERR) {
406 self.registers.sr.modify(Status::WRPRTERR::SET);
408
409 match self.state.get() {
410 FlashState::Write => {
411 self.registers.cr.modify(Control::PG::CLEAR);
412 self.client.map(|client| {
413 self.buffer.take().map(|buffer| {
414 client.write_complete(buffer, Err(hil::flash::Error::FlashError));
415 });
416 });
417 }
418 FlashState::Erase => {
419 self.client.map(|client| {
420 client.erase_complete(Err(hil::flash::Error::FlashError));
421 });
422 }
423 _ => {}
424 }
425
426 self.state.set(FlashState::Ready);
427 }
428
429 if self.registers.sr.is_set(Status::PGERR) {
430 self.registers.sr.modify(Status::PGERR::SET);
432
433 match self.state.get() {
434 FlashState::Write => {
435 self.registers.cr.modify(Control::PG::CLEAR);
436 self.client.map(|client| {
437 self.buffer.take().map(|buffer| {
438 client.write_complete(buffer, Err(hil::flash::Error::FlashError));
439 });
440 });
441 }
442 FlashState::WriteOption => {
443 self.registers.cr.modify(Control::OPTPG::CLEAR);
444 self.client.map(|client| {
445 self.buffer.take().map(|buffer| {
446 client.write_complete(buffer, Err(hil::flash::Error::FlashError));
447 });
448 });
449 }
450 FlashState::Erase => {
451 self.client.map(|client| {
452 client.erase_complete(Err(hil::flash::Error::FlashError));
453 });
454 }
455 _ => {}
456 }
457
458 self.state.set(FlashState::Ready);
459 }
460 }
461
462 pub fn program_halfword(&self) {
463 self.buffer.take().map(|buffer| {
464 let i = self.write_counter.get();
465
466 let halfword: u16 = (buffer[i] as u16) << 0 | (buffer[i + 1] as u16) << 8;
467 let page_addr = PAGE_START + self.page_number.get() * PAGE_SIZE;
468 let address = page_addr + i;
469 let location = unsafe { &*(address as *const VolatileCell<u16>) };
470 location.set(halfword);
471
472 self.buffer.replace(buffer);
473 });
474 }
475
476 pub fn erase_page(&self, page_number: usize) -> Result<(), ErrorCode> {
477 if page_number > 127 {
478 return Err(ErrorCode::INVAL);
479 }
480
481 if self.is_locked() {
482 self.unlock();
483 }
484
485 self.enable();
486 self.state.set(FlashState::Erase);
487
488 self.registers.cr.modify(Control::PER::SET);
490 self.registers
491 .ar
492 .write(Address::FAR.val((PAGE_START + page_number * PAGE_SIZE) as u32));
493 self.registers.cr.modify(Control::STRT::SET);
494
495 Ok(())
496 }
497
498 pub fn erase_all(&self) -> Result<(), ErrorCode> {
499 if self.is_locked() {
500 self.unlock();
501 }
502
503 self.enable();
504 self.state.set(FlashState::Erase);
505
506 self.registers.cr.modify(Control::MER::SET);
508 self.registers.cr.modify(Control::STRT::SET);
509
510 Ok(())
511 }
512
513 pub fn write_page(
514 &self,
515 page_number: usize,
516 buffer: &'static mut StmF303Page,
517 ) -> Result<(), (ErrorCode, &'static mut StmF303Page)> {
518 if page_number > 127 {
519 return Err((ErrorCode::INVAL, buffer));
520 }
521
522 if self.is_locked() {
523 self.unlock();
524 }
525
526 self.enable();
527 self.state.set(FlashState::Write);
528
529 self.registers.cr.modify(Control::PG::SET);
531
532 self.buffer.replace(buffer);
533 self.page_number.set(page_number);
534 self.program_halfword();
535
536 Ok(())
537 }
538
539 pub fn read_page(
540 &self,
541 page_number: usize,
542 buffer: &'static mut StmF303Page,
543 ) -> Result<(), (ErrorCode, &'static mut StmF303Page)> {
544 if page_number > 127 {
545 return Err((ErrorCode::INVAL, buffer));
546 }
547
548 let mut byte: *const u8 = (PAGE_START + page_number * PAGE_SIZE) as *const u8;
549 unsafe {
550 for i in 0..buffer.len() {
551 buffer[i] = *byte;
552 byte = byte.offset(1);
553 }
554 }
555
556 self.buffer.replace(buffer);
557 self.state.set(FlashState::Read);
558 self.deferred_call.set();
559
560 Ok(())
561 }
562
563 pub fn write_option(&self, byte_number: usize, value: u8) -> Result<(), ErrorCode> {
566 if byte_number > 7 {
567 return Err(ErrorCode::INVAL);
568 }
569
570 if self.is_locked() {
571 self.unlock();
572 }
573
574 self.unlock_option();
575 self.enable();
576 self.state.set(FlashState::WriteOption);
577
578 self.registers.cr.modify(Control::OPTPG::SET);
580
581 let address = OPT_START + byte_number * 2;
582 let location = unsafe { &*(address as *const VolatileCell<u16>) };
583 let halfword: u16 = value as u16;
584 location.set(halfword);
585
586 Ok(())
587 }
588
589 pub fn erase_option(&self) -> Result<(), ErrorCode> {
590 if self.is_locked() {
591 self.unlock();
592 }
593
594 self.unlock_option();
595 self.enable();
596 self.state.set(FlashState::EraseOption);
597
598 self.registers.cr.modify(Control::OPTER::SET);
600 self.registers.cr.modify(Control::STRT::SET);
601
602 Ok(())
603 }
604}
605
606impl DeferredCallClient for Flash {
607 fn register(&'static self) {
608 self.deferred_call.register(self);
609 }
610
611 fn handle_deferred_call(&self) {
612 self.handle_interrupt();
613 }
614}
615
616impl<C: hil::flash::Client<Self>> hil::flash::HasClient<'static, C> for Flash {
617 fn set_client(&self, client: &'static C) {
618 self.client.set(client);
619 }
620}
621
622impl hil::flash::Flash for Flash {
623 type Page = StmF303Page;
624
625 fn read_page(
626 &self,
627 page_number: usize,
628 buf: &'static mut Self::Page,
629 ) -> Result<(), (ErrorCode, &'static mut Self::Page)> {
630 self.read_page(page_number, buf)
631 }
632
633 fn write_page(
634 &self,
635 page_number: usize,
636 buf: &'static mut Self::Page,
637 ) -> Result<(), (ErrorCode, &'static mut Self::Page)> {
638 self.write_page(page_number, buf)
639 }
640
641 fn erase_page(&self, page_number: usize) -> Result<(), ErrorCode> {
642 self.erase_page(page_number)
643 }
644}