aboutsummaryrefslogtreecommitdiff
path: root/src/bringup/mod.rs
blob: e1f02780b9107124162f7552e9fcb533fa56d42a (plain) (blame)
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
use molybdos::reexport::*;

use embassy_rp::{
    adc,
    adc::Adc,
    gpio::{
        Level,
        Output,
        Pin,
    },
    i2c::{
        self,
        I2c,
    },
    peripherals::{
        I2C0,
        SPI0,
        SPI1,
        USB,
    },
    spi,
    spi::{
        Async,
        Spi,
    },
    watchdog::Watchdog,
};
use embassy_sync::{
    blocking_mutex::raw::{
        CriticalSectionRawMutex,
        RawMutex,
    },
    mutex::Mutex,
};
use molybdos::embassy_rp::peripherals::{
    DMA_CH5,
    I2C1,
    PIO0,
};
use static_cell::StaticCell;
use tap::Pipe;

use crate::SensorI2c;
use molybdos::pal::StaticOutput;

pub mod i2s;

pub use i2s::{
    I2S,
    StaticI2S,
};

embassy_rp::bind_interrupts! {
    struct Irqs {
        USBCTRL_IRQ => embassy_rp::usb::InterruptHandler<USB>;
        ADC_IRQ_FIFO => adc::InterruptHandler;
        I2C0_IRQ => i2c::InterruptHandler<I2C0>;
        I2C1_IRQ => i2c::InterruptHandler<I2C1>;
        PIO0_IRQ_0 => embassy_rp::pio::InterruptHandler<PIO0>;
    }
}

static BME_SPI: StaticCell<Mutex<CriticalSectionRawMutex, spi::Spi<SPI1, Async>>> =
    StaticCell::new();
static SD_SPI: StaticCell<Mutex<CriticalSectionRawMutex, spi::Spi<SPI0, Async>>> =
    StaticCell::new();
static ADC: StaticCell<Mutex<CriticalSectionRawMutex, Adc<adc::Async>>> = StaticCell::new();
static SENSOR_I2C: StaticCell<Mutex<CriticalSectionRawMutex, SensorI2c>> = StaticCell::new();

static PIO0: StaticCell<embassy_rp::pio::Pio<'static, PIO0>> = StaticCell::new();

pub struct Split<BmeSpi, BmeSpiMutex, SdSpi, SdSpiMutex, SensorI2c, SensorI2cMutex>
where
    SdSpiMutex: RawMutex + 'static,
    SdSpi: 'static,
    BmeSpiMutex: RawMutex + 'static,
    BmeSpi: 'static,
    SensorI2cMutex: RawMutex + 'static,
    SensorI2c: 'static,
{
    pub sd_spi:     &'static Mutex<SdSpiMutex, SdSpi>,
    pub sd_cs:      StaticOutput,
    pub bme_spi:    &'static Mutex<BmeSpiMutex, BmeSpi>,
    pub bme_cs:     StaticOutput,
    pub sensor_i2c: &'static Mutex<SensorI2cMutex, SensorI2c>,
    pub wdt:        Watchdog,
    pub usb:        molybdos::pal::UsbDriver,

    pub i2s:     i2s::I2S<'static, 'static, embassy_rp::peripherals::PIO0, 0>,
    pub i2s_dma: DMA_CH5,
    pub adc:     &'static Mutex<CriticalSectionRawMutex, Adc<'static, adc::Async>>,
    // pub leds: [StaticOutput; crate::N_LED],
}

pub fn split(
    config: embassy_rp::config::Config,
) -> Split<
    crate::BMESpi,
    CriticalSectionRawMutex,
    crate::SdSpi,
    CriticalSectionRawMutex,
    crate::SensorI2c,
    CriticalSectionRawMutex,
> {
    let mut periphs = embassy_rp::init(config);

    let wdt = Watchdog::new(periphs.WATCHDOG);

    let bme_cs = periphs.PIN_13.degrade().pipe(|cs| Output::new(cs, Level::High));
    let bme_spi = {
        let sck = periphs.PIN_10;
        let mosi = periphs.PIN_11;
        let miso = periphs.PIN_8;

        let mut conf = spi::Config::default();
        conf.frequency = 1_000_000;

        let bme_spi =
            Spi::new(periphs.SPI1, sck, mosi, miso, periphs.DMA_CH0, periphs.DMA_CH1, conf)
                .pipe(Mutex::<CriticalSectionRawMutex, _>::new);
        BME_SPI.init(bme_spi)
    };

    let sd_cs = periphs.PIN_17.degrade().pipe(|cs| Output::new(cs, Level::High));
    let sd_spi = {
        let mosi = periphs.PIN_19;
        let sck = periphs.PIN_18;
        let miso = periphs.PIN_20;

        let mut conf = spi::Config::default();
        conf.frequency = 16_000_000;

        let sd_spi =
            Spi::new(periphs.SPI0, sck, mosi, miso, periphs.DMA_CH3, periphs.DMA_CH4, conf)
                .pipe(Mutex::new);

        SD_SPI.init(sd_spi)
    };

    let i2c = {
        let mut conf = i2c::Config::default();
        conf.frequency = 400_000;

        let (dummy_scl, dummy_sda) = (periphs.PIN_15, periphs.PIN_14);

        let i2c =
            SensorI2c::new_async(periphs.I2C1, dummy_scl, dummy_sda, Irqs, conf).pipe(Mutex::new);
        SENSOR_I2C.init(i2c)
    };

    let usb_driver = embassy_rp::usb::Driver::new(periphs.USB, Irqs);

    let adc = Adc::new(periphs.ADC, Irqs, adc::Config::default());
    let adc = ADC.init(Mutex::new(adc));

    // {
    //     StaticOutput::new(periphs.PIN_24, Level::High);
    // }

    let pio0 = embassy_rp::pio::Pio::new(periphs.PIO0, Irqs);
    let pio = PIO0.init(pio0);

    let i2s = i2s::I2S::new(pio, periphs.PIN_24, periphs.PIN_23, periphs.PIN_25);

    Split {
        sd_spi,
        sd_cs,
        bme_spi,
        bme_cs,
        wdt,
        sensor_i2c: i2c,
        usb: usb_driver,
        i2s,
        i2s_dma: periphs.DMA_CH5,
        adc,
    }
}