Skip to main content

xwrust/xwds/
soc.rs

1//! XWOS RUST:SOC
2//! ========
3//!
4
5extern crate core;
6use core::cell::UnsafeCell;
7use core::ffi::*;
8use core::ops::*;
9use core::mem;
10
11use crate::types::*;
12
13
14extern "C" {
15    fn xwds_gpio_req(soc: *mut XwdsSoc, port: XwId, pinmsk: XwSq) -> XwEr;
16    fn xwds_gpio_rls(soc: *mut XwdsSoc, port: XwId, pinmsk: XwSq) -> XwEr;
17    fn xwds_gpio_cfg(soc: *mut XwdsSoc, port: XwId, pinmsk: XwSq,
18                     cfg: *mut c_void) -> XwEr;
19    fn xwds_gpio_set(soc: *mut XwdsSoc, port: XwId, pinmsk: XwSq) -> XwEr;
20    fn xwds_gpio_reset(soc: *mut XwdsSoc, port: XwId, pinmsk: XwSq) -> XwEr;
21    fn xwds_gpio_toggle(soc: *mut XwdsSoc, port: XwId, pinmsk: XwSq) -> XwEr;
22    fn xwds_gpio_output(soc: *mut XwdsSoc, port: XwId, pinmsk: XwSq,
23                        out: XwSq) -> XwEr;
24    fn xwds_gpio_input(soc: *mut XwdsSoc, port: XwId, pinmsk: XwSq,
25                       inbuf: *mut XwSq) -> XwEr;
26
27    fn xwds_eirq_req(soc: *mut XwdsSoc, port: XwId, pinmsk: XwSq,
28                     eirq: XwId, eiflag: XwSq,
29                     isr: extern "C" fn(soc: *mut Soc, eirq: XwId, arg: *mut c_void),
30                     arg: *mut c_void) -> XwEr;
31    fn xwds_eirq_rls(soc: *mut XwdsSoc, port: XwId, pinmsk: XwSq,
32                     eirq: XwId) -> XwEr;
33}
34
35/// XWOS自旋锁占用的内存大小
36#[cfg(target_pointer_width = "32")]
37pub const SIZEOF_XWDS_SOC: usize = 128;
38
39/// XWOS自旋锁占用的内存大小
40#[cfg(target_pointer_width = "64")]
41pub const SIZEOF_XWDS_SOC: usize = 256;
42
43/// SOC设备
44#[repr(C)]
45#[cfg_attr(target_pointer_width = "32", repr(align(8)))]
46#[cfg_attr(target_pointer_width = "64", repr(align(16)))]
47pub(crate) struct XwdsSoc {
48    pub(crate) obj: [u8; SIZEOF_XWDS_SOC],
49}
50
51/// SOC设备
52#[repr(C)]
53pub struct Soc {
54    pub(crate) soc: UnsafeCell<XwdsSoc>,
55}
56
57/// GPIO 端口
58pub enum GpioPort {
59    /// GPIO 端口 A
60    A = 0,
61    /// GPIO 端口 B
62    B,
63    /// GPIO 端口 C
64    C,
65    /// GPIO 端口 D
66    D,
67    /// GPIO 端口 E
68    E,
69    /// GPIO 端口 F
70    F,
71    /// GPIO 端口 G
72    G,
73    /// GPIO 端口 H
74    H,
75    /// GPIO 端口 I
76    I,
77    /// GPIO 端口 J
78    J,
79    /// GPIO 端口 K
80    K,
81    /// GPIO 端口 L
82    L,
83    /// GPIO 端口 M
84    M,
85    /// GPIO 端口 N
86    N,
87    /// GPIO 端口 O
88    O,
89    /// GPIO 端口 P
90    P,
91    /// GPIO 端口 Q
92    Q,
93    /// GPIO 端口 R
94    R,
95    /// GPIO 端口 S
96    S,
97    /// GPIO 端口 T
98    T,
99    /// GPIO 端口 U
100    U,
101    /// GPIO 端口 V
102    V,
103    /// GPIO 端口 W
104    W,
105    /// GPIO 端口 X
106    X,
107    /// GPIO 端口 Y
108    Y,
109    /// GPIO 端口 Z
110    Z,
111}
112
113/// SOC的特性:GPIO
114pub trait Gpio {
115    /// 申请GPIO
116    ///
117    /// # 参数说明
118    ///
119    /// + port: GPIO端口,取值 [`GpioPort`]
120    /// + pinmsk: GPIO引脚掩码,每一位代表一个引脚,可通过 [`pin!()`] 宏生成
121    ///
122    /// # 错误码
123    ///
124    /// + [`-ERANGE`] GPIO端口错误
125    /// + [`-EBUSY`] GPIO引脚被占用
126    ///
127    /// [`pin!()`]: crate::pin!
128    /// [`-ERANGE`]: crate::errno::ERANGE
129    /// [`-EBUSY`]: crate::errno::EBUSY
130    fn gpio_req(&self, port: GpioPort, pinmsk: XwSq) -> XwEr;
131
132    /// 释放GPIO
133    ///
134    /// # 参数说明
135    ///
136    /// + port: GPIO端口,取值 [`GpioPort`]
137    /// + pinmsk: GPIO引脚掩码,每一位代表一个引脚,可通过 [`pin!()`] 宏生成
138    ///
139    /// # 错误码
140    ///
141    /// + [`-ERANGE`] GPIO端口错误
142    /// + [`-EPERM`] GPIO引脚未被申请
143    ///
144    /// [`pin!()`]: crate::pin!
145    /// [`-ERANGE`]: crate::errno::ERANGE
146    /// [`-EPERM`]: crate::errno::EPERM
147    fn gpio_rls(&self, port: GpioPort, pinmsk: XwSq) -> XwEr;
148
149    /// 配置GPIO
150    ///
151    /// # 参数说明
152    ///
153    /// + port: GPIO端口,取值 [`GpioPort`]
154    /// + pinmsk: GPIO引脚掩码,每一位代表一个引脚,可通过 [`pin!()`] 宏生成
155    /// + cfg: 配置数据,配置结构体的定义与平台相关
156    ///
157    /// # 错误码
158    ///
159    /// + [`-ERANGE`] GPIO端口错误
160    /// + [`-EPERM`] GPIO引脚未被申请
161    /// + [`-ENOSYS`] 芯片不支持此方法
162    ///
163    /// [`pin!()`]: crate::pin!
164    /// [`-ERANGE`]: crate::errno::ERANGE
165    /// [`-EPERM`]: crate::errno::EPERM
166    /// [`-ENOSYS`]: crate::errno::ENOSYS
167    fn gpio_cfg(&self, port: GpioPort, pinmsk: XwSq, cfg: *mut c_void) -> XwEr;
168
169    /// 将GPIO设置为高电平
170    ///
171    /// # 参数说明
172    ///
173    /// + port: GPIO端口,取值 [`GpioPort`]
174    /// + pinmsk: GPIO引脚掩码,每一位代表一个引脚,可通过 [`pin!()`] 宏生成
175    ///
176    /// # 错误码
177    ///
178    /// + [`-ERANGE`] GPIO端口错误
179    /// + [`-EPERM`] GPIO引脚未被申请
180    /// + [`-ENOSYS`] 芯片不支持此方法
181    ///
182    /// [`pin!()`]: crate::pin!
183    /// [`-ERANGE`]: crate::errno::ERANGE
184    /// [`-EPERM`]: crate::errno::EPERM
185    /// [`-ENOSYS`]: crate::errno::ENOSYS
186    fn gpio_set(&self, port: GpioPort, pinmsk: XwSq) -> XwEr;
187
188    /// 将GPIO设置为低电平
189    ///
190    /// # 参数说明
191    ///
192    /// + port: GPIO端口,取值 [`GpioPort`]
193    /// + pinmsk: GPIO引脚掩码,每一位代表一个引脚,可通过 [`pin!()`] 宏生成
194    ///
195    /// # 错误码
196    ///
197    /// + [`-ERANGE`] GPIO端口错误
198    /// + [`-EPERM`] GPIO引脚未被申请
199    /// + [`-ENOSYS`] 芯片不支持此方法
200    ///
201    /// [`pin!()`]: crate::pin!
202    /// [`-ERANGE`]: crate::errno::ERANGE
203    /// [`-EPERM`]: crate::errno::EPERM
204    /// [`-ENOSYS`]: crate::errno::ENOSYS
205    fn gpio_reset(&self, port: GpioPort, pinmsk: XwSq) -> XwEr;
206
207    /// 翻转GPIO的电平
208    ///
209    /// # 参数说明
210    ///
211    /// + port: GPIO端口,取值 [`GpioPort`]
212    /// + pinmsk: GPIO引脚掩码,每一位代表一个引脚,可通过 [`pin!()`] 宏生成
213    ///
214    /// # 错误码
215    ///
216    /// + [`-ERANGE`] GPIO端口错误
217    /// + [`-EPERM`] GPIO引脚未被申请
218    /// + [`-ENOSYS`] 芯片不支持此方法
219    ///
220    /// [`pin!()`]: crate::pin!
221    /// [`-ERANGE`]: crate::errno::ERANGE
222    /// [`-EPERM`]: crate::errno::EPERM
223    /// [`-ENOSYS`]: crate::errno::ENOSYS
224    fn gpio_toggle(&self, port: GpioPort, pinmsk: XwSq) -> XwEr;
225
226    /// 写GPIO
227    ///
228    /// 输出的值 = `pinmsk` & `out`
229    ///
230    /// # 参数说明
231    ///
232    /// + port: GPIO端口,取值 [`GpioPort`]
233    /// + pinmsk: GPIO引脚掩码,每一位代表一个引脚,可通过 [`pin!()`] 宏生成
234    /// + out: 输出值,可通过 [`pin!()`] 宏生成
235    ///
236    /// # 错误码
237    ///
238    /// + [`-ERANGE`] GPIO端口错误
239    /// + [`-EPERM`] GPIO引脚未被申请
240    /// + [`-ENOSYS`] 芯片不支持此方法
241    ///
242    /// [`pin!()`]: crate::pin!
243    /// [`-ERANGE`]: crate::errno::ERANGE
244    /// [`-EPERM`]: crate::errno::EPERM
245    /// [`-ENOSYS`]: crate::errno::ENOSYS
246    fn gpio_output(&self, port: GpioPort, pinmsk: XwSq, out: XwSq) -> XwEr;
247
248    /// 读取GPIO
249    ///
250    /// 读取的值 = `pinmsk` & GPIO的端口电平状态
251    ///
252    /// # 参数说明
253    ///
254    /// + port: GPIO端口,取值 [`GpioPort`]
255    /// + pinmsk: GPIO引脚掩码,每一位代表一个引脚,可通过 [`pin!()`] 宏生成
256    ///
257    /// # 错误码
258    ///
259    /// + [`-ERANGE`] GPIO端口错误
260    /// + [`-EPERM`] GPIO引脚未被申请
261    /// + [`-ENOSYS`] 芯片不支持此方法
262    ///
263    /// [`pin!()`]: crate::pin!
264    /// [`-ERANGE`]: crate::errno::ERANGE
265    /// [`-EPERM`]: crate::errno::EPERM
266    /// [`-ENOSYS`]: crate::errno::ENOSYS
267    fn gpio_input(&self, port: GpioPort, pinmsk: XwSq) -> (XwEr, XwSq);
268}
269
270impl Gpio for Soc {
271    fn gpio_req(&self, port: GpioPort, pinmsk: XwSq) -> XwEr {
272        unsafe {
273            xwds_gpio_req(self.soc.get(),
274                          port as XwSq, pinmsk)
275        }
276    }
277
278    fn gpio_rls(&self, port: GpioPort, pinmsk: XwSq) -> XwEr {
279        unsafe {
280            xwds_gpio_rls(self.soc.get(),
281                          port as XwSq, pinmsk)
282        }
283    }
284
285    fn gpio_cfg(&self, port: GpioPort, pinmsk: XwSq, cfg: *mut c_void) -> XwEr {
286        unsafe {
287            xwds_gpio_cfg(self.soc.get(),
288                          port as XwSq, pinmsk, cfg)
289        }
290    }
291
292    fn gpio_set(&self, port: GpioPort, pinmsk: XwSq) -> XwEr {
293        unsafe {
294            xwds_gpio_set(self.soc.get(),
295                          port as XwSq, pinmsk)
296        }
297    }
298
299    fn gpio_reset(&self, port: GpioPort, pinmsk: XwSq) -> XwEr {
300        unsafe {
301            xwds_gpio_reset(self.soc.get(),
302                            port as XwSq, pinmsk)
303        }
304    }
305
306    fn gpio_toggle(&self, port: GpioPort, pinmsk: XwSq) -> XwEr {
307        unsafe {
308            xwds_gpio_toggle(self.soc.get(),
309                             port as XwSq, pinmsk)
310        }
311    }
312
313    fn gpio_output(&self, port: GpioPort, pinmsk: XwSq, out: XwSq) -> XwEr {
314        unsafe {
315            xwds_gpio_output(self.soc.get(),
316                             port as XwSq, pinmsk, out)
317        }
318    }
319
320    fn gpio_input(&self, port: GpioPort, pinmsk: XwSq) -> (XwEr, XwSq) {
321        unsafe {
322            let mut inbuf: XwSq = 0;
323            let rc = xwds_gpio_input(self.soc.get(),
324                                     port as XwSq, pinmsk, &mut inbuf);
325            (rc, inbuf)
326        }
327    }
328}
329
330/// 外部中断标志
331pub struct EirqFlag(XwSq);
332
333impl EirqFlag {
334    /// 上升沿触发
335    pub const RISING: EirqFlag = EirqFlag(bit!(0));
336    /// 下降沿触发
337    pub const FALLING: EirqFlag = EirqFlag(bit!(1));
338    /// 任意边沿触发
339    pub const EITHER: EirqFlag = EirqFlag(bit!(0, 1));
340    /// 低电平触发
341    pub const LOW: EirqFlag = EirqFlag(bit!(2));
342    /// 高电平触发
343    pub const HIGH: EirqFlag = EirqFlag(bit!(3));
344    /// 触发后唤醒系统
345    pub const WKUP: EirqFlag = EirqFlag(bit!(4));
346    /// 触发后启动DMA传输
347    pub const DMA: EirqFlag = EirqFlag(bit!(5));
348}
349
350impl From<XwSq> for EirqFlag {
351    fn from(flag: XwSq) -> Self {
352        Self(flag)
353    }
354}
355
356impl BitAnd for EirqFlag {
357    type Output = Self;
358
359    fn bitand(self, other: Self) -> Self {
360        Self(self.0 & other.0)
361    }
362}
363
364impl BitAndAssign for EirqFlag {
365    fn bitand_assign(&mut self, other: Self) {
366        self.0 &= other.0;
367    }
368}
369
370impl BitOr for EirqFlag {
371    type Output = Self;
372
373    fn bitor(self, other: Self) -> Self {
374        Self(self.0 | other.0)
375    }
376}
377
378impl BitOrAssign for EirqFlag {
379    fn bitor_assign(&mut self, other: Self) {
380        self.0 |= other.0;
381    }
382}
383
384impl BitXor for EirqFlag {
385    type Output = Self;
386
387    fn bitxor(self, other: Self) -> Self {
388        Self(self.0 ^ other.0)
389    }
390}
391
392impl BitXorAssign for EirqFlag {
393    fn bitxor_assign(&mut self, other: Self) {
394        self.0 ^= other.0;
395    }
396}
397
398/// SOC的特性:外部GPIO中断
399pub trait Eirq {
400    /// 申请外部中断
401    ///
402    /// # 参数说明
403    ///
404    /// + port: GPIO端口,取值 [`GpioPort`]
405    /// + pinmsk: GPIO引脚掩码,每一位代表一个引脚,可通过 [`pin!()`] 宏生成
406    /// + eirq: 外部中断号
407    /// + flag: 外部中断标志,取值 [`EirqFlag`] 的常量组合
408    /// + isr: 中断函数
409    ///
410    /// # 错误码
411    ///
412    /// + [`-ERANGE`] 外部中断ID错误
413    ///
414    /// [`pin!()`]: crate::pin!
415    /// [`-ERANGE`]: crate::errno::ERANGE
416    fn eirq_req(&self, port: GpioPort, pinmsk: XwSq, eirq: XwId, flag: EirqFlag,
417                isr: fn(&Self, XwId)) -> XwEr;
418
419    /// 释放外部中断
420    ///
421    /// # 参数说明
422    ///
423    /// + port: GPIO端口,取值 [`GpioPort`]
424    /// + pinmsk: GPIO引脚掩码,每一位代表一个引脚,可通过 [`pin!()`] 宏生成
425    /// + eirq: 外部中断号
426    ///
427    /// # 错误码
428    ///
429    /// + [`-ERANGE`] 外部中断ID错误
430    ///
431    /// [`pin!()`]: crate::pin!
432    /// [`-ERANGE`]: crate::errno::ERANGE
433    fn eirq_rls(&self, port: GpioPort, pinmsk: XwSq, eirq: XwId) -> XwEr;
434}
435
436impl Eirq for Soc {
437    fn eirq_req(&self, port: GpioPort, pinmsk: XwSq, eirq: XwId, flag: EirqFlag,
438                isr: fn(&Self, XwId)) -> XwEr {
439        unsafe {
440            xwds_eirq_req(self.soc.get(),
441                          port as XwSq, pinmsk, eirq, flag.0,
442                          Soc::eisr_entry, isr as *mut c_void)
443        }
444    }
445
446    fn eirq_rls(&self, port: GpioPort, pinmsk: XwSq, eirq: XwId) -> XwEr {
447        unsafe {
448            xwds_eirq_rls(self.soc.get(),
449                          port as XwSq, pinmsk, eirq)
450        }
451    }
452}
453
454impl Soc {
455    /// 外部GPIO中断函数的入口
456    extern "C" fn eisr_entry(rawsoc: *mut Soc, eirq: XwId, arg: *mut c_void) {
457        unsafe {
458            let soc = &*(rawsoc);
459            let isr = mem::transmute::<*mut c_void, fn(&Self, XwId)>(arg);
460            isr(soc, eirq);
461        }
462    }
463}