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}