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}