Skip to content

Commit 0c2ac40

Browse files
authored
Merge pull request #18 from rp-rs/update-rustc
Now builds on stable.
2 parents 7bb71a0 + 1d215be commit 0c2ac40

File tree

6 files changed

+73
-55
lines changed

6 files changed

+73
-55
lines changed

.cargo/config

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,10 @@
1-
[unstable]
2-
build-std = ["core"]
3-
build-std-features = ["panic_immediate_abort"]
4-
51
[target.'cfg(all(target_arch = "arm", target_os = "none"))']
62

73
rustflags = [
84
"-C", "link-arg=--nmagic",
95
"-C", "link-arg=-Tlink.x",
106

117
# Code-size optimizations.
12-
"-Z", "trap-unreachable=no",
138
"-C", "inline-threshold=5",
149
"-C", "no-vectorize-loops",
1510
"-C", "force-frame-pointers=no",

.github/workflows/ci.yml

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,12 @@ env:
1111

1212
jobs:
1313
build:
14-
1514
runs-on: ubuntu-latest
16-
1715
steps:
1816
- uses: actions/checkout@v2
1917
- name: Install Dependencies
2018
run: |
21-
sudo apt update
22-
rustup component add rust-src
2319
cargo install cargo-binutils
24-
rustup component add llvm-tools-preview
2520
- name: Build
2621
run: |
2722
./build.sh

README.md

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,27 @@ It implements the CMSIS-Pack ABI, so it's compatible with any tools that use it,
55

66
## Dependencies
77

8-
Run the following requirements:
8+
Run the following to install the requirements:
9+
910
```bash
10-
cargo install cargo-binutils && rustup component add llvm-tools-preview rust-src
11+
cargo install cargo-binutils
1112
```
12-
## Building
1313

14-
Building requires nightly Rust.
14+
The `rust-toolchain` file will get you the targets and components you need.
15+
16+
## Building
1517

1618
Just run `build.sh`. It spits out the flash algo in the probe-rs YAML format:
1719

18-
flash-algo$ ./build.sh
20+
```console
21+
flash-algo$ ./build.sh
1922
instructions: sLUUIACIGUoBRguI...wRwAgcEc=
2023
pc_init: 0x00000000
2124
pc_uninit: 0x0000007c
2225
pc_program_page: 0x00000088
2326
pc_erase_sector: 0x00000084
2427
pc_erase_all: 0x00000080
28+
```
2529

2630
## Hacking
2731

@@ -30,7 +34,7 @@ the glue functions for a given struct implementing it. This is generic for all c
3034

3135
`main.rs` has the actual implementation for RP2040.
3236

33-
# License
37+
## License
3438

3539
This thingy is licensed under either of
3640

rust-toolchain

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,5 @@
1-
nightly
1+
[toolchain]
2+
channel = "stable"
3+
components = [ "llvm-tools" ]
4+
profile = "minimal"
5+
targets = ["thumbv6m-none-eabi"]

src/algo.rs

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
#![macro_use]
22

3-
43
use core::arch::asm;
54
use core::num::NonZeroU32;
65

@@ -12,10 +11,6 @@ fn panic(_info: &core::panic::PanicInfo) -> ! {
1211
}
1312
}
1413

15-
pub const FUNCTION_ERASE: u32 = 1;
16-
pub const FUNCTION_PROGRAM: u32 = 2;
17-
pub const FUNCTION_VERIFY: u32 = 3;
18-
1914
pub type ErrorCode = NonZeroU32;
2015

