mirror of
https://github.com/embassy-rs/embassy.git
synced 2024-11-25 00:02:28 +00:00
example is working now
This commit is contained in:
parent
41b9a12574
commit
7c1e1ee288
@ -26,6 +26,10 @@ pub enum Ch3 {}
|
||||
/// Channel 4 marker type.
|
||||
pub enum Ch4 {}
|
||||
|
||||
fn regs_gp16(ptr: *mut ()) -> crate::pac::timer::TimGp16 {
|
||||
unsafe { crate::pac::timer::TimGp16::from_ptr(ptr) }
|
||||
}
|
||||
|
||||
/// Capture pin wrapper.
|
||||
///
|
||||
/// This wraps a pin to make it usable with capture.
|
||||
@ -76,10 +80,6 @@ impl<'d, T: GeneralInstance4Channel> InputCapture<'d, T> {
|
||||
freq: Hertz,
|
||||
counting_mode: CountingMode,
|
||||
) -> Self {
|
||||
Self::new_inner(tim, freq, counting_mode)
|
||||
}
|
||||
|
||||
fn new_inner(tim: impl Peripheral<P = T> + 'd, freq: Hertz, counting_mode: CountingMode) -> Self {
|
||||
let mut this = Self { inner: Timer::new(tim) };
|
||||
|
||||
this.inner.set_counting_mode(counting_mode);
|
||||
@ -148,11 +148,52 @@ impl<'d, T: GeneralInstance4Channel> InputCapture<'d, T> {
|
||||
}
|
||||
|
||||
fn new_future(&self, channel: Channel, mode: InputCaptureMode, tisel: InputTISelection) -> InputCaptureFuture<T> {
|
||||
self.inner.enable_channel(channel, true);
|
||||
self.inner.set_input_capture_mode(channel, mode);
|
||||
self.inner.set_input_ti_selection(channel, tisel);
|
||||
self.inner.clear_input_interrupt(channel);
|
||||
self.inner.enable_input_interrupt(channel, true);
|
||||
use stm32_metapac::timer::vals::*;
|
||||
|
||||
let regs = regs_gp16(T::regs());
|
||||
let idx = channel.index();
|
||||
|
||||
// Select the active input: TIMx_CCR1 must be linked to the TI1 input, so write the CC1S
|
||||
// bits to 01 in the TIMx_CCMR1 register. As soon as CC1S becomes different from 00,
|
||||
// the channel is configured in input and the TIMx_CCR1 register becomes read-only.
|
||||
regs.ccmr_input(idx / 2)
|
||||
.modify(|r| r.set_ccs(idx % 2, CcmrInputCcs::from(tisel)));
|
||||
|
||||
// Program the appropriate input filter duration in relation with the signal connected to the
|
||||
// timer (by programming the ICxF bits in the TIMx_CCMRx register if the input is one of
|
||||
// the TIx inputs). Let’s imagine that, when toggling, the input signal is not stable during at
|
||||
// must 5 internal clock cycles. We must program a filter duration longer than these 5
|
||||
// clock cycles. We can validate a transition on TI1 when 8 consecutive samples with the
|
||||
// new level have been detected (sampled at fDTS frequency). Then write IC1F bits to
|
||||
// 0011 in the TIMx_CCMR1 register.
|
||||
regs.ccmr_input(idx / 2)
|
||||
.modify(|r| r.set_icf(idx % 2, FilterValue::NOFILTER));
|
||||
|
||||
// Select the edge of the active transition on the TI1 channel by writing the CC1P and
|
||||
// CC1NP bits to 00 in the TIMx_CCER register (rising edge in this case).
|
||||
let ccpnp = match mode {
|
||||
InputCaptureMode::Rising => (false, false),
|
||||
InputCaptureMode::Falling => (false, true),
|
||||
InputCaptureMode::BothEdges => (true, true),
|
||||
};
|
||||
regs.ccer().modify(|r| {
|
||||
r.set_ccp(idx, ccpnp.0);
|
||||
r.set_ccnp(idx, ccpnp.1);
|
||||
});
|
||||
|
||||
// Program the input prescaler. In our example, we wish the capture to be performed at
|
||||
// each valid transition, so the prescaler is disabled (write IC1PS bits to 00 in the
|
||||
// TIMx_CCMR1 register).
|
||||
regs.ccmr_input(idx / 2).modify(|r| r.set_icpsc(idx % 2, 0));
|
||||
|
||||
// Enable capture from the counter into the capture register by setting the CC1E bit in the
|
||||
// TIMx_CCER register.
|
||||
regs.ccer().modify(|r| r.set_cce(idx, true));
|
||||
|
||||
// If needed, enable the related interrupt request by setting the CC1IE bit in the
|
||||
// TIMx_DIER register, and/or the DMA request by setting the CC1DE bit in the
|
||||
// TIMx_DIER register.
|
||||
regs.dier().modify(|r| r.set_ccie(idx, true));
|
||||
|
||||
InputCaptureFuture {
|
||||
channel,
|
||||
@ -206,7 +247,7 @@ struct InputCaptureFuture<T: GeneralInstance4Channel> {
|
||||
impl<T: GeneralInstance4Channel> Drop for InputCaptureFuture<T> {
|
||||
fn drop(&mut self) {
|
||||
critical_section::with(|_| {
|
||||
let regs = unsafe { crate::pac::timer::TimGp16::from_ptr(T::regs()) };
|
||||
let regs = regs_gp16(T::regs());
|
||||
|
||||
// disable interrupt enable
|
||||
regs.dier().modify(|w| w.set_ccie(self.channel.index(), false));
|
||||
@ -220,7 +261,7 @@ impl<T: GeneralInstance4Channel> Future for InputCaptureFuture<T> {
|
||||
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||
T::state().cc_waker[self.channel.index()].register(cx.waker());
|
||||
|
||||
let regs = unsafe { crate::pac::timer::TimGp16::from_ptr(T::regs()) };
|
||||
let regs = regs_gp16(T::regs());
|
||||
|
||||
let dier = regs.dier().read();
|
||||
if !dier.ccie(self.channel.index()) {
|
||||
|
2
examples/stm32f4/.vscode/launch.json
vendored
2
examples/stm32f4/.vscode/launch.json
vendored
@ -15,7 +15,7 @@
|
||||
"cwd": "${workspaceRoot}",
|
||||
"preLaunchTask": "Cargo Build (debug)",
|
||||
"runToEntryPoint": "main",
|
||||
"executable": "./target/thumbv7em-none-eabihf/debug/pwm_input",
|
||||
"executable": "./target/thumbv7em-none-eabihf/debug/input_capture",
|
||||
/* Run `cargo build --example itm` and uncomment this line to run itm example */
|
||||
// "executable": "./target/thumbv7em-none-eabihf/debug/examples/itm",
|
||||
"device": "STM32F446RET6",
|
||||
|
2
examples/stm32f4/.vscode/tasks.json
vendored
2
examples/stm32f4/.vscode/tasks.json
vendored
@ -9,7 +9,7 @@
|
||||
],
|
||||
"args": [
|
||||
"--bin",
|
||||
"pwm_input"
|
||||
"input_capture"
|
||||
],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
|
Loading…
Reference in New Issue
Block a user