Skip to main content

xwrust/xwds/
i2cm.rs

1//! XWOS RUST:I2C主机模式控制器
2//! ========
3//!
4
5extern crate core;
6use core::cell::UnsafeCell;
7use core::ops::*;
8
9use crate::types::*;
10
11extern "C" {
12    fn xwds_i2cm_xfer(i2cm: *mut XwdsI2cm,
13                      msg: *mut Msg,
14                      to: XwTm) -> XwEr;
15    fn xwds_i2cm_abort(i2cm: *mut XwdsI2cm,
16                       address: u16, addrmode: u16,
17                       to: XwTm) -> XwEr;
18}
19
20/// XWOS自旋锁占用的内存大小
21#[cfg(target_pointer_width = "32")]
22pub const SIZEOF_XWDS_I2CM: usize = 224;
23
24/// XWOS自旋锁占用的内存大小
25#[cfg(target_pointer_width = "64")]
26pub const SIZEOF_XWDS_I2CM: usize = 448;
27
28/// I2C主机模式控制器
29#[repr(C)]
30#[cfg_attr(target_pointer_width = "32", repr(align(8)))]
31#[cfg_attr(target_pointer_width = "64", repr(align(16)))]
32pub struct XwdsI2cm {
33    pub(crate) obj: [u8; SIZEOF_XWDS_I2CM],
34}
35
36/// I2C主机模式控制器
37#[repr(C)]
38pub struct I2cm {
39    pub(crate) i2cm: UnsafeCell<XwdsI2cm>,
40}
41
42impl I2cm {
43    /// 传输I2C消息
44    ///
45    /// # 参数说明
46    ///
47    /// + addr: 外设地址
48    /// + flag: 传输消息标志,取值 [`MsgFlag`] 的常量组合
49    /// + data: 数据数组的切片
50    /// + size: 数据大小
51    /// + to: 期望唤醒的时间点
52    ///
53    /// # 错误码
54    ///
55    /// + [`-ESHUTDOWN`] I2C主机模式控制器没有运行
56    /// + [`-EADDRNOTAVAIL`] I2C地址没有应答
57    /// + [`-ETIMEDOUT`] 传输超时
58    ///
59    /// [`-ESHUTDOWN`]: crate::errno::ESHUTDOWN
60    /// [`-EADDRNOTAVAIL`]: crate::errno::EADDRNOTAVAIL
61    /// [`-ETIMEDOUT`]: crate::errno::ETIMEDOUT
62    pub fn xfer(&self,
63                addr: u16, flag: MsgFlag, data: &mut [u8], size: XwSz,
64                to: XwTm) -> XwEr {
65        unsafe {
66            let mut msg: Msg = Msg {
67                addr: addr,
68                flag: flag.0,
69                data: data.as_mut_ptr(),
70                size: size,
71            };
72            xwds_i2cm_xfer(self.i2cm.get(), &mut msg as *mut Msg, to)
73        }
74    }
75
76    /// 中止I2C总线传输
77    ///
78    /// # 参数说明
79    ///
80    /// + addr: I2C地址
81    /// + addrflag: I2C地址模式,取值 [`MsgFlag`] 的常量组合
82    /// + to: 期望唤醒的时间点
83    ///
84    /// # 错误码
85    ///
86    /// + [`-ESHUTDOWN`] I2C主机模式控制器没有运行
87    /// + [`-EADDRNOTAVAIL`] I2C地址没有应答
88    /// + [`-ETIMEDOUT`] 传输超时
89    ///
90    /// [`-ESHUTDOWN`]: crate::errno::ESHUTDOWN
91    /// [`-EADDRNOTAVAIL`]: crate::errno::EADDRNOTAVAIL
92    /// [`-ETIMEDOUT`]: crate::errno::ETIMEDOUT
93    pub fn abort(&self,
94                 addr: u16, addrflag: MsgFlag,
95                 to: XwTm) -> XwEr {
96        unsafe {
97            xwds_i2cm_abort(self.i2cm.get(), addr, addrflag.0, to)
98        }
99    }
100}
101
102/// I2C消息
103#[repr(C)]
104struct Msg {
105    addr: u16,
106    flag: u16,
107    data: *mut u8,
108    size: XwSz,
109}
110
111/// 外部中断标志
112pub struct MsgFlag(u16);
113
114impl MsgFlag {
115    /// 7位地址
116    pub const ADDR7BIT: MsgFlag = MsgFlag(0);
117    /// 10位地址
118    pub const ADDR10BIT: MsgFlag = MsgFlag(bit!(0));
119    /// 地址掩码
120    pub const ADDRMSG: MsgFlag = MsgFlag(bit!(0));
121
122    /// 传输方向:写
123    pub const WR: MsgFlag = MsgFlag(0);
124    /// 传输方向:读
125    pub const RD: MsgFlag = MsgFlag(bit!(1));
126    /// 传输方向掩码
127    pub const DIRMSG: MsgFlag = MsgFlag(bit!(1));
128
129    /// 产生起始条件
130    pub const START: MsgFlag = MsgFlag(bit!(2));
131
132    /// 产生停止条件
133    pub const STOP: MsgFlag = MsgFlag(bit!(3));
134
135}
136
137impl From<u16> for MsgFlag {
138    fn from(flag: u16) -> Self {
139        Self(flag)
140    }
141}
142
143impl BitAnd for MsgFlag {
144    type Output = Self;
145
146    fn bitand(self, other: Self) -> Self {
147        Self(self.0 & other.0)
148    }
149}
150
151impl BitAndAssign for MsgFlag {
152    fn bitand_assign(&mut self, other: Self) {
153        self.0 &= other.0;
154    }
155}
156
157impl BitOr for MsgFlag {
158    type Output = Self;
159
160    fn bitor(self, other: Self) -> Self {
161        Self(self.0 | other.0)
162    }
163}
164
165impl BitOrAssign for MsgFlag {
166    fn bitor_assign(&mut self, other: Self) {
167        self.0 |= other.0;
168    }
169}
170
171impl BitXor for MsgFlag {
172    type Output = Self;
173
174    fn bitxor(self, other: Self) -> Self {
175        Self(self.0 ^ other.0)
176    }
177}
178
179impl BitXorAssign for MsgFlag {
180    fn bitxor_assign(&mut self, other: Self) {
181        self.0 ^= other.0;
182    }
183}