Skip to content

Commit f0c6134

Browse files
committed
test(port_arm): move the UART driver to constance_support_rza1
1 parent a639f09 commit f0c6134

File tree

8 files changed

+392
-109
lines changed

8 files changed

+392
-109
lines changed

Cargo.lock

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/constance_port_arm_test_driver/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ output-semihosting = [
3232
]
3333

3434
[dependencies]
35-
constance_support_rza1 = { path = "../constance_support_rza1", optional = true }
35+
constance_support_rza1 = { path = "../constance_support_rza1", optional = true, features = ["semver-exempt"] }
3636
constance_port_arm = { path = "../constance_port_arm", optional = true }
3737
arm_semihosting = { path = "../arm_semihosting", optional = true }
3838
constance = { path = "../constance", optional = true }
Lines changed: 12 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
use core::fmt::Write;
2-
use rza1::scif0 as scif;
1+
use constance_support_rza1::serial::ScifExt;
32

43
struct Logger;
54

@@ -9,123 +8,28 @@ impl log::Log for Logger {
98
}
109

1110
fn log(&self, record: &log::Record) {
12-
let peripherals = unsafe { rza1::Peripherals::steal() };
13-
14-
interrupt_free(|| {
15-
writeln!(
16-
SCWriter(&peripherals.SCIF2),
17-
"[{:5} {}] {}",
18-
record.level(),
19-
record.target(),
20-
record.args()
21-
)
22-
.unwrap();
23-
});
11+
constance_support_rza1::sprintln!(
12+
"[{:5} {}] {}",
13+
record.level(),
14+
record.target(),
15+
record.args()
16+
);
2417
}
2518

2619
fn flush(&self) {}
2720
}
2821

29-
#[derive(Clone, Copy)]
30-
struct SCWriter<'a>(&'a scif::RegisterBlock);
31-
32-
impl Write for SCWriter<'_> {
33-
fn write_str(&mut self, s: &str) -> core::fmt::Result {
34-
for &b in s.as_bytes() {
35-
self.write_u8(b);
36-
}
37-
Ok(())
38-
}
39-
}
40-
41-
impl SCWriter<'_> {
42-
fn write_u8(self, x: u8) {
43-
let sc = self.0;
44-
if x == b'\n' {
45-
self.write_u8(b'\r');
46-
}
47-
while sc.fsr.read().tdfe().bit_is_clear() {}
48-
sc.ftdr.write(|w| w.d().bits(x));
49-
sc.fsr
50-
.modify(|_, w| w.tdfe().clear_bit().tend().clear_bit());
51-
}
52-
}
53-
5422
pub fn init() {
55-
let peripherals = unsafe { rza1::Peripherals::steal() };
5623
let rza1::Peripherals {
5724
CPG, GPIO, SCIF2, ..
58-
} = peripherals;
59-
60-
// Supply clock to SC2
61-
CPG.stbcr4.modify(|_, w| w.mstp45().clear_bit());
25+
} = unsafe { rza1::Peripherals::steal() };
6226

63-
// On GR-PEACH, the nets `TGT_[TR]XD` are connected to `P6_[23]`. Configure
64-
// `P6_[23]` to use its 7th alternative function - `SC2`.
65-
let (mask, shift) = (0b11, 2);
27+
SCIF2.enable_clock(&CPG);
28+
SCIF2.configure_pins(&GPIO);
29+
SCIF2.configure_uart(115200);
6630

