This builds. Work? No idea (yet).
In mytypes.rs
use rp_pico::hal;
use rp_pico::hal::{
gpio::{FunctionI2c, FunctionSpi, FunctionUart, Pin, PullDown, PullUp},
i2c::I2C,
pac,
spi::Spi,
uart::UartPeripheral,
};
// --- UARTs --- //
pub type MyUartPin<P> = Pin<P, FunctionUart, PullDown>;
type MyUart<U, PTX, PRX> = UartPeripheral<hal::uart::Enabled, U, (PTX, PRX)>;
pub type MyUart0Base<PTX, PRX> = MyUart<pac::UART0, PTX, PRX>;
pub type MyUart1Base<PTX, PRX> = MyUart<pac::UART1, PTX, PRX>;
// --- I2C --- //
pub type MyI2CPin<P> = Pin<P, FunctionI2c, PullUp>;
type MyI2C<I, PSDA, PSCL> = I2C<I, (PSDA, PSCL)>;
pub type MyI2C0Base<PSDA, PSCL> = MyI2C<pac::I2C0, PSDA, PSCL>;
pub type MyI2C1Base<PSDA, PSCL> = MyI2C<pac::I2C1, PSDA, PSCL>;
// --- SPI --- //
pub type MySPIPin<P> = Pin<P, FunctionSpi, PullDown>;
type MySPI2<S, SCK, MOSI> = Spi<hal::spi::Enabled, S, (MOSI, SCK)>;
type MySPI3<S, MISO, SCK, MOSI> = Spi<hal::spi::Enabled, S, (MOSI, MISO, SCK)>;
type MySPI4<S, MISO, CS, SCK, MOSI> = Spi<hal::spi::Enabled, S, (MISO, CS, SCK, MOSI)>;
pub type MySPI0Base2<SCK, MOSI> = MySPI2<pac::SPI0, SCK, MOSI>;
pub type MySPI1Base2<SCK, MOSI> = MySPI2<pac::SPI1, SCK, MOSI>;
pub type MySPI0Base3<MISO, SCK, MOSI> = MySPI3<pac::SPI0, MISO, SCK, MOSI>;
pub type MySPI1Base3<MISO, SCK, MOSI> = MySPI3<pac::SPI1, MISO, SCK, MOSI>;
pub type MySPI0Base4<MISO, CS, SCK, MOSI> = MySPI4<pac::SPI0, MISO, CS, SCK, MOSI>;
pub type MySPI1Base4<MISO, CS, SCK, MOSI> = MySPI4<pac::SPI1, MISO, CS, SCK, MOSI>;
In pinout.rs
pub type MyUart0TxPin = MyUartPin<rp2040_hal::gpio::bank0::Gpio0>;
pub type MyUart0RxPin = MyUartPin<rp2040_hal::gpio::bank0::Gpio1>;
pub type MyI2C1SdaPin = MyI2CPin<rp2040_hal::gpio::bank0::Gpio2>;
pub type MyI2C1SclPin = MyI2CPin<rp2040_hal::gpio::bank0::Gpio3>;
pub type MyI2C0SdaPin = MyI2CPin<rp2040_hal::gpio::bank0::Gpio4>;
pub type MyI2C0SclPin = MyI2CPin<rp2040_hal::gpio::bank0::Gpio5>;
pub type MySPI1SckPin = MySPIPin<rp2040_hal::gpio::bank0::Gpio10>;
pub type MySPI1MosiPin = MySPIPin<rp2040_hal::gpio::bank0::Gpio11>;
pub type MySPI1MisoPin = MySPIPin<rp2040_hal::gpio::bank0::Gpio12>;
pub type MySPI0SckPin = MySPIPin<rp2040_hal::gpio::bank0::Gpio18>;
pub type MySPI0MosiPin = MySPIPin<rp2040_hal::gpio::bank0::Gpio19>;
pub type MySPI0MisoPin = MySPIPin<rp2040_hal::gpio::bank0::Gpio16>;
In commchan.rs
type MyCommChanMaker<D, P> = CommChan<D, P>;
pub type MyCommChan<D> = MyCommChanMaker<D, CommChanProtocol<i32>>;
RTIC's Shared resources struct in RTIC's app module:
#[shared]
struct Shared {
status: crate::AppStatus,
coresbuf: crate::buffer::Buf32,
uart0: &'static mut MyCommChan<MyUart0Hal>,
//uart1: &'static mut MyCommChan<MyUart1Hal, CommChanProtocol<i32>>,
i2c0: &'static mut MyCommChan<MyI2C0Hal>,
i2c1: &'static mut MyCommChan<MyI2C1Hal>,
spi0: &'static mut MyCommChan<MySPI0Hal>,
spi1: &'static mut MyCommChan<MySPI1Hal>,
}
RTIC's init() in main.rs:
#[init(local=[uart0_ctx: MaybeUninit<MyCommChan<MyUart0Hal>> = MaybeUninit::uninit(),/* uart1_ctx: MaybeUninit<MyCommChan<MyUart1Hal>> = MaybeUninit::uninit(),*/ i2c0_ctx: MaybeUninit<MyCommChan<MyI2C0Hal>> = MaybeUninit::uninit(), i2c1_ctx: MaybeUninit<MyCommChan<MyI2C1Hal>> = MaybeUninit::uninit(), spi0_ctx: MaybeUninit<MyCommChan<MySPI0Hal>> = MaybeUninit::uninit(), spi1_ctx: MaybeUninit<MyCommChan<MySPI1Hal>> = MaybeUninit::uninit()])]
fn init0(mut ctx: init0::Context) -> (Shared, Local) {
[...]
let pin_uart0_tx = pins.gpio0;
let pin_uart0_rx = pins.gpio1;
[ ... it continues for all pins of all periferals: I2C0 ... SPI0...]
[...]
let uart0hal: MyUart0Hal = UartPeripheral::new(
ctx.device.UART0,
(pin_uart0_tx.into_function(), pin_uart0_rx.into_function()),
&mut ctx.device.RESETS,
)
.enable(
UartConfig::new(115200.Hz(), DataBits::Eight, None, StopBits::One),
clocks.peripheral_clock.freq(),
)
.unwrap();
let uart0cc: &'static mut MyCommChan<MyUart0Hal> =
ctx.local.uart0_ctx.write(MyCommChan::new(
CommChanDevice::setup(CommChanDevice::CommChanDeviceUart(uart0hal)),
CommChanBuffer::new(),
CommChanProtocol::CommChanPlainProtocol(0),
));
[ ... similarly for I2C, SPI ...]
[...]
// return shared and local resources
(
Shared {
status: crate::AppStatus {
tick: Mono::now().ticks() as u32,
delay: 0,
gpio_levels_now: 0,
gpio_levels_last: 0,
gpio_trigger_rt_on_raise: 0,
gpio_trigger_rt_on_fall: 0,
gpio_trigger_async_on_raise: 0,
gpio_trigger_async_on_fall: 0,
gpio_trigger_async_remote_on_raise: 0,
gpio_trigger_async_remote_on_fall: 0,
},
coresbuf: siofifobuf,
uart0: uart0cc,
//uart1: uart1cc,
i2c0: i2c0cc,
i2c1: i2c1cc,
spi0: spi0cc,
spi1: spi1cc,
},
Local {},
)
}
So, at the end of the day both the buffer's producer in the ISR and the buffer consumer task can access the peripheral:
#[task(binds = UART0_IRQ, shared = [status, coresbuf, uart0])]
fn _isr_irq20_uart0(_ctx: _isr_irq20_uart0::Context) {
[... gets from uart's hw fifo and push it to the buffer ...]
}
// external (peripherals: uart, i2c, spi) rx dispatcher
#[task(priority = 3, shared = [status, uart0,/* uart1,*/ i2c0, i2c1, spi0, spi1])]
async fn t2(_ctx: t2::Context) {
loop {
[... it consumes peripherals's soft buffers ...]
Mono::delay(0.micros()).await;
}
}
I simplified a bit the code posted here (ie: removed all the initialization, inter-task communication, multicore and inter-core communication), but it's complete in terms of accessing the 'static peripherals (and my own add-ons; CommChan = device+buffer+protocol) it's beautified by the type aliasing, and I've been a good boy: I didn't type "unsafe" keyword; not even once. All without the evil macros nor adding crates!