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
#![no_std]

pub use embedded_hal as ehal;
pub use esp8266 as target;
pub use esp8266_hal_proc_macros::{interrupt, ram};

#[cfg(feature = "rt")]
pub use xtensa_lx_rt::{entry, exception};

#[cfg(all(feature = "rt", feature = "interrupt"))]
#[macro_use]
pub mod interrupt;

pub mod gpio;
pub mod prelude;
pub mod rng;
pub mod spi;
pub mod time;
pub mod timer;
pub mod uart;
pub mod watchdog;
pub mod dport;
pub mod rtccntl;

extern "C" {
    // todo: replace this with a rust implementation
    fn Cache_Read_Enable(map: u8, p: u8, v: u8);
}

/// Function handling ESP8266 specific initialization
/// then calls original Reset function
///
/// ENTRY point is defined in memory.x
/// *Note: the pre_init function is called in the original reset handler
/// after the initializations done in this function*
#[cfg(feature = "rt")]
#[doc(hidden)]
#[no_mangle]
#[ram]
pub unsafe extern "C" fn ESP8266Reset() -> ! {
    // These symbols come from `memory.x`
    extern "C" {
        static mut _rtc_bss_start: u32;
        static mut _rtc_bss_end: u32;
    }

    // setup the flash memory mapping
    Cache_Read_Enable(0, 0, 0);

    // configure the pll for the most common crystal frequency
    use rtccntl::{CrystalFrequency, RtcControlExt};
    use esp8266::Peripherals;
    let dp = Peripherals::steal();
    dp.RTCCNTL.rtc_control().set_crystal_frequency(CrystalFrequency::Crystal26MHz);

    // Initialize RTC RAM
    xtensa_lx_rt::zero_bss(&mut _rtc_bss_start, &mut _rtc_bss_end);

    // continue with default reset handler
    xtensa_lx_rt::Reset();
}