1use crate::datagram::{ReadRequest, ReadResponse, ResponseReader, WriteRequest};
7use crate::error::Error;
8use crate::registers::{
9 Chopconf, Coolconf, DrvStatus, Gconf, Gstat, Ifcnt, IholdIrun, Ioin, MicrostepResolution,
10 Mscnt, Pwmconf, ReadableRegister, SgResult, Sgthrs, Tcoolthrs, Tpwmthrs, Tstep, Vactual,
11 WritableRegister,
12};
13
14pub struct Tmc2209<U> {
41 uart: U,
43 slave_addr: u8,
45 reader: ResponseReader,
47}
48
49impl<U> Tmc2209<U> {
50 pub fn new(uart: U, slave_addr: u8) -> Self {
61 assert!(slave_addr <= 3, "Slave address must be 0-3");
62 Self {
63 uart,
64 slave_addr,
65 reader: ResponseReader::new(),
66 }
67 }
68
69 pub fn slave_addr(&self) -> u8 {
71 self.slave_addr
72 }
73
74 pub fn set_slave_addr(&mut self, addr: u8) {
80 assert!(addr <= 3, "Slave address must be 0-3");
81 self.slave_addr = addr;
82 }
83
84 pub fn uart(&self) -> &U {
86 &self.uart
87 }
88
89 pub fn uart_mut(&mut self) -> &mut U {
91 &mut self.uart
92 }
93
94 pub fn release(self) -> U {
96 self.uart
97 }
98
99 fn read_request<R: ReadableRegister>(&self) -> ReadRequest {
101 ReadRequest::new(self.slave_addr, R::ADDRESS)
102 }
103
104 fn write_request<R: WritableRegister>(&self, reg: &R) -> WriteRequest {
106 WriteRequest::new(self.slave_addr, R::ADDRESS, (*reg).into())
107 }
108}
109
110#[cfg(feature = "blocking")]
115impl<U, E> Tmc2209<U>
116where
117 U: embedded_io::Read<Error = E> + embedded_io::Write<Error = E>,
118{
119 pub fn read_register<R: ReadableRegister>(&mut self) -> Result<R, Error<E>> {
131 let request = self.read_request::<R>();
132
133 self.uart
135 .write_all(request.as_bytes())
136 .map_err(Error::Uart)?;
137 self.uart.flush().map_err(Error::Uart)?;
138
139 let mut echo_buf = [0u8; 4];
143 self.read_exact(&mut echo_buf)?;
144
145 let response = self.read_response()?;
146
147 let expected_addr = R::ADDRESS as u8;
149 if response.reg_addr() != expected_addr {
150 return Err(Error::AddressMismatch {
151 expected: expected_addr,
152 actual: response.reg_addr(),
153 });
154 }
155
156 Ok(R::from(response.data()))
157 }
158
159 pub fn write_register<R: WritableRegister>(&mut self, reg: &R) -> Result<(), Error<E>> {
171 let request = self.write_request(reg);
172
173 self.uart
175 .write_all(request.as_bytes())
176 .map_err(Error::Uart)?;
177 self.uart.flush().map_err(Error::Uart)?;
178
179 let mut echo_buf = [0u8; 8];
181 self.read_exact(&mut echo_buf)?;
182
183 Ok(())
184 }
185
186 pub fn read_raw(&mut self, reg_addr: u8) -> Result<u32, Error<E>> {
190 let request = ReadRequest::from_raw_addr(self.slave_addr, reg_addr);
191
192 self.uart
193 .write_all(request.as_bytes())
194 .map_err(Error::Uart)?;
195 self.uart.flush().map_err(Error::Uart)?;
196
197 let mut echo_buf = [0u8; 4];
199 self.read_exact(&mut echo_buf)?;
200
201 let response = self.read_response()?;
202 Ok(response.data())
203 }
204
205 pub fn write_raw(&mut self, reg_addr: u8, data: u32) -> Result<(), Error<E>> {
209 let request = WriteRequest::from_raw(self.slave_addr, reg_addr, data);
210
211 self.uart
212 .write_all(request.as_bytes())
213 .map_err(Error::Uart)?;
214 self.uart.flush().map_err(Error::Uart)?;
215
216 let mut echo_buf = [0u8; 8];
218 self.read_exact(&mut echo_buf)?;
219
220 Ok(())
221 }
222
223 fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), Error<E>> {
225 let mut total_read = 0;
226 while total_read < buf.len() {
227 let n = self.uart.read(&mut buf[total_read..]).map_err(Error::Uart)?;
228 if n == 0 {
229 return Err(Error::NoResponse);
230 }
231 total_read += n;
232 }
233 Ok(())
234 }
235
236 fn read_response(&mut self) -> Result<ReadResponse, Error<E>> {
238 self.reader.reset();
239 let mut buf = [0u8; 8];
240 self.read_exact(&mut buf)?;
241
242 let (_, result) = self.reader.feed(&buf);
243 result.ok_or(Error::NoResponse)?
244 }
245
246 pub fn is_connected(&mut self) -> bool {
254 self.read_register::<Ifcnt>().is_ok()
255 }
256
257 pub fn ifcnt(&mut self) -> Result<u8, Error<E>> {
262 let reg = self.read_register::<Ifcnt>()?;
263 Ok(reg.count())
264 }
265
266 pub fn gstat(&mut self) -> Result<Gstat, Error<E>> {
268 self.read_register()
269 }
270
271 pub fn clear_gstat(&mut self) -> Result<(), Error<E>> {
273 let gstat = Gstat::from(0x07);
275 self.write_register(&gstat)
276 }
277
278 pub fn ioin(&mut self) -> Result<Ioin, Error<E>> {
280 self.read_register()
281 }
282
283 pub fn drv_status(&mut self) -> Result<DrvStatus, Error<E>> {
285 self.read_register()
286 }
287
288 pub fn tstep(&mut self) -> Result<u32, Error<E>> {
290 let reg = self.read_register::<Tstep>()?;
291 Ok(reg.tstep())
292 }
293
294 pub fn sg_result(&mut self) -> Result<u16, Error<E>> {
296 let reg = self.read_register::<SgResult>()?;
297 Ok(reg.result())
298 }
299
300 pub fn mscnt(&mut self) -> Result<u16, Error<E>> {
302 let reg = self.read_register::<Mscnt>()?;
303 Ok(reg.count())
304 }
305
306 pub fn set_current(
314 &mut self,
315 run_current: u8,
316 hold_current: u8,
317 hold_delay: u8,
318 ) -> Result<(), Error<E>> {
319 let mut reg = IholdIrun::new();
320 reg.set_irun(run_current)
321 .set_ihold(hold_current)
322 .set_iholddelay(hold_delay);
323 self.write_register(®)
324 }
325
326 pub fn set_microsteps(&mut self, resolution: MicrostepResolution) -> Result<(), Error<E>> {
328 let mut chopconf = self.read_register::<Chopconf>()?;
329 chopconf.set_microstep_resolution(resolution);
330 self.write_register(&chopconf)
331 }
332
333 pub fn set_enabled(&mut self, enabled: bool) -> Result<(), Error<E>> {
337 let mut chopconf = self.read_register::<Chopconf>()?;
338 if enabled {
339 if chopconf.toff() == 0 {
341 chopconf.set_toff(3);
342 }
343 } else {
344 chopconf.set_toff(0);
345 }
346 self.write_register(&chopconf)
347 }
348
349 pub fn set_velocity(&mut self, velocity: i32) -> Result<(), Error<E>> {
358 let mut reg = Vactual::new();
359 reg.set_velocity(velocity);
360 self.write_register(®)
361 }
362
363 pub fn stop(&mut self) -> Result<(), Error<E>> {
365 self.set_velocity(0)
366 }
367
368 pub fn set_stall_threshold(&mut self, threshold: u8) -> Result<(), Error<E>> {
372 let mut reg = Sgthrs::new();
373 reg.set_threshold(threshold);
374 self.write_register(®)
375 }
376
377 pub fn enable_stealthchop(&mut self) -> Result<(), Error<E>> {
379 let mut gconf = self.read_register::<Gconf>()?;
380 gconf.set_en_spreadcycle(false);
381 self.write_register(&gconf)
382 }
383
384 pub fn enable_spreadcycle(&mut self) -> Result<(), Error<E>> {
386 let mut gconf = self.read_register::<Gconf>()?;
387 gconf.set_en_spreadcycle(true);
388 self.write_register(&gconf)
389 }
390
391 pub fn is_standstill(&mut self) -> Result<bool, Error<E>> {
393 let status = self.drv_status()?;
394 Ok(status.stst())
395 }
396
397 pub fn is_overtemperature_warning(&mut self) -> Result<bool, Error<E>> {
399 let status = self.drv_status()?;
400 Ok(status.otpw())
401 }
402
403 pub fn is_overtemperature_shutdown(&mut self) -> Result<bool, Error<E>> {
405 let status = self.drv_status()?;
406 Ok(status.ot())
407 }
408
409 pub fn enable_coolstep(&mut self, semin: u8, semax: u8) -> Result<(), Error<E>> {
430 let mut coolconf = Coolconf::new();
431 coolconf
432 .set_semin(semin.min(15))
433 .set_semax(semax.min(15))
434 .set_seup(0) .set_sedn(0); self.write_register(&coolconf)
437 }
438
439 pub fn disable_coolstep(&mut self) -> Result<(), Error<E>> {
441 let coolconf = Coolconf::new(); self.write_register(&coolconf)
443 }
444
445 pub fn set_coolstep_threshold(&mut self, threshold: u32) -> Result<(), Error<E>> {
454 let mut tcoolthrs = Tcoolthrs::new();
455 tcoolthrs.set_threshold(threshold);
456 self.write_register(&tcoolthrs)
457 }
458
459 pub fn set_stealthchop_threshold(&mut self, threshold: u32) -> Result<(), Error<E>> {
467 let mut tpwmthrs = Tpwmthrs::new();
468 tpwmthrs.set_threshold(threshold);
469 self.write_register(&tpwmthrs)
470 }
471
472 pub fn configure_stall_detection(&mut self, threshold: u8) -> Result<(), Error<E>> {
512 self.set_stall_threshold(threshold)?;
514
515 let mut gconf = self.read_register::<Gconf>()?;
517 gconf.set_diag0_stall(true);
518 self.write_register(&gconf)?;
519
520 Ok(())
521 }
522
523 pub fn is_stalled(&mut self) -> Result<bool, Error<E>> {
528 let sg_result = self.sg_result()?;
529 Ok(sg_result == 0)
531 }
532
533 pub fn load_indicator(&mut self) -> Result<u16, Error<E>> {
538 self.sg_result()
539 }
540
541 pub fn configure_stealthchop(
554 &mut self,
555 pwm_ofs: u8,
556 pwm_grad: u8,
557 autoscale: bool,
558 autograd: bool,
559 ) -> Result<(), Error<E>> {
560 let mut pwmconf = self.read_register::<Pwmconf>()?;
561 pwmconf
562 .set_pwm_ofs(pwm_ofs)
563 .set_pwm_grad(pwm_grad)
564 .set_pwm_autoscale(autoscale)
565 .set_pwm_autograd(autograd);
566 self.write_register(&pwmconf)
567 }
568
569 pub fn set_vsense(&mut self, high_sensitivity: bool) -> Result<(), Error<E>> {
576 let mut chopconf = self.read_register::<Chopconf>()?;
577 chopconf.set_vsense(high_sensitivity);
578 self.write_register(&chopconf)
579 }
580
581 pub fn configure_chopper(
590 &mut self,
591 toff: u8,
592 hstrt: u8,
593 hend: u8,
594 tbl: u8,
595 ) -> Result<(), Error<E>> {
596 let mut chopconf = self.read_register::<Chopconf>()?;
597 chopconf
598 .set_toff(toff.min(15))
599 .set_hstrt(hstrt.min(7))
600 .set_hend(hend.min(15))
601 .set_tbl(tbl.min(3));
602 self.write_register(&chopconf)
603 }
604
605 pub fn set_interpolation(&mut self, enabled: bool) -> Result<(), Error<E>> {
610 let mut chopconf = self.read_register::<Chopconf>()?;
611 chopconf.set_intpol(enabled);
612 self.write_register(&chopconf)
613 }
614
615 pub fn actual_current_scale(&mut self) -> Result<u8, Error<E>> {
620 let status = self.drv_status()?;
621 Ok(status.cs_actual())
622 }
623
624 pub fn is_stealthchop_active(&mut self) -> Result<bool, Error<E>> {
626 let status = self.drv_status()?;
627 Ok(status.stealth())
628 }
629
630 pub fn status_summary(&mut self) -> Result<(bool, bool, bool), Error<E>> {
634 let status = self.drv_status()?;
635
636 let errors = status.has_error();
637 let warnings = status.otpw() || status.open_load_detected();
638 let running = !status.stst();
639
640 Ok((errors, warnings, running))
641 }
642}
643
644#[cfg(feature = "async")]
649impl<U, E> Tmc2209<U>
650where
651 U: embedded_io_async::Read<Error = E> + embedded_io_async::Write<Error = E>,
652{
653 pub async fn read_register_async<R: ReadableRegister>(&mut self) -> Result<R, Error<E>> {
657 let request = self.read_request::<R>();
658
659 self.uart
661 .write_all(request.as_bytes())
662 .await
663 .map_err(Error::Uart)?;
664 self.uart.flush().await.map_err(Error::Uart)?;
665
666 let mut echo_buf = [0u8; 4];
668 self.read_exact_async(&mut echo_buf).await?;
669
670 let response = self.read_response_async().await?;
672
673 let expected_addr = R::ADDRESS as u8;
675 if response.reg_addr() != expected_addr {
676 return Err(Error::AddressMismatch {
677 expected: expected_addr,
678 actual: response.reg_addr(),
679 });
680 }
681
682 Ok(R::from(response.data()))
683 }
684
685 pub async fn write_register_async<R: WritableRegister>(
689 &mut self,
690 reg: &R,
691 ) -> Result<(), Error<E>> {
692 let request = self.write_request(reg);
693
694 self.uart
696 .write_all(request.as_bytes())
697 .await
698 .map_err(Error::Uart)?;
699 self.uart.flush().await.map_err(Error::Uart)?;
700
701 let mut echo_buf = [0u8; 8];
703 self.read_exact_async(&mut echo_buf).await?;
704
705 Ok(())
706 }
707
708 pub async fn read_raw_async(&mut self, reg_addr: u8) -> Result<u32, Error<E>> {
710 let request = ReadRequest::from_raw_addr(self.slave_addr, reg_addr);
711
712 self.uart
713 .write_all(request.as_bytes())
714 .await
715 .map_err(Error::Uart)?;
716 self.uart.flush().await.map_err(Error::Uart)?;
717
718 let mut echo_buf = [0u8; 4];
720 self.read_exact_async(&mut echo_buf).await?;
721
722 let response = self.read_response_async().await?;
723 Ok(response.data())
724 }
725
726 pub async fn write_raw_async(&mut self, reg_addr: u8, data: u32) -> Result<(), Error<E>> {
728 let request = WriteRequest::from_raw(self.slave_addr, reg_addr, data);
729
730 self.uart
731 .write_all(request.as_bytes())
732 .await
733 .map_err(Error::Uart)?;
734 self.uart.flush().await.map_err(Error::Uart)?;
735
736 let mut echo_buf = [0u8; 8];
738 self.read_exact_async(&mut echo_buf).await?;
739
740 Ok(())
741 }
742
743 async fn read_exact_async(&mut self, buf: &mut [u8]) -> Result<(), Error<E>> {
745 let mut total_read = 0;
746 while total_read < buf.len() {
747 let n = self
748 .uart
749 .read(&mut buf[total_read..])
750 .await
751 .map_err(Error::Uart)?;
752 if n == 0 {
753 return Err(Error::NoResponse);
754 }
755 total_read += n;
756 }
757 Ok(())
758 }
759
760 async fn read_response_async(&mut self) -> Result<ReadResponse, Error<E>> {
762 self.reader.reset();
763 let mut buf = [0u8; 8];
764 self.read_exact_async(&mut buf).await?;
765
766 let (_, result) = self.reader.feed(&buf);
767 result.ok_or(Error::NoResponse)?
768 }
769
770 pub async fn is_connected_async(&mut self) -> bool {
776 self.read_register_async::<Ifcnt>().await.is_ok()
777 }
778
779 pub async fn ifcnt_async(&mut self) -> Result<u8, Error<E>> {
781 let reg = self.read_register_async::<Ifcnt>().await?;
782 Ok(reg.count())
783 }
784
785 pub async fn drv_status_async(&mut self) -> Result<DrvStatus, Error<E>> {
787 self.read_register_async().await
788 }
789
790 pub async fn set_current_async(
792 &mut self,
793 run_current: u8,
794 hold_current: u8,
795 hold_delay: u8,
796 ) -> Result<(), Error<E>> {
797 let mut reg = IholdIrun::new();
798 reg.set_irun(run_current)
799 .set_ihold(hold_current)
800 .set_iholddelay(hold_delay);
801 self.write_register_async(®).await
802 }
803
804 pub async fn set_microsteps_async(
806 &mut self,
807 resolution: MicrostepResolution,
808 ) -> Result<(), Error<E>> {
809 let mut chopconf = self.read_register_async::<Chopconf>().await?;
810 chopconf.set_microstep_resolution(resolution);
811 self.write_register_async(&chopconf).await
812 }
813
814 pub async fn set_velocity_async(&mut self, velocity: i32) -> Result<(), Error<E>> {
816 let mut reg = Vactual::new();
817 reg.set_velocity(velocity);
818 self.write_register_async(®).await
819 }
820
821 pub async fn stop_async(&mut self) -> Result<(), Error<E>> {
823 self.set_velocity_async(0).await
824 }
825
826 pub async fn enable_coolstep_async(&mut self, semin: u8, semax: u8) -> Result<(), Error<E>> {
832 let mut coolconf = Coolconf::new();
833 coolconf
834 .set_semin(semin.min(15))
835 .set_semax(semax.min(15))
836 .set_seup(0)
837 .set_sedn(0);
838 self.write_register_async(&coolconf).await
839 }
840
841 pub async fn disable_coolstep_async(&mut self) -> Result<(), Error<E>> {
843 let coolconf = Coolconf::new();
844 self.write_register_async(&coolconf).await
845 }
846
847 pub async fn set_coolstep_threshold_async(&mut self, threshold: u32) -> Result<(), Error<E>> {
849 let mut tcoolthrs = Tcoolthrs::new();
850 tcoolthrs.set_threshold(threshold);
851 self.write_register_async(&tcoolthrs).await
852 }
853
854 pub async fn set_stealthchop_threshold_async(
856 &mut self,
857 threshold: u32,
858 ) -> Result<(), Error<E>> {
859 let mut tpwmthrs = Tpwmthrs::new();
860 tpwmthrs.set_threshold(threshold);
861 self.write_register_async(&tpwmthrs).await
862 }
863
864 pub async fn configure_stall_detection_async(&mut self, threshold: u8) -> Result<(), Error<E>> {
870 let mut sgthrs = Sgthrs::new();
872 sgthrs.set_threshold(threshold);
873 self.write_register_async(&sgthrs).await?;
874
875 let mut gconf = self.read_register_async::<Gconf>().await?;
877 gconf.set_diag0_stall(true);
878 self.write_register_async(&gconf).await?;
879
880 Ok(())
881 }
882
883 pub async fn is_stalled_async(&mut self) -> Result<bool, Error<E>> {
885 let sg = self.read_register_async::<SgResult>().await?;
886 Ok(sg.result() == 0)
887 }
888
889 pub async fn load_indicator_async(&mut self) -> Result<u16, Error<E>> {
891 let sg = self.read_register_async::<SgResult>().await?;
892 Ok(sg.result())
893 }
894
895 pub async fn enable_stealthchop_async(&mut self) -> Result<(), Error<E>> {
901 let mut gconf = self.read_register_async::<Gconf>().await?;
902 gconf.set_en_spreadcycle(false);
903 self.write_register_async(&gconf).await
904 }
905
906 pub async fn enable_spreadcycle_async(&mut self) -> Result<(), Error<E>> {
908 let mut gconf = self.read_register_async::<Gconf>().await?;
909 gconf.set_en_spreadcycle(true);
910 self.write_register_async(&gconf).await
911 }
912
913 pub async fn set_enabled_async(&mut self, enabled: bool) -> Result<(), Error<E>> {
915 let mut chopconf = self.read_register_async::<Chopconf>().await?;
916 if enabled {
917 if chopconf.toff() == 0 {
918 chopconf.set_toff(3);
919 }
920 } else {
921 chopconf.set_toff(0);
922 }
923 self.write_register_async(&chopconf).await
924 }
925
926 pub async fn is_standstill_async(&mut self) -> Result<bool, Error<E>> {
928 let status = self.drv_status_async().await?;
929 Ok(status.stst())
930 }
931}