67-
GPIO.pmc6
68-
.modify(|_, w| w.pmc62().set_bit().pmc63().set_bit());
69-
GPIO.pfcae6
70-
.modify(|_, w| w.pfcae62().set_bit().pfcae63().set_bit());
71-
GPIO.pfce6
72-
.modify(|_, w| w.pfce62().set_bit().pfce63().set_bit());
73-
GPIO.pfc6
74-
.modify(|_, w| w.pfc62().clear_bit().pfc63().clear_bit());
75-
GPIO.pm6
76-
.modify(|_, w| w.pm62().set_bit().pm63().clear_bit());
77-
78-
SCIF2.scr.write(|w| {
79-
w.tie()
80-
.clear_bit()
81-
.rie()
82-
.clear_bit()
83-
.te()
84-
.set_bit()
85-
.re()
86-
.clear_bit()
87-
.reie()
88-
.clear_bit()
89-
.cke()
90-
.internal_sck_in()
91-
});
92-
SCIF2.smr.write(|w| {
93-
w
94-
// Asynchronous
95-
.ca()
96-
.clear_bit()
97-
// 8-bit data
98-
.chr()
99-
.clear_bit()
100-
// No parity bits
101-
.pe()
102-
.clear_bit()
103-
// One stop bit
104-
.stop()
105-
.clear_bit()
106-
.cks()
107-
.divide_by_1()
108-
});
109-
// 66.666e6/115200/(64*2**(2*0-1))-1 = 17.0843...
110-
SCIF2.brr.write(|w| w.d().bits(17));
31+
constance_support_rza1::stdout::set_stdout(SCIF2.into_nb_writer());
11132

11233
log::set_logger(&Logger).unwrap();
11334
log::set_max_level(log::LevelFilter::Trace);
11435
}
115-
116-
#[inline]
117-
fn interrupt_free<T>(x: impl FnOnce() -> T) -> T {
118-
let cpsr: u32;
119-
unsafe { asm!("mrs {}, cpsr", out(reg)cpsr) };
120-
let unmask = (cpsr & (1 << 7)) == 0;
121-
122-
unsafe { asm!("cpsid i") };
123-
124-
let ret = x();
125-
126-
if unmask {
127-
unsafe { asm!("cpsie i") };
128-
}
129-
130-
ret
131-
}

src/constance_support_rza1/Cargo.toml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,20 @@ categories = ["embedded", "no-std"]
99
keywords = ["constance", "arm", "renesas"]
1010
repository = "https://github.com/yvt/Constance"
1111

12+
[features]
13+
semver-exempt = [
14+
"embedded-hal",
15+
"rza1/cpg",
16+
"rza1/gpio",
17+
"rza1/scif",
18+
"nb",
19+
]
20+
1221
[dependencies]
1322
constance_port_arm = { path = "../constance_port_arm" }
1423
constance_portkit = { path = "../constance_portkit" }
1524
constance = { path = "../constance" }
1625

