Skip to content

Commit 4a0027b

Browse files
committed
Add i2c.rs for hal.
1 parent 1d896fb commit 4a0027b

File tree

5 files changed

+185
-99
lines changed

5 files changed

+185
-99
lines changed
Lines changed: 1 addition & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::common::{DmaBuffer, DummyDelay};
2+
use crate::i2c::common::{I2cConfig, I2cSEvent, I2cXferMode};
23
use crate::uart::UartController;
34
use ast1060_pac::{I2cbuff, I2cglobal, Scu};
45
use core::cmp::min;
@@ -11,31 +12,6 @@ use proposed_traits::i2c_target::I2CTarget;
1112

1213
static I2CGLOBAL_INIT: AtomicBool = AtomicBool::new(false);
1314

14-
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
15-
#[repr(u32)]
16-
pub enum I2cSpeed {
17-
Standard = 100_000,
18-
Fast = 400_000,
19-
FastPlus = 1_000_000,
20-
}
21-
22-
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
23-
#[repr(u8)]
24-
pub enum I2cXferMode {
25-
DmaMode,
26-
BuffMode,
27-
ByteMode,
28-
}
29-
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
30-
#[repr(u8)]
31-
pub enum I2cSEvent {
32-
SlaveRdReq,
33-
SlaveWrReq,
34-
SlaveRdProc,
35-
SlaveWrRecvd,
36-
SlaveStop,
37-
}
38-
3915
pub trait Instance {
4016
fn ptr() -> *const ast1060_pac::i2c::RegisterBlock;
4117
fn buff_ptr() -> *const ast1060_pac::i2cbuff::RegisterBlock;
@@ -238,78 +214,6 @@ impl embedded_hal::i2c::Error for Error {
238214
}
239215
}
240216

241-
pub struct TimingConfig {
242-
pub manual_scl_high: u8,
243-
pub manual_scl_low: u8,
244-
pub manual_sda_hold: u8,
245-
pub clk_src: u32,
246-
}
247-
pub struct I2cConfig {
248-
pub xfer_mode: I2cXferMode,
249-
pub multi_master: bool,
250-
pub smbus_timeout: bool,
251-
pub smbus_alert: bool,
252-
pub timing_config: TimingConfig,
253-
pub speed: I2cSpeed,
254-
}
255-
pub struct I2cConfigBuilder {
256-
xfer_mode: I2cXferMode,
257-
multi_master: bool,
258-
smbus_timeout: bool,
259-
smbus_alert: bool,
260-
timing_config: Option<TimingConfig>,
261-
speed: I2cSpeed,
262-
}
263-
impl I2cConfigBuilder {
264-
pub fn new() -> Self {
265-
Self {
266-
xfer_mode: I2cXferMode::ByteMode,
267-
multi_master: false,
268-
smbus_alert: false,
269-
smbus_timeout: false,
270-
timing_config: None,
271-
speed: I2cSpeed::Standard,
272-
}
273-
}
274-
pub fn xfer_mode(mut self, mode: I2cXferMode) -> Self {
275-
self.xfer_mode = mode;
276-
self
277-
}
278-
pub fn multi_master(mut self, enabled: bool) -> Self {
279-
self.multi_master = enabled;
280-
self
281-
}
282-
pub fn smbus_alert(mut self, enabled: bool) -> Self {
283-
self.smbus_alert = enabled;
284-
self
285-
}
286-
pub fn smbus_timeout(mut self, enabled: bool) -> Self {
287-
self.smbus_timeout = enabled;
288-
self
289-
}
290-
pub fn speed(mut self, speed: I2cSpeed) -> Self {
291-
self.speed = speed;
292-
self
293-
}
294-
pub fn timing_config(mut self, config: TimingConfig) -> Self {
295-
self.timing_config = Some(config);
296-
self
297-
}
298-
pub fn build(self) -> I2cConfig {
299-
I2cConfig {
300-
xfer_mode: self.xfer_mode,
301-
multi_master: self.multi_master,
302-
smbus_timeout: self.smbus_timeout,
303-
smbus_alert: self.smbus_alert,
304-
timing_config: self.timing_config.unwrap_or(TimingConfig {
305-
manual_scl_high: 0,
306-
manual_scl_low: 0,
307-
manual_sda_hold: 0,
308-
clk_src: 0,
309-
}),
310-
speed: self.speed }
311-
}
312-
}
313217

