Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions rp-binary-info/src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,25 @@ macro_rules! int {
}};
}

/// Equivalent to the pico-sdk bi_2pins_with_func(p0, p1, func)
#[macro_export]
macro_rules! pins_with_function {
($pin_0:expr, $pin_1:expr, $func:expr) => {{
static ENTRY: $crate::PinsWithFunctionEntry = $crate::PinsWithFunctionEntry::new($pin_0, $pin_1, $func);
ENTRY.addr()
}};
}

/// Equivalent to the pico-sdk bi_1pin_with_name(p0, name)
#[macro_export]
macro_rules! pin_with_name {
($pin:expr, $name:expr) => {{
static ENTRY: $crate::PinWithNameEntry = $crate::PinWithNameEntry::new($pin, $name);
ENTRY.addr()
}};
}


/// Generate a static item containing the given pointer, and return its
/// [`EntryAddr`](super::EntryAddr).
///
Expand Down
63 changes: 62 additions & 1 deletion rp-binary-info/src/types.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
//! Types for the Binary Info system
use crate::consts::{TAG_RASPBERRY_PI};

// pico-sck/src/common/pico_binary_info/include/pico/binary_info/structure.h
const BI_PINS_ENCODING_MULTI: u32 = 2;

/// This is the 'Binary Info' header block that `picotool` looks for in your UF2
/// file/ELF file/Pico in Bootloader Mode to give you useful metadata about your
Expand Down Expand Up @@ -116,7 +120,7 @@ pub enum DataType {
BlockDevice = 7,
/// GPIO pins, with their function
PinsWithFunction = 8,
/// GPIO pins, with their name
/// GPIO pins, with their name pico-sdk: BINARY_INFO_TYPE_PINS_WITH_NAME
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// GPIO pins, with their name pico-sdk: BINARY_INFO_TYPE_PINS_WITH_NAME
/// GPIO pins, with their name
///
/// The Pico SDK calls this `BINARY_INFO_TYPE_PINS_WITH_NAME`

PinsWithName = 9,
/// GPIO pins, with multiple names?
PinsWithNames = 10,
Expand Down Expand Up @@ -161,6 +165,7 @@ impl StringEntry {
// core::ffi::c_char` pointers between threads. We only allow these to be
// created with static string slices, so it's OK.
unsafe impl Sync for StringEntry {}
unsafe impl Sync for PinWithNameEntry {}

/// An entry which contains both an ID (e.g. `ID_RP_BINARY_END`) and an integer.
#[repr(C)]
Expand Down Expand Up @@ -189,6 +194,62 @@ impl IntegerEntry {
}
}

/// An entry which contains a pin_encoding.
#[repr(C)]
pub struct PinsWithFunctionEntry {
header: EntryCommon,
pin_encoding: u32,
}

impl PinsWithFunctionEntry {
/// Create a new `PinsWithFunctionEntry`
pub const fn new(pin_0: u32, pin_1: u32, func: u32) -> PinsWithFunctionEntry {
PinsWithFunctionEntry {
header: EntryCommon {
data_type: DataType::PinsWithFunction,
tag: TAG_RASPBERRY_PI,
},
pin_encoding: BI_PINS_ENCODING_MULTI
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's worth noting that this is a value with multiple fields, and raspberry pi seem to indicate that there are no more pins by setting two consecutive fields to the same value.

You could also consider using bitbybit::bitfield to describe this 32-bit value, and avoid needing to do a bunch of shifts using magic numbers. I have examples you can refer to

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could then change this to take a slice of pins, rather than only two pins.

| (func << 3)
| (pin_0 << 7)
| (pin_1 << 12)
| (pin_1 << 17)
}
}

/// Get this entry's address
pub const fn addr(&self) -> EntryAddr {
EntryAddr(self as *const Self as *const u32)
}
}

/// An entry which contains a pin and a name.
#[repr(C)]
pub struct PinWithNameEntry {
header: EntryCommon,
pin_mask: u32,
label: *const core::ffi::c_char,
}

impl PinWithNameEntry {
/// Create a new `PinWithNameEntry`
pub const fn new(pin: u32, name: &'static core::ffi::CStr) -> PinWithNameEntry {
PinWithNameEntry {
header: EntryCommon {
data_type: DataType::PinsWithName,
tag: TAG_RASPBERRY_PI,
},
pin_mask: 1u32 << pin,
label: name.as_ptr()
}
}

/// Get this entry's address
pub const fn addr(&self) -> EntryAddr {
EntryAddr(self as *const Self as *const u32)
}
}

/// An alias for IntegerEntry, taking a pointer instead of an integer
#[repr(C)]
pub struct PointerEntry {
Expand Down
Loading