Skip to content

Commit e020ccc

Browse files
committed
Replace Pin with StableDeref bounds for DMA buffers
1 parent 069fee0 commit e020ccc

File tree

4 files changed

+118
-59
lines changed

4 files changed

+118
-59
lines changed

examples/i2s-controller-demo/src/main.rs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ use small_morse::{encode, State};
1414
use {
1515
core::{
1616
panic::PanicInfo,
17-
pin,
1817
sync::atomic::{compiler_fence, Ordering},
1918
},
2019
hal::{
@@ -33,8 +32,8 @@ use {
3332
#[rtic::app(device = crate::hal::pac, peripherals = true, monotonic = rtic::cyccnt::CYCCNT)]
3433
const APP: () = {
3534
struct Resources {
36-
signal_buf: pin::Pin<&'static [i16]>,
37-
mute_buf: pin::Pin<&'static [i16]>,
35+
signal_buf: &'static [i16],
36+
mute_buf: &'static [i16],
3837
#[init(None)]
3938
queue: Option<Queue<State, U256>>,
4039
producer: Producer<'static, State, U256>,
@@ -47,7 +46,7 @@ const APP: () = {
4746
btn1: Pin<Input<PullUp>>,
4847
btn2: Pin<Input<PullUp>>,
4948
led: Pin<Output<PushPull>>,
50-
transfer: Option<hal::i2s::Transfer<&'static [i16]>>,
49+
transfer: Option<Transfer<&'static [i16]>>,
5150
}
5251

5352
#[init(resources = [queue], spawn = [tick])]
@@ -125,9 +124,9 @@ const APP: () = {
125124
led: p0.p0_13.into_push_pull_output(Level::High).degrade(),
126125
uarte,
127126
uarte_timer: Timer::new(ctx.device.TIMER0),
128-
transfer: i2s.tx(pin::Pin::new(&MUTE_BUF[..])).ok(),
129-
signal_buf: pin::Pin::new(&SIGNAL_BUF[..]),
130-
mute_buf: pin::Pin::new(&MUTE_BUF[..]),
127+
transfer: i2s.tx(&MUTE_BUF[..]).ok(),
128+
signal_buf: &SIGNAL_BUF[..],
129+
mute_buf: &MUTE_BUF[..],
131130
}
132131
}
133132

examples/i2s-peripheral-demo/src/main.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ use embedded_hal::blocking::spi::Write;
88
use {
99
core::{
1010
panic::PanicInfo,
11-
pin,
1211
sync::atomic::{compiler_fence, Ordering},
1312
},
1413
hal::{
@@ -30,7 +29,7 @@ const RED: [u8; 9] = [0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x10, 0xFF];
3029
const APP: () = {
3130
struct Resources {
3231
rgb: Spim<SPIM0>,
33-
transfer: Option<hal::i2s::Transfer<&'static mut [i16]>>,
32+
transfer: Option<Transfer<&'static mut [i16]>>,
3433
}
3534

3635
#[init]
@@ -57,8 +56,6 @@ const APP: () = {
5756
None,
5857
);
5958
i2s.enable_interrupt(I2SEvent::RxPtrUpdated).start();
60-
let rx_buf = pin::Pin::new(&mut RX_BUF[..]);
61-
let transfer = i2s.rx(rx_buf).ok();
6259

6360
// Configure APA102 RGB LED control
6461
let p1 = hal::gpio::p1::Parts::new(ctx.device.P1);
@@ -79,7 +76,10 @@ const APP: () = {
7976
},
8077
0,
8178
);
82-
init::LateResources { rgb, transfer }
79+
init::LateResources {
80+
rgb,
81+
transfer: i2s.rx(&mut RX_BUF[..]).ok(),
82+
}
8383
}
8484

8585
#[task(binds = I2S, resources = [rgb, transfer])]

nrf-hal-common/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ fixed = "1.0.0"
2525
rand_core = "0.5.1"
2626
cfg-if = "0.1.10"
2727

28+
[dependencies.stable_deref_trait]
29+
version = "1.2.0"
30+
default-features = false
31+
2832
[dependencies.void]
2933
default-features = false
3034
version = "1.0.2"

nrf-hal-common/src/i2s.rs

Lines changed: 103 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use core::{
1414
ops::{Deref, DerefMut},
1515
sync::atomic::{compiler_fence, Ordering},
1616
};
17+
pub use stable_deref_trait::StableDeref;
1718

1819
use i2s::{_EVENTS_RXPTRUPD, _EVENTS_STOPPED, _EVENTS_TXPTRUPD, _TASKS_START, _TASKS_STOP};
1920

@@ -261,27 +262,26 @@ impl I2S {
261262
_ => Channels::Right,
262263
}
263264
}
264-
265265
/// Receives data into the given `buffer` until it's filled.
266266
/// Returns a value that represents the in-progress DMA transfer.
267267
#[allow(unused_mut)]
268-
pub fn rx<Word, B>(mut self, mut buffer: core::pin::Pin<B>) -> Result<Transfer<B>, Error>
268+
pub fn rx<Word, B>(mut self, mut buffer: B) -> Result<Transfer<B>, Error>
269269
where
270270
Word: SupportedWordSize,
271-
B: DerefMut + 'static,
272-
B::Target: AsMut<[Word]> + Unpin + I2SBuffer,
271+
B: DerefMut + StableDeref + 'static + I2SBuffer,
272+
B::Target: AsMut<[Word]>,
273273
{
274-
if buffer.as_mut().maxcnt() > MAX_DMA_MAXCNT {
274+
if buffer.maxcnt() > MAX_DMA_MAXCNT {
275275
return Err(Error::BufferTooLong);
276276
}
277277
self.i2s
278278
.rxd
279279
.ptr
280-
.write(|w| unsafe { w.ptr().bits(buffer.as_mut().ptr()) });
280+
.write(|w| unsafe { w.ptr().bits(buffer.ptr()) });
281281
self.i2s
282282
.rxtxd
283283
.maxcnt
284-
.write(|w| unsafe { w.bits(buffer.as_mut().maxcnt()) });
284+
.write(|w| unsafe { w.bits(buffer.maxcnt()) });
285285
Ok(Transfer {
286286
inner: Some(Inner { buffer, i2s: self }),
287287
})
@@ -294,40 +294,38 @@ impl I2S {
294294
#[allow(unused_mut)]
295295
pub fn transfer<Word, TxB, RxB>(
296296
mut self,
297-
tx_buffer: core::pin::Pin<TxB>,
298-
mut rx_buffer: core::pin::Pin<RxB>,
297+
tx_buffer: TxB,
298+
mut rx_buffer: RxB,
299299
) -> Result<TransferFullDuplex<TxB, RxB>, Error>
300300
where
301301
Word: SupportedWordSize,
302-
TxB: Deref + 'static,
303-
TxB::Target: AsRef<[Word]> + I2SBuffer,
304-
RxB: DerefMut + 'static,
305-
RxB::Target: AsMut<[Word]> + Unpin + I2SBuffer,
302+
TxB: Deref + StableDeref + 'static + I2SBuffer,
303+
TxB::Target: AsRef<[Word]>,
304+
RxB: DerefMut + StableDeref + 'static + I2SBuffer,
305+
RxB::Target: AsMut<[Word]>,
306306
{
307-
if (tx_buffer.as_ref().ptr() as usize) < SRAM_LOWER
308-
|| (tx_buffer.as_ref().ptr() as usize) > SRAM_UPPER
309-
{
307+
if (tx_buffer.ptr() as usize) < SRAM_LOWER || (tx_buffer.ptr() as usize) > SRAM_UPPER {
310308
return Err(Error::DMABufferNotInDataMemory);
311309
}
312-
if tx_buffer.as_ref().maxcnt() != rx_buffer.as_mut().maxcnt() {
310+
if tx_buffer.maxcnt() != rx_buffer.maxcnt() {
313311
return Err(Error::BuffersDontMatch);
314312
}
315-
if tx_buffer.as_ref().maxcnt() > MAX_DMA_MAXCNT {
313+
if tx_buffer.maxcnt() > MAX_DMA_MAXCNT {
316314
return Err(Error::BufferTooLong);
317315
}
318316

319317
self.i2s
320318
.txd
321319
.ptr
322-
.write(|w| unsafe { w.ptr().bits(tx_buffer.as_ref().ptr()) });
320+
.write(|w| unsafe { w.ptr().bits(tx_buffer.ptr()) });
323321
self.i2s
324322
.rxd
325323
.ptr
326-
.write(|w| unsafe { w.ptr().bits(rx_buffer.as_mut().ptr()) });
324+
.write(|w| unsafe { w.ptr().bits(rx_buffer.ptr()) });
327325
self.i2s
328326
.rxtxd
329327
.maxcnt
330-
.write(|w| unsafe { w.bits(rx_buffer.as_mut().maxcnt()) });
328+
.write(|w| unsafe { w.bits(rx_buffer.maxcnt()) });
331329

332330
self.start();
333331

@@ -343,30 +341,28 @@ impl I2S {
343341
/// Transmits the given `tx_buffer`.
344342
/// Returns a value that represents the in-progress DMA transfer.
345343
#[allow(unused_mut)]
346-
pub fn tx<Word, B>(mut self, buffer: core::pin::Pin<B>) -> Result<Transfer<B>, Error>
344+
pub fn tx<Word, B>(mut self, buffer: B) -> Result<Transfer<B>, Error>
347345
where
348346
Word: SupportedWordSize,
349-
B: Deref + 'static,
350-
B::Target: AsRef<[Word]> + I2SBuffer,
347+
B: Deref + StableDeref + 'static + I2SBuffer,
348+
B::Target: AsRef<[Word]>,
351349
{
352-
if (buffer.as_ref().ptr() as usize) < SRAM_LOWER
353-
|| (buffer.as_ref().ptr() as usize) > SRAM_UPPER
354-
{
350+
if (buffer.ptr() as usize) < SRAM_LOWER || (buffer.ptr() as usize) > SRAM_UPPER {
355351
return Err(Error::DMABufferNotInDataMemory);
356352
}
357353

358-
if buffer.as_ref().maxcnt() > MAX_DMA_MAXCNT {
354+
if buffer.maxcnt() > MAX_DMA_MAXCNT {
359355
return Err(Error::BufferTooLong);
360356
}
361357

362358
self.i2s
363359
.txd
364360
.ptr
365-
.write(|w| unsafe { w.ptr().bits(buffer.as_ref().ptr()) });
361+
.write(|w| unsafe { w.ptr().bits(buffer.ptr()) });
366362
self.i2s
367363
.rxtxd
368364
.maxcnt
369-
.write(|w| unsafe { w.bits(buffer.as_ref().maxcnt()) });
365+
.write(|w| unsafe { w.bits(buffer.maxcnt()) });
370366

371367
Ok(Transfer {
372368
inner: Some(Inner { buffer, i2s: self }),
@@ -608,8 +604,68 @@ pub trait I2SBuffer: private::Sealed {
608604
fn maxcnt(&self) -> u32;
609605
}
610606

611-
impl private::Sealed for [i8] {}
612-
impl I2SBuffer for [i8] {
607+
impl private::Sealed for &[i8] {}
608+
impl I2SBuffer for &[i8] {
609+
fn ptr(&self) -> u32 {
610+
self.as_ptr() as u32
611+
}
612+
fn maxcnt(&self) -> u32 {
613+
self.len() as u32 / 4
614+
}
615+
}
616+
617+
impl private::Sealed for &[i16] {}
618+
impl I2SBuffer for &[i16] {
619+
fn ptr(&self) -> u32 {
620+
self.as_ptr() as u32
621+
}
622+
fn maxcnt(&self) -> u32 {
623+
self.len() as u32 / 2
624+
}
625+
}
626+
627+
impl private::Sealed for &[i32] {}
628+
impl I2SBuffer for &[i32] {
629+
fn ptr(&self) -> u32 {
630+
self.as_ptr() as u32
631+
}
632+
fn maxcnt(&self) -> u32 {
633+
self.len() as u32
634+
}
635+
}
636+
637+
impl private::Sealed for &[u8] {}
638+
impl I2SBuffer for &[u8] {
639+
fn ptr(&self) -> u32 {
640+
self.as_ptr() as u32
641+
}
642+
fn maxcnt(&self) -> u32 {
643+
self.len() as u32 / 8
644+
}
645+
}
646+
647+
impl private::Sealed for &[u16] {}
648+
impl I2SBuffer for &[u16] {
649+
fn ptr(&self) -> u32 {
650+
self.as_ptr() as u32
651+
}
652+
fn maxcnt(&self) -> u32 {
653+
self.len() as u32 / 4
654+
}
655+
}
656+
657+
impl private::Sealed for &[u32] {}
658+
impl I2SBuffer for &[u32] {
659+
fn ptr(&self) -> u32 {
660+
self.as_ptr() as u32
661+
}
662+
fn maxcnt(&self) -> u32 {
663+
self.len() as u32 / 2
664+
}
665+
}
666+
667+
impl private::Sealed for &mut [i8] {}
668+
impl I2SBuffer for &mut [i8] {
613669
fn ptr(&self) -> u32 {
614670
self.as_ptr() as u32
615671
}
@@ -618,8 +674,8 @@ impl I2SBuffer for [i8] {
618674
}
619675
}
620676

621-
impl private::Sealed for [i16] {}
622-
impl I2SBuffer for [i16] {
677+
impl private::Sealed for &mut [i16] {}
678+
impl I2SBuffer for &mut [i16] {
623679
fn ptr(&self) -> u32 {
624680
self.as_ptr() as u32
625681
}
@@ -628,8 +684,8 @@ impl I2SBuffer for [i16] {
628684
}
629685
}
630686

631-
impl private::Sealed for [i32] {}
632-
impl I2SBuffer for [i32] {
687+
impl private::Sealed for &mut [i32] {}
688+
impl I2SBuffer for &mut [i32] {
633689
fn ptr(&self) -> u32 {
634690
self.as_ptr() as u32
635691
}
@@ -638,8 +694,8 @@ impl I2SBuffer for [i32] {
638694
}
639695
}
640696

641-
impl private::Sealed for [u8] {}
642-
impl I2SBuffer for [u8] {
697+
impl private::Sealed for &mut [u8] {}
698+
impl I2SBuffer for &mut [u8] {
643699
fn ptr(&self) -> u32 {
644700
self.as_ptr() as u32
645701
}
@@ -648,8 +704,8 @@ impl I2SBuffer for [u8] {
648704
}
649705
}
650706

651-
impl private::Sealed for [u16] {}
652-
impl I2SBuffer for [u16] {
707+
impl private::Sealed for &mut [u16] {}
708+
impl I2SBuffer for &mut [u16] {
653709
fn ptr(&self) -> u32 {
654710
self.as_ptr() as u32
655711
}
@@ -658,8 +714,8 @@ impl I2SBuffer for [u16] {
658714
}
659715
}
660716

661-
impl private::Sealed for [u32] {}
662-
impl I2SBuffer for [u32] {
717+
impl private::Sealed for &mut [u32] {}
718+
impl I2SBuffer for &mut [u32] {
663719
fn ptr(&self) -> u32 {
664720
self.as_ptr() as u32
665721
}
@@ -674,13 +730,13 @@ pub struct Transfer<B> {
674730
}
675731

676732
struct Inner<B> {
677-
buffer: core::pin::Pin<B>,
733+
buffer: B,
678734
i2s: I2S,
679735
}
680736

681737
impl<B> Transfer<B> {
682738
/// Blocks until the transfer is done and returns the buffer.
683-
pub fn wait(mut self) -> (core::pin::Pin<B>, I2S) {
739+
pub fn wait(mut self) -> (B, I2S) {
684740
let inner = self
685741
.inner
686742
.take()
@@ -707,14 +763,14 @@ pub struct TransferFullDuplex<TxB, RxB> {
707763
}
708764

709765
struct InnerFullDuplex<TxB, RxB> {
710-
tx_buffer: core::pin::Pin<TxB>,
711-
rx_buffer: core::pin::Pin<RxB>,
766+
tx_buffer: TxB,
767+
rx_buffer: RxB,
712768
i2s: I2S,
713769
}
714770

715771
impl<TxB, RxB> TransferFullDuplex<TxB, RxB> {
716772
/// Blocks until the transfer is done and returns the buffer.
717-
pub fn wait(mut self) -> (core::pin::Pin<TxB>, core::pin::Pin<RxB>, I2S) {
773+
pub fn wait(mut self) -> (TxB, RxB, I2S) {
718774
let inner = self
719775
.inner
720776
.take()

0 commit comments

Comments
 (0)