Merge branch 'embassy-rs:main' into main
This commit is contained in:
commit
1d4e1092c4
@ -12,7 +12,7 @@ target = "thumbv7em-none-eabi"
|
|||||||
|
|
||||||
[features]
|
[features]
|
||||||
stm32wl = ["dep:embassy-stm32"]
|
stm32wl = ["dep:embassy-stm32"]
|
||||||
time = []
|
time = ["embassy-time", "lorawan-device"]
|
||||||
defmt = ["dep:defmt", "lorawan-device/defmt"]
|
defmt = ["dep:defmt", "lorawan-device/defmt"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
@ -20,18 +20,11 @@ defmt = ["dep:defmt", "lorawan-device/defmt"]
|
|||||||
defmt = { version = "0.3", optional = true }
|
defmt = { version = "0.3", optional = true }
|
||||||
log = { version = "0.4.14", optional = true }
|
log = { version = "0.4.14", optional = true }
|
||||||
|
|
||||||
embassy-time = { version = "0.1.2", path = "../embassy-time" }
|
embassy-time = { version = "0.1.2", path = "../embassy-time", optional = true }
|
||||||
embassy-sync = { version = "0.2.0", path = "../embassy-sync" }
|
embassy-sync = { version = "0.2.0", path = "../embassy-sync" }
|
||||||
embassy-stm32 = { version = "0.1.0", path = "../embassy-stm32", default-features = false, optional = true }
|
embassy-stm32 = { version = "0.1.0", path = "../embassy-stm32", default-features = false, optional = true }
|
||||||
embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-alpha.11" }
|
|
||||||
embedded-hal-async = { version = "=0.2.0-alpha.2" }
|
embedded-hal-async = { version = "=0.2.0-alpha.2" }
|
||||||
embassy-hal-common = { version = "0.1.0", path = "../embassy-hal-common", default-features = false }
|
|
||||||
futures = { version = "0.3.17", default-features = false, features = [ "async-await" ] }
|
|
||||||
embedded-hal = { version = "0.2", features = ["unproven"] }
|
embedded-hal = { version = "0.2", features = ["unproven"] }
|
||||||
bit_field = { version = "0.10" }
|
|
||||||
|
|
||||||
lora-phy = { version = "1" }
|
lora-phy = { version = "1" }
|
||||||
lorawan-device = { version = "0.10.0", default-features = false, features = ["async"] }
|
lorawan-device = { version = "0.10.0", default-features = false, features = ["async"], optional = true }
|
||||||
|
|
||||||
[patch.crates-io]
|
|
||||||
lora-phy = { git = "https://github.com/embassy-rs/lora-phy", rev = "ad289428fd44b02788e2fa2116445cc8f640a265" }
|
|
||||||
|
@ -26,7 +26,7 @@ aligned = "0.4.1"
|
|||||||
|
|
||||||
bit_field = "0.10.2"
|
bit_field = "0.10.2"
|
||||||
stm32-device-signature = { version = "0.3.3", features = ["stm32wb5x"] }
|
stm32-device-signature = { version = "0.3.3", features = ["stm32wb5x"] }
|
||||||
stm32wb-hci = { version = "0.1.3", optional = true }
|
stm32wb-hci = { version = "0.1.4", optional = true }
|
||||||
futures = { version = "0.3.17", default-features = false, features = ["async-await"] }
|
futures = { version = "0.3.17", default-features = false, features = ["async-await"] }
|
||||||
bitflags = { version = "2.3.3", optional = true }
|
bitflags = { version = "2.3.3", optional = true }
|
||||||
|
|
||||||
|
@ -161,6 +161,18 @@ impl<'d, T: Instance> Can<'d, T> {
|
|||||||
.leave_disabled();
|
.leave_disabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Enables the peripheral and synchronizes with the bus.
|
||||||
|
///
|
||||||
|
/// This will wait for 11 consecutive recessive bits (bus idle state).
|
||||||
|
/// Contrary to enable method from bxcan library, this will not freeze the executor while waiting.
|
||||||
|
pub async fn enable(&mut self) {
|
||||||
|
while self.borrow_mut().enable_non_blocking().is_err() {
|
||||||
|
// SCE interrupt is only generated for entering sleep mode, but not leaving.
|
||||||
|
// Yield to allow other tasks to execute while can bus is initializing.
|
||||||
|
embassy_futures::yield_now().await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Queues the message to be sent but exerts backpressure
|
/// Queues the message to be sent but exerts backpressure
|
||||||
pub async fn write(&mut self, frame: &Frame) -> bxcan::TransmitStatus {
|
pub async fn write(&mut self, frame: &Frame) -> bxcan::TransmitStatus {
|
||||||
poll_fn(|cx| {
|
poll_fn(|cx| {
|
||||||
|
@ -38,11 +38,30 @@ impl Channel {
|
|||||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||||
/// Trigger sources for CH1
|
/// Trigger sources for CH1
|
||||||
pub enum Ch1Trigger {
|
pub enum Ch1Trigger {
|
||||||
Tim6,
|
#[cfg(dac_v3)]
|
||||||
Tim3,
|
Tim1,
|
||||||
Tim7,
|
|
||||||
Tim15,
|
|
||||||
Tim2,
|
Tim2,
|
||||||
|
#[cfg(not(dac_v3))]
|
||||||
|
Tim3,
|
||||||
|
#[cfg(dac_v3)]
|
||||||
|
Tim4,
|
||||||
|
#[cfg(dac_v3)]
|
||||||
|
Tim5,
|
||||||
|
Tim6,
|
||||||
|
Tim7,
|
||||||
|
#[cfg(dac_v3)]
|
||||||
|
Tim8,
|
||||||
|
Tim15,
|
||||||
|
#[cfg(dac_v3)]
|
||||||
|
Hrtim1Dactrg1,
|
||||||
|
#[cfg(dac_v3)]
|
||||||
|
Hrtim1Dactrg2,
|
||||||
|
#[cfg(dac_v3)]
|
||||||
|
Lptim1,
|
||||||
|
#[cfg(dac_v3)]
|
||||||
|
Lptim2,
|
||||||
|
#[cfg(dac_v3)]
|
||||||
|
Lptim3,
|
||||||
Exti9,
|
Exti9,
|
||||||
Software,
|
Software,
|
||||||
}
|
}
|
||||||
@ -50,14 +69,30 @@ pub enum Ch1Trigger {
|
|||||||
impl Ch1Trigger {
|
impl Ch1Trigger {
|
||||||
fn tsel(&self) -> dac::vals::Tsel1 {
|
fn tsel(&self) -> dac::vals::Tsel1 {
|
||||||
match self {
|
match self {
|
||||||
Ch1Trigger::Tim6 => dac::vals::Tsel1::TIM6_TRGO,
|
#[cfg(dac_v3)]
|
||||||
|
Ch1Trigger::Tim1 => dac::vals::Tsel1::TIM1_TRGO,
|
||||||
|
Ch1Trigger::Tim2 => dac::vals::Tsel1::TIM2_TRGO,
|
||||||
#[cfg(not(dac_v3))]
|
#[cfg(not(dac_v3))]
|
||||||
Ch1Trigger::Tim3 => dac::vals::Tsel1::TIM3_TRGO,
|
Ch1Trigger::Tim3 => dac::vals::Tsel1::TIM3_TRGO,
|
||||||
#[cfg(dac_v3)]
|
#[cfg(dac_v3)]
|
||||||
Ch1Trigger::Tim3 => dac::vals::Tsel1::TIM1_TRGO,
|
Ch1Trigger::Tim4 => dac::vals::Tsel1::TIM4_TRGO,
|
||||||
|
#[cfg(dac_v3)]
|
||||||
|
Ch1Trigger::Tim5 => dac::vals::Tsel1::TIM5_TRGO,
|
||||||
|
Ch1Trigger::Tim6 => dac::vals::Tsel1::TIM6_TRGO,
|
||||||
Ch1Trigger::Tim7 => dac::vals::Tsel1::TIM7_TRGO,
|
Ch1Trigger::Tim7 => dac::vals::Tsel1::TIM7_TRGO,
|
||||||
|
#[cfg(dac_v3)]
|
||||||
|
Ch1Trigger::Tim8 => dac::vals::Tsel1::TIM8_TRGO,
|
||||||
Ch1Trigger::Tim15 => dac::vals::Tsel1::TIM15_TRGO,
|
Ch1Trigger::Tim15 => dac::vals::Tsel1::TIM15_TRGO,
|
||||||
Ch1Trigger::Tim2 => dac::vals::Tsel1::TIM2_TRGO,
|
#[cfg(dac_v3)]
|
||||||
|
Ch1Trigger::Hrtim1Dactrg1 => dac::vals::Tsel1::HRTIM1_DACTRG1,
|
||||||
|
#[cfg(dac_v3)]
|
||||||
|
Ch1Trigger::Hrtim1Dactrg2 => dac::vals::Tsel1::HRTIM1_DACTRG2,
|
||||||
|
#[cfg(dac_v3)]
|
||||||
|
Ch1Trigger::Lptim1 => dac::vals::Tsel1::LPTIM1_OUT,
|
||||||
|
#[cfg(dac_v3)]
|
||||||
|
Ch1Trigger::Lptim2 => dac::vals::Tsel1::LPTIM2_OUT,
|
||||||
|
#[cfg(dac_v3)]
|
||||||
|
Ch1Trigger::Lptim3 => dac::vals::Tsel1::LPTIM3_OUT,
|
||||||
Ch1Trigger::Exti9 => dac::vals::Tsel1::EXTI9,
|
Ch1Trigger::Exti9 => dac::vals::Tsel1::EXTI9,
|
||||||
Ch1Trigger::Software => dac::vals::Tsel1::SOFTWARE,
|
Ch1Trigger::Software => dac::vals::Tsel1::SOFTWARE,
|
||||||
}
|
}
|
||||||
@ -129,7 +164,7 @@ pub trait DacChannel<T: Instance, Tx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Set mode register of the given channel
|
/// Set mode register of the given channel
|
||||||
#[cfg(dac_v2)]
|
#[cfg(any(dac_v2, dac_v3))]
|
||||||
fn set_channel_mode(&mut self, val: u8) -> Result<(), Error> {
|
fn set_channel_mode(&mut self, val: u8) -> Result<(), Error> {
|
||||||
T::regs().mcr().modify(|reg| {
|
T::regs().mcr().modify(|reg| {
|
||||||
reg.set_mode(Self::CHANNEL.index(), val);
|
reg.set_mode(Self::CHANNEL.index(), val);
|
||||||
@ -216,8 +251,9 @@ impl<'d, T: Instance, Tx> DacCh1<'d, T, Tx> {
|
|||||||
pub fn new(
|
pub fn new(
|
||||||
peri: impl Peripheral<P = T> + 'd,
|
peri: impl Peripheral<P = T> + 'd,
|
||||||
dma: impl Peripheral<P = Tx> + 'd,
|
dma: impl Peripheral<P = Tx> + 'd,
|
||||||
_pin: impl Peripheral<P = impl DacPin<T, 1>> + 'd,
|
pin: impl Peripheral<P = impl DacPin<T, 1>> + crate::gpio::sealed::Pin + 'd,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
pin.set_as_analog();
|
||||||
into_ref!(peri, dma);
|
into_ref!(peri, dma);
|
||||||
T::enable();
|
T::enable();
|
||||||
T::reset();
|
T::reset();
|
||||||
@ -226,7 +262,7 @@ impl<'d, T: Instance, Tx> DacCh1<'d, T, Tx> {
|
|||||||
|
|
||||||
// Configure each activated channel. All results can be `unwrap`ed since they
|
// Configure each activated channel. All results can be `unwrap`ed since they
|
||||||
// will only error if the channel is not configured (i.e. ch1, ch2 are false)
|
// will only error if the channel is not configured (i.e. ch1, ch2 are false)
|
||||||
#[cfg(dac_v2)]
|
#[cfg(any(dac_v2, dac_v3))]
|
||||||
dac.set_channel_mode(0).unwrap();
|
dac.set_channel_mode(0).unwrap();
|
||||||
dac.enable_channel().unwrap();
|
dac.enable_channel().unwrap();
|
||||||
dac.set_trigger_enable(true).unwrap();
|
dac.set_trigger_enable(true).unwrap();
|
||||||
@ -252,7 +288,6 @@ impl<'d, T: Instance, Tx> DacCh1<'d, T, Tx> {
|
|||||||
/// Note that for performance reasons in circular mode the transfer complete interrupt is disabled.
|
/// Note that for performance reasons in circular mode the transfer complete interrupt is disabled.
|
||||||
///
|
///
|
||||||
/// **Important:** Channel 1 has to be configured for the DAC instance!
|
/// **Important:** Channel 1 has to be configured for the DAC instance!
|
||||||
#[cfg(all(bdma, not(dma)))] // It currently only works with BDMA-only chips (DMA should theoretically work though)
|
|
||||||
pub async fn write(&mut self, data: ValueArray<'_>, circular: bool) -> Result<(), Error>
|
pub async fn write(&mut self, data: ValueArray<'_>, circular: bool) -> Result<(), Error>
|
||||||
where
|
where
|
||||||
Tx: DmaCh1<T>,
|
Tx: DmaCh1<T>,
|
||||||
@ -327,8 +362,9 @@ impl<'d, T: Instance, Tx> DacCh2<'d, T, Tx> {
|
|||||||
pub fn new(
|
pub fn new(
|
||||||
_peri: impl Peripheral<P = T> + 'd,
|
_peri: impl Peripheral<P = T> + 'd,
|
||||||
dma: impl Peripheral<P = Tx> + 'd,
|
dma: impl Peripheral<P = Tx> + 'd,
|
||||||
_pin: impl Peripheral<P = impl DacPin<T, 2>> + 'd,
|
pin: impl Peripheral<P = impl DacPin<T, 2>> + crate::gpio::sealed::Pin + 'd,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
pin.set_as_analog();
|
||||||
into_ref!(_peri, dma);
|
into_ref!(_peri, dma);
|
||||||
T::enable();
|
T::enable();
|
||||||
T::reset();
|
T::reset();
|
||||||
@ -340,7 +376,7 @@ impl<'d, T: Instance, Tx> DacCh2<'d, T, Tx> {
|
|||||||
|
|
||||||
// Configure each activated channel. All results can be `unwrap`ed since they
|
// Configure each activated channel. All results can be `unwrap`ed since they
|
||||||
// will only error if the channel is not configured (i.e. ch1, ch2 are false)
|
// will only error if the channel is not configured (i.e. ch1, ch2 are false)
|
||||||
#[cfg(dac_v2)]
|
#[cfg(any(dac_v2, dac_v3))]
|
||||||
dac.set_channel_mode(0).unwrap();
|
dac.set_channel_mode(0).unwrap();
|
||||||
dac.enable_channel().unwrap();
|
dac.enable_channel().unwrap();
|
||||||
dac.set_trigger_enable(true).unwrap();
|
dac.set_trigger_enable(true).unwrap();
|
||||||
@ -364,7 +400,6 @@ impl<'d, T: Instance, Tx> DacCh2<'d, T, Tx> {
|
|||||||
/// Note that for performance reasons in circular mode the transfer complete interrupt is disabled.
|
/// Note that for performance reasons in circular mode the transfer complete interrupt is disabled.
|
||||||
///
|
///
|
||||||
/// **Important:** Channel 2 has to be configured for the DAC instance!
|
/// **Important:** Channel 2 has to be configured for the DAC instance!
|
||||||
#[cfg(all(bdma, not(dma)))] // It currently only works with BDMA-only chips (DMA should theoretically work though)
|
|
||||||
pub async fn write(&mut self, data: ValueArray<'_>, circular: bool) -> Result<(), Error>
|
pub async fn write(&mut self, data: ValueArray<'_>, circular: bool) -> Result<(), Error>
|
||||||
where
|
where
|
||||||
Tx: DmaCh2<T>,
|
Tx: DmaCh2<T>,
|
||||||
@ -442,9 +477,11 @@ impl<'d, T: Instance, TxCh1, TxCh2> Dac<'d, T, TxCh1, TxCh2> {
|
|||||||
peri: impl Peripheral<P = T> + 'd,
|
peri: impl Peripheral<P = T> + 'd,
|
||||||
dma_ch1: impl Peripheral<P = TxCh1> + 'd,
|
dma_ch1: impl Peripheral<P = TxCh1> + 'd,
|
||||||
dma_ch2: impl Peripheral<P = TxCh2> + 'd,
|
dma_ch2: impl Peripheral<P = TxCh2> + 'd,
|
||||||
_pin_ch1: impl Peripheral<P = impl DacPin<T, 1>> + 'd,
|
pin_ch1: impl Peripheral<P = impl DacPin<T, 1>> + crate::gpio::sealed::Pin + 'd,
|
||||||
_pin_ch2: impl Peripheral<P = impl DacPin<T, 2>> + 'd,
|
pin_ch2: impl Peripheral<P = impl DacPin<T, 2>> + crate::gpio::sealed::Pin + 'd,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
pin_ch1.set_as_analog();
|
||||||
|
pin_ch2.set_as_analog();
|
||||||
into_ref!(peri, dma_ch1, dma_ch2);
|
into_ref!(peri, dma_ch1, dma_ch2);
|
||||||
T::enable();
|
T::enable();
|
||||||
T::reset();
|
T::reset();
|
||||||
@ -461,12 +498,12 @@ impl<'d, T: Instance, TxCh1, TxCh2> Dac<'d, T, TxCh1, TxCh2> {
|
|||||||
|
|
||||||
// Configure each activated channel. All results can be `unwrap`ed since they
|
// Configure each activated channel. All results can be `unwrap`ed since they
|
||||||
// will only error if the channel is not configured (i.e. ch1, ch2 are false)
|
// will only error if the channel is not configured (i.e. ch1, ch2 are false)
|
||||||
#[cfg(dac_v2)]
|
#[cfg(any(dac_v2, dac_v3))]
|
||||||
dac_ch1.set_channel_mode(0).unwrap();
|
dac_ch1.set_channel_mode(0).unwrap();
|
||||||
dac_ch1.enable_channel().unwrap();
|
dac_ch1.enable_channel().unwrap();
|
||||||
dac_ch1.set_trigger_enable(true).unwrap();
|
dac_ch1.set_trigger_enable(true).unwrap();
|
||||||
|
|
||||||
#[cfg(dac_v2)]
|
#[cfg(any(dac_v2, dac_v3))]
|
||||||
dac_ch2.set_channel_mode(0).unwrap();
|
dac_ch2.set_channel_mode(0).unwrap();
|
||||||
dac_ch2.enable_channel().unwrap();
|
dac_ch2.enable_channel().unwrap();
|
||||||
dac_ch2.set_trigger_enable(true).unwrap();
|
dac_ch2.set_trigger_enable(true).unwrap();
|
||||||
|
@ -466,15 +466,53 @@ impl<'a, C: Channel, W: Word> RingBuffer<'a, C, W> {
|
|||||||
self.ringbuf.clear(DmaCtrlImpl(self.channel.reborrow()));
|
self.ringbuf.clear(DmaCtrlImpl(self.channel.reborrow()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Read bytes from the ring buffer
|
/// Read elements from the ring buffer
|
||||||
/// Return a tuple of the length read and the length remaining in the buffer
|
/// Return a tuple of the length read and the length remaining in the buffer
|
||||||
/// If not all of the bytes were read, then there will be some bytes in the buffer remaining
|
/// If not all of the elements were read, then there will be some elements in the buffer remaining
|
||||||
/// The length remaining is the capacity, ring_buf.len(), less the bytes remaining after the read
|
/// The length remaining is the capacity, ring_buf.len(), less the elements remaining after the read
|
||||||
/// OverrunError is returned if the portion to be read was overwritten by the DMA controller.
|
/// OverrunError is returned if the portion to be read was overwritten by the DMA controller.
|
||||||
pub fn read(&mut self, buf: &mut [W]) -> Result<(usize, usize), OverrunError> {
|
pub fn read(&mut self, buf: &mut [W]) -> Result<(usize, usize), OverrunError> {
|
||||||
self.ringbuf.read(DmaCtrlImpl(self.channel.reborrow()), buf)
|
self.ringbuf.read(DmaCtrlImpl(self.channel.reborrow()), buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Read an exact number of elements from the ringbuffer.
|
||||||
|
///
|
||||||
|
/// Returns the remaining number of elements available for immediate reading.
|
||||||
|
/// OverrunError is returned if the portion to be read was overwritten by the DMA controller.
|
||||||
|
///
|
||||||
|
/// Async/Wake Behavior:
|
||||||
|
/// The underlying DMA peripheral only can wake us when its buffer pointer has reached the halfway point,
|
||||||
|
/// and when it wraps around. This means that when called with a buffer of length 'M', when this
|
||||||
|
/// ring buffer was created with a buffer of size 'N':
|
||||||
|
/// - If M equals N/2 or N/2 divides evenly into M, this function will return every N/2 elements read on the DMA source.
|
||||||
|
/// - Otherwise, this function may need up to N/2 extra elements to arrive before returning.
|
||||||
|
pub async fn read_exact(&mut self, buffer: &mut [W]) -> Result<usize, OverrunError> {
|
||||||
|
use core::future::poll_fn;
|
||||||
|
use core::sync::atomic::compiler_fence;
|
||||||
|
|
||||||
|
let mut read_data = 0;
|
||||||
|
let buffer_len = buffer.len();
|
||||||
|
|
||||||
|
poll_fn(|cx| {
|
||||||
|
self.set_waker(cx.waker());
|
||||||
|
|
||||||
|
compiler_fence(Ordering::SeqCst);
|
||||||
|
|
||||||
|
match self.read(&mut buffer[read_data..buffer_len]) {
|
||||||
|
Ok((len, remaining)) => {
|
||||||
|
read_data += len;
|
||||||
|
if read_data == buffer_len {
|
||||||
|
Poll::Ready(Ok(remaining))
|
||||||
|
} else {
|
||||||
|
Poll::Pending
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => Poll::Ready(Err(e)),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
|
||||||
/// The capacity of the ringbuffer
|
/// The capacity of the ringbuffer
|
||||||
pub fn cap(&self) -> usize {
|
pub fn cap(&self) -> usize {
|
||||||
self.ringbuf.cap()
|
self.ringbuf.cap()
|
||||||
|
@ -28,6 +28,12 @@ pub struct TransferOptions {
|
|||||||
pub flow_ctrl: FlowControl,
|
pub flow_ctrl: FlowControl,
|
||||||
/// FIFO threshold for DMA FIFO mode. If none, direct mode is used.
|
/// FIFO threshold for DMA FIFO mode. If none, direct mode is used.
|
||||||
pub fifo_threshold: Option<FifoThreshold>,
|
pub fifo_threshold: Option<FifoThreshold>,
|
||||||
|
/// Enable circular DMA
|
||||||
|
pub circular: bool,
|
||||||
|
/// Enable half transfer interrupt
|
||||||
|
pub half_transfer_ir: bool,
|
||||||
|
/// Enable transfer complete interrupt
|
||||||
|
pub complete_transfer_ir: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for TransferOptions {
|
impl Default for TransferOptions {
|
||||||
@ -37,6 +43,9 @@ impl Default for TransferOptions {
|
|||||||
mburst: Burst::Single,
|
mburst: Burst::Single,
|
||||||
flow_ctrl: FlowControl::Dma,
|
flow_ctrl: FlowControl::Dma,
|
||||||
fifo_threshold: None,
|
fifo_threshold: None,
|
||||||
|
circular: false,
|
||||||
|
half_transfer_ir: false,
|
||||||
|
complete_transfer_ir: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -365,7 +374,13 @@ impl<'a, C: Channel> Transfer<'a, C> {
|
|||||||
});
|
});
|
||||||
w.set_pinc(vals::Inc::FIXED);
|
w.set_pinc(vals::Inc::FIXED);
|
||||||
w.set_teie(true);
|
w.set_teie(true);
|
||||||
w.set_tcie(true);
|
w.set_tcie(options.complete_transfer_ir);
|
||||||
|
if options.circular {
|
||||||
|
w.set_circ(vals::Circ::ENABLED);
|
||||||
|
debug!("Setting circular mode");
|
||||||
|
} else {
|
||||||
|
w.set_circ(vals::Circ::DISABLED);
|
||||||
|
}
|
||||||
#[cfg(dma_v1)]
|
#[cfg(dma_v1)]
|
||||||
w.set_trbuff(true);
|
w.set_trbuff(true);
|
||||||
|
|
||||||
@ -646,7 +661,7 @@ impl<'a, C: Channel, W: Word> RingBuffer<'a, C, W> {
|
|||||||
w.set_minc(vals::Inc::INCREMENTED);
|
w.set_minc(vals::Inc::INCREMENTED);
|
||||||
w.set_pinc(vals::Inc::FIXED);
|
w.set_pinc(vals::Inc::FIXED);
|
||||||
w.set_teie(true);
|
w.set_teie(true);
|
||||||
w.set_htie(true);
|
w.set_htie(options.half_transfer_ir);
|
||||||
w.set_tcie(true);
|
w.set_tcie(true);
|
||||||
w.set_circ(vals::Circ::ENABLED);
|
w.set_circ(vals::Circ::ENABLED);
|
||||||
#[cfg(dma_v1)]
|
#[cfg(dma_v1)]
|
||||||
@ -696,15 +711,53 @@ impl<'a, C: Channel, W: Word> RingBuffer<'a, C, W> {
|
|||||||
self.ringbuf.clear(DmaCtrlImpl(self.channel.reborrow()));
|
self.ringbuf.clear(DmaCtrlImpl(self.channel.reborrow()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Read bytes from the ring buffer
|
/// Read elements from the ring buffer
|
||||||
/// Return a tuple of the length read and the length remaining in the buffer
|
/// Return a tuple of the length read and the length remaining in the buffer
|
||||||
/// If not all of the bytes were read, then there will be some bytes in the buffer remaining
|
/// If not all of the elements were read, then there will be some elements in the buffer remaining
|
||||||
/// The length remaining is the capacity, ring_buf.len(), less the bytes remaining after the read
|
/// The length remaining is the capacity, ring_buf.len(), less the elements remaining after the read
|
||||||
/// OverrunError is returned if the portion to be read was overwritten by the DMA controller.
|
/// OverrunError is returned if the portion to be read was overwritten by the DMA controller.
|
||||||
pub fn read(&mut self, buf: &mut [W]) -> Result<(usize, usize), OverrunError> {
|
pub fn read(&mut self, buf: &mut [W]) -> Result<(usize, usize), OverrunError> {
|
||||||
self.ringbuf.read(DmaCtrlImpl(self.channel.reborrow()), buf)
|
self.ringbuf.read(DmaCtrlImpl(self.channel.reborrow()), buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Read an exact number of elements from the ringbuffer.
|
||||||
|
///
|
||||||
|
/// Returns the remaining number of elements available for immediate reading.
|
||||||
|
/// OverrunError is returned if the portion to be read was overwritten by the DMA controller.
|
||||||
|
///
|
||||||
|
/// Async/Wake Behavior:
|
||||||
|
/// The underlying DMA peripheral only can wake us when its buffer pointer has reached the halfway point,
|
||||||
|
/// and when it wraps around. This means that when called with a buffer of length 'M', when this
|
||||||
|
/// ring buffer was created with a buffer of size 'N':
|
||||||
|
/// - If M equals N/2 or N/2 divides evenly into M, this function will return every N/2 elements read on the DMA source.
|
||||||
|
/// - Otherwise, this function may need up to N/2 extra elements to arrive before returning.
|
||||||
|
pub async fn read_exact(&mut self, buffer: &mut [W]) -> Result<usize, OverrunError> {
|
||||||
|
use core::future::poll_fn;
|
||||||
|
use core::sync::atomic::compiler_fence;
|
||||||
|
|
||||||
|
let mut read_data = 0;
|
||||||
|
let buffer_len = buffer.len();
|
||||||
|
|
||||||
|
poll_fn(|cx| {
|
||||||
|
self.set_waker(cx.waker());
|
||||||
|
|
||||||
|
compiler_fence(Ordering::SeqCst);
|
||||||
|
|
||||||
|
match self.read(&mut buffer[read_data..buffer_len]) {
|
||||||
|
Ok((len, remaining)) => {
|
||||||
|
read_data += len;
|
||||||
|
if read_data == buffer_len {
|
||||||
|
Poll::Ready(Ok(remaining))
|
||||||
|
} else {
|
||||||
|
Poll::Pending
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => Poll::Ready(Err(e)),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
|
||||||
// The capacity of the ringbuffer
|
// The capacity of the ringbuffer
|
||||||
pub fn cap(&self) -> usize {
|
pub fn cap(&self) -> usize {
|
||||||
self.ringbuf.cap()
|
self.ringbuf.cap()
|
||||||
|
@ -72,10 +72,10 @@ impl<'a, W: Word> DmaRingBuffer<'a, W> {
|
|||||||
self.cap() - remaining_transfers
|
self.cap() - remaining_transfers
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Read bytes from the ring buffer
|
/// Read elements from the ring buffer
|
||||||
/// Return a tuple of the length read and the length remaining in the buffer
|
/// Return a tuple of the length read and the length remaining in the buffer
|
||||||
/// If not all of the bytes were read, then there will be some bytes in the buffer remaining
|
/// If not all of the elements were read, then there will be some elements in the buffer remaining
|
||||||
/// The length remaining is the capacity, ring_buf.len(), less the bytes remaining after the read
|
/// The length remaining is the capacity, ring_buf.len(), less the elements remaining after the read
|
||||||
/// OverrunError is returned if the portion to be read was overwritten by the DMA controller.
|
/// OverrunError is returned if the portion to be read was overwritten by the DMA controller.
|
||||||
pub fn read(&mut self, mut dma: impl DmaCtrl, buf: &mut [W]) -> Result<(usize, usize), OverrunError> {
|
pub fn read(&mut self, mut dma: impl DmaCtrl, buf: &mut [W]) -> Result<(usize, usize), OverrunError> {
|
||||||
/*
|
/*
|
||||||
@ -95,11 +95,11 @@ impl<'a, W: Word> DmaRingBuffer<'a, W> {
|
|||||||
*/
|
*/
|
||||||
let end = self.pos(dma.get_remaining_transfers());
|
let end = self.pos(dma.get_remaining_transfers());
|
||||||
if self.start == end && dma.get_complete_count() == 0 {
|
if self.start == end && dma.get_complete_count() == 0 {
|
||||||
// No bytes are available in the buffer
|
// No elements are available in the buffer
|
||||||
Ok((0, self.cap()))
|
Ok((0, self.cap()))
|
||||||
} else if self.start < end {
|
} else if self.start < end {
|
||||||
// The available, unread portion in the ring buffer DOES NOT wrap
|
// The available, unread portion in the ring buffer DOES NOT wrap
|
||||||
// Copy out the bytes from the dma buffer
|
// Copy out the elements from the dma buffer
|
||||||
let len = self.copy_to(buf, self.start..end);
|
let len = self.copy_to(buf, self.start..end);
|
||||||
|
|
||||||
compiler_fence(Ordering::SeqCst);
|
compiler_fence(Ordering::SeqCst);
|
||||||
@ -128,7 +128,7 @@ impl<'a, W: Word> DmaRingBuffer<'a, W> {
|
|||||||
// The DMA writer has wrapped since we last read and is currently
|
// The DMA writer has wrapped since we last read and is currently
|
||||||
// writing (or the next byte added will be) in the beginning of the ring buffer.
|
// writing (or the next byte added will be) in the beginning of the ring buffer.
|
||||||
|
|
||||||
// The provided read buffer is not large enough to include all bytes from the tail of the dma buffer.
|
// The provided read buffer is not large enough to include all elements from the tail of the dma buffer.
|
||||||
|
|
||||||
// Copy out from the dma buffer
|
// Copy out from the dma buffer
|
||||||
let len = self.copy_to(buf, self.start..self.cap());
|
let len = self.copy_to(buf, self.start..self.cap());
|
||||||
@ -154,8 +154,8 @@ impl<'a, W: Word> DmaRingBuffer<'a, W> {
|
|||||||
// The DMA writer has wrapped since we last read and is currently
|
// The DMA writer has wrapped since we last read and is currently
|
||||||
// writing (or the next byte added will be) in the beginning of the ring buffer.
|
// writing (or the next byte added will be) in the beginning of the ring buffer.
|
||||||
|
|
||||||
// The provided read buffer is large enough to include all bytes from the tail of the dma buffer,
|
// The provided read buffer is large enough to include all elements from the tail of the dma buffer,
|
||||||
// so the next read will not have any unread tail bytes in the ring buffer.
|
// so the next read will not have any unread tail elements in the ring buffer.
|
||||||
|
|
||||||
// Copy out from the dma buffer
|
// Copy out from the dma buffer
|
||||||
let tail = self.copy_to(buf, self.start..self.cap());
|
let tail = self.copy_to(buf, self.start..self.cap());
|
||||||
@ -180,7 +180,7 @@ impl<'a, W: Word> DmaRingBuffer<'a, W> {
|
|||||||
}
|
}
|
||||||
/// Copy from the dma buffer at `data_range` into `buf`
|
/// Copy from the dma buffer at `data_range` into `buf`
|
||||||
fn copy_to(&mut self, buf: &mut [W], data_range: Range<usize>) -> usize {
|
fn copy_to(&mut self, buf: &mut [W], data_range: Range<usize>) -> usize {
|
||||||
// Limit the number of bytes that can be copied
|
// Limit the number of elements that can be copied
|
||||||
let length = usize::min(data_range.len(), buf.len());
|
let length = usize::min(data_range.len(), buf.len());
|
||||||
|
|
||||||
// Copy from dma buffer into read buffer
|
// Copy from dma buffer into read buffer
|
||||||
|
@ -265,63 +265,9 @@ pub(crate) mod sealed {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn _configure_pwr() {
|
fn _configure_pwr() {
|
||||||
// TODO: move this to RCC
|
// TODO: move the rest of this to rcc
|
||||||
|
|
||||||
let pwr = crate::pac::PWR;
|
|
||||||
let rcc = crate::pac::RCC;
|
let rcc = crate::pac::RCC;
|
||||||
|
|
||||||
rcc.cfgr().modify(|w| w.set_stopwuck(true));
|
|
||||||
|
|
||||||
pwr.cr1().modify(|w| w.set_dbp(true));
|
|
||||||
pwr.cr1().modify(|w| w.set_dbp(true));
|
|
||||||
|
|
||||||
// configure LSE
|
|
||||||
rcc.bdcr().modify(|w| w.set_lseon(true));
|
|
||||||
|
|
||||||
// select system clock source = PLL
|
|
||||||
// set PLL coefficients
|
|
||||||
// m: 2,
|
|
||||||
// n: 12,
|
|
||||||
// r: 3,
|
|
||||||
// q: 4,
|
|
||||||
// p: 3,
|
|
||||||
let src_bits = 0b11;
|
|
||||||
let pllp = (3 - 1) & 0b11111;
|
|
||||||
let pllq = (4 - 1) & 0b111;
|
|
||||||
let pllr = (3 - 1) & 0b111;
|
|
||||||
let plln = 12 & 0b1111111;
|
|
||||||
let pllm = (2 - 1) & 0b111;
|
|
||||||
rcc.pllcfgr().modify(|w| {
|
|
||||||
w.set_pllsrc(src_bits);
|
|
||||||
w.set_pllm(pllm);
|
|
||||||
w.set_plln(plln);
|
|
||||||
w.set_pllr(pllr);
|
|
||||||
w.set_pllp(pllp);
|
|
||||||
w.set_pllpen(true);
|
|
||||||
w.set_pllq(pllq);
|
|
||||||
w.set_pllqen(true);
|
|
||||||
});
|
|
||||||
// enable PLL
|
|
||||||
rcc.cr().modify(|w| w.set_pllon(true));
|
|
||||||
rcc.cr().write(|w| w.set_hsion(false));
|
|
||||||
// while !rcc.cr().read().pllrdy() {}
|
|
||||||
|
|
||||||
// configure SYSCLK mux to use PLL clocl
|
|
||||||
rcc.cfgr().modify(|w| w.set_sw(0b11));
|
|
||||||
|
|
||||||
// configure CPU1 & CPU2 dividers
|
|
||||||
rcc.cfgr().modify(|w| w.set_hpre(0)); // not divided
|
|
||||||
rcc.extcfgr().modify(|w| {
|
|
||||||
w.set_c2hpre(0b1000); // div2
|
|
||||||
w.set_shdhpre(0); // not divided
|
|
||||||
});
|
|
||||||
|
|
||||||
// apply APB1 / APB2 values
|
|
||||||
rcc.cfgr().modify(|w| {
|
|
||||||
w.set_ppre1(0b000); // not divided
|
|
||||||
w.set_ppre2(0b000); // not divided
|
|
||||||
});
|
|
||||||
|
|
||||||
// TODO: required
|
// TODO: required
|
||||||
// set RF wake-up clock = LSE
|
// set RF wake-up clock = LSE
|
||||||
rcc.csr().modify(|w| w.set_rfwkpsel(0b01));
|
rcc.csr().modify(|w| w.set_rfwkpsel(0b01));
|
||||||
|
@ -78,6 +78,14 @@ pub struct Clocks {
|
|||||||
/// The existence of this value indicates that the clock configuration can no longer be changed
|
/// The existence of this value indicates that the clock configuration can no longer be changed
|
||||||
static mut CLOCK_FREQS: MaybeUninit<Clocks> = MaybeUninit::uninit();
|
static mut CLOCK_FREQS: MaybeUninit<Clocks> = MaybeUninit::uninit();
|
||||||
|
|
||||||
|
#[cfg(stm32wb)]
|
||||||
|
/// RCC initialization function
|
||||||
|
pub(crate) unsafe fn init(config: Config) {
|
||||||
|
set_freqs(compute_clocks(&config));
|
||||||
|
|
||||||
|
configure_clocks(&config);
|
||||||
|
}
|
||||||
|
|
||||||
/// Sets the clock frequencies
|
/// Sets the clock frequencies
|
||||||
///
|
///
|
||||||
/// Safety: Sets a mutable global.
|
/// Safety: Sets a mutable global.
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
use crate::pac::RCC;
|
use crate::rcc::Clocks;
|
||||||
use crate::rcc::{set_freqs, Clocks};
|
use crate::time::{khz, mhz, Hertz};
|
||||||
use crate::time::Hertz;
|
|
||||||
|
|
||||||
/// Most of clock setup is copied from stm32l0xx-hal, and adopted to the generated PAC,
|
/// Most of clock setup is copied from stm32l0xx-hal, and adopted to the generated PAC,
|
||||||
/// and with the addition of the init function to configure a system clock.
|
/// and with the addition of the init function to configure a system clock.
|
||||||
@ -13,11 +12,94 @@ pub const HSI_FREQ: Hertz = Hertz(16_000_000);
|
|||||||
/// LSI speed
|
/// LSI speed
|
||||||
pub const LSI_FREQ: Hertz = Hertz(32_000);
|
pub const LSI_FREQ: Hertz = Hertz(32_000);
|
||||||
|
|
||||||
/// System clock mux source
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub enum ClockSrc {
|
pub enum HsePrescaler {
|
||||||
HSE(Hertz),
|
NotDivided,
|
||||||
HSI16,
|
Div2,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<HsePrescaler> for bool {
|
||||||
|
fn from(value: HsePrescaler) -> Self {
|
||||||
|
match value {
|
||||||
|
HsePrescaler::NotDivided => false,
|
||||||
|
HsePrescaler::Div2 => true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Hse {
|
||||||
|
pub prediv: HsePrescaler,
|
||||||
|
|
||||||
|
pub frequency: Hertz,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// System clock mux source
|
||||||
|
#[derive(Clone, Copy, PartialEq)]
|
||||||
|
pub enum Sysclk {
|
||||||
|
/// MSI selected as sysclk
|
||||||
|
MSI,
|
||||||
|
/// HSI selected as sysclk
|
||||||
|
HSI,
|
||||||
|
/// HSE selected as sysclk
|
||||||
|
HSE,
|
||||||
|
/// PLL selected as sysclk
|
||||||
|
Pll,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Sysclk> for u8 {
|
||||||
|
fn from(value: Sysclk) -> Self {
|
||||||
|
match value {
|
||||||
|
Sysclk::MSI => 0b00,
|
||||||
|
Sysclk::HSI => 0b01,
|
||||||
|
Sysclk::HSE => 0b10,
|
||||||
|
Sysclk::Pll => 0b11,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, PartialEq)]
|
||||||
|
pub enum PllSource {
|
||||||
|
Hsi,
|
||||||
|
Msi,
|
||||||
|
Hse,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<PllSource> for u8 {
|
||||||
|
fn from(value: PllSource) -> Self {
|
||||||
|
match value {
|
||||||
|
PllSource::Msi => 0b01,
|
||||||
|
PllSource::Hsi => 0b10,
|
||||||
|
PllSource::Hse => 0b11,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum Pll48Source {
|
||||||
|
PllSai,
|
||||||
|
Pll,
|
||||||
|
Msi,
|
||||||
|
Hsi48,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct PllMux {
|
||||||
|
/// Source clock selection.
|
||||||
|
pub source: PllSource,
|
||||||
|
|
||||||
|
/// PLL pre-divider (DIVM). Must be between 1 and 63.
|
||||||
|
pub prediv: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Pll {
|
||||||
|
/// PLL multiplication factor. Must be between 4 and 512.
|
||||||
|
pub mul: u16,
|
||||||
|
|
||||||
|
/// PLL P division factor. If None, PLL P output is disabled. Must be between 1 and 128.
|
||||||
|
/// On PLL1, it must be even (in particular, it cannot be 1.)
|
||||||
|
pub divp: Option<u16>,
|
||||||
|
/// PLL Q division factor. If None, PLL Q output is disabled. Must be between 1 and 128.
|
||||||
|
pub divq: Option<u16>,
|
||||||
|
/// PLL R division factor. If None, PLL R output is disabled. Must be between 1 and 128.
|
||||||
|
pub divr: Option<u16>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// AHB prescaler
|
/// AHB prescaler
|
||||||
@ -84,86 +166,250 @@ impl Into<u8> for AHBPrescaler {
|
|||||||
|
|
||||||
/// Clocks configutation
|
/// Clocks configutation
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
pub mux: ClockSrc,
|
pub hse: Option<Hse>,
|
||||||
pub ahb_pre: AHBPrescaler,
|
pub lse: Option<Hertz>,
|
||||||
|
pub sys: Sysclk,
|
||||||
|
pub mux: Option<PllMux>,
|
||||||
|
pub pll48: Option<Pll48Source>,
|
||||||
|
|
||||||
|
pub pll: Option<Pll>,
|
||||||
|
pub pllsai: Option<Pll>,
|
||||||
|
|
||||||
|
pub ahb1_pre: AHBPrescaler,
|
||||||
|
pub ahb2_pre: AHBPrescaler,
|
||||||
|
pub ahb3_pre: AHBPrescaler,
|
||||||
pub apb1_pre: APBPrescaler,
|
pub apb1_pre: APBPrescaler,
|
||||||
pub apb2_pre: APBPrescaler,
|
pub apb2_pre: APBPrescaler,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub const WPAN_DEFAULT: Config = Config {
|
||||||
|
hse: Some(Hse {
|
||||||
|
frequency: mhz(32),
|
||||||
|
prediv: HsePrescaler::NotDivided,
|
||||||
|
}),
|
||||||
|
lse: Some(khz(32)),
|
||||||
|
sys: Sysclk::Pll,
|
||||||
|
mux: Some(PllMux {
|
||||||
|
source: PllSource::Hse,
|
||||||
|
prediv: 2,
|
||||||
|
}),
|
||||||
|
pll48: None,
|
||||||
|
|
||||||
|
pll: Some(Pll {
|
||||||
|
mul: 12,
|
||||||
|
divp: Some(3),
|
||||||
|
divq: Some(4),
|
||||||
|
divr: Some(3),
|
||||||
|
}),
|
||||||
|
pllsai: None,
|
||||||
|
|
||||||
|
ahb1_pre: AHBPrescaler::NotDivided,
|
||||||
|
ahb2_pre: AHBPrescaler::Div2,
|
||||||
|
ahb3_pre: AHBPrescaler::NotDivided,
|
||||||
|
apb1_pre: APBPrescaler::NotDivided,
|
||||||
|
apb2_pre: APBPrescaler::NotDivided,
|
||||||
|
};
|
||||||
|
|
||||||
impl Default for Config {
|
impl Default for Config {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn default() -> Config {
|
fn default() -> Config {
|
||||||
Config {
|
Config {
|
||||||
mux: ClockSrc::HSI16,
|
hse: None,
|
||||||
ahb_pre: AHBPrescaler::NotDivided,
|
lse: None,
|
||||||
|
sys: Sysclk::HSI,
|
||||||
|
mux: None,
|
||||||
|
pll48: None,
|
||||||
|
pll: None,
|
||||||
|
pllsai: None,
|
||||||
|
|
||||||
|
ahb1_pre: AHBPrescaler::NotDivided,
|
||||||
|
ahb2_pre: AHBPrescaler::NotDivided,
|
||||||
|
ahb3_pre: AHBPrescaler::NotDivided,
|
||||||
apb1_pre: APBPrescaler::NotDivided,
|
apb1_pre: APBPrescaler::NotDivided,
|
||||||
apb2_pre: APBPrescaler::NotDivided,
|
apb2_pre: APBPrescaler::NotDivided,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) unsafe fn init(config: Config) {
|
pub(crate) fn compute_clocks(config: &Config) -> Clocks {
|
||||||
let (sys_clk, sw) = match config.mux {
|
let hse_clk = config.hse.as_ref().map(|hse| match hse.prediv {
|
||||||
ClockSrc::HSI16 => {
|
HsePrescaler::NotDivided => hse.frequency,
|
||||||
// Enable HSI16
|
HsePrescaler::Div2 => hse.frequency / 2u32,
|
||||||
RCC.cr().write(|w| w.set_hsion(true));
|
|
||||||
while !RCC.cr().read().hsirdy() {}
|
|
||||||
|
|
||||||
(HSI_FREQ.0, 0x01)
|
|
||||||
}
|
|
||||||
ClockSrc::HSE(freq) => {
|
|
||||||
// Enable HSE
|
|
||||||
RCC.cr().write(|w| w.set_hseon(true));
|
|
||||||
while !RCC.cr().read().hserdy() {}
|
|
||||||
|
|
||||||
(freq.0, 0x02)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
RCC.cfgr().modify(|w| {
|
|
||||||
w.set_sw(sw.into());
|
|
||||||
w.set_hpre(config.ahb_pre.into());
|
|
||||||
w.set_ppre1(config.apb1_pre.into());
|
|
||||||
w.set_ppre2(config.apb2_pre.into());
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let ahb_freq: u32 = match config.ahb_pre {
|
let mux_clk = config.mux.as_ref().map(|pll_mux| {
|
||||||
|
(match pll_mux.source {
|
||||||
|
PllSource::Hse => hse_clk.unwrap(),
|
||||||
|
PllSource::Hsi => HSI_FREQ,
|
||||||
|
_ => unreachable!(),
|
||||||
|
} / pll_mux.prediv)
|
||||||
|
});
|
||||||
|
|
||||||
|
let (pll_r, _pll_q, _pll_p) = match &config.pll {
|
||||||
|
Some(pll) => {
|
||||||
|
let pll_vco = mux_clk.unwrap() * pll.mul as u32;
|
||||||
|
|
||||||
|
(
|
||||||
|
pll.divr.map(|divr| pll_vco / divr),
|
||||||
|
pll.divq.map(|divq| pll_vco / divq),
|
||||||
|
pll.divp.map(|divp| pll_vco / divp),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
None => (None, None, None),
|
||||||
|
};
|
||||||
|
|
||||||
|
let sys_clk = match config.sys {
|
||||||
|
Sysclk::HSE => hse_clk.unwrap(),
|
||||||
|
Sysclk::HSI => HSI_FREQ,
|
||||||
|
Sysclk::Pll => pll_r.unwrap(),
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let ahb1_clk = match config.ahb1_pre {
|
||||||
AHBPrescaler::NotDivided => sys_clk,
|
AHBPrescaler::NotDivided => sys_clk,
|
||||||
pre => {
|
pre => {
|
||||||
let pre: u8 = pre.into();
|
let pre: u8 = pre.into();
|
||||||
let pre = 1 << (pre as u32 - 7);
|
let pre = 1u32 << (pre as u32 - 7);
|
||||||
sys_clk / pre
|
sys_clk / pre
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let (apb1_freq, apb1_tim_freq) = match config.apb1_pre {
|
let ahb2_clk = match config.ahb2_pre {
|
||||||
APBPrescaler::NotDivided => (ahb_freq, ahb_freq),
|
AHBPrescaler::NotDivided => sys_clk,
|
||||||
pre => {
|
pre => {
|
||||||
let pre: u8 = pre.into();
|
let pre: u8 = pre.into();
|
||||||
let pre: u8 = 1 << (pre - 3);
|
let pre = 1u32 << (pre as u32 - 7);
|
||||||
let freq = ahb_freq / pre as u32;
|
sys_clk / pre
|
||||||
(freq, freq * 2)
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let (apb2_freq, apb2_tim_freq) = match config.apb2_pre {
|
let ahb3_clk = match config.ahb3_pre {
|
||||||
APBPrescaler::NotDivided => (ahb_freq, ahb_freq),
|
AHBPrescaler::NotDivided => sys_clk,
|
||||||
pre => {
|
pre => {
|
||||||
let pre: u8 = pre.into();
|
let pre: u8 = pre.into();
|
||||||
let pre: u8 = 1 << (pre - 3);
|
let pre = 1u32 << (pre as u32 - 7);
|
||||||
let freq = ahb_freq / pre as u32;
|
sys_clk / pre
|
||||||
(freq, freq * 2)
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
set_freqs(Clocks {
|
let (apb1_clk, apb1_tim_clk) = match config.apb1_pre {
|
||||||
sys: Hertz(sys_clk),
|
APBPrescaler::NotDivided => (ahb1_clk, ahb1_clk),
|
||||||
ahb1: Hertz(ahb_freq),
|
pre => {
|
||||||
ahb2: Hertz(ahb_freq),
|
let pre: u8 = pre.into();
|
||||||
ahb3: Hertz(ahb_freq),
|
let pre: u8 = 1 << (pre - 3);
|
||||||
apb1: Hertz(apb1_freq),
|
let freq = ahb1_clk / pre as u32;
|
||||||
apb2: Hertz(apb2_freq),
|
(freq, freq * 2u32)
|
||||||
apb1_tim: Hertz(apb1_tim_freq),
|
}
|
||||||
apb2_tim: Hertz(apb2_tim_freq),
|
};
|
||||||
|
|
||||||
|
let (apb2_clk, apb2_tim_clk) = match config.apb2_pre {
|
||||||
|
APBPrescaler::NotDivided => (ahb1_clk, ahb1_clk),
|
||||||
|
pre => {
|
||||||
|
let pre: u8 = pre.into();
|
||||||
|
let pre: u8 = 1 << (pre - 3);
|
||||||
|
let freq = ahb1_clk / pre as u32;
|
||||||
|
(freq, freq * 2u32)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Clocks {
|
||||||
|
sys: sys_clk,
|
||||||
|
ahb1: ahb1_clk,
|
||||||
|
ahb2: ahb2_clk,
|
||||||
|
ahb3: ahb3_clk,
|
||||||
|
apb1: apb1_clk,
|
||||||
|
apb2: apb2_clk,
|
||||||
|
apb1_tim: apb1_tim_clk,
|
||||||
|
apb2_tim: apb2_tim_clk,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn configure_clocks(config: &Config) {
|
||||||
|
let pwr = crate::pac::PWR;
|
||||||
|
let rcc = crate::pac::RCC;
|
||||||
|
|
||||||
|
let needs_hsi = if let Some(pll_mux) = &config.mux {
|
||||||
|
pll_mux.source == PllSource::Hsi
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
};
|
||||||
|
|
||||||
|
if needs_hsi || config.sys == Sysclk::HSI {
|
||||||
|
rcc.cr().modify(|w| {
|
||||||
|
w.set_hsion(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
while !rcc.cr().read().hsirdy() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
match &config.lse {
|
||||||
|
Some(_) => {
|
||||||
|
rcc.cfgr().modify(|w| w.set_stopwuck(true));
|
||||||
|
|
||||||
|
pwr.cr1().modify(|w| w.set_dbp(true));
|
||||||
|
pwr.cr1().modify(|w| w.set_dbp(true));
|
||||||
|
|
||||||
|
rcc.bdcr().modify(|w| w.set_lseon(true));
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
match &config.hse {
|
||||||
|
Some(hse) => {
|
||||||
|
rcc.cr().modify(|w| {
|
||||||
|
w.set_hsepre(hse.prediv.into());
|
||||||
|
w.set_hseon(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
while !rcc.cr().read().hserdy() {}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
match &config.mux {
|
||||||
|
Some(pll_mux) => {
|
||||||
|
rcc.pllcfgr().modify(|w| {
|
||||||
|
w.set_pllm(pll_mux.prediv);
|
||||||
|
w.set_pllsrc(pll_mux.source.into());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
};
|
||||||
|
|
||||||
|
match &config.pll {
|
||||||
|
Some(pll) => {
|
||||||
|
rcc.pllcfgr().modify(|w| {
|
||||||
|
w.set_plln(pll.mul as u8);
|
||||||
|
pll.divp.map(|divp| {
|
||||||
|
w.set_pllpen(true);
|
||||||
|
w.set_pllp((divp - 1) as u8)
|
||||||
|
});
|
||||||
|
pll.divq.map(|divq| {
|
||||||
|
w.set_pllqen(true);
|
||||||
|
w.set_pllq((divq - 1) as u8)
|
||||||
|
});
|
||||||
|
pll.divr.map(|divr| {
|
||||||
|
// w.set_pllren(true);
|
||||||
|
w.set_pllr((divr - 1) as u8);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
rcc.cr().modify(|w| w.set_pllon(true));
|
||||||
|
|
||||||
|
while !rcc.cr().read().pllrdy() {}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
rcc.cfgr().modify(|w| {
|
||||||
|
w.set_sw(config.sys.into());
|
||||||
|
w.set_hpre(config.ahb1_pre.into());
|
||||||
|
w.set_ppre1(config.apb1_pre.into());
|
||||||
|
w.set_ppre2(config.apb2_pre.into());
|
||||||
|
});
|
||||||
|
|
||||||
|
rcc.extcfgr().modify(|w| {
|
||||||
|
w.set_c2hpre(config.ahb2_pre.into());
|
||||||
|
w.set_shdhpre(config.ahb3_pre.into());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -225,6 +225,9 @@ const DMA_TRANSFER_OPTIONS: crate::dma::TransferOptions = crate::dma::TransferOp
|
|||||||
mburst: crate::dma::Burst::Incr4,
|
mburst: crate::dma::Burst::Incr4,
|
||||||
flow_ctrl: crate::dma::FlowControl::Peripheral,
|
flow_ctrl: crate::dma::FlowControl::Peripheral,
|
||||||
fifo_threshold: Some(crate::dma::FifoThreshold::Full),
|
fifo_threshold: Some(crate::dma::FifoThreshold::Full),
|
||||||
|
circular: false,
|
||||||
|
half_transfer_ir: false,
|
||||||
|
complete_transfer_ir: true,
|
||||||
};
|
};
|
||||||
#[cfg(all(sdmmc_v1, not(dma)))]
|
#[cfg(all(sdmmc_v1, not(dma)))]
|
||||||
const DMA_TRANSFER_OPTIONS: crate::dma::TransferOptions = crate::dma::TransferOptions {
|
const DMA_TRANSFER_OPTIONS: crate::dma::TransferOptions = crate::dma::TransferOptions {
|
||||||
|
@ -34,3 +34,6 @@ log = { version = "0.4.17", optional = true }
|
|||||||
[[bin]]
|
[[bin]]
|
||||||
name = "rtos_trace"
|
name = "rtos_trace"
|
||||||
required-features = ["nightly"]
|
required-features = ["nightly"]
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
debug = 2
|
||||||
|
@ -19,3 +19,6 @@ cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-sing
|
|||||||
cortex-m-rt = "0.7.0"
|
cortex-m-rt = "0.7.0"
|
||||||
panic-probe = { version = "0.3", features = ["print-defmt"] }
|
panic-probe = { version = "0.3", features = ["print-defmt"] }
|
||||||
futures = { version = "0.3.17", default-features = false, features = ["async-await"] }
|
futures = { version = "0.3.17", default-features = false, features = ["async-await"] }
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
debug = 2
|
||||||
|
@ -57,5 +57,5 @@ embedded-hal-async = { version = "0.2.0-alpha.2", optional = true }
|
|||||||
num-integer = { version = "0.1.45", default-features = false }
|
num-integer = { version = "0.1.45", default-features = false }
|
||||||
microfft = "0.5.0"
|
microfft = "0.5.0"
|
||||||
|
|
||||||
[patch.crates-io]
|
[profile.release]
|
||||||
lora-phy = { git = "https://github.com/embassy-rs/lora-phy", rev = "ad289428fd44b02788e2fa2116445cc8f640a265" }
|
debug = 2
|
||||||
|
@ -53,3 +53,6 @@ rand = { version = "0.8.4", default-features = false }
|
|||||||
embedded-storage = "0.3.0"
|
embedded-storage = "0.3.0"
|
||||||
usbd-hid = "0.6.0"
|
usbd-hid = "0.6.0"
|
||||||
serde = { version = "1.0.136", default-features = false }
|
serde = { version = "1.0.136", default-features = false }
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
debug = 2
|
||||||
|
@ -54,7 +54,4 @@ pio = "0.2.1"
|
|||||||
rand = { version = "0.8.5", default-features = false }
|
rand = { version = "0.8.5", default-features = false }
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
debug = true
|
debug = 2
|
||||||
|
|
||||||
[patch.crates-io]
|
|
||||||
lora-phy = { git = "https://github.com/embassy-rs/lora-phy", rev = "ad289428fd44b02788e2fa2116445cc8f640a265" }
|
|
||||||
|
@ -23,3 +23,6 @@ clap = { version = "3.0.0-beta.5", features = ["derive"] }
|
|||||||
rand_core = { version = "0.6.3", features = ["std"] }
|
rand_core = { version = "0.6.3", features = ["std"] }
|
||||||
heapless = { version = "0.7.5", default-features = false }
|
heapless = { version = "0.7.5", default-features = false }
|
||||||
static_cell = { version = "1.1", features = ["nightly"]}
|
static_cell = { version = "1.1", features = ["nightly"]}
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
debug = 2
|
||||||
|
@ -20,3 +20,6 @@ embedded-hal = "0.2.6"
|
|||||||
panic-probe = { version = "0.3", features = ["print-defmt"] }
|
panic-probe = { version = "0.3", features = ["print-defmt"] }
|
||||||
futures = { version = "0.3.17", default-features = false, features = ["async-await"] }
|
futures = { version = "0.3.17", default-features = false, features = ["async-await"] }
|
||||||
heapless = { version = "0.7.5", default-features = false }
|
heapless = { version = "0.7.5", default-features = false }
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
debug = 2
|
||||||
|
@ -18,3 +18,6 @@ embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["de
|
|||||||
embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] }
|
embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] }
|
||||||
embassy-time = { version = "0.1.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
|
embassy-time = { version = "0.1.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
|
||||||
static_cell = { version = "1.1", features = ["nightly"]}
|
static_cell = { version = "1.1", features = ["nightly"]}
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
debug = 2
|
||||||
|
@ -26,3 +26,6 @@ nb = "1.0.0"
|
|||||||
|
|
||||||
[profile.dev]
|
[profile.dev]
|
||||||
opt-level = "s"
|
opt-level = "s"
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
debug = 2
|
||||||
|
@ -21,3 +21,6 @@ panic-probe = { version = "0.3", features = ["print-defmt"] }
|
|||||||
futures = { version = "0.3.17", default-features = false, features = ["async-await"] }
|
futures = { version = "0.3.17", default-features = false, features = ["async-await"] }
|
||||||
heapless = { version = "0.7.5", default-features = false }
|
heapless = { version = "0.7.5", default-features = false }
|
||||||
nb = "1.0.0"
|
nb = "1.0.0"
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
debug = 2
|
||||||
|
@ -25,3 +25,6 @@ heapless = { version = "0.7.5", default-features = false }
|
|||||||
nb = "1.0.0"
|
nb = "1.0.0"
|
||||||
embedded-storage = "0.3.0"
|
embedded-storage = "0.3.0"
|
||||||
static_cell = { version = "1.1", features = ["nightly"]}
|
static_cell = { version = "1.1", features = ["nightly"]}
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
debug = 2
|
||||||
|
@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0"
|
|||||||
# Change stm32f429zi to your chip name, if necessary.
|
# Change stm32f429zi to your chip name, if necessary.
|
||||||
embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "unstable-traits", "defmt", "stm32f429zi", "unstable-pac", "memory-x", "time-driver-any", "exti", "embedded-sdmmc", "chrono"] }
|
embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "unstable-traits", "defmt", "stm32f429zi", "unstable-pac", "memory-x", "time-driver-any", "exti", "embedded-sdmmc", "chrono"] }
|
||||||
embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] }
|
embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] }
|
||||||
embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers", "arch-cortex-m", "executor-thread", "executor-interrupt"] }
|
embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] }
|
||||||
embassy-time = { version = "0.1.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "unstable-traits", "tick-hz-32_768"] }
|
embassy-time = { version = "0.1.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "unstable-traits", "tick-hz-32_768"] }
|
||||||
embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] }
|
embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] }
|
||||||
embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "nightly"] }
|
embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "nightly"] }
|
||||||
|
@ -40,10 +40,13 @@ async fn main(_spawner: Spawner) {
|
|||||||
|
|
||||||
can.as_mut()
|
can.as_mut()
|
||||||
.modify_config()
|
.modify_config()
|
||||||
.set_bit_timing(0x001c0003) // http://www.bittiming.can-wiki.info/
|
|
||||||
.set_loopback(true) // Receive own frames
|
.set_loopback(true) // Receive own frames
|
||||||
.set_silent(true)
|
.set_silent(true)
|
||||||
.enable();
|
.leave_disabled();
|
||||||
|
|
||||||
|
can.set_bitrate(1_000_000);
|
||||||
|
|
||||||
|
can.enable().await;
|
||||||
|
|
||||||
let mut i: u8 = 0;
|
let mut i: u8 = 0;
|
||||||
loop {
|
loop {
|
||||||
|
@ -14,11 +14,11 @@ async fn main(_spawner: Spawner) -> ! {
|
|||||||
info!("Hello World, dude!");
|
info!("Hello World, dude!");
|
||||||
|
|
||||||
let mut dac = DacCh1::new(p.DAC, NoDma, p.PA4);
|
let mut dac = DacCh1::new(p.DAC, NoDma, p.PA4);
|
||||||
|
unwrap!(dac.set_trigger_enable(false));
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
for v in 0..=255 {
|
for v in 0..=255 {
|
||||||
unwrap!(dac.set(Value::Bit8(to_sine_wave(v))));
|
unwrap!(dac.set(Value::Bit8(to_sine_wave(v))));
|
||||||
dac.trigger();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,3 +28,6 @@ rand_core = "0.6.3"
|
|||||||
critical-section = "1.1"
|
critical-section = "1.1"
|
||||||
embedded-storage = "0.3.0"
|
embedded-storage = "0.3.0"
|
||||||
static_cell = { version = "1.1", features = ["nightly"]}
|
static_cell = { version = "1.1", features = ["nightly"]}
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
debug = 2
|
||||||
|
@ -20,3 +20,6 @@ embedded-hal = "0.2.6"
|
|||||||
panic-probe = { version = "0.3", features = ["print-defmt"] }
|
panic-probe = { version = "0.3", features = ["print-defmt"] }
|
||||||
futures = { version = "0.3.17", default-features = false, features = ["async-await"] }
|
futures = { version = "0.3.17", default-features = false, features = ["async-await"] }
|
||||||
heapless = { version = "0.7.5", default-features = false }
|
heapless = { version = "0.7.5", default-features = false }
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
debug = 2
|
||||||
|
@ -22,3 +22,6 @@ embedded-hal = "0.2.6"
|
|||||||
panic-probe = { version = "0.3", features = ["print-defmt"] }
|
panic-probe = { version = "0.3", features = ["print-defmt"] }
|
||||||
futures = { version = "0.3.17", default-features = false, features = ["async-await"] }
|
futures = { version = "0.3.17", default-features = false, features = ["async-await"] }
|
||||||
heapless = { version = "0.7.5", default-features = false }
|
heapless = { version = "0.7.5", default-features = false }
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
debug = 2
|
||||||
|
@ -21,11 +21,11 @@ fn main() -> ! {
|
|||||||
let p = embassy_stm32::init(config);
|
let p = embassy_stm32::init(config);
|
||||||
|
|
||||||
let mut dac = DacCh1::new(p.DAC1, NoDma, p.PA4);
|
let mut dac = DacCh1::new(p.DAC1, NoDma, p.PA4);
|
||||||
|
unwrap!(dac.set_trigger_enable(false));
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
for v in 0..=255 {
|
for v in 0..=255 {
|
||||||
unwrap!(dac.set(Value::Bit8(to_sine_wave(v))));
|
unwrap!(dac.set(Value::Bit8(to_sine_wave(v))));
|
||||||
dac.trigger();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,5 +34,5 @@ heapless = { version = "0.7.5", default-features = false }
|
|||||||
embedded-hal = "0.2.6"
|
embedded-hal = "0.2.6"
|
||||||
static_cell = "1.1"
|
static_cell = "1.1"
|
||||||
|
|
||||||
[patch.crates-io]
|
[profile.release]
|
||||||
lora-phy = { git = "https://github.com/embassy-rs/lora-phy", rev = "ad289428fd44b02788e2fa2116445cc8f640a265" }
|
debug = 2
|
||||||
|
@ -20,3 +20,6 @@ panic-probe = { version = "0.3", features = ["print-defmt"] }
|
|||||||
futures = { version = "0.3.17", default-features = false, features = ["async-await"] }
|
futures = { version = "0.3.17", default-features = false, features = ["async-await"] }
|
||||||
heapless = { version = "0.7.5", default-features = false }
|
heapless = { version = "0.7.5", default-features = false }
|
||||||
embedded-storage = "0.3.0"
|
embedded-storage = "0.3.0"
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
debug = 2
|
||||||
|
@ -27,3 +27,6 @@ heapless = { version = "0.7.5", default-features = false }
|
|||||||
chrono = { version = "^0.4", default-features = false }
|
chrono = { version = "^0.4", default-features = false }
|
||||||
|
|
||||||
micromath = "2.0.0"
|
micromath = "2.0.0"
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
debug = 2
|
||||||
|
@ -13,11 +13,11 @@ fn main() -> ! {
|
|||||||
info!("Hello World!");
|
info!("Hello World!");
|
||||||
|
|
||||||
let mut dac = DacCh1::new(p.DAC1, NoDma, p.PA4);
|
let mut dac = DacCh1::new(p.DAC1, NoDma, p.PA4);
|
||||||
|
unwrap!(dac.set_trigger_enable(false));
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
for v in 0..=255 {
|
for v in 0..=255 {
|
||||||
unwrap!(dac.set(Value::Bit8(to_sine_wave(v))));
|
unwrap!(dac.set(Value::Bit8(to_sine_wave(v))));
|
||||||
dac.trigger();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,3 +27,6 @@ heapless = { version = "0.7.5", default-features = false }
|
|||||||
rand_core = { version = "0.6.3", default-features = false }
|
rand_core = { version = "0.6.3", default-features = false }
|
||||||
embedded-io = { version = "0.4.0", features = ["async"] }
|
embedded-io = { version = "0.4.0", features = ["async"] }
|
||||||
static_cell = { version = "1.1", features = ["nightly"]}
|
static_cell = { version = "1.1", features = ["nightly"]}
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
debug = 2
|
||||||
|
@ -23,3 +23,6 @@ futures = { version = "0.3.17", default-features = false, features = ["async-awa
|
|||||||
heapless = { version = "0.7.5", default-features = false }
|
heapless = { version = "0.7.5", default-features = false }
|
||||||
|
|
||||||
micromath = "2.0.0"
|
micromath = "2.0.0"
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
debug = 2
|
||||||
|
@ -52,3 +52,6 @@ required-features = ["ble"]
|
|||||||
[[bin]]
|
[[bin]]
|
||||||
name = "gatt_server"
|
name = "gatt_server"
|
||||||
required-features = ["ble"]
|
required-features = ["ble"]
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
debug = 2
|
||||||
|
@ -28,5 +28,5 @@ futures = { version = "0.3.17", default-features = false, features = ["async-awa
|
|||||||
heapless = { version = "0.7.5", default-features = false }
|
heapless = { version = "0.7.5", default-features = false }
|
||||||
chrono = { version = "^0.4", default-features = false }
|
chrono = { version = "^0.4", default-features = false }
|
||||||
|
|
||||||
[patch.crates-io]
|
[profile.release]
|
||||||
lora-phy = { git = "https://github.com/embassy-rs/lora-phy", rev = "ad289428fd44b02788e2fa2116445cc8f640a265" }
|
debug = 2
|
||||||
|
@ -17,3 +17,6 @@ wasm-bindgen = "0.2"
|
|||||||
web-sys = { version = "0.3", features = ["Document", "Element", "HtmlElement", "Node", "Window" ] }
|
web-sys = { version = "0.3", features = ["Document", "Element", "HtmlElement", "Node", "Window" ] }
|
||||||
log = "0.4.11"
|
log = "0.4.11"
|
||||||
critical-section = { version = "1.1", features = ["std"] }
|
critical-section = { version = "1.1", features = ["std"] }
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
debug = 2
|
||||||
|
@ -12,6 +12,7 @@ use common::*;
|
|||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_stm32::bind_interrupts;
|
use embassy_stm32::bind_interrupts;
|
||||||
use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler};
|
use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler};
|
||||||
|
use embassy_stm32::rcc::WPAN_DEFAULT;
|
||||||
use embassy_stm32_wpan::hci::host::uart::UartHci;
|
use embassy_stm32_wpan::hci::host::uart::UartHci;
|
||||||
use embassy_stm32_wpan::hci::host::{AdvertisingFilterPolicy, EncryptionKey, HostHci, OwnAddressType};
|
use embassy_stm32_wpan::hci::host::{AdvertisingFilterPolicy, EncryptionKey, HostHci, OwnAddressType};
|
||||||
use embassy_stm32_wpan::hci::types::AdvertisingType;
|
use embassy_stm32_wpan::hci::types::AdvertisingType;
|
||||||
@ -40,7 +41,10 @@ async fn run_mm_queue(memory_manager: mm::MemoryManager) {
|
|||||||
|
|
||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
async fn main(spawner: Spawner) {
|
async fn main(spawner: Spawner) {
|
||||||
let p = embassy_stm32::init(config());
|
let mut config = config();
|
||||||
|
config.rcc = WPAN_DEFAULT;
|
||||||
|
|
||||||
|
let p = embassy_stm32::init(config);
|
||||||
info!("Hello World!");
|
info!("Hello World!");
|
||||||
|
|
||||||
let config = Config::default();
|
let config = Config::default();
|
||||||
|
@ -10,6 +10,7 @@ use common::*;
|
|||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_stm32::bind_interrupts;
|
use embassy_stm32::bind_interrupts;
|
||||||
use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler};
|
use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler};
|
||||||
|
use embassy_stm32::rcc::WPAN_DEFAULT;
|
||||||
use embassy_stm32_wpan::mac::commands::{AssociateRequest, GetRequest, ResetRequest, SetRequest};
|
use embassy_stm32_wpan::mac::commands::{AssociateRequest, GetRequest, ResetRequest, SetRequest};
|
||||||
use embassy_stm32_wpan::mac::event::MacEvent;
|
use embassy_stm32_wpan::mac::event::MacEvent;
|
||||||
use embassy_stm32_wpan::mac::typedefs::{
|
use embassy_stm32_wpan::mac::typedefs::{
|
||||||
@ -31,7 +32,10 @@ async fn run_mm_queue(memory_manager: mm::MemoryManager) {
|
|||||||
|
|
||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
async fn main(spawner: Spawner) {
|
async fn main(spawner: Spawner) {
|
||||||
let p = embassy_stm32::init(config());
|
let mut config = config();
|
||||||
|
config.rcc = WPAN_DEFAULT;
|
||||||
|
|
||||||
|
let p = embassy_stm32::init(config);
|
||||||
info!("Hello World!");
|
info!("Hello World!");
|
||||||
|
|
||||||
let config = Config::default();
|
let config = Config::default();
|
||||||
|
Loading…
Reference in New Issue
Block a user