#![doc = include_str!("../docs/how_servos_work.md")]
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),+))
}};
}
#[cfg(not(feature = "host"))]
#[doc(hidden)]
#[macro_export]
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 {
$($fields:tt)*
}
) => {
$crate::__servo_player_impl! {
@__fill_defaults
vis: pub(self),
name: $name,
pin: _UNSET_,
slice: _UNSET_,
channel: _UNSET_,
min_us: $crate::servo::SERVO_MIN_US_DEFAULT,
max_us: $crate::servo::SERVO_MAX_US_DEFAULT,
max_degrees: $crate::servo::ServoRp::DEFAULT_MAX_DEGREES,
max_steps: 16,
direction: $crate::servo::Direction::Forward,
fields: [ $($fields)* ]
}
};
(
$vis:vis $name:ident {
$($fields:tt)*
}
) => {
$crate::__servo_player_impl! {
@__fill_defaults
vis: $vis,
name: $name,
pin: _UNSET_,
slice: _UNSET_,
channel: _UNSET_,
min_us: $crate::servo::SERVO_MIN_US_DEFAULT,
max_us: $crate::servo::SERVO_MAX_US_DEFAULT,
max_degrees: $crate::servo::ServoRp::DEFAULT_MAX_DEGREES,
max_steps: 16,
direction: $crate::servo::Direction::Forward,
fields: [ $($fields)* ]
}
};
(@__fill_defaults
vis: $vis:vis,
name: $name:ident,
pin: $pin:tt,
slice: $slice:tt,
channel: $channel:tt,
min_us: $min_us:expr,
max_us: $max_us:expr,
max_degrees: $max_degrees:expr,
max_steps: $max_steps:expr,
direction: $direction:expr,
fields: [ pin: $pin_value:ident $(, $($rest:tt)* )? ]
) => {
$crate::__servo_player_impl! {
@__fill_defaults
vis: $vis,
name: $name,
pin: $pin_value,
slice: $slice,
channel: $channel,
min_us: $min_us,
max_us: $max_us,
max_degrees: $max_degrees,
max_steps: $max_steps,
direction: $direction,
fields: [ $($($rest)*)? ]
}
};
(@__fill_defaults
vis: $vis:vis,
name: $name:ident,
pin: $pin:tt,
slice: $slice:tt,
channel: $channel:tt,
min_us: $min_us:expr,
max_us: $max_us:expr,
max_degrees: $max_degrees:expr,
max_steps: $max_steps:expr,
direction: $direction:expr,
fields: [ pin: $pin_value:ident ]
) => {
$crate::__servo_player_impl! {
@__fill_defaults
vis: $vis,
name: $name,
pin: $pin_value,
slice: $slice,
channel: $channel,
min_us: $min_us,
max_us: $max_us,
max_degrees: $max_degrees,
max_steps: $max_steps,
direction: $direction,
fields: [ ]
}
};
(@__fill_defaults
vis: $vis:vis,
name: $name:ident,
pin: $pin:tt,
slice: $slice:tt,
channel: $channel:tt,
min_us: $min_us:expr,
max_us: $max_us:expr,
max_degrees: $max_degrees:expr,
max_steps: $max_steps:expr,
direction: $direction:expr,
fields: [ slice: $slice_value:ident $(, $($rest:tt)* )? ]
) => {
$crate::__servo_player_impl! {
@__fill_defaults
vis: $vis,
name: $name,
pin: $pin,
slice: $slice_value,
channel: $channel,
min_us: $min_us,
max_us: $max_us,
max_degrees: $max_degrees,
max_steps: $max_steps,
direction: $direction,
fields: [ $($($rest)*)? ]
}
};
(@__fill_defaults
vis: $vis:vis,
name: $name:ident,
pin: $pin:tt,
slice: $slice:tt,
channel: $channel:tt,
min_us: $min_us:expr,
max_us: $max_us:expr,
max_degrees: $max_degrees:expr,
max_steps: $max_steps:expr,
direction: $direction:expr,
fields: [ slice: $slice_value:ident ]
) => {
$crate::__servo_player_impl! {
@__fill_defaults
vis: $vis,
name: $name,
pin: $pin,
slice: $slice_value,
channel: $channel,
min_us: $min_us,
max_us: $max_us,
max_degrees: $max_degrees,
max_steps: $max_steps,
direction: $direction,
fields: [ ]
}
};
(@__fill_defaults
vis: $vis:vis,
name: $name:ident,
pin: $pin:tt,
slice: $slice:tt,
channel: $channel:tt,
min_us: $min_us:expr,
max_us: $max_us:expr,
max_degrees: $max_degrees:expr,
max_steps: $max_steps:expr,
direction: $direction:expr,
fields: [ min_us: $min_us_value:expr $(, $($rest:tt)* )? ]
) => {
$crate::__servo_player_impl! {
@__fill_defaults
vis: $vis,
name: $name,
pin: $pin,
slice: $slice,
channel: $channel,
min_us: $min_us_value,
max_us: $max_us,
max_degrees: $max_degrees,
max_steps: $max_steps,
direction: $direction,
fields: [ $($($rest)*)? ]
}
};
(@__fill_defaults
vis: $vis:vis,
name: $name:ident,
pin: $pin:tt,
slice: $slice:tt,
channel: $channel:tt,
min_us: $min_us:expr,
max_us: $max_us:expr,
max_degrees: $max_degrees:expr,
max_steps: $max_steps:expr,
direction: $direction:expr,
fields: [ min_us: $min_us_value:expr ]
) => {
$crate::__servo_player_impl! {
@__fill_defaults
vis: $vis,
name: $name,
pin: $pin,
slice: $slice,
channel: $channel,
min_us: $min_us_value,
max_us: $max_us,
max_degrees: $max_degrees,
max_steps: $max_steps,
direction: $direction,
fields: [ ]
}
};
(@__fill_defaults
vis: $vis:vis,
name: $name:ident,
pin: $pin:tt,
slice: $slice:tt,
channel: $channel:tt,
min_us: $min_us:expr,
max_us: $max_us:expr,
max_degrees: $max_degrees:expr,
max_steps: $max_steps:expr,
direction: $direction:expr,
fields: [ max_us: $max_us_value:expr $(, $($rest:tt)* )? ]
) => {
$crate::__servo_player_impl! {
@__fill_defaults
vis: $vis,
name: $name,
pin: $pin,
slice: $slice,
channel: $channel,
min_us: $min_us,
max_us: $max_us_value,
max_degrees: $max_degrees,
max_steps: $max_steps,
direction: $direction,
fields: [ $($($rest)*)? ]
}
};
(@__fill_defaults
vis: $vis:vis,
name: $name:ident,
pin: $pin:tt,
slice: $slice:tt,
channel: $channel:tt,
min_us: $min_us:expr,
max_us: $max_us:expr,
max_degrees: $max_degrees:expr,
max_steps: $max_steps:expr,
direction: $direction:expr,
fields: [ max_us: $max_us_value:expr ]
) => {
$crate::__servo_player_impl! {
@__fill_defaults
vis: $vis,
name: $name,
pin: $pin,
slice: $slice,
channel: $channel,
min_us: $min_us,
max_us: $max_us_value,
max_degrees: $max_degrees,
max_steps: $max_steps,
direction: $direction,
fields: [ ]
}
};
(@__fill_defaults
vis: $vis:vis,
name: $name:ident,
pin: $pin:tt,
slice: $slice:tt,
channel: $channel:tt,
min_us: $min_us:expr,
max_us: $max_us:expr,
max_degrees: $max_degrees:expr,
max_steps: $max_steps:expr,
direction: $direction:expr,
fields: [ max_degrees: $max_degrees_value:expr $(, $($rest:tt)* )? ]
) => {
$crate::__servo_player_impl! {
@__fill_defaults
vis: $vis,
name: $name,
pin: $pin,
slice: $slice,
channel: $channel,
min_us: $min_us,
max_us: $max_us,
max_degrees: $max_degrees_value,
max_steps: $max_steps,
direction: $direction,
fields: [ $($($rest)*)? ]
}
};
(@__fill_defaults
vis: $vis:vis,
name: $name:ident,
pin: $pin:tt,
slice: $slice:tt,
channel: $channel:tt,
min_us: $min_us:expr,
max_us: $max_us:expr,
max_degrees: $max_degrees:expr,
max_steps: $max_steps:expr,
direction: $direction:expr,
fields: [ max_degrees: $max_degrees_value:expr ]
) => {
$crate::__servo_player_impl! {
@__fill_defaults
vis: $vis,
name: $name,
pin: $pin,
slice: $slice,
channel: $channel,
min_us: $min_us,
max_us: $max_us,
max_degrees: $max_degrees_value,
max_steps: $max_steps,
direction: $direction,
fields: [ ]
}
};
(@__fill_defaults
vis: $vis:vis,
name: $name:ident,
pin: $pin:tt,
slice: $slice:tt,
channel: $channel:tt,
min_us: $min_us:expr,
max_us: $max_us:expr,
max_degrees: $max_degrees:expr,
max_steps: $max_steps:expr,
direction: $direction:expr,
fields: [ max_steps: $max_steps_value:expr $(, $($rest:tt)* )? ]
) => {
$crate::__servo_player_impl! {
@__fill_defaults
vis: $vis,
name: $name,
pin: $pin,
slice: $slice,
channel: $channel,
min_us: $min_us,
max_us: $max_us,
max_degrees: $max_degrees,
max_steps: $max_steps_value,
direction: $direction,
fields: [ $($($rest)*)? ]
}
};
(@__fill_defaults
vis: $vis:vis,
name: $name:ident,
pin: $pin:tt,
slice: $slice:tt,
channel: $channel:tt,
min_us: $min_us:expr,
max_us: $max_us:expr,
max_degrees: $max_degrees:expr,
max_steps: $max_steps:expr,
direction: $direction:expr,
fields: [ max_steps: $max_steps_value:expr ]
) => {
$crate::__servo_player_impl! {
@__fill_defaults
vis: $vis,
name: $name,
pin: $pin,
slice: $slice,
channel: $channel,
min_us: $min_us,
max_us: $max_us,
max_degrees: $max_degrees,
max_steps: $max_steps_value,
direction: $direction,
fields: [ ]
}
};
(@__fill_defaults
vis: $vis:vis,
name: $name:ident,
pin: $pin:tt,
slice: $slice:tt,
channel: $channel:tt,
min_us: $min_us:expr,
max_us: $max_us:expr,
max_degrees: $max_degrees:expr,
max_steps: $max_steps:expr,
direction: $direction:expr,
fields: [ channel: A $(, $($rest:tt)* )? ]
) => {
$crate::__servo_player_impl! {
@__fill_defaults
vis: $vis,
name: $name,
pin: $pin,
slice: $slice,
channel: A,
min_us: $min_us,
max_us: $max_us,
max_degrees: $max_degrees,
max_steps: $max_steps,
direction: $direction,
fields: [ $($($rest)*)? ]
}
};
(@__fill_defaults
vis: $vis:vis,
name: $name:ident,
pin: $pin:tt,
slice: $slice:tt,
channel: $channel:tt,
min_us: $min_us:expr,
max_us: $max_us:expr,
max_degrees: $max_degrees:expr,
max_steps: $max_steps:expr,
direction: $direction:expr,
fields: [ channel: A ]
) => {
$crate::__servo_player_impl! {
@__fill_defaults
vis: $vis,
name: $name,
pin: $pin,
slice: $slice,
channel: A,
min_us: $min_us,
max_us: $max_us,
max_degrees: $max_degrees,
max_steps: $max_steps,
direction: $direction,
fields: [ ]
}
};
(@__fill_defaults
vis: $vis:vis,
name: $name:ident,
pin: $pin:tt,
slice: $slice:tt,
channel: $channel:tt,
min_us: $min_us:expr,
max_us: $max_us:expr,
max_degrees: $max_degrees:expr,
max_steps: $max_steps:expr,
direction: $direction:expr,
fields: [ channel: B $(, $($rest:tt)* )? ]
) => {
$crate::__servo_player_impl! {
@__fill_defaults
vis: $vis,
name: $name,
pin: $pin,
slice: $slice,
channel: B,
min_us: $min_us,
max_us: $max_us,
max_degrees: $max_degrees,
max_steps: $max_steps,
direction: $direction,
fields: [ $($($rest)*)? ]
}
};
(@__fill_defaults
vis: $vis:vis,
name: $name:ident,
pin: $pin:tt,
slice: $slice:tt,
channel: $channel:tt,
min_us: $min_us:expr,
max_us: $max_us:expr,
max_degrees: $max_degrees:expr,
max_steps: $max_steps:expr,
direction: $direction:expr,
fields: [ channel: B ]
) => {
$crate::__servo_player_impl! {
@__fill_defaults
vis: $vis,
name: $name,
pin: $pin,
slice: $slice,
channel: B,
min_us: $min_us,
max_us: $max_us,
max_degrees: $max_degrees,
max_steps: $max_steps,
direction: $direction,
fields: [ ]
}
};
(@__fill_defaults
vis: $vis:vis,
name: $name:ident,
pin: $pin:tt,
slice: $slice:tt,
channel: $channel:tt,
min_us: $min_us:expr,
max_us: $max_us:expr,
max_degrees: $max_degrees:expr,
max_steps: $max_steps:expr,
direction: $direction:expr,
fields: [ even $(, $($rest:tt)* )? ]
) => {
$crate::__servo_player_impl! {
@__fill_defaults
vis: $vis,
name: $name,
pin: $pin,
slice: $slice,
channel: A,
min_us: $min_us,
max_us: $max_us,
max_degrees: $max_degrees,
max_steps: $max_steps,
direction: $direction,
fields: [ $($($rest)*)? ]
}
};
(@__fill_defaults
vis: $vis:vis,
name: $name:ident,
pin: $pin:tt,
slice: $slice:tt,
channel: $channel:tt,
min_us: $min_us:expr,
max_us: $max_us:expr,
max_degrees: $max_degrees:expr,
max_steps: $max_steps:expr,
direction: $direction:expr,
fields: [ even ]
) => {
$crate::__servo_player_impl! {
@__fill_defaults
vis: $vis,
name: $name,
pin: $pin,
slice: $slice,
channel: A,
min_us: $min_us,
max_us: $max_us,
max_degrees: $max_degrees,
max_steps: $max_steps,
direction: $direction,
fields: [ ]
}
};
(@__fill_defaults
vis: $vis:vis,
name: $name:ident,
pin: $pin:tt,
slice: $slice:tt,
channel: $channel:tt,
min_us: $min_us:expr,
max_us: $max_us:expr,
max_degrees: $max_degrees:expr,
max_steps: $max_steps:expr,
direction: $direction:expr,
fields: [ odd $(, $($rest:tt)* )? ]
) => {
$crate::__servo_player_impl! {
@__fill_defaults
vis: $vis,
name: $name,
pin: $pin,
slice: $slice,
channel: B,
min_us: $min_us,
max_us: $max_us,
max_degrees: $max_degrees,
max_steps: $max_steps,
direction: $direction,
fields: [ $($($rest)*)? ]
}
};
(@__fill_defaults
vis: $vis:vis,
name: $name:ident,
pin: $pin:tt,
slice: $slice:tt,
channel: $channel:tt,
min_us: $min_us:expr,
max_us: $max_us:expr,
max_degrees: $max_degrees:expr,
max_steps: $max_steps:expr,
direction: $direction:expr,
fields: [ odd ]
) => {
$crate::__servo_player_impl! {
@__fill_defaults
vis: $vis,
name: $name,
pin: $pin,
slice: $slice,
channel: B,
min_us: $min_us,
max_us: $max_us,
max_degrees: $max_degrees,
max_steps: $max_steps,
direction: $direction,
fields: [ ]
}
};
(@__fill_defaults
vis: $vis:vis,
name: $name:ident,
pin: $pin:tt,
slice: $slice:tt,
channel: $channel:tt,
min_us: $min_us:expr,
max_us: $max_us:expr,
max_degrees: $max_degrees:expr,
max_steps: $max_steps:expr,
direction: $direction:expr,
fields: [ direction: $new_direction:expr $(, $($rest:tt)* )? ]
) => {
$crate::__servo_player_impl! {
@__fill_defaults
vis: $vis,
name: $name,
pin: $pin,
slice: $slice,
channel: $channel,
min_us: $min_us,
max_us: $max_us,
max_degrees: $max_degrees,
max_steps: $max_steps,
direction: $new_direction,
fields: [ $($($rest)*)? ]
}
};
(@__fill_defaults
vis: $vis:vis,
name: $name:ident,
pin: $pin:tt,
slice: $slice:tt,
channel: $channel:tt,
min_us: $min_us:expr,
max_us: $max_us:expr,
max_degrees: $max_degrees:expr,
max_steps: $max_steps:expr,
direction: $direction:expr,
fields: [ ]
) => {
$crate::__servo_player_impl! {
@__build
vis: $vis,
name: $name,
pin: $pin,
slice: $slice,
channel: $channel,
min_us: $min_us,
max_us: $max_us,
max_degrees: $max_degrees,
max_steps: $max_steps,
direction: $direction
}
};
(@__build
vis: $vis:vis,
name: $name:ident,
pin: _UNSET_,
slice: $slice:tt,
channel: $channel:tt,
min_us: $min_us:expr,
max_us: $max_us:expr,
max_degrees: $max_degrees:expr,
max_steps: $max_steps:expr,
direction: $direction:expr
) => {
compile_error!("servo_player! requires `pin: ...`");
};
(@__build
vis: $vis:vis,
name: $name:ident,
pin: $pin:ident,
slice: _UNSET_,
channel: $channel:tt,
min_us: $min_us:expr,
max_us: $max_us:expr,
max_degrees: $max_degrees:expr,
max_steps: $max_steps:expr,
direction: $direction:expr
) => {
$crate::servo::paste::paste! {
static [<$name:upper _SERVO_PLAYER_STATIC>]: $crate::servo::ServoPlayerStatic<$max_steps> =
$crate::servo::ServoPlayerHandle::<$max_steps>::new_static();
static [<$name:upper _SERVO_PLAYER_CELL>]: ::static_cell::StaticCell<$name> =
::static_cell::StaticCell::new();
#[allow(missing_docs)]
$vis struct $name {
servo_player_handle: $crate::servo::ServoPlayerHandle<$max_steps>,
}
#[allow(missing_docs)]
impl $name {
pub const MAX_STEPS: usize = $max_steps;
pub fn new<S: 'static>(
pin: impl Into<::embassy_rp::Peri<'static, ::embassy_rp::peripherals::$pin>>,
slice: impl Into<::embassy_rp::Peri<'static, S>>,
spawner: ::embassy_executor::Spawner,
) -> $crate::Result<&'static Self>
where
::embassy_rp::peripherals::$pin: $crate::servo::ServoPwmPin<S>,
S: ::embassy_rp::PeripheralType,
{
let pin = pin.into();
let slice = slice.into();
let servo = $crate::servo::servo_from_pin_slice(
pin,
slice,
$min_us,
$max_us,
$max_degrees,
$direction
);
let token = [<$name:snake _servo_player_task>](&[<$name:upper _SERVO_PLAYER_STATIC>], servo);
spawner.spawn(token?);
let servo_player_handle =
$crate::servo::ServoPlayerHandle::new(&[<$name:upper _SERVO_PLAYER_STATIC>]);
Ok([<$name:upper _SERVO_PLAYER_CELL>].init(Self { servo_player_handle }))
}
}
impl $crate::servo::Servo for $name {
const DEFAULT_MAX_DEGREES: u16 = $max_degrees;
fn set_degrees(&self, degrees: u16) {
$crate::servo::__servo_player_set_degrees(&self.servo_player_handle, degrees);
}
fn hold(&self) {
$crate::servo::__servo_player_hold(&self.servo_player_handle);
}
fn relax(&self) {
$crate::servo::__servo_player_relax(&self.servo_player_handle);
}
}
impl $crate::servo::ServoPlayer<$max_steps> for $name {
const MAX_STEPS: usize = Self::MAX_STEPS;
fn animate<I>(&self, steps: I, at_end: $crate::servo::AtEnd)
where
I: ::core::iter::IntoIterator,
I::Item: ::core::borrow::Borrow<(u16, ::embassy_time::Duration)>,
{
$crate::servo::__servo_player_animate(&self.servo_player_handle, steps, at_end);
}
}
#[::embassy_executor::task]
async fn [<$name:snake _servo_player_task>](
servo_player_static: &'static $crate::servo::ServoPlayerStatic<$max_steps>,
servo: $crate::servo::ServoRp<'static>,
) -> ! {
$crate::servo::device_loop(servo_player_static, servo).await
}
}
};
(@__build
vis: $vis:vis,
name: $name:ident,
pin: $pin:ident,
slice: $slice:ident,
channel: $channel:tt,
min_us: $min_us:expr,
max_us: $max_us:expr,
max_degrees: $max_degrees:expr,
max_steps: $max_steps:expr,
direction: $direction:expr
) => {
$crate::servo::paste::paste! {
static [<$name:upper _SERVO_PLAYER_STATIC>]: $crate::servo::ServoPlayerStatic<$max_steps> =
$crate::servo::ServoPlayerHandle::<$max_steps>::new_static();
static [<$name:upper _SERVO_PLAYER_CELL>]: ::static_cell::StaticCell<$name> =
::static_cell::StaticCell::new();
#[allow(missing_docs)]
$vis struct $name {
servo_player_handle: $crate::servo::ServoPlayerHandle<$max_steps>,
}
#[allow(missing_docs)]
impl $name {
pub const MAX_STEPS: usize = $max_steps;
pub fn new(
pin: impl Into<::embassy_rp::Peri<'static, ::embassy_rp::peripherals::$pin>>,
slice: impl Into<::embassy_rp::Peri<'static, ::embassy_rp::peripherals::$slice>>,
spawner: ::embassy_executor::Spawner,
) -> $crate::Result<&'static Self> {
let pin = pin.into();
let slice = slice.into();
let servo = $crate::__servo_player_impl! {
@__build_servo
pin: pin,
slice: slice,
channel: $channel,
min_us: $min_us,
max_us: $max_us,
max_degrees: $max_degrees,
max_steps: $max_steps,
direction: $direction
};
let token = [<$name:snake _servo_player_task>](&[<$name:upper _SERVO_PLAYER_STATIC>], servo);
spawner.spawn(token?);
let servo_player_handle =
$crate::servo::ServoPlayerHandle::new(&[<$name:upper _SERVO_PLAYER_STATIC>]);
Ok([<$name:upper _SERVO_PLAYER_CELL>].init(Self { servo_player_handle }))
}
}
impl $crate::servo::Servo for $name {
const DEFAULT_MAX_DEGREES: u16 = $max_degrees;
fn set_degrees(&self, degrees: u16) {
$crate::servo::__servo_player_set_degrees(&self.servo_player_handle, degrees);
}
fn hold(&self) {
$crate::servo::__servo_player_hold(&self.servo_player_handle);
}
fn relax(&self) {
$crate::servo::__servo_player_relax(&self.servo_player_handle);
}
}
impl $crate::servo::ServoPlayer<$max_steps> for $name {
const MAX_STEPS: usize = Self::MAX_STEPS;
fn animate<I>(&self, steps: I, at_end: $crate::servo::AtEnd)
where
I: ::core::iter::IntoIterator,
I::Item: ::core::borrow::Borrow<(u16, ::embassy_time::Duration)>,
{
$crate::servo::__servo_player_animate(&self.servo_player_handle, steps, at_end);
}
}
#[::embassy_executor::task]
async fn [<$name:snake _servo_player_task>](
servo_player_static: &'static $crate::servo::ServoPlayerStatic<$max_steps>,
servo: $crate::servo::ServoRp<'static>,
) -> ! {
$crate::servo::device_loop(servo_player_static, servo).await
}
}
};
(@__build_servo
pin: $pin:expr,
slice: $slice:expr,
channel: _UNSET_,
min_us: $min_us:expr,
max_us: $max_us:expr,
max_degrees: $max_degrees:expr,
max_steps: $max_steps:expr,
direction: $direction:expr
) => {
$crate::servo::servo_from_pin_slice(
$pin,
$slice,
$min_us,
$max_us,
$max_degrees,
$direction,
)
};
(@__build_servo
pin: $pin:expr,
slice: $slice:expr,
channel: A,
min_us: $min_us:expr,
max_us: $max_us:expr,
max_degrees: $max_degrees:expr,
max_steps: $max_steps:expr,
direction: $direction:expr
) => {
$crate::servo::ServoRp::new_output_a(
embassy_rp::pwm::Pwm::new_output_a(
$slice,
$pin,
embassy_rp::pwm::Config::default(),
),
$min_us,
$max_us,
$max_degrees,
$direction,
)
};
(@__build_servo
pin: $pin:expr,
slice: $slice:expr,
channel: B,
min_us: $min_us:expr,
max_us: $max_us:expr,
max_degrees: $max_degrees:expr,
max_steps: $max_steps:expr,
direction: $direction:expr
) => {
$crate::servo::ServoRp::new_output_b(
embassy_rp::pwm::Pwm::new_output_b(
$slice,
$pin,
embassy_rp::pwm::Config::default(),
),
$min_us,
$max_us,
$max_degrees,
$direction,
)
};
(
$($fields:tt)*
) => {
$crate::__servo_player_impl! {
@__fill_defaults
vis: pub(self),
name: ServoPlayerGenerated,
pin: _UNSET_,
slice: _UNSET_,
channel: _UNSET_,
min_us: $crate::servo::SERVO_MIN_US_DEFAULT,
max_us: $crate::servo::SERVO_MAX_US_DEFAULT,
max_degrees: $crate::servo::ServoRp::DEFAULT_MAX_DEGREES,
max_steps: 16,
direction: $crate::servo::Direction::Forward,
fields: [ $($fields)* ]
}
};
}