1use core::cell::Cell;
8use kernel::utilities::registers::FieldValue;
9use kernel::ErrorCode;
10
11use crate::gpio;
12use kernel::hil;
13use kernel::utilities::cells::OptionalCell;
14use kernel::utilities::cells::TakeCell;
15use kernel::utilities::registers::interfaces::{ReadWriteable, Readable, Writeable};
16use kernel::utilities::registers::{register_bitfields, ReadOnly, ReadWrite};
17use kernel::utilities::StaticRef;
18
19use kernel::deferred_call::{DeferredCall, DeferredCallClient};
20
21#[repr(C)]
22pub struct UartRegisters {
23 txdata: ReadWrite<u32, txdata::Register>,
25 rxdata: ReadWrite<u32, rxdata::Register>,
27 txctrl: ReadWrite<u32, txctrl::Register>,
29 rxctrl: ReadWrite<u32, rxctrl::Register>,
31 ie: ReadWrite<u32, interrupt::Register>,
33 ip: ReadOnly<u32, interrupt::Register>,
35 div: ReadWrite<u32, div::Register>,
37}
38
39register_bitfields![u32,
40 txdata [
41 full OFFSET(31) NUMBITS(1) [],
42 data OFFSET(0) NUMBITS(8) []
43 ],
44 rxdata [
45 empty OFFSET(31) NUMBITS(1) [],
46 data OFFSET(0) NUMBITS(8) []
47 ],
48 txctrl [
49 txcnt OFFSET(16) NUMBITS(3) [],
50 nstop OFFSET(1) NUMBITS(1) [
51 OneStopBit = 0,
52 TwoStopBits = 1
53 ],
54 txen OFFSET(0) NUMBITS(1) []
55 ],
56 rxctrl [
57 counter OFFSET(16) NUMBITS(3) [],
58 enable OFFSET(0) NUMBITS(1) []
59 ],
60 interrupt [
61 rxwm OFFSET(1) NUMBITS(1) [],
62 txwm OFFSET(0) NUMBITS(1) []
63 ],
64 div [
65 div OFFSET(0) NUMBITS(16) []
66 ]
67];
68
69#[derive(Copy, Clone, PartialEq)]
70enum UARTStateTX {
71 Idle,
72 Transmitting,
73 AbortRequested,
74}
75
76#[derive(Copy, Clone, PartialEq)]
77enum UARTStateRX {
78 Idle,
79 Receiving,
80 AbortRequested,
81}
82
83pub struct Uart<'a> {
84 registers: StaticRef<UartRegisters>,
85 clock_frequency: u32,
86 stop_bits: Cell<hil::uart::StopBits>,
87
88 tx_client: OptionalCell<&'a dyn hil::uart::TransmitClient>,
89 rx_client: OptionalCell<&'a dyn hil::uart::ReceiveClient>,
90
91 tx_buffer: TakeCell<'static, [u8]>,
92 tx_len: Cell<usize>,
93 tx_position: Cell<usize>,
94 tx_status: Cell<UARTStateTX>,
95
96 rx_buffer: TakeCell<'static, [u8]>,
97 rx_len: Cell<usize>,
98 rx_position: Cell<usize>,
99 rx_status: Cell<UARTStateRX>,
100
101 deferred_call: DeferredCall,
102}
103
104#[derive(Copy, Clone)]
105pub struct UartParams {
106 pub baud_rate: u32,
107}
108
109impl<'a> Uart<'a> {
110 pub fn new(base: StaticRef<UartRegisters>, clock_frequency: u32) -> Uart<'a> {
111 Uart {
112 registers: base,
113 clock_frequency,
114 stop_bits: Cell::new(hil::uart::StopBits::One),
115
116 tx_client: OptionalCell::empty(),
117 rx_client: OptionalCell::empty(),
118
119 tx_buffer: TakeCell::empty(),
120 tx_len: Cell::new(0),
121 tx_position: Cell::new(0),
122 tx_status: Cell::new(UARTStateTX::Idle),
123
124 rx_buffer: TakeCell::empty(),
125 rx_len: Cell::new(0),
126 rx_position: Cell::new(0),
127 rx_status: Cell::new(UARTStateRX::Idle),
128
129 deferred_call: DeferredCall::new(),
130 }
131 }
132
133 pub fn initialize_gpio_pins(&self, tx: &gpio::GpioPin, rx: &gpio::GpioPin) {
135 tx.iof0();
136 rx.iof0();
137 }
138
139 fn set_baud_rate(&self, baud_rate: u32) {
140 let regs = self.registers;
141
142 let divisor = (self.clock_frequency / baud_rate) - 1;
146
147 regs.div.write(div::div.val(divisor));
148 }
149
150 fn get_stop_bits(&self) -> FieldValue<u32, txctrl::Register> {
151 match self.stop_bits.get() {
152 hil::uart::StopBits::One => txctrl::nstop::OneStopBit,
153 hil::uart::StopBits::Two => txctrl::nstop::TwoStopBits,
154 }
155 }
156
157 pub fn disable(&self) {
158 let regs = self.registers;
159 regs.txctrl.modify(txctrl::txen::CLEAR);
160 regs.rxctrl.modify(rxctrl::enable::CLEAR);
161
162 self.disable_rx_interrupt();
163 self.disable_tx_interrupt();
164 }
165
166 fn enable_tx_interrupt(&self) {
167 let regs = self.registers;
168 regs.ie.modify(interrupt::txwm::SET);
169 }
170
171 fn enable_rx_interrupt(&self) {
172 let regs = self.registers;
173 regs.ie.modify(interrupt::rxwm::SET);
174 }
175
176 fn disable_rx_interrupt(&self) {
177 let regs = self.registers;
178 regs.ie.modify(interrupt::rxwm::CLEAR);
179 }
180
181 fn disable_tx_interrupt(&self) {
182 let regs = self.registers;
183 regs.ie.modify(interrupt::txwm::CLEAR);
184 }
185
186 fn uart_is_writable(&self) -> bool {
187 !self.registers.txdata.is_set(txdata::full)
188 }
189
190 fn tx_progress(&self) {
191 while self.uart_is_writable() && self.tx_position.get() < self.tx_len.get() {
192 self.tx_buffer.map(|buf| {
193 self.registers
194 .txdata
195 .set(buf[self.tx_position.get()].into());
196 self.tx_position.replace(self.tx_position.get() + 1);
197 });
198 }
199 }
200
201 fn rx_progress(&self) {
202 while self.rx_position.get() < self.rx_len.get() {
203 let rxdata_copy = self.registers.rxdata.extract();
204
205 if rxdata_copy.read(rxdata::empty) == 1 {
206 break;
207 }
208
209 self.rx_buffer.map(|buf| {
210 buf[self.rx_position.get()] = rxdata_copy.read(rxdata::data) as u8;
211 self.rx_position.replace(self.rx_position.get() + 1);
212 });
213 }
214 }
215
216 pub fn handle_interrupt(&self) {
217 let regs = self.registers;
218
219 let pending_interrupts = regs.ip.extract();
221
222 if self.tx_status.get() == UARTStateTX::Transmitting
224 && pending_interrupts.is_set(interrupt::txwm)
225 {
226 if self.tx_position.get() == self.tx_len.get() {
231 regs.txctrl.write(txctrl::txen::CLEAR);
233 self.disable_tx_interrupt();
234 self.tx_status.set(UARTStateTX::Idle);
235
236 self.tx_client.map(|client| {
238 self.tx_buffer.take().map(|buffer| {
239 client.transmitted_buffer(buffer, self.tx_len.get(), Ok(()));
240 });
241 });
242 } else {
243 self.tx_progress();
244 }
245 }
246
247 if self.rx_status.get() == UARTStateRX::Receiving
248 && pending_interrupts.is_set(interrupt::rxwm)
249 {
250 self.disable_rx_interrupt();
251 self.rx_progress();
254
255 if self.rx_position.get() == self.rx_len.get() {
256 regs.rxctrl.write(rxctrl::enable::CLEAR);
258 self.rx_status.replace(UARTStateRX::Idle);
259
260 self.rx_client.map(|client| {
262 if let Some(buf) = self.rx_buffer.take() {
263 client.received_buffer(
264 buf,
265 self.rx_len.get(),
266 Ok(()),
267 hil::uart::Error::None,
268 );
269 }
270 });
271 } else {
272 self.enable_rx_interrupt();
273 }
274 }
275 }
276
277 pub fn transmit_sync(&self, bytes: &[u8]) {
278 let regs = self.registers;
279
280 regs.txctrl
282 .write(txctrl::txen::SET + self.get_stop_bits() + txctrl::txcnt.val(1));
283
284 for b in bytes.iter() {
285 while regs.txdata.is_set(txdata::full) {}
286 regs.txdata.write(txdata::data.val(*b as u32));
287 }
288 }
289}
290
291impl DeferredCallClient for Uart<'_> {
292 fn register(&'static self) {
293 self.deferred_call.register(self)
294 }
295
296 fn handle_deferred_call(&self) {
297 if self.tx_status.get() == UARTStateTX::AbortRequested {
298 self.tx_client.map(|client| {
300 self.tx_buffer.take().map(|buf| {
301 client.transmitted_buffer(buf, self.tx_position.get(), Err(ErrorCode::CANCEL));
302 });
303 });
304 self.tx_status.set(UARTStateTX::Idle);
305 }
306
307 if self.rx_status.get() == UARTStateRX::AbortRequested {
308 self.rx_client.map(|client| {
310 self.rx_buffer.take().map(|buf| {
311 client.received_buffer(
312 buf,
313 self.rx_position.get(),
314 Err(ErrorCode::CANCEL),
315 hil::uart::Error::Aborted,
316 );
317 });
318 });
319 self.rx_status.set(UARTStateRX::Idle);
320 }
321 }
322}
323
324impl hil::uart::Configure for Uart<'_> {
325 fn configure(&self, params: hil::uart::Parameters) -> Result<(), ErrorCode> {
326 if params.parity != hil::uart::Parity::None {
328 return Err(ErrorCode::NOSUPPORT);
329 }
330 if params.hw_flow_control {
331 return Err(ErrorCode::NOSUPPORT);
332 }
333
334 self.set_baud_rate(params.baud_rate);
336
337 self.stop_bits.set(params.stop_bits);
339
340 Ok(())
341 }
342}
343
344impl<'a> hil::uart::Transmit<'a> for Uart<'a> {
345 fn set_transmit_client(&self, client: &'a dyn hil::uart::TransmitClient) {
346 self.tx_client.set(client);
347 }
348
349 fn transmit_buffer(
350 &self,
351 tx_buffer: &'static mut [u8],
352 tx_len: usize,
353 ) -> Result<(), (ErrorCode, &'static mut [u8])> {
354 if self.tx_status.get() != UARTStateTX::Idle {
355 Err((ErrorCode::BUSY, tx_buffer))
356 } else if tx_len == 0 || tx_len > tx_buffer.len() {
357 Err((ErrorCode::SIZE, tx_buffer))
358 } else {
359 self.tx_status.set(UARTStateTX::Transmitting);
360
361 self.tx_buffer.replace(tx_buffer);
363 self.tx_len.set(tx_len);
364 self.tx_position.set(0);
365
366 self.registers
369 .txctrl
370 .write(txctrl::txen::SET + self.get_stop_bits() + txctrl::txcnt.val(1));
371
372 self.enable_tx_interrupt();
374
375 Ok(())
376 }
377 }
378
379 fn transmit_abort(&self) -> Result<(), ErrorCode> {
380 if self.tx_status.get() != UARTStateTX::Idle {
381 self.registers.txctrl.write(txctrl::txen::CLEAR);
382 self.disable_tx_interrupt();
383 self.tx_status.set(UARTStateTX::AbortRequested);
384
385 self.deferred_call.set();
386
387 Err(ErrorCode::BUSY)
388 } else {
389 Ok(())
390 }
391 }
392
393 fn transmit_word(&self, _word: u32) -> Result<(), ErrorCode> {
394 Err(ErrorCode::FAIL)
395 }
396}
397
398impl<'a> hil::uart::Receive<'a> for Uart<'a> {
399 fn set_receive_client(&self, client: &'a dyn hil::uart::ReceiveClient) {
400 self.rx_client.set(client);
401 }
402
403 fn receive_buffer(
404 &self,
405 rx_buffer: &'static mut [u8],
406 rx_len: usize,
407 ) -> Result<(), (ErrorCode, &'static mut [u8])> {
408 if self.rx_status.get() != UARTStateRX::Idle {
409 Err((ErrorCode::BUSY, rx_buffer))
410 } else if rx_len > rx_buffer.len() {
411 Err((ErrorCode::SIZE, rx_buffer))
412 } else {
413 self.rx_status.set(UARTStateRX::Receiving);
414
415 self.rx_buffer.put(Some(rx_buffer));
416 self.rx_position.set(0);
417 self.rx_len.set(rx_len);
418
419 self.registers
422 .rxctrl
423 .write(rxctrl::enable::SET + rxctrl::counter.val(0));
424
425 self.enable_rx_interrupt();
426
427 Ok(())
428 }
429 }
430
431 fn receive_abort(&self) -> Result<(), ErrorCode> {
432 if self.rx_status.get() != UARTStateRX::Idle {
433 self.registers.rxctrl.write(rxctrl::enable::CLEAR);
434 self.disable_rx_interrupt();
435 self.rx_status.set(UARTStateRX::AbortRequested);
436
437 self.deferred_call.set();
438
439 Err(ErrorCode::BUSY)
440 } else {
441 Ok(())
442 }
443 }
444
445 fn receive_word(&self) -> Result<(), ErrorCode> {
446 Err(ErrorCode::FAIL)
447 }
448}