-
Hello there! Recently, I try to convert the PPM signal into the PWM signal, I found pins.p2-pins.p10 can new by #![no_std]
#![no_main]
use teensy4_panic as _;
#[rtic::app(device = teensy4_bsp, peripherals = true, dispatchers = [KPP])]
mod app {
use core::i16;
use bsp::board;
use bsp::hal::flexpwm;
use bsp::{hal::iomuxc, pins};
use imxrt_log as logging;
use rtic_monotonics::{
systick::{self, Systick},
Monotonic,
};
use teensy4_bsp as bsp;
// If you're using a Teensy 4.1 or MicroMod, you should eventually
// change 't40' to 't41' or micromod, respectively.
use board::t40 as my_board;
const PWM_PRESCALER: flexpwm::Prescaler = flexpwm::Prescaler::Prescaler64;
const PIN_CONFIG: iomuxc::Config = iomuxc::Config::zero()
.set_pull_keeper(Some(iomuxc::PullKeeper::Pullup22k))
.set_open_drain(pins::OpenDrain::Enabled);
/// There are no resources shared across tasks.
#[shared]
struct Shared {}
/// These resources are local to individual tasks.
#[local]
struct Local {
led: board::Led,
poller: logging::Poller,
ppm: bsp::hal::gpio::Input<bsp::pins::t40::P14>,
last_time: u32,
ppm_data: [u16; 9],
channel: usize,
}
#[init]
fn init(cx: init::Context) -> (Shared, Local) {
let board::Resources {
mut gpio2,
mut gpio1,
mut pins,
usb,
flexpwm1,
..
} = my_board(cx.device);
let led = board::led(&mut gpio2, pins.p13);
let poller = logging::log::usbd(usb, logging::Interrupts::Enabled).unwrap();
iomuxc::configure(&mut pins.p14, PIN_CONFIG);
let ppm = gpio1.input(pins.p14);
let mut sm2 = flexpwm1.1 .0;
let mut pwm = flexpwm1.0;
// Keep running in wait, debug modes.
sm2.set_debug_enable(true);
sm2.set_wait_enable(true);
// Run on the IPG clock.
sm2.set_clock_select(flexpwm::ClockSelect::Ipg);
// Divide the IPG clock by 1.
sm2.set_prescaler(PWM_PRESCALER);
// Allow PWM outputs to operate independently.
sm2.set_pair_operation(flexpwm::PairOperation::Independent);
// Reload every time the full reload value register compares.
sm2.set_load_mode(flexpwm::LoadMode::reload_full());
sm2.set_load_frequency(1);
// Count over the full range of i16 values.
flexpwm::Output::new_a(pins.p1);
sm2.set_initial_count(&pwm, i16::MIN);
sm2.set_value(flexpwm::FULL_RELOAD_VALUE_REGISTER, i16::MAX);
sm2.set_turn_on(flexpwm::Channel::B, -(i16::MAX as f32 / 20.0) as i16);
sm2.set_turn_off(flexpwm::Channel::B, (i16::MAX as f32 / 20.0) as i16);
sm2.set_output_enable(&mut pwm, flexpwm::Channel::B, true);
// Load the values into the PWM registers.
sm2.set_load_ok(&mut pwm);
// Start running.
sm2.set_running(&mut pwm, true);
gpio1.set_interrupt(&ppm, Some(bsp::hal::gpio::Trigger::EitherEdge));
let ppm_data = [0u16; 9];
let channel = 0;
led.set();
Systick::start(
cx.core.SYST,
board::ARM_FREQUENCY / 100,
rtic_monotonics::create_systick_token!(),
);
let last_time = 0;
(
Shared {},
Local {
led,
poller,
ppm,
ppm_data,
channel,
last_time,
},
)
}
#[task(binds=GPIO1_COMBINED_16_31, local=[led, ppm, last_time, ppm_data, channel])]
fn ppm_interrupt(cx: ppm_interrupt::Context) {
let now = Systick::now().ticks();
let elapsed = now - *cx.local.last_time;
*cx.local.last_time = now;
if *cx.local.channel < cx.local.ppm_data.len() {
cx.local.ppm_data[*cx.local.channel] = elapsed as u16;
*cx.local.channel += 1;
if *cx.local.channel >= cx.local.ppm_data.len() {
*cx.local.channel = 0;
log::info!("PPM Data: {:?}", cx.local.ppm_data);
}
}
cx.local.ppm.clear_triggered();
}
#[idle]
fn idle(_: idle::Context) -> ! {
loop {
cortex_m::asm::wfi();
}
}
#[task(binds = USB_OTG1, local = [poller])]
fn log_over_usb(cx: log_over_usb::Context) {
cx.local.poller.poll();
}
}
ps. the pins.p14 is interrupted by |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
To use something like your example, we'd need support in imxrt-iomuxc in order to use pin 1 in its PWM alternate. This table shows that pin 1 is a FlexPWM 1 output type X. However, imxrt-iomuxc only supports output types A and B. We'd need to add support for output type X, then provide implementations for the pad corresponding to pin 1. We likely need support in imxrt-hal, too. I haven't worked with these auxiliary output signals, so I'm not sure how to account for them in the API. |
Beta Was this translation helpful? Give feedback.
To use something like your example, we'd need support in imxrt-iomuxc in order to use pin 1 in its PWM alternate. This table shows that pin 1 is a FlexPWM 1 output type X. However, imxrt-iomuxc only supports output types A and B. We'd need to add support for output type X, then provide implementations for the pad corresponding to pin 1.
We likely need support in imxrt-hal, too. I haven't worked with these auxiliary output signals, so I'm not sure how to account for them in the API.