aboutsummaryrefslogtreecommitdiff
path: root/src/imxrt10xx.rs
blob: fe414fec2c50fca20360300bd36e36c388146ec7 (plain)
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
use core::marker::PhantomData;

use imxrt_drivers_ccm_10xx::{ccm, ccm_analog};
use imxrt_drivers_dcdc as dcdc;
use imxrt_drivers_flexspi as flexspi;

const FLEXSPI1_BASE: u32 = 0x6000_0000;

pub trait Imxrt10xx: 'static {
    const FLEXSPI1_INSTANCE: flexspi::Instance;
    const CCM_INSTANCE: ccm::Instance;
    const CCM_ANALOG_INSTANCE: ccm_analog::Instance;
    const DCDC_INSTANCE: dcdc::Instance;

    const FLEXSPI_FIFO_CAPACITY_BYTES: usize;

    fn configure_clocks(ccm: ccm::Instance, ccm_analog: ccm_analog::Instance, dcdc: dcdc::Instance);
}

pub struct Algorithm<C: Imxrt10xx, F: crate::ImxrtFlashAlgorithm>(PhantomData<(C, F)>);

impl<C: Imxrt10xx, F: crate::ImxrtFlashAlgorithm> Algorithm<C, F> {
    pub const fn flash_size_bytes() -> usize {
        F::FLASH_CAPACITY_BYTES
    }
    pub const fn flash_address() -> usize {
        FLEXSPI1_BASE as _
    }
    pub const fn sector_size_bytes() -> usize {
        F::FLASH_SECTOR_SIZE_BYTES
    }
    pub const fn page_size_bytes() -> usize {
        F::FLASH_PAGE_SIZE_BYTES
    }

    pub fn initialize() -> Self {
        C::configure_clocks(C::CCM_INSTANCE, C::CCM_ANALOG_INSTANCE, C::DCDC_INSTANCE);
        crate::reset(C::FLEXSPI1_INSTANCE, F::FLASH_CAPACITY_BYTES / 1024, 128);
        F::initialize(C::FLEXSPI1_INSTANCE);
        Algorithm(PhantomData)
    }

    pub fn flash_read(&mut self, address: usize, data: &mut [u8]) {
        crate::flash::read(C::FLEXSPI1_INSTANCE, address, data);
    }

    pub fn flash_erase_sector(&mut self, address: usize) {
        crate::flash::erase_sector(C::FLEXSPI1_INSTANCE, address);
    }

    pub fn flash_write(&mut self, address: usize, data: &[u8]) {
        crate::flash::write(C::FLEXSPI1_INSTANCE, address, data);
    }
}

impl<C: Imxrt10xx, F: crate::ImxrtFlashAlgorithm> flash_algorithm::FlashAlgorithm
    for Algorithm<C, F>
{
    fn new(
        _: u32,
        _: u32,
        _: flash_algorithm::Function,
    ) -> Result<Self, flash_algorithm::ErrorCode> {
        Ok(Self::initialize())
    }

    fn erase_all(&mut self) -> Result<(), flash_algorithm::ErrorCode> {
        crate::flash::erase_chip(C::FLEXSPI1_INSTANCE);
        Ok(())
    }

    fn erase_sector(&mut self, address: u32) -> Result<(), flash_algorithm::ErrorCode> {
        self.flash_erase_sector(address.saturating_sub(FLEXSPI1_BASE) as usize);
        Ok(())
    }

    fn program_page(
        &mut self,
        address: u32,
        data: &[u8],
    ) -> Result<(), flash_algorithm::ErrorCode> {
        self.flash_write(address.saturating_sub(FLEXSPI1_BASE) as usize, data);
        Ok(())
    }

    fn read_flash(
        &mut self,
        address: u32,
        data: &mut [u8],
    ) -> Result<(), flash_algorithm::ErrorCode> {
        self.flash_read(address.saturating_sub(FLEXSPI1_BASE) as usize, data);
        Ok(())
    }
}

impl<C: Imxrt10xx, F: crate::ImxrtFlashAlgorithm> Drop for Algorithm<C, F> {
    fn drop(&mut self) {
        F::deinitialize(C::FLEXSPI1_INSTANCE);
    }
}