Skip to content

Commit

Permalink
Demonstrate GPIO interrupts on the LPC55S69-EVK board.
Browse files Browse the repository at this point in the history
Pressing the USER button generates an interrupt to the button task.

A single press will increment the RGB pattern.

Quick (~1.5s) successive presses 2nd, 3rd, and subsequent will respecitvely
  - turn off LEDs
  - blink LEDs
  - cycle through RBG pattern including all off.

Minor updates to other app.toml files:
  - add `pint` and `inputmux` peripherals to their `gpio_driver` tasks.
  - when compiling all targets, some needed slight allocation
    adjustments not related to this PR.

Future: The unimplemented combinations could return an error/fault if called.
  • Loading branch information
lzrd committed Nov 26, 2024
1 parent 70ecce9 commit d7bbc5b
Show file tree
Hide file tree
Showing 9 changed files with 650 additions and 0 deletions.
38 changes: 38 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

160 changes: 160 additions & 0 deletions app/lpc55xpresso/app-button.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
name = "lpc55xpresso-button"
target = "thumbv8m.main-none-eabihf"
board = "lpcxpresso55s69"
chip = "../../chips/lpc55"
stacksize = 1024
image-names = ["a", "b"]
fwid = true

[kernel]
name = "lpc55xpresso"
features = ["dump", "dice-self"]
requires = {flash = 55040, ram = 4096}

[caboose]
region = "flash"
size = 256
default = true

[tasks.jefe]
name = "task-jefe"
priority = 0
max-sizes = {flash = 16384, ram = 2048}
start = true
features = ["dump"]
stacksize = 1536
notifications = ["fault", "timer"]
extern-regions = ["sram2"]

[tasks.jefe.config.allowed-callers]
request_reset = ["update_server"]

[tasks.hiffy]
name = "task-hiffy"
priority = 5
features = ["lpc55", "gpio"]
max-sizes = {flash = 32768, ram = 16384 }
stacksize = 2048
start = true
task-slots = ["gpio_driver", "update_server"]

[tasks.idle]
name = "task-idle"
priority = 7
max-sizes = {flash = 256, ram = 256}
stacksize = 256
start = true

[tasks.update_server]
name = "lpc55-update-server"
priority = 3
max-sizes = {flash = 26720, ram = 16704}
stacksize = 8192
start = true
sections = {bootstate = "usbsram"}
uses = ["flash_controller", "hash_crypt"]
notifications = ["flash-irq", "hashcrypt-irq"]
interrupts = {"flash_controller.irq" = "flash-irq", "hash_crypt.irq" = "hashcrypt-irq"}
task-slots = [{"syscon" = "syscon_driver"}, "jefe"]

[tasks.syscon_driver]
name = "drv-lpc55-syscon"
priority = 2
max-sizes = {flash = 8192, ram = 2048}
uses = ["syscon", "anactrl", "pmc"]
start = true
stacksize = 1000
task-slots = ["jefe"]

[tasks.gpio_driver]
name = "drv-lpc55-gpio"
priority = 3
max-sizes = {flash = 8192, ram = 2048}
uses = ["gpio", "iocon", "pint", "inputmux"]
start = true
stacksize = 1000
task-slots = ["syscon_driver"]

[tasks.user_leds]
name = "drv-user-leds"
features = ["lpc55"]
priority = 4
max-sizes = {flash = 8192, ram = 2048}
start = true
stacksize = 1000
task-slots = ["gpio_driver"]
notifications = ["timer"]

[tasks.button]
name = "task-button"
priority = 6
start = true
notifications = ["timer", "button-irq"]
interrupts = { "pint.irq0" = "button-irq"}
stacksize = 4096
task-slots = ["gpio_driver", {"syscon" = "syscon_driver"}]

[tasks.button.config]
pins = [
{ name = "BUTTON", pin = { port = 1, pin = 9}, alt = 0, pint = 0, direction = "input", opendrain = "normal" },
{ name = "RED_LED", pin = { port = 1, pin = 6}, alt = 0, direction = "output", value = true },
{ name = "GREEN_LED", pin = { port = 1, pin = 7}, alt = 0, direction = "output", value = true },
{ name = "BLUE_LED", pin = { port = 1, pin = 4}, alt = 0, direction = "output", value = true },
]

[tasks.usart_driver]
name = "drv-lpc55-usart"
priority = 4
max-sizes = {flash = 8192, ram = 2048}
uses = ["flexcomm0"]
start = true
notifications = ["usart-irq"]
interrupts = {"flexcomm0.irq" = "usart-irq"}
stacksize = 1000
task-slots = ["gpio_driver", "syscon_driver"]

[tasks.usart_driver.config]
pins = [
{ pin = { port = 0, pin = 29}, alt = 1},
{ pin = { port = 0, pin = 30}, alt = 1}
]

[tasks.i2c_driver]
name = "drv-lpc55-i2c"
priority = 4
uses = ["flexcomm4"]
start = true
stacksize = 1000
task-slots = ["gpio_driver", "syscon_driver"]

[tasks.rng_driver]
name = "drv-lpc55-rng"
priority = 3
max-sizes = {flash = 16384, ram = 4096}
uses = ["rng", "pmc"]
start = true
stacksize = 2200
task-slots = ["syscon_driver"]

