This commit is contained in:
10
bootloader/src/lib.rs
Normal file
10
bootloader/src/lib.rs
Normal file
@ -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>;
|
||||
}
|
@ -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
|
||||
@ -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() -> ! {
|
||||
@ -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];
|
||||
@ -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);
|
||||
|
||||
@ -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
|
||||
|
Reference in New Issue
Block a user