26+
embedded-hal = { version = "0.2.4", optional = true }
1727
rza1 = { version = "0.2.0", features = ["ostm"] }
28+
nb = { version = "0.1.2", optional = true }
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
//! Pin configuration
2+
// This module is only intended to be used internally, hence the semver
3+
// exemption. It probably should be in a HAL crate, but there's no HAL crate
4+
// for RZ/A1.
5+
#![cfg(feature = "semver-exempt")]
6+
7+
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
8+
pub enum AltMode {
9+
Gpio,
10+
Alt1,
11+
Alt2,
12+
Alt3,
13+
Alt4,
14+
Alt5,
15+
Alt6,
16+
Alt7,
17+
Alt8,
18+
}
19+
20+
pub type Pin = (u8, u8);
21+
22+
pub trait GpioExt {
23+
/// Configure the alternate function mode of the specified pin.
24+
fn set_alt_mode(&self, pin: Pin, mode: AltMode) -> &Self;
25+
26+
/// Configure the specified pin for output.
27+
fn set_output(&self, pin: Pin) -> &Self;
28+
29+
/// Configure the specified pin for input.
30+
fn set_input(&self, pin: Pin) -> &Self;
31+
}
32+
33+
unsafe fn set_bit16(reg: *mut u16, bit: u8) {
34+
unsafe { reg.write_volatile(reg.read_volatile() | (1u16 << bit)) };
35+
}
36+
37+
unsafe fn clear_bit16(reg: *mut u16, bit: u8) {
38+
unsafe { reg.write_volatile(reg.read_volatile() & !(1u16 << bit)) };
39+
}
40+
41+
#[inline]
42+
fn panic_if_pin_is_invalid((n, m): Pin) {
43+
assert!(n >= 1 && n < 12, "1 <= {} < 12", n);
44+
assert!(m < 16, "0 <= {} < 16", m);
45+
}
46+
47+
impl GpioExt for rza1::gpio::RegisterBlock {
48+
#[inline]
49+
fn set_alt_mode(&self, (n, m): Pin, mode: AltMode) -> &Self {
50+
panic_if_pin_is_invalid((n, m));
51+
52+
let pmc = (&self.pmc1 as *const _ as *mut u16).wrapping_add((n - 1) as usize * 2);
53+
let pfcae = (&self.pfcae1 as *const _ as *mut u16).wrapping_add((n - 1) as usize * 2);
54+
let pfce = (&self.pfce1 as *const _ as *mut u16).wrapping_add((n - 1) as usize * 2);
55+
let pfc = (&self.pfc1 as *const _ as *mut u16).wrapping_add((n - 1) as usize * 2);
56+
57+
unsafe {
58+
match mode {
59+
AltMode::Gpio => {
60+
clear_bit16(pmc, m);
61+
}
62+
AltMode::Alt1 => {
63+
set_bit16(pmc, m);
64+
clear_bit16(pfcae, m);
65+
clear_bit16(pfce, m);
66+
clear_bit16(pfc, m);
67+
}
68+
AltMode::Alt2 => {
69+
set_bit16(pmc, m);
70+
clear_bit16(pfcae, m);
71+
clear_bit16(pfce, m);
72+
set_bit16(pfc, m);
73+
}
74+
AltMode::Alt3 => {
75+
set_bit16(pmc, m);
76+
clear_bit16(pfcae, m);
77+
set_bit16(pfce, m);
78+
clear_bit16(pfc, m);
79+
}
80+
AltMode::Alt4 => {
81+
set_bit16(pmc, m);
82+
clear_bit16(pfcae, m);
83+
set_bit16(pfce, m);
84+
set_bit16(pfc, m);
85+
}
86+
AltMode::Alt5 => {
87+
set_bit16(pmc, m);
88+
set_bit16(pfcae, m);
89+
clear_bit16(pfce, m);
90+
clear_bit16(pfc, m);
91+
}
92+
AltMode::Alt6 => {
93+
set_bit16(pmc, m);
94+
set_bit16(pfcae, m);
95+
clear_bit16(pfce, m);
96+
set_bit16(pfc, m);
97+
}
98+
AltMode::Alt7 => {
99+
set_bit16(pmc, m);
100+
set_bit16(pfcae, m);
101+
set_bit16(pfce, m);
102+
clear_bit16(pfc, m);
103+
}
104+
AltMode::Alt8 => {
105+
set_bit16(pmc, m);
106+
set_bit16(pfcae, m);
107+
set_bit16(pfce, m);
108+
set_bit16(pfc, m);
109+
}
110+
}
111+
}
112+
self
113+
}
114+
115+
#[inline]
116+
fn set_output(&self, (n, m): Pin) -> &Self {
117+
panic_if_pin_is_invalid((n, m));
118+
let pm = (&self.pm1 as *const _ as *mut u16).wrapping_add((n - 1) as usize * 2);
119+
unsafe { clear_bit16(pm, m) };
120+
self
121+
}
122+
123+
#[inline]
124+
fn set_input(&self, (n, m): Pin) -> &Self {
125+
panic_if_pin_is_invalid((n, m));
126+
let pm = (&self.pm1 as *const _ as *mut u16).wrapping_add((n - 1) as usize * 2);
127+
unsafe { set_bit16(pm, m) };
128+
self
129+
}
130+
}

src/constance_support_rza1/src/lib.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
//! [RZ/A1H]: https://www.renesas.com/us/en/products/microcontrollers-microprocessors/rz/rza/rza1h.html
66
//! [GR-PEACH]: https://www.renesas.com/us/en/products/gadget-renesas/boards/gr-peach.html
77
#![feature(const_fn)]
8+
#![feature(asm)]
89
#![feature(unsafe_block_in_unsafe_fn)] // `unsafe fn` doesn't imply `unsafe {}`
910
#![deny(unsafe_op_in_unsafe_fn)]
1011
#![no_std]
@@ -29,3 +30,7 @@ pub mod os_timer {
2930
}
3031

3132
pub use self::os_timer::cfg::*;
33+
34+
pub mod gpio;
35+
pub mod serial;
36+
pub mod stdout;

0 commit comments

Comments
 (0)