Skip to content
Merged
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
173 changes: 173 additions & 0 deletions hal/blocking/src/gpio_port.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
// Licensed under the Apache-2.0 license

/// This represents a common set of GPIO operation errors. Implementations are
/// free to define more specific or additional error types. However, by providing
/// a mapping to these common errors, generic code can still react to them.
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
#[non_exhaustive]
pub enum GpioErrorKind {
/// The specified GPIO port does not exist
InvalidPort,
/// The specified pin(s) do not exist on this port
InvalidPin,
/// The requested configuration is not supported
UnsupportedConfiguration,
/// The pins cannot be configured as requested (e.g., reserved pins)
ConfigurationFailed,
/// Cannot change pins currently used by another peripheral
PinInUse,
/// The interrupt requested cannot be configured
InterruptConfigurationFailed,
/// The requested operation is not allowed in the current state
PermissionDenied,
/// Hardware failure during operation
HardwareFailure,
/// Operation timed out
Timeout,
/// The pin is not configured for the requested operation
/// (e.g., reading output value from input pin)
InvalidMode,
}

/// Trait for GPIO errors
pub trait GpioError: core::fmt::Debug {
/// Convert error to a generic error kind
///
/// By using this method, errors freely defined by GPIO implementations
/// can be converted to a set of generic errors upon which generic
/// code can act.
fn kind(&self) -> GpioErrorKind;
}

impl GpioError for core::convert::Infallible {
fn kind(&self) -> GpioErrorKind {
match *self {}
}
}

/// Edge sensitivity for interrupt configuration
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum EdgeSensitivity {
/// Trigger on rising edge
RisingEdge,
/// Trigger on falling edge
FallingEdge,
/// Trigger on both rising and falling edges
BothEdges,
/// Trigger on high level
HighLevel,
/// Trigger on low level
LowLevel,
}

/// Operations for interrupt control
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum InterruptOperation {
/// Enable interrupts
Enable,
/// Disable interrupts
Disable,
/// Clear pending interrupts
Clear,
/// Check if interrupts are pending
IsPending,
}

/// Trait for types that define an error type for GPIO operations
pub trait GpioErrorType {
/// Error type for GPIO operations
type Error: GpioError;
}

/// Type used to represent pin masks
pub trait PinMask: Copy + core::fmt::Debug {
/// Create an empty mask (no pins selected)
fn empty() -> Self;

/// Create a mask with all pins selected
fn all() -> Self;

/// Check if the mask is empty
fn is_empty(&self) -> bool;

/// Check if the mask contains the specified pins
fn contains(&self, other: Self) -> bool;

/// Merge two masks
fn union(&self, other: Self) -> Self;

/// Get intersection of two masks
fn intersection(&self, other: Self) -> Self;

/// Toggle pins in mask
fn toggle(&self) -> Self;
}

/// Base trait for GPIO port operations with integrated error handling
pub trait GpioPort: GpioErrorType {
/// Configuration type for GPIO pins
type Config;

/// Mask type for pin identification
type Mask: PinMask;

/// Configure GPIO pins with specified configuration
fn configure(&mut self, pins: Self::Mask, config: Self::Config) -> Result<(), Self::Error>;

/// Set and clear pins atomically using set and reset masks
fn set_reset(
&mut self,
set_mask: Self::Mask,
reset_mask: Self::Mask,
) -> Result<(), Self::Error>;

/// Read current state of input pins
fn read_input(&self) -> Result<Self::Mask, Self::Error>;

/// Toggle specified output pins
fn toggle(&mut self, pins: Self::Mask) -> Result<(), Self::Error>;
}

/// Trait for GPIO interrupt capabilities with integrated error handling
pub trait GpioInterrupt: GpioErrorType {
/// Mask type for pin identification
type Mask: PinMask;

/// Configure interrupt sensitivity for specified pins
fn irq_configure(
&mut self,
mask: Self::Mask,
sensitivity: EdgeSensitivity,
) -> Result<(), Self::Error>;

/// Control interrupt operations (enable, disable, etc.)
fn irq_control(
&mut self,
mask: Self::Mask,
operation: InterruptOperation,
) -> Result<bool, Self::Error>;

/// Register a callback for interrupt handling
fn register_interrupt_handler<F>(
&mut self,
mask: Self::Mask,
handler: F,
) -> Result<(), Self::Error>
where
F: FnMut(Self::Mask) + Send + 'static;
}

/// Trait for splitting a GPIO port into individual pins
pub trait SplitPort: GpioPort + Sized {
/// Container type returned when splitting the port
type PortPins;

/// Split the port into a container of pins
fn split(self) -> Self::PortPins;
}

/// Combined trait for full GPIO functionality
pub trait GpioController: GpioPort + GpioInterrupt {}

/// Automatically implement GpioController for any type implementing both required traits
impl<T: GpioPort + GpioInterrupt> GpioController for T {}
16 changes: 13 additions & 3 deletions hal/blocking/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,24 @@
// Licensed under the Apache-2.0 license

//! Blocking/synchronous HAL traits for OpenPRoT
//! Blocking (synchronous) HAL traits for OpenPRoT
//!
//! This crate re-exports embedded-hal 1.0 traits for blocking hardware abstraction
//! layer operations such as SPI, I2C, GPIO, and other hardware interfaces.
//! This crate provides a blocking (synchronous) hardware abstraction layer (HAL) for
//! OpenPRoT-compliant platforms. It includes platform-specific modules such as reset
//! control and re-exports traits from `embedded-hal` 1.0 for common hardware interfaces
//! like SPI, I2C, GPIO, and delays.
//!
//! The goal is to offer a unified, safe, and no_std-compatible interface for embedded
//! development across multiple chip families.

#![no_std]
#![forbid(unsafe_code)]
#![deny(missing_docs)]

/// Gpio port module
pub mod gpio_port;
/// Reset and clocking traits for OpenPRoT HAL
pub mod system_control;

// Re-export embedded-hal 1.0 traits
pub use embedded_hal::delay::DelayNs;
pub use embedded_hal::digital::{InputPin, OutputPin, StatefulOutputPin};
Expand Down
Loading