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}