[tasks.dump_agent]
name = "task-dump-agent"
features = ["no-rot"]
priority = 5
max-sizes = {flash = 32768, ram = 2240 }
start = true
task-slots = ["jefe"]
stacksize = 1536
extern-regions = ["sram2"]

[tasks.attest]
name = "task-attest"
priority = 5
max-sizes = {flash = 35072, ram = 16384}
stacksize = 12304
start = false
extern-regions = ["dice_alias", "dice_certs"]

[signing.certs]
signing-certs = ["../../support/fake_certs/fake_certificate.der.crt"]
root-certs = ["../../support/fake_certs/fake_certificate.der.crt"]
private-key = "../../support/fake_certs/fake_private_key.pem"
43 changes: 43 additions & 0 deletions idl/button.idol
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// User Button and LED API

Interface(
name: "Button",
ops: {
"press": (
reply: Result(
ok: "u8",
err: CLike("ButtonError"),
),
idempotent: true,
),
"off": (
reply: Result(
ok: "()",
err: CLike("ButtonError"),
),
idempotent: true,
),
"set": (
args: {
"rgb": "u8",
},
reply: Result(
ok: "()",
err: CLike("ButtonError"),
),
idempotent: true,
),
"blink": (
description: "blinks the LED at a fixed speed",
args: {
"on": "u32",
"off": "u32",
},
reply: Result(
ok: "()",
err: CLike("ButtonError"),
),
idempotent: true,
),
},
)
28 changes: 28 additions & 0 deletions task/button-api/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
[package]
name = "button-api"
version = "0.1.0"
edition = "2021"

[features]

[dependencies]
counters = { path = "../../lib/counters" }
derive-idol-err = { path = "../../lib/derive-idol-err" }
hubpack = { workspace = true }
idol-runtime = { workspace = true }
num-traits = { workspace = true }
serde = { workspace = true }
userlib = { path = "../../sys/userlib", features = ["panic-messages"] }
zerocopy = { workspace = true }

[build-dependencies]
idol = { workspace = true }
serde = { workspace = true }

[lib]
test = false
doctest = false
bench = false

[lints]
workspace = true
10 changes: 10 additions & 0 deletions task/button-api/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

use std::error::Error;

fn main() -> Result<(), Box<dyn Error + Send + Sync>> {
idol::client::build_client_stub("../../idl/button.idol", "client_stub.rs")?;
Ok(())
}
24 changes: 24 additions & 0 deletions task/button-api/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

//! API crate for the 'button' task.
#![no_std]

use derive_idol_err::IdolError;
use userlib::{sys_send, FromPrimitive};

#[derive(Copy, Clone, Debug, FromPrimitive, IdolError, counters::Count)]
pub enum ButtonError {
InvalidValue = 1,
TaskRestarted = 2,
}

impl From<idol_runtime::ServerDeath> for ButtonError {
fn from(_: idol_runtime::ServerDeath) -> Self {
ButtonError::TaskRestarted
}
}

include!(concat!(env!("OUT_DIR"), "/client_stub.rs"));
38 changes: 38 additions & 0 deletions task/button/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
[package]
name = "task-button"
version = "0.1.0"
edition = "2021"

[dependencies]
drv-lpc55-gpio-api = { path = "../../drv/lpc55-gpio-api"}
button-api = { path = "../button-api"}
arrayvec.workspace = true
hubpack = { workspace = true }
idol-runtime = { workspace = true }
num-traits = { workspace = true }
serde = { workspace = true }
serde_with = { version = "3.3.0", default-features = false, features = ["macros"] }
static-cell = { path = "../../lib/static-cell" }
unwrap-lite = { path = "../../lib/unwrap-lite" }
userlib = { path = "../../sys/userlib", features = ["panic-messages"] }
zerocopy = { workspace = true }

[build-dependencies]
anyhow.workspace = true
idol.workspace = true
serde.workspace = true
quote = { workspace = true }
build-lpc55pins = { path = "../../build/lpc55pins" }
build-util = { path = "../../build/util" }

[features]
no-ipc-counters = ["idol/no-counters"]

[[bin]]
name = "task-button"
test = false
doctest = false
bench = false

[lints]
workspace = true
33 changes: 33 additions & 0 deletions task/button/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

use anyhow::Result;
use build_lpc55pins::PinConfig;
use idol::{server::ServerStyle, CounterSettings};
use serde::Deserialize;

#[derive(Deserialize)]
#[serde(deny_unknown_fields, rename_all = "kebab-case")]
struct TaskConfig {
pins: Vec<PinConfig>,
}

fn main() -> Result<()> {
build_util::expose_target_board();
build_util::build_notifications()?;

idol::Generator::new()
.with_counters(CounterSettings::default().with_server_counters(false))
.build_server_support(
"../../idl/button.idol",
"server_stub.rs",
ServerStyle::InOrder,
)
.unwrap();

let task_config = build_util::task_config::<TaskConfig>()?;
build_lpc55pins::codegen(task_config.pins)?;

Ok(())
}
Loading

0 comments on commit d7bbc5b

Please sign in to comment.