ad7124_rs/
lib.rs

1//! # AD7124 Driver
2//!
3//! A platform-independent driver for the AD7124 family (AD7124-4/AD7124-8) with comprehensive embedded-hal support.
4//!
5//! This v4.0 driver implements lessons learned from comprehensive architecture refactoring:
6//! - **Unified Naming**: Family-consistent type naming throughout
7//! - **Core-Transport Separation**: Business logic independent of transport layer
8//! - **Embassy Ready**: Full async/await support with Embassy templates
9//! - **Simple Construction**: Direct driver construction for both sync and async
10//!
11//! ## Features
12//!
13//! - **Multiple Device Support**: AD7124-4 (4-channel), AD7124-8 (8-channel)
14//! - **Transport Layer**: SPI with embedded-hal integration
15//! - **Sync & Async**: Both blocking and non-blocking APIs
16//! - **24-bit Precision**: High-resolution ADC measurements
17//! - **Programmable Gain**: 1x to 128x amplification
18//! - **Multiple Reference Sources**: Internal 2.5V, external, or AVDD-AVSS
19//! - **No-std Compatible**: Works in embedded environments
20//! - **C FFI Support**: Static library generation for C integration
21//!
22//! ## Quick Start
23//!
24//! ### Synchronous Usage
25//!
26//! ```rust,ignore
27//! use ad7124_rs::{AD7124Sync, DeviceType, SpiTransport};
28//!
29//! // Create SPI transport (example with embedded-hal)
30//! let transport = SpiTransport::new(spi, cs, delay);
31//!
32//! // Create and initialize driver
33//! let mut adc = AD7124Sync::new(transport, DeviceType::AD7124_8)?;
34//! adc.init()?;
35//!
36//! // Setup single-ended measurement on channel 0
37//! adc.setup_single_ended(0, ad7124_rs::ChannelInput::Ain0, 0)?;
38//!
39//! // Read voltage
40//! let voltage = adc.read_voltage(0)?;
41//! println!("Voltage: {:.3}V", voltage);
42//! ```
43//!
44//! ### Asynchronous Usage
45//!
46//! ```rust,ignore
47//! use ad7124_rs::{AD7124Async, DeviceType, SpiTransport};
48//!
49//! // Create SPI transport
50//! let transport = SpiTransport::new(spi, cs, delay);
51//!
52//! // Create and initialize async driver
53//! let mut adc = AD7124Async::new(transport, DeviceType::AD7124_8)?;
54//! adc.init().await?;
55//!
56//! // Setup differential measurement
57//! adc.setup_differential(0, ad7124_driver::ChannelInput::Ain0,
58//!                       ad7124_driver::ChannelInput::Ain1, 0).await?;
59//!
60//! // Read voltage
61//! let voltage = adc.read_voltage(0).await?;
62//! ```
63//!
64
65#![no_std]
66#![cfg_attr(not(feature = "capi"), deny(unsafe_code))]
67#![warn(missing_docs)]
68#![warn(
69    missing_debug_implementations,
70    rust_2018_idioms,
71    trivial_casts,
72    unused_qualifications
73)]
74
75// Core modules - always available
76pub mod device_type;
77pub mod errors;
78pub mod registers;
79pub mod transport;
80
81// Driver core implementation
82pub mod ad7124;
83
84// C FFI interface (optional feature)
85#[cfg(feature = "capi")]
86pub mod ffi;
87
88// Re-exports for convenience
89pub use device_type::{DeviceCapabilities, DeviceFeature, DeviceType};
90pub use errors::{AD7124CoreError, AD7124Error};
91pub use registers::*;
92
93// Transport re-exports
94pub use transport::{spi_speeds, SpiSpeedValidator, SyncSpiTransport};
95
96#[cfg(feature = "async")]
97pub use transport::AsyncSpiTransport;
98
99#[cfg(feature = "embedded-hal")]
100pub use transport::SpiTransport;
101
102// Driver re-exports from ad7124 module (unified API)
103pub use ad7124::AD7124Sync;
104
105#[cfg(feature = "async")]
106pub use ad7124::AD7124Async;
107
108// Configuration re-exports
109pub use ad7124::{AD7124Config, ChannelConfig, FilterConfig, SetupConfig};
110
111/// Library version information
112pub mod version {
113    /// Major version
114    pub const MAJOR: u32 = 4;
115    /// Minor version  
116    pub const MINOR: u32 = 0;
117    /// Patch version
118    pub const PATCH: u32 = 0;
119    /// Version string
120    pub const VERSION: &str = concat!(
121        env!("CARGO_PKG_VERSION_MAJOR"),
122        ".",
123        env!("CARGO_PKG_VERSION_MINOR"),
124        ".",
125        env!("CARGO_PKG_VERSION_PATCH")
126    );
127}
128
129/// Common type aliases for convenience
130pub mod types {
131    use crate::AD7124Error;
132
133    /// Standard result type for AD7124 operations
134    pub type Result<T, TransportE = (), PinE = ()> =
135        core::result::Result<T, AD7124Error<TransportE, PinE>>;
136
137    /// Core error result type
138    pub type CoreResult<T> = core::result::Result<T, crate::errors::AD7124CoreError>;
139
140    /// Device capabilities type
141    pub type Capabilities = crate::device_type::DeviceCapabilities;
142
143    /// Configuration type
144    pub type Config = crate::ad7124::AD7124Config;
145}
146
147/// Prelude module for common imports
148pub mod prelude {
149    pub use crate::ad7124::{AD7124Config, AD7124Sync, ChannelConfig, FilterConfig, SetupConfig};
150    pub use crate::device_type::{DeviceCapabilities, DeviceType};
151    pub use crate::errors::{AD7124CoreError, AD7124Error};
152    pub use crate::registers::{
153        ChannelInput, ClockSource, OperatingMode, PgaGain, PowerMode, ReferenceSource,
154    };
155    pub use crate::transport::SyncSpiTransport;
156    pub use crate::types::{CoreResult, Result};
157
158    #[cfg(feature = "async")]
159    pub use crate::ad7124::AD7124Async;
160
161    #[cfg(feature = "async")]
162    pub use crate::transport::AsyncSpiTransport;
163
164    #[cfg(feature = "embedded-hal")]
165    pub use crate::transport::SpiTransport;
166}
167
168/// Compile-time feature validation
169const _: () = {
170    #[cfg(all(feature = "async", not(feature = "embedded-hal-async")))]
171    compile_error!("async feature requires embedded-hal-async feature");
172
173    #[cfg(all(
174        feature = "full-async",
175        not(all(feature = "async", feature = "embedded-hal-async"))
176    ))]
177    compile_error!("full-async feature requires both async and embedded-hal-async features");
178};
179
180// Panic handler for C FFI builds - applications should provide their own
181#[cfg(all(not(test), feature = "capi"))]
182#[panic_handler]
183fn panic(_info: &core::panic::PanicInfo<'_>) -> ! {
184    loop {}
185}