tmc2209/
reg.rs

1//! Declaration of the TMC2209 registers and their implementations.
2//!
3//! Please refer to the TMC2209 datasheet for information on what each of these registers and their
4//! fields mean. The register map is described under section 5 of the datasheet.
5//!
6//! https://www.trinamic.com/fileadmin/assets/Products/ICs_Documents/TMC2209_Datasheet_V103.pdf
7
8#![allow(non_camel_case_types)]
9
10// Register Traits
11// --------------------------------------------------------
12
13/// Implemented for all register types.
14///
15/// NOTE: This should not be implemented for custom types. If the user attempts to request a custom
16/// register type from the register `Map`, the method call will hang indefinitely.
17pub trait Register: Into<State> {
18    const ADDRESS: Address;
19}
20
21/// Implemented for all registers that can be read from.
22pub trait ReadableRegister: Register + From<u32> {}
23
24/// Implemented for all registers that can be written to.
25pub trait WritableRegister: Register + Into<u32> {}
26
27/// An error that might occur in the case that an address could not be parsed.
28#[derive(Debug)]
29#[cfg_attr(feature = "ufmt", derive(ufmt::derive::uDebug))]
30pub struct UnknownAddress;
31
32/// An error indicating an unexpected `State`.
33#[derive(Debug)]
34#[cfg_attr(feature = "ufmt", derive(ufmt::derive::uDebug))]
35pub struct UnexpectedAddress;
36
37// Register Declarations
38// --------------------------------------------------------
39
40bitfield! {
41    #[derive(Clone, Copy, Eq, Hash, PartialEq)]
42    #[cfg_attr(feature = "hash", derive(hash32_derive::Hash32))]
43    #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
44    #[cfg_attr(feature = "ufmt", derive(ufmt::derive::uDebug))]
45    pub struct GCONF(u32);
46    impl Debug;
47    u16;
48    pub i_scale_analog, set_i_scale_analog: 0;
49    pub internal_rsense, set_internal_rsense: 1;
50    pub en_spread_cycle, set_en_spread_cycle: 2;
51    pub shaft, set_shaft: 3;
52    pub index_otpw, set_index_otpw: 4;
53    pub index_step, set_index_step: 5;
54    pub pdn_disable, set_pdn_disable: 6;
55    pub mstep_reg_select, set_mstep_reg_select: 7;
56    pub multistep_filt, set_multistep_filt: 8;
57    pub test_mode, set_test_mode: 9;
58}
59
60bitfield! {
61    #[derive(Clone, Copy, Default, Eq, Hash, PartialEq)]
62    #[cfg_attr(feature = "hash", derive(hash32_derive::Hash32))]
63    #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
64    #[cfg_attr(feature = "ufmt", derive(ufmt::derive::uDebug))]
65    pub struct GSTAT(u32);
66    impl Debug;
67    u8;
68    pub reset, _: 0;
69    pub drv_err, _: 1;
70    pub uv_cp, _: 2;
71}
72
73#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
74#[cfg_attr(feature = "hash", derive(hash32_derive::Hash32))]
75#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
76#[cfg_attr(feature = "ufmt", derive(ufmt::derive::uDebug))]
77pub struct IFCNT(pub u32);
78
79bitfield! {
80    #[derive(Clone, Copy, Default, Eq, Hash, PartialEq)]
81    #[cfg_attr(feature = "hash", derive(hash32_derive::Hash32))]
82    #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
83    #[cfg_attr(feature = "ufmt", derive(ufmt::derive::uDebug))]
84    pub struct SLAVECONF(u32);
85    impl Debug;
86    u8;
87    pub get, set: 11, 8;
88}
89
90bitfield! {
91    #[derive(Clone, Copy, Default, Eq, Hash, PartialEq)]
92    #[cfg_attr(feature = "hash", derive(hash32_derive::Hash32))]
93    #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
94    #[cfg_attr(feature = "ufmt", derive(ufmt::derive::uDebug))]
95    pub struct OTP_PROG(u32);
96    impl Debug;
97    u16;
98    pub otp_bit, set_otp_bit: 2, 0;
99    pub otp_byte, set_otp_byte: 5, 4;
100    pub opt_magic, set_otp_magic: 15, 8;
101}
102
103bitfield! {
104    #[derive(Clone, Copy, Default, Eq, Hash, PartialEq)]
105    #[cfg_attr(feature = "hash", derive(hash32_derive::Hash32))]
106    #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
107    #[cfg_attr(feature = "ufmt", derive(ufmt::derive::uDebug))]
108    pub struct OTP_READ(u32);
109    impl Debug;
110    u8;
111    pub otp_fclktrim, _: 4, 0;
112    pub otp_ottrim, _: 5;
113    pub otp_internal_rsense, _: 6;
114    pub otp_tbl, _: 7;
115    pub otp_pwm_grad, _: 11, 8;
116    pub otp_pwm_autograd, _: 12;
117    pub otp_tpwmthrs, _: 15, 13;
118    pub otp_pwm_ofs, _: 16;
119    pub otp_pwm_reg, _: 17;
120    pub otp_pwm_freq, _: 18;
121    pub otp_iholdddelay, _: 20, 19;
122    pub otp_ihold, _: 22, 21;
123    pub otp_en_spread_cycle, _: 23;
124}
125
126bitfield! {
127    #[derive(Clone, Copy, Default, Eq, Hash, PartialEq)]
128    #[cfg_attr(feature = "hash", derive(hash32_derive::Hash32))]
129    #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
130    #[cfg_attr(feature = "ufmt", derive(ufmt::derive::uDebug))]
131    pub struct IOIN(u32);
132    impl Debug;
133    u16;
134    pub enn, _: 0;
135    pub ms1, _: 2;
136    pub ms2, _: 3;
137    pub diag, _: 4;
138    pub pdn_uart, _: 6;
139    pub step, _: 7;
140    pub spread_en, _: 8;
141    pub dir, _: 9;
142    u8;
143    pub version, _: 31, 24;
144}
145
146bitfield! {
147    #[derive(Clone, Copy, Default, Eq, Hash, PartialEq)]
148    #[cfg_attr(feature = "hash", derive(hash32_derive::Hash32))]
149    #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
150    #[cfg_attr(feature = "ufmt", derive(ufmt::derive::uDebug))]
151    pub struct FACTORY_CONF(u32);
152    impl Debug;
153    u8;
154    pub fclktrim, set_fclktrim: 4, 0;
155    pub ottrim, set_ottrim: 9, 8;
156}
157
158bitfield! {
159    #[derive(Clone, Copy, Eq, Hash, PartialEq)]
160    #[cfg_attr(feature = "hash", derive(hash32_derive::Hash32))]
161    #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
162    #[cfg_attr(feature = "ufmt", derive(ufmt::derive::uDebug))]
163    pub struct IHOLD_IRUN(u32);
164    impl Debug;
165    u8;
166    pub ihold, set_ihold: 4, 0;
167    pub irun, set_irun: 12, 8;
168    pub ihold_delay, set_ihold_delay: 19, 16;
169}
170
171#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
172#[cfg_attr(feature = "hash", derive(hash32_derive::Hash32))]
173#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
174#[cfg_attr(feature = "ufmt", derive(ufmt::derive::uDebug))]
175pub struct TPOWERDOWN(pub u32);
176
177bitfield! {
178    #[derive(Clone, Copy, Default, Eq, Hash, PartialEq)]
179    #[cfg_attr(feature = "hash", derive(hash32_derive::Hash32))]
180    #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
181    #[cfg_attr(feature = "ufmt", derive(ufmt::derive::uDebug))]
182    pub struct TSTEP(u32);
183    impl Debug;
184    u32;
185    pub get, _: 19, 0;
186}
187
188bitfield! {
189    #[derive(Clone, Copy, Default, Eq, Hash, PartialEq)]
190    #[cfg_attr(feature = "hash", derive(hash32_derive::Hash32))]
191    #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
192    #[cfg_attr(feature = "ufmt", derive(ufmt::derive::uDebug))]
193    pub struct TPWMTHRS(u32);
194    impl Debug;
195    u32;
196    pub get, set: 19, 0;
197}
198
199bitfield! {
200    #[derive(Clone, Copy, Default, Eq, Hash, PartialEq)]
201    #[cfg_attr(feature = "hash", derive(hash32_derive::Hash32))]
202    #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
203    #[cfg_attr(feature = "ufmt", derive(ufmt::derive::uDebug))]
204    pub struct VACTUAL(u32);
205    impl Debug;
206    i32;
207    pub get, set: 23, 0;
208}
209
210bitfield! {
211    #[derive(Clone, Copy, Default, Eq, Hash, PartialEq)]
212    #[cfg_attr(feature = "hash", derive(hash32_derive::Hash32))]
213    #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
214    #[cfg_attr(feature = "ufmt", derive(ufmt::derive::uDebug))]
215    pub struct TCOOLTHRS(u32);
216    impl Debug;
217    u32;
218    pub get, set: 19, 0;
219}
220
221#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
222#[cfg_attr(feature = "hash", derive(hash32_derive::Hash32))]
223#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
224#[cfg_attr(feature = "ufmt", derive(ufmt::derive::uDebug))]
225pub struct SGTHRS(pub u32);
226
227bitfield! {
228    #[derive(Clone, Copy, Default, Eq, Hash, PartialEq)]
229    #[cfg_attr(feature = "hash", derive(hash32_derive::Hash32))]
230    #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
231    #[cfg_attr(feature = "ufmt", derive(ufmt::derive::uDebug))]
232    pub struct SG_RESULT(u32);
233    impl Debug;
234    u16;
235    pub get, _: 9, 0;
236}
237
238bitfield! {
239    #[derive(Clone, Copy, Default, Eq, Hash, PartialEq)]
240    #[cfg_attr(feature = "hash", derive(hash32_derive::Hash32))]
241    #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
242    #[cfg_attr(feature = "ufmt", derive(ufmt::derive::uDebug))]
243    pub struct COOLCONF(u32);
244    impl Debug;
245    u16;
246    pub semin, set_semin: 3, 0;
247    pub seup, set_seup: 6, 5;
248    pub semax, set_semax: 11, 8;
249    pub sedn, set_sedn: 14, 13;
250    pub seimin, set_seimin: 15;
251}
252
253bitfield! {
254    #[derive(Clone, Copy, Default, Eq, Hash, PartialEq)]
255    #[cfg_attr(feature = "hash", derive(hash32_derive::Hash32))]
256    #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
257    #[cfg_attr(feature = "ufmt", derive(ufmt::derive::uDebug))]
258    pub struct MSCNT(u32);
259    impl Debug;
260    u16;
261    pub get, _: 9, 0;
262}
263
264bitfield! {
265    #[derive(Clone, Copy, Default, Eq, Hash, PartialEq)]
266    #[cfg_attr(feature = "hash", derive(hash32_derive::Hash32))]
267    #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
268    #[cfg_attr(feature = "ufmt", derive(ufmt::derive::uDebug))]
269    pub struct MSCURACT(u32);
270    impl Debug;
271    u16;
272    pub cur_a, _: 8, 0;
273    pub cur_b, _: 24, 16;
274}
275
276bitfield! {
277    #[derive(Clone, Copy, Eq, Hash, PartialEq)]
278    #[cfg_attr(feature = "hash", derive(hash32_derive::Hash32))]
279    #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
280    #[cfg_attr(feature = "ufmt", derive(ufmt::derive::uDebug))]
281    pub struct CHOPCONF(u32);
282    impl Debug;
283    u32;
284    pub toff, set_toff: 3, 0;
285    pub hstrt, set_hstrt: 6, 4;
286    pub hend, set_hend: 10, 7;
287    pub tbl, set_tbl: 16, 15;
288    pub vsense, set_vsense: 17;
289    pub mres, set_mres: 27, 24;
290    pub ntpol, set_intpol: 28;
291    pub dedge, set_dedge: 29;
292    pub diss2g, set_diss2g: 30;
293    pub diss2vs, set_diss2vs: 31;
294}
295
296bitfield! {
297    #[derive(Clone, Copy, Default, Eq, Hash, PartialEq)]
298    #[cfg_attr(feature = "hash", derive(hash32_derive::Hash32))]
299    #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
300    #[cfg_attr(feature = "ufmt", derive(ufmt::derive::uDebug))]
301    pub struct DRV_STATUS(u32);
302    impl Debug;
303    u32;
304    pub otpw, _: 0;
305    pub ot, _: 1;
306    pub s2ga, _: 2;
307    pub s2gb, _: 3;
308    pub s2vsa, _: 4;
309    pub s2vsb, _: 5;
310    pub ola, _: 6;
311    pub olb, _: 7;
312    pub t120, _: 8;
313    pub t143, _: 9;
314    pub t150, _: 10;
315    pub t157, _: 11;
316    pub cs_actual, _: 20, 16;
317    pub stealth, _: 30;
318    pub stst, _: 31;
319}
320
321bitfield! {
322    #[derive(Clone, Copy, Eq, Hash, PartialEq)]
323    #[cfg_attr(feature = "hash", derive(hash32_derive::Hash32))]
324    #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
325    #[cfg_attr(feature = "ufmt", derive(ufmt::derive::uDebug))]
326    pub struct PWMCONF(u32);
327    impl Debug;
328    u8;
329    pub pwm_ofs, set_pwm_ofs: 7, 0;
330    pub pwm_grad, set_pwm_grad: 15, 8;
331    pub pwm_freq, set_pwm_freq: 17, 16;
332    pub pwm_autoscale, set_pwm_autoscale: 18;
333    pub pwm_autograd, set_pwm_autograd: 19;
334    pub freewheel, set_freewheel: 21, 20;
335    pub pwm_reg, set_pwm_reg: 27, 24;
336    pub pwm_lim, set_pwm_lim: 31, 28;
337}
338
339bitfield! {
340    #[derive(Clone, Copy, Default, Eq, Hash, PartialEq)]
341    #[cfg_attr(feature = "hash", derive(hash32_derive::Hash32))]
342    #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
343    #[cfg_attr(feature = "ufmt", derive(ufmt::derive::uDebug))]
344    pub struct PWM_SCALE(u32);
345    impl Debug;
346    u8;
347    pub pwm_scale_sum, _: 7, 0;
348    u16;
349    pub pwm_scale_auto, _: 24, 16;
350}
351
352bitfield! {
353    #[derive(Clone, Copy, Default, Eq, Hash, PartialEq)]
354    #[cfg_attr(feature = "hash", derive(hash32_derive::Hash32))]
355    #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
356    #[cfg_attr(feature = "ufmt", derive(ufmt::derive::uDebug))]
357    pub struct PWM_AUTO(u32);
358    impl Debug;
359    u8;
360    pub pwm_ofs_auto, _: 7, 0;
361    pub pwm_grad_auto, _: 23, 16;
362}
363
364// Implementation Macros
365// --------------------------------------------------------
366
367/// A macro for generating `ReadableRegister` and `WritableRegister` implementations for the
368/// register types based on the `R`, `W` or `RW` prefix.
369macro_rules! impl_rw {
370    (RW $T:ident) => {
371        impl ReadableRegister for $T {}
372        impl WritableRegister for $T {}
373    };
374    (R $T:ident) => {
375        impl ReadableRegister for $T {}
376    };
377    (W $T:ident) => {
378        impl WritableRegister for $T {}
379    };
380}
381
382macro_rules! is_readable {
383    (RW) => {
384        true
385    };
386    (R) => {
387        true
388    };
389    (W) => {
390        false
391    };
392}
393
394macro_rules! is_writable {
395    (RW) => {
396        true
397    };
398    (R) => {
399        false
400    };
401    (W) => {
402        true
403    };
404}
405
406macro_rules! map_indices {
407    ($ix:expr, $T:ident) => {
408        pub(crate) const $T: usize = $ix;
409    };
410    ($ix:expr, $T:ident, $($Ts:ident),*) => {
411        pub(crate) const $T: usize = $ix;
412        map_indices!($T + 1, $($Ts),*);
413    };
414}
415
416/// A macro for generating the `Address` enum along with the `Register` trait implementations.
417macro_rules! impl_registers {
418    ($($RW:ident $addr:literal $T:ident $map_access:ident $map_access_mut:ident,)*) => {
419        /// Generate a private, unique index for each register into the `Map`'s inner array.
420        mod map_index {
421            map_indices!(0, $($T),*);
422        }
423
424        /// A dynamic representation of a register's 8-bit address.
425        #[repr(u8)]
426        #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
427        #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
428        #[cfg_attr(feature = "ufmt", derive(ufmt::derive::uDebug))]
429        pub enum Address {
430            $(
431                $T = $addr,
432            )*
433        }
434
435        /// A dynamic representation of a register's 32-bit state.
436        #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
437        #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
438        #[cfg_attr(feature = "ufmt", derive(ufmt::derive::uDebug))]
439        pub enum State {
440            $(
441                $T($T),
442            )*
443        }
444
445        /// A map of the state of all registers in the TMC2209.
446        #[derive(Clone, Debug, Eq, Hash, PartialEq)]
447        #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
448        #[cfg_attr(feature = "ufmt", derive(ufmt::derive::uDebug))]
449        pub struct Map {
450            arr: MapArray,
451        }
452
453        /// The inner array storing all register state.
454        ///
455        /// Each register is laid out in the array in the order in which they are declared in the
456        /// `impl_registers` macro. The `map_index` module is used internally to map register
457        /// addresses and their state to the associated elements in the array.
458        type MapArray = [State; COUNT];
459
460        /// The total number of documented registers in the TMC2209.
461        ///
462        /// Useful for statically allocated register maps, etc.
463        pub const COUNT: usize = 0 $(+ { let _ = Address::$T; 1 })*;
464
465        impl Map {
466            /// The total number of documented registers in the TMC2209.
467            pub const LEN: usize = COUNT;
468
469            /// Read-only access to the register of the given type.
470            pub fn reg<T>(&self) -> &T
471            where
472                T: 'static + Register,
473            {
474                self.state(T::ADDRESS)
475                    .reg::<T>()
476                    // We gaurantee that `TmcRegisters` will always have state for each register, but need
477                    // to avoid generating panicking branches, so we use an infinite loop rather than
478                    // unwrap.
479                    .unwrap_or_else(|_| loop {})
480            }
481
482            /// Mutable access to the register of the given type.
483            pub fn reg_mut<T>(&mut self) -> &mut T
484            where
485                T: 'static + Register,
486            {
487                self.state_mut(T::ADDRESS)
488                    .reg_mut::<T>()
489                    // We gaurantee that `TmcRegisters` will always have state for each register, but need
490                    // to avoid generating panicking branches, so we use an infinite loop rather than
491                    // unwrap.
492                    .unwrap_or_else(|_| loop {})
493            }
494
495            /// Read-only access to the dynamic representation of the register state at the given
496            /// address.
497            pub fn state(&self, addr: Address) -> &State {
498                match addr {
499                    $(
500                        // We gaurantee that `Map` will always have state for each register.
501                        Address::$T => unsafe {
502                            self.arr.get_unchecked(map_index::$T)
503                        }
504                    )*
505                }
506            }
507
508            /// Mutable access to the dynamic representation of the register state at the given
509            /// address.
510            ///
511            /// Note: This should remain private for internal use only, as the user should never be
512            /// allowed to change the stored `State` to a different variant.
513            fn state_mut(&mut self, addr: Address) -> &mut State {
514                match addr {
515                    $(
516                        // We gaurantee that `Map` will always have state for each register.
517                        Address::$T => unsafe {
518                            self.arr.get_unchecked_mut(map_index::$T)
519                        }
520                    )*
521                }
522            }
523
524            /// Update the given register state.
525            pub fn set_state(&mut self, state: State) {
526                *self.state_mut(state.addr()) = state;
527            }
528
529            // Generate the short-hand names for gaining direct access to typed register state.
530            $(
531                pub fn $map_access(&self) -> &$T {
532                    self.reg::<$T>()
533                }
534
535                pub fn $map_access_mut(&mut self) -> &mut $T {
536                    self.reg_mut::<$T>()
537                }
538            )*
539        }
540
541        impl Address {
542            /// All register addresses.
543            pub const ALL: &'static [Self] = &[
544                $(
545                    Self::$T,
546                )*
547            ];
548
549            /// Whether or not we can send a read request to the register address.
550            pub fn readable(&self) -> bool {
551                match *self {
552                    $(
553                        Self::$T => is_readable!($RW),
554                    )*
555                }
556            }
557
558            /// Whether or not we can send a write request to the register address.
559            pub fn writable(&self) -> bool {
560                match *self {
561                    $(
562                        Self::$T => is_writable!($RW),
563                    )*
564                }
565            }
566        }
567
568        impl State {
569            /// Construct a register state from its address and data represented as a `u32`.
570            pub fn from_addr_and_data(addr: Address, data: u32) -> Self {
571                match addr {
572                    $(
573                        Address::$T => State::$T(<_>::from(data)),
574                    )*
575                }
576            }
577
578            /// Construct the default register state associated with the given address.
579            pub fn from_addr_default(addr: Address) -> Self {
580                match addr {
581                    $(
582                        Address::$T => State::$T(<_>::default()),
583                    )*
584                }
585            }
586
587            /// The address of the register with which this state is associated.
588            pub fn addr(&self) -> Address {
589                match *self {
590                    $(
591                        State::$T(_) => Address::$T,
592                    )*
593                }
594            }
595
596            /// Attempt to retrieve a reference to a register of type `R` from the dynamic register
597            /// `State` representation.
598            ///
599            /// Returns an `Err` if the register type does not match.
600            pub fn reg<R>(&self) -> Result<&R, UnexpectedAddress>
601            where
602                R: 'static + Register,
603            {
604                match *self {
605                    $(
606                        Self::$T(ref r) => (r as &dyn core::any::Any)
607                            .downcast_ref()
608                            .ok_or(UnexpectedAddress),
609                    )*
610                }
611            }
612
613            /// Attempt to retrieve a mutable reference to a register of type `R` from the dynamic
614            /// register `State` representation.
615            ///
616            /// Returns an `Err` if the register type does not match.
617            pub fn reg_mut<R>(&mut self) -> Result<&mut R, UnexpectedAddress>
618            where
619                R: 'static + Register,
620            {
621                match *self {
622                    $(
623                        Self::$T(ref mut r) => (r as &mut dyn core::any::Any)
624                            .downcast_mut()
625                            .ok_or(UnexpectedAddress),
626                    )*
627                }
628            }
629        }
630
631        impl Default for Map {
632            fn default() -> Self {
633                let arr = [$(
634                    State::$T($T::default()),
635                )*];
636                Map { arr }
637            }
638        }
639
640        impl core::ops::Deref for Map {
641            type Target = MapArray;
642            fn deref(&self) -> &Self::Target {
643                &self.arr
644            }
645        }
646
647        #[cfg(feature = "hash")]
648        impl hash32::Hash for Address {
649            fn hash<H>(&self, state: &mut H)
650            where
651                H: hash32::Hasher,
652            {
653                (*self as u8).hash(state)
654            }
655        }
656
657        #[cfg(feature = "hash")]
658        impl hash32::Hash for State {
659            fn hash<H>(&self, state: &mut H)
660            where
661                H: hash32::Hasher,
662            {
663                let u: u32 = (*self).into();
664                u.hash(state)
665            }
666        }
667
668        impl core::ops::Index<Address> for Map {
669            type Output = State;
670            fn index(&self, addr: Address) -> &Self::Output {
671                self.state(addr)
672            }
673        }
674
675        impl core::ops::IndexMut<Address> for Map {
676            fn index_mut(&mut self, addr: Address) -> &mut Self::Output {
677                self.state_mut(addr)
678            }
679        }
680
681        impl Into<u8> for Address {
682            fn into(self) -> u8 {
683                self as u8
684            }
685        }
686
687        impl Into<u32> for State {
688            fn into(self) -> u32 {
689                match self {
690                    $(
691                        State::$T(r) => r.into(),
692                    )*
693                }
694            }
695        }
696
697        impl core::convert::TryFrom<u8> for Address {
698            type Error = UnknownAddress;
699            fn try_from(u: u8) -> Result<Self, Self::Error> {
700                let reg = match u {
701                    $(
702                        $addr => Self::$T,
703                    )*
704                    _ => return Err(UnknownAddress),
705                };
706                Ok(reg)
707            }
708        }
709
710        $(
711            impl From<u32> for $T {
712                fn from(u: u32) -> $T {
713                    $T(u)
714                }
715            }
716
717            impl From<$T> for State {
718                fn from(r: $T) -> Self {
719                    State::$T(r)
720                }
721            }
722
723            impl Into<u32> for $T {
724                fn into(self) -> u32 {
725                    self.0 as u32
726                }
727            }
728
729            impl Register for $T {
730                const ADDRESS: Address = Address::$T;
731            }
732
733            impl core::convert::TryFrom<State> for $T {
734                type Error = UnexpectedAddress;
735                fn try_from(state: State) -> Result<Self, Self::Error> {
736                    match state {
737                        State::$T(s) => Ok(s),
738                        _ => Err(UnexpectedAddress),
739                    }
740                }
741            }
742        )*
743
744        $(
745            impl_rw!{$RW $T}
746        )*
747    };
748}
749
750// Register Implementations
751// --------------------------------------------------------
752
753impl_registers! {
754    // General Registers.
755    RW 0x00 GCONF gconf gconf_mut,
756    RW 0x01 GSTAT gstat gstat_mut,
757    R  0x02 IFCNT ifcnt ifcnt_mut,
758    W  0x03 SLAVECONF slaveconf slaveconf_mut,
759    W  0x04 OTP_PROG otp_prog otp_prog_mut,
760    R  0x05 OTP_READ otp_read otp_read_mut,
761    R  0x06 IOIN ioin ioin_mut,
762    RW 0x07 FACTORY_CONF factory_conf factory_conf_mut,
763
764    // Velocity Dependent Control.
765    W  0x10 IHOLD_IRUN ihold_irun ihold_irun_mut,
766    W  0x11 TPOWERDOWN tpowerdown tpowerdown_mut,
767    R  0x12 TSTEP tstep tstep_mut,
768    W  0x13 TPWMTHRS tpwmthrs tpwmthrs_mut,
769    W  0x22 VACTUAL vactual vactual_mut,
770
771    // StallGuard Control.
772    W  0x14 TCOOLTHRS tcoolthrs tcoolthrs_mut,
773    W  0x40 SGTHRS sgthrs sgthrs_mut,
774    R  0x41 SG_RESULT sg_result sg_result_mut,
775    W  0x42 COOLCONF coolconf coolconf_mut,
776
777    // Sequencer Registers.
778    R  0x6A MSCNT mscnt mscnt_mut,
779    R  0x6B MSCURACT mscuract mscuract_mut,
780
781    // Chopper Control Registers.
782    RW 0x6C CHOPCONF chopconf chopconf_mut,
783    R  0x6F DRV_STATUS drv_status drv_status_mut,
784    RW 0x70 PWMCONF pwmconf pwmconf_mut,
785    R  0x71 PWM_SCALE pwm_scale pwm_scale_mut,
786    R  0x72 PWM_AUTO pwm_auto pwm_auto_mut,
787}
788
789impl VACTUAL {
790    /// Creates the `VACTUAL` register enabled for UART control but in a stopped state.
791    pub const ENABLED_STOPPED: Self = VACTUAL(1);
792}
793
794// Default Register States (taken from TMC-API reference).
795// --------------------------------------------------------
796
797impl Default for GCONF {
798    fn default() -> Self {
799        Self(0x00000041)
800    }
801}
802
803impl Default for IHOLD_IRUN {
804    fn default() -> Self {
805        Self(0x00001F00)
806    }
807}
808
809impl Default for CHOPCONF {
810    fn default() -> Self {
811        Self(0x10000053)
812    }
813}
814
815impl Default for PWMCONF {
816    fn default() -> Self {
817        Self(0xC10D0024)
818    }
819}
820
821impl Default for TPOWERDOWN {
822    fn default() -> Self {
823        Self(20)
824    }
825}
826
827// Sanity Checks
828// --------------------------------------------------------
829
830#[test]
831fn test_slaveconf() {
832    let mut s = SLAVECONF(0);
833    assert_eq!(s.0, 0b000000000000);
834    s.set(15);
835    assert_eq!(s.0, 0b111100000000);
836}
837
838#[test]
839fn test_gconf() {
840    let mut g = GCONF(0);
841    assert_eq!(g.0, 0b0000000000);
842    g.set_i_scale_analog(true);
843    assert_eq!(g.0, 0b0000000001);
844    g.set_test_mode(true);
845    assert_eq!(g.0, 0b1000000001);
846    g = Default::default();
847    assert_eq!(g.0, 0x00000041);
848}