2116
pub trait FlashAlgo: Sized + 'static {
@@ -38,6 +33,12 @@ macro_rules! algo {
3833
static mut _IS_INIT: bool = false;
3934
static mut _ALGO_INSTANCE: MaybeUninit<$type> = MaybeUninit::uninit();
4035

36+
/// Initialise the Flash Algorithm
37+
///
38+
/// # Safety
39+
///
40+
/// Will disable execution from Flash. Ensure you are running from SRAM
41+
/// and do not call any flash-based based functions.
4142
#[no_mangle]
4243
#[link_section = ".entry"]
4344
pub unsafe extern "C" fn Init(addr: u32, clock: u32, function: u32) -> u32 {
@@ -53,16 +54,25 @@ macro_rules! algo {
5354
Err(e) => e.get(),
5455
}
5556
}
57+
/// Uninitialise the Flash Algorithm
5658
#[no_mangle]
5759
#[link_section = ".entry"]
58-
pub unsafe extern "C" fn UnInit() -> u32 {
59-
if !_IS_INIT {
60-
return 1;
60+
pub extern "C" fn UnInit() -> u32 {
61+
unsafe {
62+
if !_IS_INIT {
63+
return 1;
64+
}
65+
_ALGO_INSTANCE.as_mut_ptr().drop_in_place();
66+
_IS_INIT = false;
6167
}
62-
_ALGO_INSTANCE.as_mut_ptr().drop_in_place();
63-
_IS_INIT = false;
6468
0
6569
}
70+
/// Erase the flash chip.
71+
///
72+
/// # Safety
73+
///
74+
/// Will erase the flash chip. Ensure you really want to erase the
75+
/// flash chip.
6676
#[no_mangle]
6777
#[link_section = ".entry"]
6878
pub unsafe extern "C" fn EraseChip() -> u32 {
@@ -75,6 +85,11 @@ macro_rules! algo {
7585
Err(e) => e.get(),
7686
}
7787
}
88+
/// Erase the a sector on the flash chip.
89+
///
90+
/// # Safety
91+
///
92+
/// Will erase the given sector. Pass a valid sector address.
7893
#[no_mangle]
7994
#[link_section = ".entry"]
8095
pub unsafe extern "C" fn EraseSector(addr: u32) -> u32 {
@@ -87,6 +102,12 @@ macro_rules! algo {
87102
Err(e) => e.get(),
88103
}
89104
}
105+
/// Write to a page on the flash chip.
106+
///
107+
/// # Safety
108+
///
109+
/// Will program the given page. Pass a valid page address, and a
110+
/// valid pointer to at least `size` bytes of data.
90111
#[no_mangle]
91112
#[link_section = ".entry"]
92113
pub unsafe extern "C" fn ProgramPage(addr: u32, size: u32, data: *const u8) -> u32 {

src/main.rs

Lines changed: 27 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3,28 +3,27 @@
33

44
mod algo;
55

6-
use core::mem;
76
use core::mem::MaybeUninit;
87

98
use self::algo::*;
109

11-
fn find_func<T>(tag: [u8; 2]) -> T {
12-
let tag = u16::from_le_bytes(tag);
13-
10+
fn find_func<T>(tag: [u8; 2]) -> Option<T> {
11+
let tag = u16::from_le_bytes(tag) as u32;
12+
type RomTableLookupFn = unsafe extern "C" fn(table: *const u16, code: u32) -> usize;
13+
/// This location in flash holds a 16-bit truncated pointer for the ROM lookup function
14+
const ROM_TABLE_LOOKUP_PTR: *const u16 = 0x0000_0018 as _;
15+
/// This location in flash holds a 16-bit truncated pointer for the ROM function table
16+
/// (there's also a ROM data table which we don't need)
17+
const FUNC_TABLE: *const u16 = 0x0000_0014 as _;
1418
unsafe {
15-
let mut entry = *(0x00000014 as *const u16) as *const u16;
16-
loop {
17-
let entry_tag = entry.read();
18-
if entry_tag == 0 {
19-
panic!("Func not found");
20-
}
21-
entry = entry.add(1);
22-
let entry_addr = entry.read();
23-
entry = entry.add(1);
24-
if entry_tag == tag {
25-
return mem::transmute_copy(&(entry_addr as u32));
26-
}
19+
let lookup_func = ROM_TABLE_LOOKUP_PTR.read() as usize;
20+
let lookup_func: RomTableLookupFn = core::mem::transmute(lookup_func);
21+
let table = FUNC_TABLE.read() as usize;
22+
let result = lookup_func(table as *const u16, tag);
23+
if result == 0 {
24+
return None;
2725
}
26+
Some(core::mem::transmute_copy(&result))
2827
}
2928
}
3029

@@ -38,15 +37,15 @@ struct ROMFuncs {
3837
}
3938

4039
impl ROMFuncs {
41-
fn load() -> Self {
42-
ROMFuncs {
43-
connect_internal_flash: find_func(*b"IF"),
44-
flash_exit_xip: find_func(*b"EX"),
45-
flash_range_erase: find_func(*b"RE"),
46-
flash_range_program: find_func(*b"RP"),
47-
flash_flush_cache: find_func(*b"FC"),
48-
flash_enter_cmd_xip: find_func(*b"CX"),
49-
}
40+
fn load() -> Option<Self> {
41+
Some(ROMFuncs {
42+
connect_internal_flash: find_func(*b"IF")?,
43+
flash_exit_xip: find_func(*b"EX")?,
44+
flash_range_erase: find_func(*b"RE")?,
45+
flash_range_program: find_func(*b"RP")?,
46+
flash_flush_cache: find_func(*b"FC")?,
47+
flash_enter_cmd_xip: find_func(*b"CX")?,
48+
})
5049
}
5150
}
5251

@@ -58,14 +57,14 @@ algo!(RP2040Algo);
5857

5958
const BLOCK_SIZE: u32 = 65536;
6059
const SECTOR_SIZE: u32 = 4096;
61-
const PAGE_SIZE: u32 = 256;
6260
const BLOCK_ERASE_CMD: u8 = 0xd8;
6361
const FLASH_BASE: u32 = 0x1000_0000;
6462

6563
impl FlashAlgo for RP2040Algo {
6664
fn new(_address: u32, _clock: u32, _function: u32) -> Result<Self, ErrorCode> {
67-
let funcs = ROMFuncs::load();
68-
65+
let Some(funcs) = ROMFuncs::load() else {
66+
return Err(ErrorCode::new(1).unwrap());
67+
};
6968
(funcs.connect_internal_flash)();
7069
(funcs.flash_exit_xip)();
7170
Ok(Self { funcs })

0 commit comments

Comments
 (0)