1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
//! Interface for reading, writing, and erasing flash storage pages. //! //! Operates on single pages. The page size is set by the associated type //! `page`. Here is an example of a page type: //! //! ```rust //! // Size in bytes //! const PAGE_SIZE: u32 = 1024; //! //! pub struct NewChipPage(pub [u8; PAGE_SIZE as usize]); //! //! impl NewChipPage { //! pub const fn new() -> NewChipPage { //! NewChipPage([0; PAGE_SIZE as usize]) //! } //! //! fn len(&self) -> usize { //! self.0.len() //! } //! } //! //! impl Index<usize> for NewChipPage { //! type Output = u8; //! //! fn index(&self, idx: usize) -> &u8 { //! &self.0[idx] //! } //! } //! //! impl IndexMut<usize> for NewChipPage { //! fn index_mut(&mut self, idx: usize) -> &mut u8 { //! &mut self.0[idx] //! } //! } //! //! impl AsMut<[u8]> for NewChipPage { //! fn as_mut(&mut self) -> &mut [u8] { //! &mut self.0 //! } //! } //! ``` //! //! Then a basic implementation of this trait should look like: //! //! ```rust //! //! impl hil::flash::HasClient for NewChipStruct { //! fn set_client(&'a self, client: &'a C) { } //! } //! //! impl hil::flash::Flash for NewChipStruct { //! type Page = NewChipPage; //! //! fn read_page(&self, page_number: usize, buf: &'static mut Self::Page) -> ReturnCode { } //! fn write_page(&self, page_number: usize, buf: &'static mut Self::Page) -> ReturnCode { } //! fn erase_page(&self, page_number: usize) -> ReturnCode { } //! } //! ``` //! //! A user of this flash interface might look like: //! //! ```rust //! pub struct FlashUser<'a, F: hil::flash::Flash + 'static> { //! driver: &'a F, //! buffer: TakeCell<'static, F::Page>, //! } //! //! impl<'a, F: hil::flash::Flash + 'a> FlashUser<'a, F> { //! pub fn new(driver: &'a F, buffer: &'static mut F::Page) -> FlashUser<'a, F> { //! FlashUser { //! driver: driver, //! buffer: TakeCell::new(buffer), //! } //! } //! } //! //! impl<'a, F: hil::flash::Flash + 'a> hil::flash::Client<F> for FlashUser<'a, F> { //! fn read_complete(&self, buffer: &'static mut F::Page, error: hil::flash::Error) {} //! fn write_complete(&self, buffer: &'static mut F::Page, error: hil::flash::Error) { } //! fn erase_complete(&self, error: hil::flash::Error) {} //! } //! ``` use returncode::ReturnCode; /// Flash errors returned in the callbacks. #[derive(Copy, Clone, Debug, Eq, PartialEq)] pub enum Error { /// Success. CommandComplete, /// An error occurred during the flash operation. FlashError, } pub trait HasClient<'a, C> { /// Set the client for this flash peripheral. The client will be called /// when operations complete. fn set_client(&'a self, client: &'a C); } /// A page of writable persistent flash memory. pub trait Flash { /// Type of a single flash page for the given implementation. type Page: AsMut<[u8]>; /// Read a page of flash into the buffer. fn read_page(&self, page_number: usize, buf: &'static mut Self::Page) -> ReturnCode; /// Write a page of flash from the buffer. fn write_page(&self, page_number: usize, buf: &'static mut Self::Page) -> ReturnCode; /// Erase a page of flash. fn erase_page(&self, page_number: usize) -> ReturnCode; } /// Implement `Client` to receive callbacks from `Flash`. pub trait Client<F: Flash> { /// Flash read complete. fn read_complete(&self, read_buffer: &'static mut F::Page, error: Error); /// Flash write complete. fn write_complete(&self, write_buffer: &'static mut F::Page, error: Error); /// Flash erase complete. fn erase_complete(&self, error: Error); }