314218
const I2C_TOTAL: usize = 4;
315219
#[link_section = ".ram_nc"]

src/i2c/common.rs

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
2+
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
3+
#[repr(u32)]
4+
pub enum I2cSpeed {
5+
Standard = 100_000,
6+
Fast = 400_000,
7+
FastPlus = 1_000_000,
8+
}
9+
10+
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
11+
#[repr(u8)]
12+
pub enum I2cXferMode {
13+
DmaMode,
14+
BuffMode,
15+
ByteMode,
16+
}
17+
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
18+
#[repr(u8)]
19+
pub enum I2cSEvent {
20+
SlaveRdReq,
21+
SlaveWrReq,
22+
SlaveRdProc,
23+
SlaveWrRecvd,
24+
SlaveStop,
25+
}
26+
27+
pub struct TimingConfig {
28+
pub manual_scl_high: u8,
29+
pub manual_scl_low: u8,
30+
pub manual_sda_hold: u8,
31+
pub clk_src: u32,
32+
}
33+
pub struct I2cConfig {
34+
pub xfer_mode: I2cXferMode,
35+
pub multi_master: bool,
36+
pub smbus_timeout: bool,
37+
pub smbus_alert: bool,
38+
pub timing_config: TimingConfig,
39+
pub speed: I2cSpeed,
40+
}
41+
pub struct I2cConfigBuilder {
42+
xfer_mode: I2cXferMode,
43+
multi_master: bool,
44+
smbus_timeout: bool,
45+
smbus_alert: bool,
46+
timing_config: Option<TimingConfig>,
47+
speed: I2cSpeed,
48+
}
49+
impl I2cConfigBuilder {
50+
pub fn new() -> Self {
51+
Self {
52+
xfer_mode: I2cXferMode::ByteMode,
53+
multi_master: false,
54+
smbus_alert: false,
55+
smbus_timeout: false,
56+
timing_config: None,
57+
speed: I2cSpeed::Standard,
58+
}
59+
}
60+
pub fn xfer_mode(mut self, mode: I2cXferMode) -> Self {
61+
self.xfer_mode = mode;
62+
self
63+
}
64+
pub fn multi_master(mut self, enabled: bool) -> Self {
65+
self.multi_master = enabled;
66+
self
67+
}
68+
pub fn smbus_alert(mut self, enabled: bool) -> Self {
69+
self.smbus_alert = enabled;
70+
self
71+
}
72+
pub fn smbus_timeout(mut self, enabled: bool) -> Self {
73+
self.smbus_timeout = enabled;
74+
self
75+
}
76+
pub fn speed(mut self, speed: I2cSpeed) -> Self {
77+
self.speed = speed;
78+
self
79+
}
80+
pub fn timing_config(mut self, config: TimingConfig) -> Self {
81+
self.timing_config = Some(config);
82+
self
83+
}
84+
pub fn build(self) -> I2cConfig {
85+
I2cConfig {
86+
xfer_mode: self.xfer_mode,
87+
multi_master: self.multi_master,
88+
smbus_timeout: self.smbus_timeout,
89+
smbus_alert: self.smbus_alert,
90+
timing_config: self.timing_config.unwrap_or(TimingConfig {
91+
manual_scl_high: 0,
92+
manual_scl_low: 0,
93+
manual_sda_hold: 0,
94+
clk_src: 0,
95+
}),
96+
speed: self.speed }
97+
}
98+
}

