Add tx_frame & add todos
This commit is contained in:
parent
a64d6a4985
commit
5e383f004a
@ -39,8 +39,8 @@ pub mod gpio;
|
|||||||
pub mod gpiote;
|
pub mod gpiote;
|
||||||
#[cfg(any(feature = "nrf52832", feature = "nrf52833", feature = "nrf52840"))]
|
#[cfg(any(feature = "nrf52832", feature = "nrf52833", feature = "nrf52840"))]
|
||||||
pub mod i2s;
|
pub mod i2s;
|
||||||
pub mod nvmc;
|
|
||||||
pub mod nfc;
|
pub mod nfc;
|
||||||
|
pub mod nvmc;
|
||||||
#[cfg(any(
|
#[cfg(any(
|
||||||
feature = "nrf52810",
|
feature = "nrf52810",
|
||||||
feature = "nrf52811",
|
feature = "nrf52811",
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
|
//! NFC Tag Driver
|
||||||
|
|
||||||
#![macro_use]
|
#![macro_use]
|
||||||
|
|
||||||
use core::future::poll_fn;
|
use core::future::poll_fn;
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
use core::sync::atomic::{compiler_fence, Ordering};
|
use core::sync::atomic::{compiler_fence, Ordering};
|
||||||
@ -25,25 +28,16 @@ impl interrupt::typelevel::Handler<interrupt::typelevel::NFCT> for InterruptHand
|
|||||||
r.intenclr.write(|w| w.rxframeend().clear());
|
r.intenclr.write(|w| w.rxframeend().clear());
|
||||||
WAKER.wake();
|
WAKER.wake();
|
||||||
}
|
}
|
||||||
|
|
||||||
if r.events_rxerror.read().bits() != 0 {
|
if r.events_rxerror.read().bits() != 0 {
|
||||||
r.intenclr.write(|w| w.rxerror().clear());
|
r.intenclr.write(|w| w.rxerror().clear());
|
||||||
WAKER.wake();
|
WAKER.wake();
|
||||||
}
|
}
|
||||||
|
|
||||||
// if r.events_calibratedone.read().bits() != 0 {
|
if r.events_endtx.read().bits() != 0 {
|
||||||
// r.intenclr.write(|w| w.calibratedone().clear());
|
r.intenclr.write(|w| w.endtx().clear());
|
||||||
// WAKER.wake();
|
WAKER.wake();
|
||||||
// }
|
}
|
||||||
|
|
||||||
// if r.events_end.read().bits() != 0 {
|
|
||||||
// r.intenclr.write(|w| w.end().clear());
|
|
||||||
// WAKER.wake();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if r.events_started.read().bits() != 0 {
|
|
||||||
// r.intenclr.write(|w| w.started().clear());
|
|
||||||
// WAKER.wake();
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,18 +79,71 @@ impl<'d> NfcT<'d> {
|
|||||||
|
|
||||||
fn stop_recv_frame() {
|
fn stop_recv_frame() {
|
||||||
let r = Self::regs();
|
let r = Self::regs();
|
||||||
|
|
||||||
|
r.intenclr.write(|w| w.rxframeend().set_bit());
|
||||||
|
r.intenclr.write(|w| w.rxerror().set_bit());
|
||||||
|
|
||||||
compiler_fence(Ordering::SeqCst);
|
compiler_fence(Ordering::SeqCst);
|
||||||
|
|
||||||
r.intenset.write(|w| w.rxframeend().clear_bit());
|
// FIXME: this might take too long, maybe on start we clear?
|
||||||
r.intenset.write(|w| w.rxerror().clear_bit());
|
while r.events_rxframeend.read().bits() == 0 && r.events_rxerror.read().bits() == 0 {}
|
||||||
r.events_rxframeend.reset();
|
r.events_rxframeend.reset();
|
||||||
r.events_rxerror.reset();
|
r.events_rxerror.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn stop_tx_frame() {
|
||||||
|
let r = Self::regs();
|
||||||
|
r.intenclr.write(|w| w.endtx().set_bit());
|
||||||
|
|
||||||
|
compiler_fence(Ordering::SeqCst);
|
||||||
|
|
||||||
|
// FIXME: this might take too long, maybe on start we clear?
|
||||||
|
while r.events_endtx.read().bits() == 0 {}
|
||||||
|
r.events_endtx.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Transmit an NFC frame
|
||||||
|
/// `buf` is not pointing to the Data RAM region, an EasyDMA transfer may result in a hard fault or RAM corruption.
|
||||||
|
pub async fn tx_frame(&mut self, buf: &[u8]) {
|
||||||
|
// TODO: requires buf slice in ram validation
|
||||||
|
let r = Self::regs();
|
||||||
|
|
||||||
|
let on_drop = OnDrop::new(Self::stop_tx_frame);
|
||||||
|
|
||||||
|
//Setup DMA
|
||||||
|
r.packetptr.write(|w| unsafe { w.bits(buf.as_ptr() as u32) });
|
||||||
|
r.maxlen.write(|w| unsafe { w.bits(buf.len() as _) });
|
||||||
|
|
||||||
|
r.events_endtx.reset();
|
||||||
|
r.intenset.write(|w| w.endtx().set());
|
||||||
|
|
||||||
|
// Start enablerxdata only after configs are finished writing
|
||||||
|
compiler_fence(Ordering::SeqCst);
|
||||||
|
|
||||||
|
// Enter TX state
|
||||||
|
r.tasks_starttx.write(|w| w.tasks_starttx().set_bit());
|
||||||
|
|
||||||
|
// Wait for 'rxframeend'/'rxerror' event.
|
||||||
|
poll_fn(|cx| {
|
||||||
|
let r = Self::regs();
|
||||||
|
|
||||||
|
WAKER.register(cx.waker());
|
||||||
|
|
||||||
|
if r.events_endtx.read().bits() != 0 {
|
||||||
|
r.events_endtx.reset();
|
||||||
|
return Poll::Ready(());
|
||||||
|
}
|
||||||
|
|
||||||
|
Poll::Pending
|
||||||
|
})
|
||||||
|
.await;
|
||||||
|
|
||||||
|
drop(on_drop);
|
||||||
|
}
|
||||||
|
|
||||||
/// Waits for a single frame to be loaded into `buf`
|
/// Waits for a single frame to be loaded into `buf`
|
||||||
/// `buf`` is not pointing to the Data RAM region, an EasyDMA transfer may result in a hard fault or RAM corruption.
|
/// `buf` is not pointing to the Data RAM region, an EasyDMA transfer may result in a hard fault or RAM corruption.
|
||||||
pub async fn recv_frame<const N: usize>(&mut self, buf: &mut [u8; N]) -> Result<(), Error> {
|
pub async fn recv_frame<const N: usize>(&mut self, buf: &mut [u8; N]) -> Result<(), Error> {
|
||||||
// NOTE: Tx variant requires buf slice in ram validation
|
|
||||||
let r = Self::regs();
|
let r = Self::regs();
|
||||||
|
|
||||||
let on_drop = OnDrop::new(Self::stop_recv_frame);
|
let on_drop = OnDrop::new(Self::stop_recv_frame);
|
||||||
@ -111,6 +158,9 @@ impl<'d> NfcT<'d> {
|
|||||||
r.intenset.write(|w| w.rxframeend().set());
|
r.intenset.write(|w| w.rxframeend().set());
|
||||||
r.intenset.write(|w| w.rxerror().set());
|
r.intenset.write(|w| w.rxerror().set());
|
||||||
|
|
||||||
|
// Start enablerxdata only after configs are finished writing
|
||||||
|
compiler_fence(Ordering::SeqCst);
|
||||||
|
|
||||||
// Enter RX state
|
// Enter RX state
|
||||||
r.tasks_enablerxdata.write(|w| w.tasks_enablerxdata().set_bit());
|
r.tasks_enablerxdata.write(|w| w.tasks_enablerxdata().set_bit());
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user