Skip to content

Instantly share code, notes, and snippets.

@CirrusNeptune
Created May 30, 2021 20:42
Show Gist options
  • Save CirrusNeptune/898881b0520183cc734af9cebb46effe to your computer and use it in GitHub Desktop.
Save CirrusNeptune/898881b0520183cc734af9cebb46effe to your computer and use it in GitHub Desktop.
// This is used in tandem with a proc_macro derived from a command enum.
// The proc_macro contains the actual macro_rules! mpsse {...} extended with
// generated abstractions (yes this works!!!)
#[macro_export]
macro_rules! __mpsse_base {
// ftdi <=> { command1(); command2(); ... commandN(); };
($ft:ident <=> {$($commands:tt)*}; $($tail:tt)*) => {
mpsse!(((let, (@cc1101 $ft, __buf, (), {})), 0) {$($commands)*} -> []);
mpsse!($($tail)*);
};
// Practical abstraction of CS line for SPI devices.
($passthru:tt {cs_low(); $($tail:tt)*} -> [$($out:tt)*]) => {
mpsse!($passthru {set_gpio_lower(0x0, 0xb); $($tail)*} -> [$($out)*]);
};
($passthru:tt {cs_high(); $($tail:tt)*} -> [$($out:tt)*]) => {
mpsse!($passthru {set_gpio_lower(0x8, 0xb); $($tail)*} -> [$($out)*]);
};
// Send command
($passthru:tt {command_strobe($cmd:expr); $($tail:tt)*} -> [$($out:tt)*]) => {
::tracing::trace!(">CC1101 {:?}", $cmd as ::libftd2xx_cc1101::Command);
mpsse!($passthru {
cs_low();
clock_bits_out(::libftd2xx::ClockBitsOut::MsbNeg, $cmd, 8);
cs_high();
$($tail)*
} -> [$($out)*]);
};
// Send command and read status
((($const_let:tt, (@cc1101 $ft:tt, $buf:ident, ($($ret_ids:ident,)*), {$($post_reads:tt)*})), $read_len:expr)
{let $stat_id:ident = command_strobe($cmd:expr); $($tail:tt)*} -> [$($out:tt)*]) => {
::tracing::trace!(">CC1101 {:?}", $cmd as ::libftd2xx_cc1101::Command);
mpsse!((($const_let, (@cc1101 $ft, $buf, ($($ret_ids,)* $stat_id,), {
$($post_reads)*
let $stat_id = ::libftd2xx_cc1101::Status::from_bytes([$buf[$read_len]]);
::tracing::trace!("<CC1101 {:?}", $stat_id);
})), $read_len) {
cs_low();
clock_bits(::libftd2xx::ClockBits::MsbPosIn, $cmd, 8);
cs_high();
$($tail)*
} -> [$($out)*]);
};
// Perform write only without returns
((($_const_let:tt, (@cc1101 $ft:tt, $buf:ident, (), {$($post_reads:tt)*})), 0)
{} -> [$($out:tt)*]) => {
{
$ft.write_all(&[$($out)*]).unwrap();
$($post_reads)*
}
};
// Perform write/read without returns
((($_const_let:tt, (@cc1101 $ft:tt, $buf:ident, (), {$($post_reads:tt)*})), $read_len:expr)
{} -> [$($out:tt)*]) => {
{
$ft.write_all(&[$($out)* ::libftd2xx::MpsseCmd::SendImmediate as u8]).unwrap();
let mut $buf: [u8; $read_len] = [0; $read_len];
$ft.read_all(&mut $buf).unwrap();
$($post_reads)*
};
};
// Perform write only with returns
((($_const_let:tt, (@cc1101 $ft:tt, $buf:ident, ($($ret_ids:ident,)*), {$($post_reads:tt)*})), 0)
{} -> [$($out:tt)*]) => {
let ($($ret_ids,)*) = {
$ft.write_all(&[$($out)*]).unwrap();
$($post_reads)*
($($ret_ids,)*)
}
};
// Perform write/read with returns
((($_const_let:tt, (@cc1101 $ft:tt, $buf:ident, ($($ret_ids:ident,)*), {$($post_reads:tt)*})), $read_len:expr)
{} -> [$($out:tt)*]) => {
let ($($ret_ids,)*) = {
$ft.write_all(&[$($out)* ::libftd2xx::MpsseCmd::SendImmediate as u8]).unwrap();
let mut $buf: [u8; $read_len] = [0; $read_len];
$ft.read_all(&mut $buf).unwrap();
$($post_reads)*
($($ret_ids,)*)
};
};
// Everything else handled by libftd2xx crate implementation.
($($tokens:tt)*) => {
::libftd2xx::mpsse!($($tokens)*);
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment