1
1
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 } ;
3
3
use stm32f0x2:: interrupt:: Interrupt :: { USART1 , USART3_4 } ;
4
4
5
- const FREQUENCY : u32 = 48000000 ;
5
+ const FREQUENCY : u32 = 48_000_000 ;
6
6
7
7
pub enum Uarts {
8
8
Uart1 ,
9
9
Uart3 ,
10
+ Uart4 ,
10
11
}
11
12
12
13
pub enum NBits {
@@ -267,6 +268,118 @@ impl Uart {
267
268
} ) ;
268
269
Uart { uart }
269
270
}
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
+ }
270
383
}
271
384
}
272
385
@@ -282,6 +395,11 @@ impl Uart {
282
395
// the byte is stored in the UART3 transmit register
283
396
uart3. tdr . write ( |w| w. tdr ( ) . bits ( byte as u16 ) ) ;
284
397
} ) ,
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
+ } ) ,
285
403
}
286
404
}
287
405
@@ -309,6 +427,17 @@ impl Uart {
309
427
false
310
428
}
311
429
} ) ,
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
+ } ) ,
312
441
}
313
442
}
314
443
@@ -334,6 +463,16 @@ impl Uart {
334
463
None
335
464
}
336
465
} ) ,
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
+ } ) ,
337
476
}
338
477
}
339
478
}
0 commit comments