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
42 changes: 40 additions & 2 deletions src/ariel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use crate::{
krate::{Crate, DependencyFull},
laze::{LazeContext, LazeFile, StringOrVecString},
parse_sbd_files,
sbd::{Board, Button, Led, SbdFile},
sbd::{Board, Button, Led, SbdFile, Uart},
};

#[derive(argh::FromArgs, Debug)]
Expand Down Expand Up @@ -183,6 +183,9 @@ pub fn render_ariel_board_crate(sbd: &SbdFile) -> FileMap {
if board.has_buttons() {
board_builder.provides.insert("has_buttons".into());
}
if board.has_host_facing_uart() {
board_builder.provides.insert("has_host_facing_uart".into());
}

if let Some(swi) = board.ariel.swi {
board_builder.provides.insert("has_swi".into());
Expand Down Expand Up @@ -248,6 +251,12 @@ fn render_board_rs(board: &Board) -> String {
pub fn render_build_rs(boards: &[Board]) -> String {
let mut build_rs = String::new();

// Not done in the krate.rs prettifier because this does not work on files that are later
// inlined.
//
// Conditional until <https://github.com/rust-lang/rust/issues/54726> is resolved.
build_rs.push_str("#![cfg_attr(rustfmt, rustfmt::skip)]\n\n");

build_rs.push_str("pub fn main() {\n");

for board in boards {
Expand Down Expand Up @@ -306,14 +315,17 @@ fn render_pins(board: &Board) -> String {

pins.push_str("pub mod pins {\n");

if board.has_leds() || board.has_buttons() {
if board.has_leds() || board.has_buttons() || board.has_uarts() {
pins.push_str("use ariel_os_hal::hal::peripherals;\n\n");
if let Some(leds) = board.leds.as_ref() {
pins.push_str(&render_led_pins(leds));
}
if let Some(buttons) = board.buttons.as_ref() {
pins.push_str(&render_button_pins(buttons));
}
if let Some(uarts) = board.uarts.as_ref() {
pins.push_str(&render_uarts(uarts));
}
}

pins.push_str("}\n");
Expand Down Expand Up @@ -348,3 +360,29 @@ fn render_button_pins(buttons: &[Button]) -> String {

buttons_rs
}

fn render_uarts(uarts: &[Uart]) -> String {
let mut code = String::new();

code.push_str("ariel_os_hal::define_uarts![\n");

for (uart_number, uart) in uarts.iter().enumerate() {
let name = uart.name.as_ref().map_or_else(|| format!("_unnamed_uart_{uart_number}").into(), std::borrow::Cow::from);
let Some(device) = uart.possible_peripherals.as_ref().and_then(|v| v.first()) else {
eprintln!("warning: No peripheral defined for UART, making it unusable in Ariel output.");
eprintln!("Affected UART: {uart:?}");
continue;
};
if uart.possible_peripherals.as_ref().is_some_and(|v| v.len() > 1) {
eprintln!("warning: Multiple hardware devices are available, but Ariel OS does not process any but the first.");
eprintln!("Affected UART: {uart:?}");
}
// Deferring to a macro so that any actual logic in there is handled in the OS where it
// belongs; this merely processes the data into a format usable there.
writeln!(code, "{{ name: {}, device: {}, tx: {}, rx: {}, host_facing: {} }},", name, device, uart.tx_pin, uart.rx_pin, uart.host_facing).unwrap();
}

code.push_str("];\n");

code
}
5 changes: 1 addition & 4 deletions src/krate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,7 @@ impl Crate {
let formatted = prettyplease::unparse(&syntax_tree);
content.clear();
content.push_str("// @generated\n");
content.push_str("//! Generated by sbd-gen\n");
// Condition is a workaround for <https://github.com/rust-lang/rust/issues/54726>
// -- otherwise, generated code is limited to nightly.
content.push_str("#![cfg_attr(rustfmt, rustfmt::skip)]\n\n");
content.push_str("// Generated by sbd-gen\n");
content.push_str(&formatted);
}
});
Expand Down
49 changes: 49 additions & 0 deletions src/sbd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use crate::{

#[serde_as]
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct SbdFile {
pub include: Option<Vec<String>>,
#[serde_as(as = "Option<KeyValueMap<_>>")]
Expand All @@ -20,6 +21,7 @@ pub struct SbdFile {

#[serde_as]
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct Board {
#[serde(rename = "$key$")]
pub name: String,
Expand Down Expand Up @@ -61,9 +63,26 @@ impl Board {
false
}
}

pub fn has_uarts(&self) -> bool {
if let Some(uarts) = &self.uarts {
!uarts.is_empty()
} else {
false
}
}

pub fn has_host_facing_uart(&self) -> bool {
if let Some(uarts) = &self.uarts {
uarts.iter().any(|u| u.host_facing)
} else {
false
}
}
}

#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
// FIXME: update Ariel and then #[serde(deny_unknown_fields)]
pub struct Led {
#[serde(rename = "$key$")]
pub name: String,
Expand All @@ -73,6 +92,7 @@ pub struct Led {
}

#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
// FIXME: update Ariel and then #[serde(deny_unknown_fields)]
pub struct Button {
#[serde(rename = "$key$")]
pub name: String,
Expand All @@ -81,20 +101,23 @@ pub struct Button {
}

#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
#[serde(rename_all = "snake_case")]
#[serde(tag = "type")]
pub enum Quirk {
SetPin(SetPinOp),
}

#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct SetPinOp {
pub description: Option<String>,
pub pin: String,
pub level: PinLevel,
}

#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, Default)]
#[serde(deny_unknown_fields)]
#[serde(rename_all = "snake_case")]
pub enum PinLevel {
#[default]
Expand All @@ -103,18 +126,44 @@ pub enum PinLevel {
}

#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct Debugger {
#[serde(rename = "type")]
pub type_: String,
pub uart: Option<Uart>,
}

#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct Uart {
#[serde(rename = "$key$")]
pub name: Option<String>,
pub rx_pin: String,
pub tx_pin: String,
pub cts_pin: Option<String>,
pub rts_pin: Option<String>,
/// Peripheral device names, each of which is fundamentally available to serve this connection
/// as the peripheral that takes control of the TX and RX pins.
///
/// This item is on the fringe of being a fact about the board, because while it is a fact, it
/// is a pure function of the MCU and the assigned pins.
///
/// The way this is used in Ariel is also just borderline correct, as Ariel OS's UART devices
/// are (at least on platforms such as nRF) composite devices that combine a UART driver with
/// several other related peripherals (eg. `UARTE0 => UARTE0 + TIMER4 + PPI_CH14 + PPI_CH15 +
/// PPI_GROUP5`), encompassing an instance of MCU specific information that is encoded in the
/// Ariel OS source code. The way these names are used there is correct under the (currently
/// valid) assumption that the composite items are named after the main UART driver they
/// include. (Also, currently, Ariel OS picks the first of them, while generally this is not an
/// ordered structure).
pub possible_peripherals: Option<Vec<String>>,

/// Set if the board supports using it with a host system (e.g. the build host), and this UART
/// would typically face that system.
///
/// For example, this is set on boards with built-in programmers on UARTs that are exposed by
/// the programmer as USB serial devices. Typical applications querying this are tools that
/// reprot debug or measurement data.
#[serde(default)]
pub host_facing: bool,
}
6 changes: 3 additions & 3 deletions src/snapshots/sbd_gen__tests__sbd_ariel.snap
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ expression: ariel
FileMap {
map: {
"Cargo.toml": "# @generated\n\n[package]\nname = \"ariel-os-boards\"\n\n[package.edition]\nworkspace = true\n\n[package.license]\nworkspace = true\n\n[package.rust-version]\nworkspace = true\n\n[dependencies.ariel-os-embassy-common]\nworkspace = true\n\n[dependencies.ariel-os-hal]\nworkspace = true\n\n[dependencies.cfg-if]\nworkspace = true\n\n[features]\nno-boards = []\n",
"build.rs": "// @generated\n//! Generated by sbd-gen\n#![cfg_attr(rustfmt, rustfmt::skip)]\n\npub fn main() {\n println!(\"cargo::rustc-check-cfg=cfg(context, values(\\\"nrf52840dk\\\"))\");\n}\n",
"build.rs": "// @generated\n// Generated by sbd-gen\n#![cfg_attr(rustfmt, rustfmt::skip)]\npub fn main() {\n println!(\"cargo::rustc-check-cfg=cfg(context, values(\\\"nrf52840dk\\\"))\");\n}\n",
"laze.yml": "# yamllint disable-file\n\nbuilders:\n- name: nrf52840dk\n parent: nrf52840\n provides:\n - has_buttons\n - has_leds\n - has_usb_device_port\n",
"src/lib.rs": "// @generated\n//! Generated by sbd-gen\n#![cfg_attr(rustfmt, rustfmt::skip)]\n\n#![no_std]\ncfg_if::cfg_if! {\n if #[cfg(context = \"nrf52840dk\")] { include!(\"nrf52840dk.rs\"); } else {}\n}\n",
"src/nrf52840dk.rs": "// @generated\n//! Generated by sbd-gen\n#![cfg_attr(rustfmt, rustfmt::skip)]\n\npub mod pins {\n use ariel_os_hal::hal::peripherals;\n ariel_os_hal::define_peripherals!(\n LedPeripherals { led0 : P0_13, led1 : P0_14, led2 : P0_15, led3 : P0_16, }\n );\n ariel_os_hal::define_peripherals!(\n ButtonPeripherals { button0 : P0_11, button1 : P0_12, button2 : P0_24, button3 :\n P0_25, }\n );\n}\n#[allow(unused_variables)]\npub fn init(peripherals: &mut ariel_os_hal::hal::OptionalPeripherals) {}\n",
"src/lib.rs": "// @generated\n// Generated by sbd-gen\n#![no_std]\ncfg_if::cfg_if! {\n if #[cfg(context = \"nrf52840dk\")] { include!(\"nrf52840dk.rs\"); } else {}\n}\n",
"src/nrf52840dk.rs": "// @generated\n// Generated by sbd-gen\npub mod pins {\n use ariel_os_hal::hal::peripherals;\n ariel_os_hal::define_peripherals!(\n LedPeripherals { led0 : P0_13, led1 : P0_14, led2 : P0_15, led3 : P0_16, }\n );\n ariel_os_hal::define_peripherals!(\n ButtonPeripherals { button0 : P0_11, button1 : P0_12, button2 : P0_24, button3 :\n P0_25, }\n );\n}\n#[allow(unused_variables)]\npub fn init(peripherals: &mut ariel_os_hal::hal::OptionalPeripherals) {}\n",
},
tagfile: Some(
".sbd-gen",
Expand Down
Loading