Skip to content

Commit 8a51576

Browse files
Add support for usart4.
1 parent f6e1292 commit 8a51576

File tree

1 file changed

+141
-2
lines changed

1 file changed

+141
-2
lines changed

stm32f0_hal/src/uart.rs

Lines changed: 141 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
use cortex_m;
2-
use stm32f0x2::{USART1 as UART1, USART3 as UART3, GPIOA, GPIOB, NVIC, RCC};
2+
use stm32f0x2::{USART1 as UART1, USART3 as UART3, USART4 as UART4, GPIOA, GPIOB, NVIC, RCC};
33
use stm32f0x2::interrupt::Interrupt::{USART1, USART3_4};
44

5-
const FREQUENCY: u32 = 48000000;
5+
const FREQUENCY: u32 = 48_000_000;
66

77
pub enum Uarts {
88
Uart1,
99
Uart3,
10+
Uart4,
1011
}
1112

1213
pub enum NBits {
@@ -267,6 +268,118 @@ impl Uart {
267268
});
268269
Uart { uart }
269270
}
271+
Uarts::Uart4 => {
272+
cortex_m::interrupt::free(|cs| {
273+
let rcc = RCC.borrow(cs);
274+
let nvic = NVIC.borrow(cs);
275+
let gpioa = GPIOA.borrow(cs);
276+
let uart = UART4.borrow(cs);
277+
// Enable GPIOA Clock into the Advanced High-performance Bus
278+
rcc.ahbenr.modify(|_, w| w.iopaen().enabled());
279+
// Enable USART4 Clock into the Advanced Peripheral Bus 1
280+
rcc.apb1enr.modify(|_, w| w.usart4en().enabled());
281+
282+
// Configure speed of PA0/PA1 (refer to the datasheet for the frequency, the power supply and load conditions)
283+
gpioa
284+
.ospeedr
285+
.modify(|_, w| w.ospeedr0().high_speed().ospeedr1().high_speed());
286+
// Use pull-up on PA0/1
287+
gpioa
288+
.pupdr
289+
.modify(|_, w| w.pupdr0().pull_up().pupdr1().pull_up());
290+
// Configure PA0/PA1 Alternate Function 4 -> USART4 (PA0 -> TX & PA1 -> RX)
291+
gpioa.afrl.modify(|_, w| w.afrl0().af4().afrl1().af4());
292+
// PA0 & PA1 as Alternate function (USART4 peripheral)
293+
gpioa
294+
.moder
295+
.modify(|_, w| w.moder0().alternate().moder1().alternate());
296+
// PA0 & PA1 push-pull configuration
297+
gpioa
298+
.otyper
299+
.modify(|_, w| w.ot0().push_pull().ot1().push_pull());
300+
301+
// Configure UART1 : Word length
302+
match nbits {
303+
NBits::_8bits => {
304+
uart.cr1.modify(|_, w| w.m()._8bits());
305+
}
306+
NBits::_9bits => {
307+
uart.cr1.modify(|_, w| w.m()._9bits());
308+
}
309+
}
310+
// Configure UART1 : Parity
311+
match parity {
312+
Parity::None => {
313+
uart.cr1.modify(|_, w| w.pce().disabled());
314+
}
315+
Parity::Even => {
316+
uart.cr1.modify(|_, w| w.pce().enabled());
317+
uart.cr1.modify(|_, w| w.ps().even());
318+
}
319+
Parity::Odd => {
320+
uart.cr1.modify(|_, w| w.pce().enabled());
321+
uart.cr1.modify(|_, w| w.ps().odd());
322+
}
323+
}
324+
// Configure UART4: Transfert Direction - Oversampling - RX Interrupt
325+
uart.cr1.modify(|_, w| {
326+
w.te()
327+
.enabled()
328+
.re()
329+
.enabled()
330+
.over8()
331+
.over8()
332+
.rxneie()
333+
.enabled()
334+
});
335+
// Configure UART1 : stop bit
336+
match nbstopbits {
337+
StopBits::_0b5 => {
338+
uart.cr2.modify(|_, w| w.stop().half_stop());
339+
}
340+
StopBits::_1b => {
341+
uart.cr2.modify(|_, w| w.stop()._1stop());
342+
}
343+
StopBits::_1b5 => {
344+
uart.cr2.modify(|_, w| w.stop()._1half_stop());
345+
}
346+
StopBits::_2b => {
347+
uart.cr2.modify(|_, w| w.stop()._2stop());
348+
}
349+
}
350+
351+
// Configure UART4: disable hardware flow control - Overrun interrupt
352+
uart.cr3.modify(|_, w| {
353+
w.rtse()
354+
.disabled()
355+
.ctse()
356+
.disabled()
357+
.ctsie()
358+
.disabled()
359+
.ovrdis()
360+
.disabled()
361+
});
362+
// Configure UART4: baudrate
363+
uart.brr.modify(|_, w| {
364+
w.div_fraction()
365+
.bits((FREQUENCY / (baudrate / 2)) as u8 & 0x0F)
366+
});
367+
uart.brr.modify(|_, w| {
368+
w.div_mantissa()
369+
.bits(((FREQUENCY / (baudrate / 2)) >> 4) as u16)
370+
});
371+
// Configure UART4: Asynchronous mode
372+
uart.cr2
373+
.modify(|_, w| w.linen().disabled().clken().disabled());
374+
// UART4 enabled
375+
uart.cr1.modify(|_, w| w.ue().enabled());
376+
377+
// Interrupt UART4 activated into NVIC
378+
nvic.enable(USART3_4);
379+
nvic.clear_pending(USART3_4);
380+
});
381+
Uart { uart }
382+
}
270383
}
271384
}
272385

@@ -282,6 +395,11 @@ impl Uart {
282395
// the byte is stored in the UART3 transmit register
283396
uart3.tdr.write(|w| w.tdr().bits(byte as u16));
284397
}),
398+
Uarts::Uart4 => cortex_m::interrupt::free(|cs| {
399+
let uart4 = UART4.borrow(cs);
400+
// the byte is stored in the UART4 transmit register
401+
uart4.tdr.write(|w| w.tdr().bits(byte as u16));
402+
}),
285403
}
286404
}
287405

@@ -309,6 +427,17 @@ impl Uart {
309427
false
310428
}
311429
}),
430+
Uarts::Uart4 => cortex_m::interrupt::free(|cs| {
431+
let uart4 = UART4.borrow(cs);
432+
// Check the Transmit Completed flag status
433+
if uart4.isr.read().tc().bit_is_set() {
434+
// if transmit completed, clear the transmit completed flag and return true
435+
uart4.icr.write(|w| w.tccf().clear_bit());
436+
true
437+
} else {
438+
false
439+
}
440+
}),
312441
}
313442
}
314443

@@ -334,6 +463,16 @@ impl Uart {
334463
None
335464
}
336465
}),
466+
Uarts::Uart4 => cortex_m::interrupt::free(|cs| {
467+
let uart4 = UART4.borrow(cs);
468+
// Check the Receive Not Empty flag flag status
469+
if uart4.isr.read().rxne().bit_is_set() {
470+
// if true, read the received data and finish the rxne flag cleared procedure
471+
Some(uart4.rdr.read().rdr().bits() as u8)
472+
} else {
473+
None
474+
}
475+
}),
337476
}
338477
}
339478
}

0 commit comments

Comments
 (0)