Skip to content

Commit

Permalink
Add the now-working AllegroRegister derive macro
Browse files Browse the repository at this point in the history
  • Loading branch information
johngigantic committed Oct 27, 2023
1 parent 51f8418 commit 2bb7c38
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 141 deletions.
167 changes: 71 additions & 96 deletions derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,68 +10,85 @@ use syn::{parse_macro_input, DeriveInput};

mod chips;

#[proc_macro_derive(Messages)]
pub fn spi_message_derive(item: TokenStream) -> TokenStream {
let DeriveInput {ident, attrs, ..} = parse_macro_input!(item as DeriveInput);
// #[proc_macro_derive(AllegroRegister)]
// pub fn allegro_derive(item: TokenStream) -> TokenStream {
// let DeriveInput {ident, attrs, ..} = parse_macro_input!(item as DeriveInput);

let bitsize = analyze_bitsize(&attrs);

quote! {
impl crate::io::spi::Messages for #ident {

}
}.into()
}

// /// Derive macro to implement the allegro_motor_drivers::io::SpiMessages trait.
// ///
// /// Please note that a compile failure will occur if derive macros are defined in the wrong order,
// /// or if the bitsize derive macro is not used at all. This occurs because derive macros are parsed
// /// from the outside in, and each macro depends on implementations defined by other macros.
// /// ```compile_fail
// /// #[allegro_register(chip = "a4910")]
// /// struct MyStruct {
// /// field_1: bool,
// /// }
// /// ```
// ///
// /// ```compile_fail
// /// #[bitsize(1)]
// /// #[allegro_register(chip = "a4910")]
// /// struct MyStruct {
// /// field_1: bool,
// /// }
// /// ```
// ///
// #[proc_macro_attribute]
// pub fn allegro_register(macro_args: TokenStream, item: TokenStream) -> TokenStream {
// // let original_struct = proc_macro2::TokenStream::from(item.clone());
// let DeriveInput { attrs, .. } = parse_macro_input!(macro_args as DeriveInput);
// let original_struct = parse_macro_input!(item as DeriveInput);
// let ident = syn::Ident::new(&original_struct.ident.to_string(), proc_macro2::Span::call_site());


// let chip = match analyze_chip(&attrs) {
// Ok(chip_name) => chip_name,
// Err(error_message) => return error_message.to_compile_error().into(),
// };

// let read_request_function = generate_read_request(chip.register_size, chip.parity);
// let read_response_function = generate_read_response(chip.register_size, chip.parity);
// let write_request_function = generate_write_request(chip.register_size, chip.parity);
// let bitsize = analyze_bitsize(&attrs);

// quote! {
// #original_struct
// impl crate::regs::AllegroRegister<bilge::prelude::UInt<usize, #bitsize>> for #ident {
// fn get_value(&self) -> u16 {
// self.value.into()
// }

// fn set_value(&mut self, value: bilge::prelude::UInt<usize, #bitsize>) {
// self.value = value;
// }
// }
// }.into()
// }

// impl crate::io::spi::Messages for #ident {
// #read_request_function
// #read_response_function
// #write_request_function
// fn analyze_bitsize(attrs: &Vec<syn::Attribute>) -> u16 {
// let mut bitsizes = attrs.iter().filter_map(|attr| {
// if attr.path().is_ident("bitsize") {
// let a: syn::LitInt = attr.parse_args().unwrap();
// Some(a.base10_parse::<u16>().unwrap())
// } else {
// None
// }
// });

// match bitsizes.next() {
// Some(bitsize) => bitsize,
// None => panic!("'bitsize' not found in object attributes."),
// }
// .into()
// }


/// Derive macro to implement the allegro_motor_drivers::regs::AllegroRegister trait.
///
/// Please note that a compile failure will occur if derive macros are defined in the wrong order,
/// or if the bitsize derive macro is not used at all. This occurs because derive macros are parsed
/// from the outside in, and each macro depends on implementations defined by other macros.
/// ```compile_fail
/// #[allegro_register(chip = "a4910")]
/// struct MyStruct {
/// field_1: bool,
/// }
/// ```
///
/// ```compile_fail
/// #[bitsize(1)]
/// #[allegro_register(chip = "a4910")]
/// struct MyStruct {
/// field_1: bool,
/// }
/// ```
///
#[proc_macro_derive(AllegroRegister)]
pub fn allegro_derive(item: TokenStream) -> TokenStream {
let DeriveInput { ident, .. } = parse_macro_input!(item as DeriveInput);

let source_file = proc_macro::Span::call_site().source_file().clone().path();
let chip_name = source_file.iter().nth(2).unwrap().to_str().unwrap();
let chip = chips::CHIPS.into_iter().find(|chip| {chip.name == chip_name}).unwrap();
let bitsize = proc_macro2::Literal::u16_unsuffixed(chip.register_size);

quote! {
impl crate::regs::AllegroRegister<bilge::prelude::UInt<u16, #bitsize>> for #ident {
fn get_value(&self) -> u16 {
self.value.into()
}

fn set_value(&mut self, value: bilge::prelude::UInt<u16, #bitsize>) {
self.value = value;
}
}
}
.into()
}

// fn analyze_chip(attrs: &[syn::Attribute]) -> Result<chips::Chip, syn::Error> {
// let mut selected_chip = chips::Chip::default();

