1#![doc(html_root_url = "https://docs.rs/is31fl3743b-driver/latest")]
12#![doc = include_str!("../README.md")]
13#![cfg_attr(not(test), no_std)]
14
15use core::ops::{Deref, DerefMut, Index, IndexMut};
16
17#[cfg(feature = "is_blocking")]
18use embedded_hal::{
19 delay::DelayNs,
20 spi::{Operation, SpiDevice},
21};
22#[cfg(not(feature = "is_blocking"))]
23use embedded_hal_async::{
24 delay::DelayNs,
25 spi::{Operation, SpiDevice},
26};
27
28mod registers;
29pub use registers::*;
30
31const SW_MIN: u8 = 1;
32const SW_MAX: u8 = 11;
33const CS_MIN: u8 = 1;
34const CS_MAX: u8 = 18;
35const OPEN_REG_MIN: u8 = 0x03;
36const OPEN_REG_MAX: u8 = 0x23;
37const NUM_OPEN_REG: usize = ((OPEN_REG_MAX - OPEN_REG_MIN) + 1) as usize;
38const LED_REG_MIN: u8 = 0x01;
39const LED_REG_MAX: u8 = 0xC6;
40const NUM_LED_REG: usize = ((LED_REG_MAX - LED_REG_MIN) + 1) as usize;
41
42#[derive(Clone, Copy, PartialEq, Eq)]
44pub enum SWx {
45 SW1,
47 SW2,
49 SW3,
51 SW4,
53 SW5,
55 SW6,
57 SW7,
59 SW8,
61 SW9,
63 SW10,
65 SW11,
67}
68
69impl From<SWx> for u8 {
70 fn from(swx: SWx) -> Self {
71 match swx {
72 SWx::SW1 => 1,
73 SWx::SW2 => 2,
74 SWx::SW3 => 3,
75 SWx::SW4 => 4,
76 SWx::SW5 => 5,
77 SWx::SW6 => 6,
78 SWx::SW7 => 7,
79 SWx::SW8 => 8,
80 SWx::SW9 => 9,
81 SWx::SW10 => 10,
82 SWx::SW11 => 11,
83 }
84 }
85}
86
87impl TryFrom<u8> for SWx {
88 type Error = ();
89
90 fn try_from(value: u8) -> Result<Self, Self::Error> {
91 match value {
92 1 => Ok(SWx::SW1),
93 2 => Ok(SWx::SW2),
94 3 => Ok(SWx::SW3),
95 4 => Ok(SWx::SW4),
96 5 => Ok(SWx::SW5),
97 6 => Ok(SWx::SW6),
98 7 => Ok(SWx::SW7),
99 8 => Ok(SWx::SW8),
100 9 => Ok(SWx::SW9),
101 10 => Ok(SWx::SW10),
102 11 => Ok(SWx::SW11),
103 _ => Err(()),
104 }
105 }
106}
107
108#[derive(Clone, Copy, PartialEq, Eq)]
110pub enum CSy {
111 CS1,
113 CS2,
115 CS3,
117 CS4,
119 CS5,
121 CS6,
123 CS7,
125 CS8,
127 CS9,
129 CS10,
131 CS11,
133 CS12,
135 CS13,
137 CS14,
139 CS15,
141 CS16,
143 CS17,
145 CS18,
147}
148
149impl From<CSy> for u8 {
150 fn from(csy: CSy) -> Self {
151 match csy {
152 CSy::CS1 => 1,
153 CSy::CS2 => 2,
154 CSy::CS3 => 3,
155 CSy::CS4 => 4,
156 CSy::CS5 => 5,
157 CSy::CS6 => 6,
158 CSy::CS7 => 7,
159 CSy::CS8 => 8,
160 CSy::CS9 => 9,
161 CSy::CS10 => 10,
162 CSy::CS11 => 11,
163 CSy::CS12 => 12,
164 CSy::CS13 => 13,
165 CSy::CS14 => 14,
166 CSy::CS15 => 15,
167 CSy::CS16 => 16,
168 CSy::CS17 => 17,
169 CSy::CS18 => 18,
170 }
171 }
172}
173
174impl TryFrom<u8> for CSy {
175 type Error = ();
176
177 fn try_from(value: u8) -> Result<Self, Self::Error> {
178 match value {
179 1 => Ok(CSy::CS1),
180 2 => Ok(CSy::CS2),
181 3 => Ok(CSy::CS3),
182 4 => Ok(CSy::CS4),
183 5 => Ok(CSy::CS5),
184 6 => Ok(CSy::CS6),
185 7 => Ok(CSy::CS7),
186 8 => Ok(CSy::CS8),
187 9 => Ok(CSy::CS9),
188 10 => Ok(CSy::CS10),
189 11 => Ok(CSy::CS11),
190 12 => Ok(CSy::CS12),
191 13 => Ok(CSy::CS13),
192 14 => Ok(CSy::CS14),
193 15 => Ok(CSy::CS15),
194 16 => Ok(CSy::CS16),
195 17 => Ok(CSy::CS17),
196 18 => Ok(CSy::CS18),
197 _ => Err(()),
198 }
199 }
200}
201
202fn led_reg_offset(swx: SWx, csy: CSy) -> u8 {
206 (u8::from(csy) + (u8::from(swx) - 1) * CS_MAX) - LED_REG_MIN
207}
208
209#[allow(clippy::cast_possible_truncation)]
211const fn raw_from_percent(percent: u8) -> u8 {
212 debug_assert!(percent <= 100);
213 ((0xFF * percent as u16) / 100) as u8
214}
215
216#[cfg(feature = "preserve_registers")]
217#[derive(Clone, Copy, Debug)]
218struct LedRegList([u8; NUM_LED_REG]);
219#[cfg(feature = "preserve_registers")]
220impl LedRegList {
221 fn inner_ref(&self) -> &[u8; NUM_LED_REG] {
222 &self.0
223 }
224}
225
226#[cfg(feature = "preserve_registers")]
227impl Index<usize> for LedRegList {
228 type Output = u8;
229 fn index(&self, index: usize) -> &Self::Output {
230 &self.0[index]
231 }
232}
233
234#[cfg(feature = "preserve_registers")]
235impl IndexMut<usize> for LedRegList {
236 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
237 &mut self.0[index]
238 }
239}
240
241#[cfg(feature = "preserve_registers")]
242impl Default for LedRegList {
243 fn default() -> Self {
244 Self([0x00; NUM_LED_REG])
245 }
246}
247
248#[derive(Default, Clone, Copy, Debug)]
250struct CachedReg {
251 config: Configuration,
252 gcc: GlobalCurrentControl,
253 res_phase: PullDownUpResistorSelection,
254 temperature: TemperatureStatus,
255 spread_spectrum: SpreadSpectrum,
256 #[cfg(feature = "preserve_registers")]
257 pwm: LedRegList,
258 #[cfg(feature = "preserve_registers")]
259 scaling: LedRegList,
260}
261
262#[derive(Clone, Copy, Debug)]
266pub struct OpenShortTestResult([u8; NUM_OPEN_REG]);
267
268impl OpenShortTestResult {
269 #[must_use]
271 pub fn all_leds_ok(&self) -> bool {
272 self.0.iter().all(|&r| r == 0)
273 }
274
275 #[must_use]
277 pub fn led_ok(&self, swx: u8, csy: u8) -> bool {
278 debug_assert!((SW_MIN..=SW_MAX).contains(&swx) && (CS_MIN..=CS_MAX).contains(&csy));
279
280 let idx = usize::from(((csy - 1) / 6) + ((swx - 1) * 3));
282 let bit = (csy - 1) % 6;
283
284 self.0[idx] & (1 << bit) == 0
285 }
286}
287
288#[derive(Clone, Copy, Debug)]
290pub struct Is31fl3743b<const N: usize, SPI>([Is31fl3743bDevice<SPI>; N]);
291
292impl<const N: usize, SPI: SpiDevice> Index<usize> for Is31fl3743b<N, SPI> {
293 type Output = Is31fl3743bDevice<SPI>;
294 fn index(&self, index: usize) -> &Self::Output {
295 &self.0[index]
296 }
297}
298
299impl<const N: usize, SPI: SpiDevice> IndexMut<usize> for Is31fl3743b<N, SPI> {
300 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
301 &mut self.0[index]
302 }
303}
304
305impl<const N: usize, SPI: SpiDevice> Deref for Is31fl3743b<N, SPI> {
306 type Target = Is31fl3743bDevice<SPI>;
307
308 fn deref(&self) -> &Self::Target {
309 &self.0[0]
310 }
311}
312
313impl<const N: usize, SPI: SpiDevice> DerefMut for Is31fl3743b<N, SPI> {
314 fn deref_mut(&mut self) -> &mut Self::Target {
315 &mut self.0[0]
316 }
317}
318
319#[maybe_async::maybe_async]
320impl<const N: usize, SPI: SpiDevice> Is31fl3743b<N, SPI> {
321 pub async fn new_with_sync(spi: [SPI; N]) -> Result<Self, SPI::Error> {
335 let mut devices = spi.map(|spi| Is31fl3743bDevice::new(spi));
336
337 for slave in devices.iter_mut().skip(1) {
339 slave.reset().await?;
340 slave.enable_sync(Sync::Slave).await?;
341 slave.enable().await?;
342 }
343
344 devices[0].reset().await?;
346 devices[0].enable_sync(Sync::Master).await?;
347 devices[0].enable().await?;
348
349 Ok(Self(devices))
350 }
351
352 pub fn destroy_with_sync(self) -> [SPI; N] {
354 self.0.map(Is31fl3743bDevice::destroy)
355 }
356}
357
358#[maybe_async::maybe_async]
359impl<SPI: SpiDevice> Is31fl3743b<1, SPI> {
360 pub async fn new(spi: SPI) -> Result<Self, SPI::Error> {
369 let mut devices = [Is31fl3743bDevice::new(spi); 1];
370 devices[0].reset().await?;
371 devices[0].enable().await?;
372
373 Ok(Self(devices))
374 }
375
376 #[allow(clippy::missing_panics_doc)]
378 pub fn destroy(self) -> SPI {
379 self.0
382 .into_iter()
383 .next()
384 .expect("Array is non-empty; this will never panic")
385 .destroy()
386 }
387}
388
389#[derive(Clone, Copy, Debug)]
391pub struct Is31fl3743bDevice<SPI> {
392 spi: SPI,
394
395 cached_reg: CachedReg,
397}
398
399#[maybe_async::maybe_async]
400impl<SPI: SpiDevice> Is31fl3743bDevice<SPI> {
401 pub async fn set_led_brightness(
412 &mut self,
413 swx: SWx,
414 csy: CSy,
415 brightness_percentage: u8,
416 ) -> Result<(), SPI::Error> {
417 let raw = raw_from_percent(brightness_percentage);
418 self.set_led_brightness_bulk(swx, csy, &[raw]).await
419 }
420
421 pub async fn set_led_brightness_bulk(
429 &mut self,
430 start_swx: SWx,
431 start_csy: CSy,
432 raw_brightness_values: &[u8],
433 ) -> Result<(), SPI::Error> {
434 let addr_offset = led_reg_offset(start_swx, start_csy);
435 self.write_multiple_with_addr_offset(Register::Pwm, addr_offset, raw_brightness_values)
436 .await
437 }
438
439 pub async fn set_led_peak_current(&mut self, swx: SWx, csy: CSy, scale_percentage: u8) -> Result<(), SPI::Error> {
448 let raw = raw_from_percent(scale_percentage);
449 self.set_led_peak_current_bulk(swx, csy, &[raw]).await
450 }
451
452 pub async fn set_led_peak_current_bulk(
460 &mut self,
461 start_swx: SWx,
462 start_csy: CSy,
463 raw_scale_values: &[u8],
464 ) -> Result<(), SPI::Error> {
465 let addr_offset = led_reg_offset(start_swx, start_csy);
466 self.write_multiple_with_addr_offset(Register::Scaling, addr_offset, raw_scale_values)
467 .await
468 }
469
470 pub async fn enable(&mut self) -> Result<(), SPI::Error> {
476 self.set_configuration_reg(self.cached_reg.config.with_ssd(true)).await
477 }
478
479 pub async fn disable(&mut self) -> Result<(), SPI::Error> {
485 self.set_configuration_reg(self.cached_reg.config.with_ssd(false)).await
486 }
487
488 pub async fn switch_column_enable_upto(&mut self, switch_column: SwxSetting) -> Result<(), SPI::Error> {
498 self.set_configuration_reg(self.cached_reg.config.with_sws(switch_column))
499 .await
500 }
501
502 pub async fn set_global_current(&mut self, scale_percentage: u8) -> Result<(), SPI::Error> {
514 let gcc = GlobalCurrentControl::from(raw_from_percent(scale_percentage));
515 self.set_global_current_control_reg(gcc).await
516 }
517
518 pub async fn set_cs_pullup(&mut self, pur: Resistor) -> Result<(), SPI::Error> {
526 self.set_pdr_pur_resistor_reg(self.cached_reg.res_phase.with_cspur(pur))
527 .await
528 }
529
530 pub async fn set_sw_pulldown(&mut self, pdr: Resistor) -> Result<(), SPI::Error> {
538 self.set_pdr_pur_resistor_reg(self.cached_reg.res_phase.with_swpdr(pdr))
539 .await
540 }
541
542 pub async fn enable_phase_delay(&mut self) -> Result<(), SPI::Error> {
550 self.set_pdr_pur_resistor_reg(self.cached_reg.res_phase.with_phc(true))
551 .await
552 }
553
554 pub async fn disable_phase_delay(&mut self) -> Result<(), SPI::Error> {
560 self.set_pdr_pur_resistor_reg(self.cached_reg.res_phase.with_phc(false))
561 .await
562 }
563
564 pub async fn detect_shorts(&mut self, delay: impl DelayNs) -> Result<OpenShortTestResult, SPI::Error> {
576 self.open_short_test(Open::EnableShort, delay).await
577 }
578
579 pub async fn detect_opens(&mut self, delay: impl DelayNs) -> Result<OpenShortTestResult, SPI::Error> {
591 self.open_short_test(Open::EnableOpen, delay).await
592 }
593
594 pub async fn set_thermal_rolloff(&mut self, trof: ThermalRollOff) -> Result<(), SPI::Error> {
600 self.set_temperature_status_reg(self.cached_reg.temperature.with_trof(trof))
601 .await
602 }
603
604 pub async fn set_temperature_point(&mut self, ts: TemperaturePoint) -> Result<(), SPI::Error> {
610 self.set_temperature_status_reg(self.cached_reg.temperature.with_ts(ts))
611 .await
612 }
613
614 pub async fn enable_spread_spectrum(&mut self) -> Result<(), SPI::Error> {
620 self.set_spread_spectrum_reg(self.cached_reg.spread_spectrum.with_ssp(true))
621 .await
622 }
623
624 pub async fn disable_spread_spectrum(&mut self) -> Result<(), SPI::Error> {
630 self.set_spread_spectrum_reg(self.cached_reg.spread_spectrum.with_ssp(false))
631 .await
632 }
633
634 pub async fn set_spread_spectrum_cycle_time(&mut self, clt: CycleTime) -> Result<(), SPI::Error> {
640 self.set_spread_spectrum_reg(self.cached_reg.spread_spectrum.with_clt(clt))
641 .await
642 }
643
644 pub async fn set_spread_spectrum_range(&mut self, rng: Range) -> Result<(), SPI::Error> {
650 self.set_spread_spectrum_reg(self.cached_reg.spread_spectrum.with_rng(rng))
651 .await
652 }
653
654 pub async fn enable_sync(&mut self, mode: Sync) -> Result<(), SPI::Error> {
667 self.set_spread_spectrum_reg(self.cached_reg.spread_spectrum.with_sync(mode))
668 .await
669 }
670
671 pub async fn disable_sync(&mut self) -> Result<(), SPI::Error> {
677 self.enable_sync(Sync::Disabled).await
678 }
679
680 pub async fn reset(&mut self) -> Result<(), SPI::Error> {
686 self.write(Register::Reset, 0xAE).await?;
687 self.cached_reg = CachedReg::default();
688 Ok(())
689 }
690
691 async fn open_short_test(
695 &mut self,
696 test: Open,
697 mut delay: impl DelayNs,
698 ) -> Result<OpenShortTestResult, SPI::Error> {
699 let tmp_gcc = self.cached_reg.gcc;
701 let tmp_res_phase = self.cached_reg.res_phase;
702
703 #[cfg(feature = "preserve_registers")]
704 let tmp_pwm = self.cached_reg.pwm;
705 #[cfg(feature = "preserve_registers")]
706 let tmp_scaling = self.cached_reg.scaling;
707
708 if self.cached_reg.config.osde() != Open::Disabled {
710 self.set_configuration_reg(self.cached_reg.config.with_osde(Open::Disabled))
711 .await?;
712 }
713
714 self.write_multiple(Register::Pwm, &[0xFF; NUM_LED_REG]).await?;
716 #[cfg(feature = "preserve_registers")]
717 {
718 self.cached_reg.pwm = LedRegList([0xFF; NUM_LED_REG]);
719 }
720 self.write_multiple(Register::Scaling, &[0xFF; NUM_LED_REG]).await?;
721 #[cfg(feature = "preserve_registers")]
722 {
723 self.cached_reg.scaling = LedRegList([0xFF; NUM_LED_REG]);
724 }
725
726 self.set_global_current_control_reg(GlobalCurrentControl::from(0x0F))
728 .await?;
729
730 self.set_pdr_pur_resistor_reg(PullDownUpResistorSelection::from(0b0000_0000))
732 .await?;
733
734 self.set_configuration_reg(self.cached_reg.config.with_osde(test))
736 .await?;
737
738 delay.delay_ms(1).await;
740
741 self.set_global_current_control_reg(tmp_gcc).await?;
743
744 self.set_pdr_pur_resistor_reg(tmp_res_phase).await?;
746
747 #[cfg(feature = "preserve_registers")]
749 {
750 self.write_multiple(Register::Pwm, tmp_pwm.inner_ref()).await?;
751 self.cached_reg.pwm = tmp_pwm;
752
753 self.write_multiple(Register::Scaling, tmp_scaling.inner_ref()).await?;
754 self.cached_reg.scaling = tmp_scaling;
755 }
756
757 Ok(OpenShortTestResult(
759 self.read_multiple_with_addr_offset::<NUM_OPEN_REG>(Register::Open, 0)
760 .await?,
761 ))
762 }
763
764 pub async fn set_pwm_reg(&mut self, n: u8, value: u8) -> Result<(), SPI::Error> {
770 debug_assert!((LED_REG_MIN..=LED_REG_MAX).contains(&n));
771
772 let offset = n - LED_REG_MIN;
773 self.write_with_addr_offset(Register::Pwm, offset, value).await?;
774 #[cfg(feature = "preserve_registers")]
775 {
776 self.cached_reg.pwm[offset as usize] = value;
777 }
778 Ok(())
779 }
780
781 pub async fn set_scaling_reg(&mut self, n: u8, value: u8) -> Result<(), SPI::Error> {
787 debug_assert!((LED_REG_MIN..=LED_REG_MAX).contains(&n));
788
789 let offset = n - LED_REG_MIN;
790 self.write_with_addr_offset(Register::Scaling, offset, value).await?;
791 #[cfg(feature = "preserve_registers")]
792 {
793 self.cached_reg.scaling[offset as usize] = value;
794 }
795 Ok(())
796 }
797
798 pub async fn set_configuration_reg(&mut self, value: Configuration) -> Result<(), SPI::Error> {
804 self.write(Register::Configuration, value.into()).await?;
805 self.cached_reg.config = value;
806 Ok(())
807 }
808
809 pub async fn set_global_current_control_reg(&mut self, value: GlobalCurrentControl) -> Result<(), SPI::Error> {
815 self.write(Register::GlobalCurrentControl, value.into()).await?;
816 self.cached_reg.gcc = value;
817 Ok(())
818 }
819
820 pub async fn set_pdr_pur_resistor_reg(&mut self, value: PullDownUpResistorSelection) -> Result<(), SPI::Error> {
826 self.write(Register::PullDownUpResistorSelection, value.into()).await?;
827 self.cached_reg.res_phase = value;
828 Ok(())
829 }
830
831 pub async fn set_temperature_status_reg(&mut self, value: TemperatureStatus) -> Result<(), SPI::Error> {
837 self.write(Register::TemperatureStatus, value.into()).await?;
838 self.cached_reg.temperature = value;
839 Ok(())
840 }
841
842 pub async fn set_spread_spectrum_reg(&mut self, value: SpreadSpectrum) -> Result<(), SPI::Error> {
848 self.write(Register::SpreadSpectrum, value.into()).await?;
849 self.cached_reg.spread_spectrum = value;
850 Ok(())
851 }
852
853 pub async fn open_reg(&mut self, n: u8) -> Result<u8, SPI::Error> {
859 debug_assert!((OPEN_REG_MIN..=OPEN_REG_MAX).contains(&n));
860 self.read_with_addr_offset(Register::Open, n - OPEN_REG_MIN).await
861 }
862
863 #[cfg(feature = "preserve_registers")]
865 pub fn pwm_reg(&mut self, n: u8) -> u8 {
866 debug_assert!((LED_REG_MIN..=LED_REG_MAX).contains(&n));
867 self.cached_reg.pwm[(n - LED_REG_MIN) as usize]
868 }
869
870 #[cfg(feature = "preserve_registers")]
872 pub fn scaling_reg(&mut self, n: u8) -> u8 {
873 debug_assert!((LED_REG_MIN..=LED_REG_MAX).contains(&n));
874 self.cached_reg.scaling[(n - LED_REG_MIN) as usize]
875 }
876
877 pub fn configuration_reg(&mut self) -> Configuration {
879 self.cached_reg.config
880 }
881
882 pub fn global_current_control_reg(&mut self) -> GlobalCurrentControl {
884 self.cached_reg.gcc
885 }
886
887 pub fn pdr_pur_resistor_reg(&mut self) -> PullDownUpResistorSelection {
889 self.cached_reg.res_phase
890 }
891
892 pub fn temperature_status_reg(&mut self) -> TemperatureStatus {
894 self.cached_reg.temperature
895 }
896
897 pub fn spread_spectrum_reg(&mut self) -> SpreadSpectrum {
899 self.cached_reg.spread_spectrum
900 }
901
902 async fn read_with_addr_offset(&mut self, reg: Register, offset: u8) -> Result<u8, SPI::Error> {
903 let data = self.read_multiple_with_addr_offset::<1>(reg, offset).await?;
904 Ok(data[0])
905 }
906
907 fn new(spi: SPI) -> Self {
908 Self {
909 spi,
910 cached_reg: CachedReg::default(),
911 }
912 }
913
914 fn destroy(self) -> SPI {
915 self.spi
916 }
917
918 async fn read_multiple_with_addr_offset<const N: usize>(
919 &mut self,
920 reg: Register,
921 offset: u8,
922 ) -> Result<[u8; N], SPI::Error> {
923 let cmd_byte: u8 = Command::default()
924 .with_rw(CommandType::Read)
925 .with_page(reg.page())
926 .into();
927
928 let write_buf = [cmd_byte, u8::from(reg) + offset];
929 let write_op = Operation::Write(&write_buf);
930
931 let mut data: [u8; N] = [0; N];
933 let read_op = Operation::Read(&mut data);
934
935 self.spi.transaction(&mut [write_op, read_op]).await?;
941 Ok(data)
942 }
943
944 async fn write(&mut self, reg: Register, value: u8) -> Result<(), SPI::Error> {
945 self.write_with_addr_offset(reg, 0, value).await
946 }
947
948 async fn write_with_addr_offset(&mut self, reg: Register, offset: u8, value: u8) -> Result<(), SPI::Error> {
949 let cmd_byte: u8 = Command::default()
950 .with_rw(CommandType::Write)
951 .with_page(reg.page())
952 .into();
953 self.spi.write(&[cmd_byte, u8::from(reg) + offset, value]).await
954 }
955
956 async fn write_multiple(&mut self, reg: Register, data: &[u8]) -> Result<(), SPI::Error> {
957 self.write_multiple_with_addr_offset(reg, 0, data).await
958 }
959
960 async fn write_multiple_with_addr_offset(
961 &mut self,
962 reg: Register,
963 offset: u8,
964 data: &[u8],
965 ) -> Result<(), SPI::Error> {
966 let cmd_byte: u8 = Command::default()
967 .with_rw(CommandType::Write)
968 .with_page(reg.page())
969 .into();
970 let cmd_write_buf = [cmd_byte, u8::from(reg) + offset];
971
972 let cmd_write_op = Operation::Write(&cmd_write_buf);
973 let data_write_op = Operation::Write(data);
974 self.spi.transaction(&mut [cmd_write_op, data_write_op]).await
975 }
976}
977
978#[cfg(test)]
979mod tests {
980 use embedded_hal_mock::eh1::spi::{Mock, Transaction};
981
982 use super::*;
983
984 #[maybe_async::test(feature = "is_blocking", async(not(feature = "is_blocking"), tokio::test))]
985 async fn write_configuration_register() {
986 let expectations = vec![
987 Transaction::transaction_start(),
989 Transaction::write_vec(vec![0x52, 0x2F, 0xAE]),
990 Transaction::transaction_end(),
991 Transaction::transaction_start(),
993 Transaction::write_vec(vec![0x52, 0x00, 0x09]),
994 Transaction::transaction_end(),
995 Transaction::transaction_start(),
997 Transaction::write_vec(vec![0x52, 0x00, 0x69]),
998 Transaction::transaction_end(),
999 ];
1000
1001 let mock = Mock::new(&expectations);
1002
1003 let mut m = Is31fl3743b::new(mock).await.unwrap();
1004 m.switch_column_enable_upto(SwxSetting::Sw5).await.unwrap();
1005
1006 let mut mock = m.destroy();
1007 mock.done();
1008 }
1009
1010 #[maybe_async::test(feature = "is_blocking", async(not(feature = "is_blocking"), tokio::test))]
1011 async fn new_with_sync() {
1012 let expectations1 = vec![
1013 Transaction::transaction_start(),
1015 Transaction::write_vec(vec![0x52, 0x2F, 0xAE]),
1016 Transaction::transaction_end(),
1017 Transaction::transaction_start(),
1019 Transaction::write_vec(vec![0x52, 0x25, 0xC0]),
1020 Transaction::transaction_end(),
1021 Transaction::transaction_start(),
1023 Transaction::write_vec(vec![0x52, 0x00, 0x09]),
1024 Transaction::transaction_end(),
1025 ];
1026 let expectations2 = vec![
1027 Transaction::transaction_start(),
1029 Transaction::write_vec(vec![0x52, 0x2F, 0xAE]),
1030 Transaction::transaction_end(),
1031 Transaction::transaction_start(),
1033 Transaction::write_vec(vec![0x52, 0x25, 0x80]),
1034 Transaction::transaction_end(),
1035 Transaction::transaction_start(),
1037 Transaction::write_vec(vec![0x52, 0x00, 0x09]),
1038 Transaction::transaction_end(),
1039 ];
1040
1041 let mock1 = Mock::new(&expectations1);
1042 let mock2 = Mock::new(&expectations2);
1043 let mocks = [mock1, mock2];
1044
1045 let m = Is31fl3743b::new_with_sync(mocks).await.unwrap();
1046
1047 let mocks = m.destroy_with_sync();
1048 mocks.into_iter().for_each(|mut mock| mock.done());
1049 }
1050
1051 #[test]
1052 fn led_register_calculation() {
1053 assert_eq!(led_reg_offset(SWx::SW1, CSy::CS1), 0x00);
1054 assert_eq!(led_reg_offset(SWx::SW4, CSy::CS16), 0x45);
1055 assert_eq!(led_reg_offset(SWx::SW9, CSy::CS2), 0x91);
1056 assert_eq!(led_reg_offset(SWx::SW11, CSy::CS18), 0xC5);
1057 }
1058}