src/i2c/i2c.rs

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
use crate::uart::UartController;
2+
use crate::i2c::common::I2cConfig;
3+
use embedded_hal::i2c::{Operation, SevenBitAddress};
4+
use embedded_io::Write;
5+
6+
trait HardwareInterface {
7+
type Error: embedded_hal::i2c::Error + core::fmt::Debug;
8+
9+
// Methods return hardware-specific errors
10+
fn reset(&mut self);
11+
fn configure_timing(&mut self, config: &I2cConfig) -> Result<(), Self::Error>;
12+
fn enable_interrupts(&mut self, mask: u32);
13+
fn clear_interrupts(&mut self, mask: u32);
14+
//fn start_transfer(&mut self, state: &TransferState, mode: TransferMode) -> Result<(), Self::Error>;
15+
//fn handle_interrupt(&mut self) -> InterruptStatus;
16+
fn is_bus_busy(&self) -> bool;
17+
fn recover_bus(&mut self) -> Result<(), Self::Error>;
18+
19+
20+
21+
}
22+
23+
trait Logger {
24+
fn debug(&mut self, msg: &str);
25+
fn error(&mut self, msg: &str);
26+
}
27+
28+
// No-op implementation for production builds
29+
struct NoOpLogger;
30+
impl Logger for NoOpLogger {
31+
fn debug(&mut self, _msg: &str) {}
32+
fn error(&mut self, _msg: &str) {}
33+
}
34+
35+
// UART logger adapter (separate concern)
36+
struct UartLogger<'a> {
37+
uart: &'a mut UartController<'a>,
38+
}
39+
40+
impl<'a> Logger for UartLogger<'a> {
41+
fn debug(&mut self, msg: &str) {
42+
writeln!(self.uart, "{}", msg).ok();
43+
}
44+
fn error(&mut self, msg: &str) {
45+
writeln!(self.uart, "ERROR: {}", msg).ok();
46+
}
47+
}
48+
pub struct I2cController<H: HardwareInterface, L: Logger = NoOpLogger> {
49+
hardware: H,
50+
logger: L,
51+
}
52+
53+
impl<H: HardwareInterface, L: Logger> embedded_hal::i2c::ErrorType for I2cController<H, L> {
54+
type Error = H::Error;
55+
}
56+
impl<H: HardwareInterface, L: Logger> embedded_hal::i2c::I2c for I2cController<H, L> {
57+
fn read(&mut self, addr: SevenBitAddress, buffer: &mut [u8]) -> Result<(), Self::Error> {
58+
self.hardware.read(addr, buffer)
59+
}
60+
61+
fn write(&mut self, addr: SevenBitAddress, bytes: &[u8]) -> Result<(), Self::Error> {
62+
self.hardware.write(addr, bytes)
63+
}
64+
65+
fn write_read(
66+
&mut self,
67+
addr: SevenBitAddress,
68+
bytes: &[u8],
69+
buffer: &mut [u8],
70+
) -> Result<(), Self::Error> {
71+
self.hardware.write_read(addr, bytes, buffer)
72+
}
73+
74+
fn transaction(
75+
&mut self,
76+
addr: SevenBitAddress,
77+
operations: &mut [Operation<'_>],
78+
) -> Result<(), Self::Error> {
79+
self.hardware.transaction_slice(addr, operations)
80+
}
81+
}

src/i2c/mod.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1-
pub mod i2ccontroller;
1+
pub mod common;
2+
pub mod ast1060_i2c;
3+
//pub mod i2c;

src/tests/functional/i2c_test.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
use crate::pinctrl;
22
use crate::uart::{self, Config, UartController};
33
use crate::common::DummyDelay;
4-
use crate::i2c::i2ccontroller::{I2cConfigBuilder, I2cController, I2cSpeed, I2cXferMode};
4+
use crate::i2c::ast1060_i2c::I2cController;
5+
use crate::i2c::common::{I2cSpeed, I2cXferMode, I2cConfigBuilder};
56
use ast1060_pac::Peripherals;
67
use embedded_hal::delay::DelayNs;
78
use embedded_hal::i2c::ErrorKind;

0 commit comments

Comments
 (0)