Skip to content

Commit

Permalink
re-worked SPI code
Browse files Browse the repository at this point in the history
  • Loading branch information
robamu committed Sep 20, 2024
1 parent 8ca46b2 commit dc77f3a
Show file tree
Hide file tree
Showing 10 changed files with 573 additions and 435 deletions.
10 changes: 10 additions & 0 deletions bootloader/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#![no_std]

use core::convert::Infallible;

/// Simple trait which makes swapping the NVM easier. NVMs only need to implement this interface.
pub trait NvmInterface {
fn write(&mut self, address: u32, data: &[u8]) -> Result<(), Infallible>;
fn read(&mut self, address: u32, buf: &mut [u8]) -> Result<(), Infallible>;
fn verify(&mut self, address: u32, data: &[u8]) -> Result<bool, Infallible>;
}
59 changes: 22 additions & 37 deletions bootloader/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,34 +1,15 @@
//! Vorago bootloader which can boot from two images.
//!
//! Bootloader memory map
//!
//! * <0x0> Bootloader start <code up to 0x3FFE bytes>
//! * <0x3FFE> Bootloader CRC <halfword>
//! * <0x4000> App image A start <code up to 0x1DFFC (~120K) bytes>
//! * <0x21FFC> App image A CRC check length <halfword>
//! * <0x21FFE> App image A CRC check value <halfword>
//! * <0x22000> App image B start <code up to 0x1DFFC (~120K) bytes>
//! * <0x3FFFC> App image B CRC check length <halfword>
//! * <0x3FFFE> App image B CRC check value <halfword>
//! * <0x40000> <end>
//!
//! As opposed to the Vorago example code, this bootloader assumes a 40 MHz external clock
//! but does not scale that clock up.
#![no_main]
#![no_std]
use bootloader::NvmInterface;
use cortex_m_rt::entry;
use crc::{Crc, CRC_16_IBM_3740};
use embedded_hal_bus::spi::{ExclusiveDevice, NoDelay};
#[cfg(not(feature = "rtt-panic"))]
use panic_halt as _;
#[cfg(feature = "rtt-panic")]
use panic_rtt_target as _;
use rtt_target::{rprintln, rtt_init_print};
use va108xx_hal::{
pac,
spi::{RomMiso, RomMosi, RomSck, Spi, SpiClkConfig, SpiConfig},
time::Hertz,
};
use va108xx_hal::{pac, time::Hertz};
use vorago_reb1::m95m01::M95M01;

// Useful for debugging and see what the bootloader is doing. Enabled currently, because
Expand Down Expand Up @@ -84,10 +65,22 @@ enum AppSel {
B,
}

/// Complex type, but this is the price we pay for nice abstraction. It is also very explicit.
pub type Nvm = M95M01<
ExclusiveDevice<Spi<pac::Spic, (RomSck, RomMiso, RomMosi), u8>, dummy_pin::DummyPin, NoDelay>,
>;
pub struct NvmWrapper(pub M95M01);

// Newtype pattern. We could now more easily swap the used NVM type.
impl NvmInterface for NvmWrapper {
fn write(&mut self, address: u32, data: &[u8]) -> Result<(), core::convert::Infallible> {
self.0.write(address, data)
}

fn read(&mut self, address: u32, buf: &mut [u8]) -> Result<(), core::convert::Infallible> {
self.0.read(address, buf)
}

fn verify(&mut self, address: u32, data: &[u8]) -> Result<bool, core::convert::Infallible> {
self.0.verify(address, data)
}
}

#[entry]
fn main() -> ! {
Expand All @@ -98,17 +91,7 @@ fn main() -> ! {
let mut dp = pac::Peripherals::take().unwrap();
let cp = cortex_m::Peripherals::take().unwrap();

let spi = Spi::new(
&mut dp.sysconfig,
CLOCK_FREQ,
dp.spic,
(RomSck, RomMiso, RomMosi),
// These values are taken from the vorago bootloader app, don't want to experiment here..
SpiConfig::default().clk_cfg(SpiClkConfig::new(2, 4)),
);
let mut nvm =
M95M01::new(ExclusiveDevice::new_no_delay(spi, dummy_pin::DummyPin::new_low()).unwrap())
.expect("creating NVM structure failed");
let mut nvm = M95M01::new(&mut dp.sysconfig, CLOCK_FREQ, dp.spic);

if FLASH_SELF {
let mut first_four_bytes: [u8; 4] = [0; 4];
Expand Down Expand Up @@ -153,6 +136,8 @@ fn main() -> ! {
}
}

let mut nvm = NvmWrapper(nvm);

// Check bootloader's CRC (and write it if blank)
check_own_crc(&dp.sysconfig, &cp, &mut nvm);

Expand All @@ -170,7 +155,7 @@ fn main() -> ! {
}
}

fn check_own_crc(sysconfig: &pac::Sysconfig, cp: &cortex_m::Peripherals, nvm: &mut Nvm) {
fn check_own_crc(sysconfig: &pac::Sysconfig, cp: &cortex_m::Peripherals, nvm: &mut NvmWrapper) {
let crc_exp = unsafe { (BOOTLOADER_CRC_ADDR as *const u16).read_unaligned().to_be() };
// I'd prefer to use [core::slice::from_raw_parts], but that is problematic
// because the address of the bootloader is 0x0, so the NULL check fails and the functions
Expand Down
3 changes: 0 additions & 3 deletions examples/simple/examples/spi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@ fn main() -> ! {
dp.spia,
(sck, miso, mosi),
spi_cfg,
None,
);
spia.set_fill_word(FILL_WORD);
spia_ref.borrow_mut().replace(spia.downgrade());
Expand All @@ -98,7 +97,6 @@ fn main() -> ! {
dp.spia,
(sck, miso, mosi),
spi_cfg,
None,
);
spia.set_fill_word(FILL_WORD);
spia_ref.borrow_mut().replace(spia.downgrade());
Expand All @@ -115,7 +113,6 @@ fn main() -> ! {
dp.spib,
(sck, miso, mosi),
spi_cfg,
None,
);
spib.set_fill_word(FILL_WORD);
spib_ref.borrow_mut().replace(spib.downgrade());
Expand Down
Loading

0 comments on commit dc77f3a

Please sign in to comment.