Skip to content

Commit ca71955

Browse files
authored
Merge pull request #211 from korken89/const_generics
Moved to const generics
2 parents e87fc27 + 26c4833 commit ca71955

File tree

4 files changed

+39
-83
lines changed

4 files changed

+39
-83
lines changed

Cargo.toml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@ edition = "2018"
2424
cortex-m = "0.6.3"
2525
nb = "0.1.1"
2626
stm32l4 = "0.13.0"
27-
as-slice = "0.1"
28-
generic-array = "0.13"
2927

3028
[dependencies.rand_core]
3129
version = "0.6.2"

examples/rtic_frame_serial_dma.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
#![no_std]
1212

1313
use hal::{
14-
dma::{self, consts, DMAFrame, FrameReader, FrameSender},
14+
dma::{self, DMAFrame, FrameReader, FrameSender},
1515
prelude::*,
1616
rcc::{ClockSecuritySystem, CrystalBypass, MsiFreq},
1717
serial::{self, Config, Serial},
@@ -27,15 +27,15 @@ use stm32l4xx_hal as hal;
2727
// The pool gives out `Box<DMAFrame>`s that can hold 8 bytes
2828
pool!(
2929
#[allow(non_upper_case_globals)]
30-
SerialDMAPool: DMAFrame<consts::U8>
30+
SerialDMAPool: DMAFrame<8>
3131
);
3232

3333
#[app(device = stm32l4xx_hal::stm32, peripherals = true)]
3434
const APP: () = {
3535
struct Resources {
3636
rx: serial::Rx<hal::stm32::USART2>,
37-
frame_reader: FrameReader<Box<SerialDMAPool>, dma::dma1::C6, consts::U8>,
38-
frame_sender: FrameSender<Box<SerialDMAPool>, dma::dma1::C7, consts::U8>,
37+
frame_reader: FrameReader<Box<SerialDMAPool>, dma::dma1::C6, 8>,
38+
frame_sender: FrameSender<Box<SerialDMAPool>, dma::dma1::C7, 8>,
3939
}
4040

4141
#[init]
@@ -94,7 +94,7 @@ const APP: () = {
9494
};
9595

9696
// Serial frame sender (DMA based)
97-
let fs: FrameSender<Box<SerialDMAPool>, _, _> = serial_tx.frame_sender(dma_ch7);
97+
let fs: FrameSender<Box<SerialDMAPool>, _, 8> = serial_tx.frame_sender(dma_ch7);
9898

9999
init::LateResources {
100100
rx: serial_rx,

src/dma.rs

Lines changed: 30 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,6 @@ use core::ptr;
1010
use core::slice;
1111

1212
use crate::rcc::AHB1;
13-
use as_slice::AsSlice;
14-
pub use generic_array::typenum::{self, consts};
15-
use generic_array::{ArrayLength, GenericArray};
1613
use stable_deref_trait::StableDeref;
1714

1815
#[non_exhaustive]
@@ -34,21 +31,18 @@ pub enum Half {
3431
}
3532

3633
/// Frame reader "worker", access and handling of frame reads is made through this structure.
37-
pub struct FrameReader<BUFFER, CHANNEL, N>
34+
pub struct FrameReader<BUFFER, CHANNEL, const N: usize>
3835
where
3936
BUFFER: Sized + StableDeref<Target = DMAFrame<N>> + DerefMut + 'static,
40-
N: ArrayLength<MaybeUninit<u8>>,
4137
{
4238
buffer: BUFFER,
4339
channel: CHANNEL,
4440
matching_character: u8,
45-
_marker: core::marker::PhantomData<N>, // Needed to make the compiler happy
4641
}
4742

48-
impl<BUFFER, CHANNEL, N> FrameReader<BUFFER, CHANNEL, N>
43+
impl<BUFFER, CHANNEL, const N: usize> FrameReader<BUFFER, CHANNEL, N>
4944
where
5045
BUFFER: Sized + StableDeref<Target = DMAFrame<N>> + DerefMut + 'static,
51-
N: ArrayLength<MaybeUninit<u8>>,
5246
{
5347
pub(crate) fn new(
5448
buffer: BUFFER,
@@ -59,33 +53,28 @@ where
5953
buffer,
6054
channel,
6155
matching_character,
62-
_marker: core::marker::PhantomData,
6356
}
6457
}
6558
}
6659

6760
/// Frame sender "worker", access and handling of frame transmissions is made through this
6861
/// structure.
69-
pub struct FrameSender<BUFFER, CHANNEL, N>
62+
pub struct FrameSender<BUFFER, CHANNEL, const N: usize>
7063
where
7164
BUFFER: Sized + StableDeref<Target = DMAFrame<N>> + DerefMut + 'static,
72-
N: ArrayLength<MaybeUninit<u8>>,
7365
{
7466
buffer: Option<BUFFER>,
7567
channel: CHANNEL,
76-
_marker: core::marker::PhantomData<N>,
7768
}
7869

79-
impl<BUFFER, CHANNEL, N> FrameSender<BUFFER, CHANNEL, N>
70+
impl<BUFFER, CHANNEL, const N: usize> FrameSender<BUFFER, CHANNEL, N>
8071
where
8172
BUFFER: Sized + StableDeref<Target = DMAFrame<N>> + DerefMut + 'static,
82-
N: ArrayLength<MaybeUninit<u8>>,
8373
{
8474
pub(crate) fn new(channel: CHANNEL) -> FrameSender<BUFFER, CHANNEL, N> {
8575
Self {
8676
buffer: None,
8777
channel,
88-
_marker: core::marker::PhantomData,
8978
}
9079
}
9180
}
@@ -96,27 +85,18 @@ where
9685
/// used with, for example, [`heapless::pool`] to create a pool of serial frames.
9786
///
9887
/// [`heapless::pool`]: https://docs.rs/heapless/0.5.3/heapless/pool/index.html
99-
pub struct DMAFrame<N>
100-
where
101-
N: ArrayLength<MaybeUninit<u8>>,
102-
{
88+
pub struct DMAFrame<const N: usize> {
10389
len: u16,
104-
buf: GenericArray<MaybeUninit<u8>, N>,
90+
buf: [MaybeUninit<u8>; N],
10591
}
10692

107-
impl<N> fmt::Debug for DMAFrame<N>
108-
where
109-
N: ArrayLength<MaybeUninit<u8>>,
110-
{
93+
impl<const N: usize> fmt::Debug for DMAFrame<N> {
11194
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
11295
write!(f, "{:?}", self.read())
11396
}
11497
}
11598

116-
impl<N> fmt::Write for DMAFrame<N>
117-
where
118-
N: ArrayLength<MaybeUninit<u8>>,
119-
{
99+
impl<const N: usize> fmt::Write for DMAFrame<N> {
120100
fn write_str(&mut self, s: &str) -> fmt::Result {
121101
let free = self.free();
122102

@@ -129,29 +109,21 @@ where
129109
}
130110
}
131111

132-
impl<N> Default for DMAFrame<N>
133-
where
134-
N: ArrayLength<MaybeUninit<u8>>,
135-
{
112+
impl<const N: usize> Default for DMAFrame<N> {
136113
fn default() -> Self {
137114
Self::new()
138115
}
139116
}
140117

141-
impl<N> DMAFrame<N>
142-
where
143-
N: ArrayLength<MaybeUninit<u8>>,
144-
{
118+
impl<const N: usize> DMAFrame<N> {
119+
const INIT: MaybeUninit<u8> = MaybeUninit::uninit();
145120
/// Creates a new node for the Serial DMA
146121
#[inline]
147-
pub fn new() -> Self {
148-
// Create an uninitialized array of `MaybeUninit<u8>`. The `assume_init` is
149-
// safe because the type we are claiming to have initialized here is a
150-
// bunch of `MaybeUninit`s, which do not require initialization.
151-
#[allow(clippy::uninit_assumed_init)]
122+
pub const fn new() -> Self {
123+
// Create an uninitialized array of `MaybeUninit<u8>`.
152124
Self {
153125
len: 0,
154-
buf: unsafe { MaybeUninit::uninit().assume_init() },
126+
buf: [Self::INIT; N],
155127
}
156128
}
157129

@@ -162,7 +134,7 @@ where
162134
pub fn write(&mut self) -> &mut [u8] {
163135
// Initialize remaining memory with a safe value
164136
for elem in &mut self.buf[self.len as usize..] {
165-
*elem = MaybeUninit::zeroed();
137+
*elem = MaybeUninit::new(0);
166138
}
167139

168140
self.len = self.max_len() as u16;
@@ -183,7 +155,7 @@ where
183155
/// Gives an uninitialized `&mut [MaybeUninit<u8>]` slice to write into, the `set_len` method
184156
/// must then be used to set the actual number of bytes written.
185157
#[inline]
186-
pub fn write_uninit(&mut self) -> &mut [MaybeUninit<u8>] {
158+
pub fn write_uninit(&mut self) -> &mut [MaybeUninit<u8>; N] {
187159
&mut self.buf
188160
}
189161

@@ -256,7 +228,7 @@ where
256228
/// Get the max length of the frame
257229
#[inline]
258230
pub fn max_len(&self) -> usize {
259-
N::to_usize()
231+
N
260232
}
261233

262234
/// Checks if the frame is empty
@@ -281,13 +253,9 @@ where
281253
}
282254
}
283255

284-
impl<N> AsSlice for DMAFrame<N>
285-
where
286-
N: ArrayLength<MaybeUninit<u8>>,
287-
{
288-
type Element = u8;
289-
290-
fn as_slice(&self) -> &[Self::Element] {
256+
impl<const N: usize> AsRef<[u8]> for DMAFrame<N> {
257+
#[inline]
258+
fn as_ref(&self) -> &[u8] {
291259
self.read()
292260
}
293261
}
@@ -394,10 +362,7 @@ macro_rules! dma {
394362
$(
395363
pub mod $dmaX {
396364
use core::sync::atomic::{self, Ordering};
397-
use as_slice::{AsSlice};
398365
use crate::stm32::{$DMAX, dma1};
399-
use core::mem::MaybeUninit;
400-
use generic_array::ArrayLength;
401366
use core::ops::DerefMut;
402367
use core::ptr;
403368
use stable_deref_trait::StableDeref;
@@ -525,10 +490,9 @@ macro_rules! dma {
525490

526491
}
527492

528-
impl<BUFFER, N> FrameSender<BUFFER, $CX, N>
493+
impl<BUFFER, const N: usize> FrameSender<BUFFER, $CX, N>
529494
where
530495
BUFFER: Sized + StableDeref<Target = DMAFrame<N>> + DerefMut + 'static,
531-
N: ArrayLength<MaybeUninit<u8>>,
532496
{
533497
/// This method should be called in the transfer complete interrupt of the
534498
/// DMA, will return the sent frame if the transfer was truly completed.
@@ -593,10 +557,9 @@ macro_rules! dma {
593557
}
594558
}
595559

596-
impl<BUFFER, N> FrameReader<BUFFER, $CX, N>
560+
impl<BUFFER, const N: usize> FrameReader<BUFFER, $CX, N>
597561
where
598562
BUFFER: Sized + StableDeref<Target = DMAFrame<N>> + DerefMut + 'static,
599-
N: ArrayLength<MaybeUninit<u8>>,
600563
{
601564
/// This function should be called from the transfer complete interrupt of
602565
/// the corresponding DMA channel.
@@ -726,7 +689,7 @@ macro_rules! dma {
726689
where
727690
F: FnOnce(&[T], Half) -> Result<(usize, R), ()>,
728691
B: StableDeref<Target = [H; 2]> + 'static,
729-
H: AsSlice<Element=T>,
692+
H: AsRef<[T]>,
730693
{
731694
// this inverts expectation and returns the half being _written_
732695
let buf = match self.readable_half {
@@ -737,7 +700,7 @@ macro_rules! dma {
737700
// [ x x x x y y y y y z | z z z z z z z z z z ]
738701
// ^- pending=11
739702
let pending = self.channel.get_cndtr() as usize; // available bytes in _whole_ buffer
740-
let slice = buf.as_slice();
703+
let slice = buf.as_ref();
741704
let capacity = slice.len(); // capacity of _half_ a buffer
742705
// <--- capacity=10 --->
743706
// [ x x x x y y y y y z | z z z z z z z z z z ]
@@ -754,7 +717,7 @@ macro_rules! dma {
754717
// ^- end=9
755718
// ^- consumed_offset=4
756719
// [y y y y y] <-- slice
757-
let slice = &buf.as_slice()[self.consumed_offset..end];
720+
let slice = &buf.as_ref()[self.consumed_offset..end];
758721
match f(slice, self.readable_half) {
759722
Ok((l, r)) => { self.consumed_offset += l; Ok(r) },
760723
Err(_) => Err(Error::BufferError),
@@ -767,14 +730,14 @@ macro_rules! dma {
767730
where
768731
F: FnOnce(&[T], Half) -> R,
769732
B: StableDeref<Target = [H; 2]> + 'static,
770-
H: AsSlice<Element=T>,
733+
H: AsRef<[T]>,
771734
{
772735
let half_being_read = self.readable_half()?;
773736
let buf = match half_being_read {
774737
Half::First => &self.buffer[0],
775738
Half::Second => &self.buffer[1],
776739
};
777-
let slice = &buf.as_slice()[self.consumed_offset..];
740+
let slice = &buf.as_ref()[self.consumed_offset..];
778741
self.consumed_offset = 0;
779742
Ok(f(slice, half_being_read))
780743
}
@@ -844,13 +807,13 @@ macro_rules! dma {
844807
impl<BUFFER, PAYLOAD> Transfer<W, &'static mut BUFFER, $CX, PAYLOAD> {
845808
pub fn peek<T>(&self) -> &[T]
846809
where
847-
BUFFER: AsSlice<Element=T>,
810+
BUFFER: AsRef<[T]>
848811
{
849812
let pending = self.channel.get_cndtr() as usize;
850813

851-
let capacity = self.buffer.as_slice().len();
814+
let capacity = self.buffer.as_ref().len();
852815

853-
&self.buffer.as_slice()[..(capacity - pending)]
816+
&self.buffer.as_ref()[..(capacity - pending)]
854817
}
855818
}
856819
)+

src/serial.rs

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,11 @@
22
//!
33
//! This module support both polling and interrupt based accesses to the serial peripherals.
44
5-
use as_slice::AsMutSlice;
65
use core::fmt;
76
use core::marker::PhantomData;
8-
use core::mem::MaybeUninit;
97
use core::ops::DerefMut;
108
use core::ptr;
119
use core::sync::atomic::{self, Ordering};
12-
use generic_array::ArrayLength;
1310
use stable_deref_trait::StableDeref;
1411

1512
use crate::hal::serial::{self, Write};
@@ -512,9 +509,9 @@ macro_rules! hal {
512509
) -> CircBuffer<B, $rx_chan>
513510
where
514511
B: StableDeref<Target = [H; 2]> + DerefMut + 'static,
515-
H: AsMutSlice<Element = u8>
512+
H: AsMut<[u8]>
516513
{
517-
let buf = buffer[0].as_mut_slice();
514+
let buf = buffer[0].as_mut();
518515
chan.set_peripheral_address(unsafe{ &(*pac::$USARTX::ptr()).rdr as *const _ as u32 }, false);
519516
chan.set_memory_address(buf.as_ptr() as u32, true);
520517
chan.set_transfer_length((buf.len() * 2) as u16);
@@ -553,14 +550,13 @@ macro_rules! hal {
553550

554551
/// Create a frame reader that can either react on the Character match interrupt or
555552
/// Transfer Complete from the DMA.
556-
pub fn frame_read<BUFFER, N>(
553+
pub fn frame_read<BUFFER, const N: usize>(
557554
&self,
558555
mut channel: $rx_chan,
559556
buffer: BUFFER,
560557
) -> FrameReader<BUFFER, $rx_chan, N>
561558
where
562559
BUFFER: Sized + StableDeref<Target = DMAFrame<N>> + DerefMut + 'static,
563-
N: ArrayLength<MaybeUninit<u8>>,
564560
{
565561
let usart = unsafe{ &(*pac::$USARTX::ptr()) };
566562

@@ -684,13 +680,12 @@ macro_rules! hal {
684680

685681
impl Tx<pac::$USARTX> {
686682
/// Creates a new DMA frame sender
687-
pub fn frame_sender<BUFFER, N>(
683+
pub fn frame_sender<BUFFER, const N: usize>(
688684
&self,
689685
mut channel: $tx_chan,
690686
) -> FrameSender<BUFFER, $tx_chan, N>
691687
where
692688
BUFFER: Sized + StableDeref<Target = DMAFrame<N>> + DerefMut + 'static,
693-
N: ArrayLength<MaybeUninit<u8>>,
694689
{
695690
let usart = unsafe{ &(*pac::$USARTX::ptr()) };
696691

0 commit comments

Comments
 (0)