Expand All @@ -96,45 +113,3 @@ pub fn spi_message_derive(item: TokenStream) -> TokenStream {
// }
// Ok(selected_chip)
// }

fn generate_read_request(chip: &chips::Chip) -> proc_macro2::TokenStream {
let address_size: u16 = 16 - (1 + chip.register_size + (chip.parity as u16));

quote! {
fn read_request(&self) -> u16 {
return 0;
}
}
}

fn generate_read_response(chip: &chips::Chip) -> proc_macro2::TokenStream {
quote! {
fn read_response(&mut self, value: u16) {

}
}
}

fn generate_write_request(chip: &chips::Chip) -> proc_macro2::TokenStream {
quote! {
fn write_request(&self) -> u16 {
0
}
}
}

fn analyze_bitsize(attrs: &Vec<syn::Attribute>) -> u16 {
let mut bitsizes = attrs.iter().filter_map(|attr| {
if attr.path().is_ident("bitsize") {
let a: syn::LitInt = attr.parse_args().unwrap();
Some(a.base10_parse::<u16>().unwrap())
} else {
None
}
});

match bitsizes.next() {
Some(bitsize) => bitsize,
None => panic!("'bitsize' not found in object attributes."),
}
}
27 changes: 4 additions & 23 deletions drivers/src/a4910/regs/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
extern crate allegro_motor_derive;

use allegro_motor_derive::AllegroRegister;
use bilge::prelude::*;

use crate::regs::{AllegroRegister, ConstantAddress};
use crate::regs::ConstantAddress;
use super::A4910Reg;

#[bitsize(6)]
Expand Down Expand Up @@ -78,28 +79,18 @@ impl Default for VdsThreshold {
}

#[bitsize(13)]
#[derive(PartialEq, Clone, Copy, DebugBits, DefaultBits, FromBits)]
#[derive(PartialEq, Clone, Copy, DebugBits, DefaultBits, FromBits, AllegroRegister)]
pub struct Config0 {
pub dt: DeadTime,
pub bt: FaultBlankingTime,
}

impl AllegroRegister<u13> for Config0 {
fn get_value(&self) -> u16 {
self.value.into()
}

fn set_value(&mut self, value: u13) {
self.value = value
}
}

impl ConstantAddress<A4910Reg> for Config0 {
const ADDRESS: A4910Reg = A4910Reg::Config0;
}

#[bitsize(13)]
#[derive(PartialEq, Clone, Copy, DebugBits, DefaultBits, FromBits)]
#[derive(PartialEq, Clone, Copy, DebugBits, DefaultBits, FromBits, AllegroRegister)]
pub struct Config1 {
pub vt: VdsThreshold,
reserved: u1,
Expand All @@ -109,16 +100,6 @@ pub struct Config1 {
pub csb: CurrentSenseBandwidth,
}

impl AllegroRegister<u13> for Config1 {
fn get_value(&self) -> u16 {
self.value.into()
}

fn set_value(&mut self, value: u13) {
self.value = value
}
}

impl ConstantAddress<A4910Reg> for Config1 {
const ADDRESS: A4910Reg = A4910Reg::Config1;
}
Expand Down
15 changes: 3 additions & 12 deletions drivers/src/a4910/regs/mask.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@
//!
//! The mask register enables or disables detection of various faults.
use allegro_motor_derive::AllegroRegister;
use bilge::prelude::*;

use crate::regs::{AllegroRegister, ConstantAddress};
use crate::regs::ConstantAddress;
use super::A4910Reg;

#[bitsize(13)]
#[derive(PartialEq, Clone, Copy, DebugBits, Default, FromBits)]
#[derive(PartialEq, Clone, Copy, DebugBits, Default, FromBits, AllegroRegister)]
pub struct Mask {
pub cl: bool,
pub ch: bool,
Expand All @@ -25,16 +26,6 @@ pub struct Mask {
reserved: u1,
}

impl AllegroRegister<u13> for Mask {
fn get_value(&self) -> u16 {
self.value.into()
}

fn set_value(&mut self, value: u13) {
self.value = value;
}
}

impl ConstantAddress<A4910Reg> for Mask {
const ADDRESS: A4910Reg = A4910Reg::Mask;
}
21 changes: 11 additions & 10 deletions drivers/src/a4910/regs/run.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
//! Run configuration register
use bilge::prelude::*;
use allegro_motor_derive::AllegroRegister;

use crate::regs::{AllegroRegister, ConstantAddress};
use crate::regs::ConstantAddress;
use super::A4910Reg;

#[bitsize(13)]
#[derive(PartialEq, Clone, Copy, DebugBits, Default, FromBits)]
#[derive(PartialEq, Clone, Copy, DebugBits, Default, FromBits, AllegroRegister)]
pub struct Run {
pub cl: bool,
pub ch: bool,
Expand All @@ -17,15 +18,15 @@ pub struct Run {
reserved: u7,
}

impl AllegroRegister<u13> for Run {
fn get_value(&self) -> u16 {
self.value.into()
}
// impl AllegroRegister<u13> for Run {
// fn get_value(&self) -> u16 {
// self.value.into()
// }

fn set_value(&mut self, value: u13) {
self.value = value;
}
}
// fn set_value(&mut self, value: u13) {
// self.value = value;
// }
// }

impl ConstantAddress<A4910Reg> for Run {
const ADDRESS: A4910Reg = A4910Reg::Run;
Expand Down

0 comments on commit 2bb7c38

Please sign in to comment.