pub mod servo_player_generated;
#[doc(hidden)]
#[macro_export]
macro_rules! combine {
() => {
[]
};
($single:expr) => {
$single
};
($first:expr, $second:expr) => {{
const FIRST: &[(u16, ::embassy_time::Duration)] = &$first;
const SECOND: &[(u16, ::embassy_time::Duration)] = &$second;
$crate::servo::combine::<{FIRST.len()}, {SECOND.len()}, {FIRST.len() + SECOND.len()}>($first, $second)
}};
($first:expr, $($rest:expr),+ $(,)?) => {{
const FIRST: &[(u16, ::embassy_time::Duration)] = &$first;
const REST: &[(u16, ::embassy_time::Duration)] = &$crate::combine!($($rest),+);
$crate::servo::combine::<{FIRST.len()}, {REST.len()}, {FIRST.len() + REST.len()}>($first, $crate::combine!($($rest),+))
}};
}
#[macro_export]
#[doc(hidden)]
macro_rules! servo_player {
($($tt:tt)*) => { $crate::__servo_player_impl! { $($tt)* } };
}
#[doc(inline)]
pub use servo_player;
#[doc(hidden)]
#[macro_export]
macro_rules! __servo_player_impl {
(
$name:ident {
pin: $pin:ident,
timer: $timer:ident,
channel: $channel:ident,
$(min_us: $min_us:expr,)?
$(max_us: $max_us:expr,)?
$(max_degrees: $max_degrees:expr,)?
$(direction: $direction:expr,)?
$(max_steps: $max_steps:expr $(,)?)?
}
) => {
$crate::servo::paste::paste! {
pub struct $name;
// Link-time ownership claims: duplicate timer or channel selection across the
#[used]
#[unsafe(no_mangle)]
static [<__device_envoy_esp_ledc_timer_claim_ $timer:lower>]: u8 = 0;
#[used]
#[unsafe(no_mangle)]
static [<__device_envoy_esp_ledc_channel_claim_ $channel:lower>]: u8 = 0;
static [<$name:upper _SERVO_STATIC>]: $crate::servo::ServoStatic =
$crate::servo::ServoStatic::new_static(
::esp_hal::ledc::timer::Number::$timer,
::esp_hal::ledc::channel::Number::$channel,
$crate::__servo_player_impl!(@min_us $($min_us)?),
$crate::__servo_player_impl!(@max_us $($max_us)?),
$crate::__servo_player_impl!(@max_degrees $($max_degrees)?),
$crate::__servo_player_impl!(@direction $($direction)?),
);
static [<$name:upper _SERVO_PLAYER_STATIC>]:
$crate::servo::ServoPlayerStatic<{ $crate::__servo_player_impl!(@max_steps $($max_steps)?) }> =
$crate::servo::ServoPlayerHandle::<{ $crate::__servo_player_impl!(@max_steps $($max_steps)?) }>::new_static();
impl $name {
pub const MAX_STEPS: usize = $crate::__servo_player_impl!(@max_steps $($max_steps)?);
pub fn new(
ledc: &::esp_hal::ledc::Ledc<'static>,
pin: ::esp_hal::peripherals::$pin<'static>,
spawner: ::embassy_executor::Spawner,
) -> $crate::Result<$crate::servo::ServoPlayerHandle<{ $crate::__servo_player_impl!(@max_steps $($max_steps)?) }>> {
let servo = $crate::servo::ServoEsp::new(&[<$name:upper _SERVO_STATIC>], ledc, pin)?;
let token = [<__ $name:snake _servo_player_task>](&[<$name:upper _SERVO_PLAYER_STATIC>], servo);
spawner.spawn(token?);
Ok($crate::servo::ServoPlayerHandle::new(&[<$name:upper _SERVO_PLAYER_STATIC>]))
}
}
#[::embassy_executor::task]
async fn [<__ $name:snake _servo_player_task>](
servo_player_static: &'static $crate::servo::ServoPlayerStatic<{ $crate::__servo_player_impl!(@max_steps $($max_steps)?) }>,
servo: $crate::servo::ServoEsp,
) -> ! {
$crate::servo::device_loop(servo_player_static, servo).await
}
}
};
(
$vis:vis $name:ident {
pin: $pin:ident,
timer: $timer:ident,
channel: $channel:ident,
$(min_us: $min_us:expr,)?
$(max_us: $max_us:expr,)?
$(max_degrees: $max_degrees:expr,)?
$(direction: $direction:expr,)?
$(max_steps: $max_steps:expr $(,)?)?
}
) => {
$crate::__paste! {
$crate::__servo_player_impl! {
[<__ $name _visibility_inner>] {
pin: $pin,
timer: $timer,
channel: $channel,
$(min_us: $min_us,)?
$(max_us: $max_us,)?
$(max_degrees: $max_degrees,)?
$(direction: $direction,)?
$(max_steps: $max_steps,)?
}
}
$vis type $name = [<__ $name _visibility_inner>];
}
};
(@min_us $min_us:expr) => { $min_us };
(@min_us) => { $crate::servo::SERVO_MIN_US_DEFAULT };
(@max_us $max_us:expr) => { $max_us };
(@max_us) => { $crate::servo::SERVO_MAX_US_DEFAULT };
(@max_degrees $max_degrees:expr) => { $max_degrees };
(@max_degrees) => { $crate::servo::ServoEsp::DEFAULT_MAX_DEGREES };
(@direction $direction:expr) => { $direction };
(@direction) => { $crate::servo::Direction::Forward };
(@max_steps $max_steps:expr) => { $max_steps };
(@max_steps) => { 16 };
}