1use stm32f7xx_hal::{
10 gpio::{self, Output, PinState, PushPull},
11 prelude::*,
12 spi::{self, Enabled, Spi},
13};
14
15pub struct SpiBus<I, P> {
17 spi: Spi<I, P, Enabled<u8>>,
18}
19
20impl<I, P> SpiBus<I, P>
21where
22 I: spi::Instance,
23 P: spi::Pins<I>,
24{
25 pub fn new(spi: Spi<I, P, Enabled<u8>>) -> Self {
26 Self { spi }
27 }
28
29 pub fn transfer_byte(&mut self, byte: u8) -> Result<u8, spi::Error> {
31 let mut tmp = [byte];
32 self.spi.transfer(&mut tmp)?;
33 Ok(tmp[0])
34 }
35
36 #[inline]
38 pub fn write_byte(&mut self, byte: u8) -> Result<(), spi::Error> {
39 let _ = self.transfer_byte(byte)?;
40 Ok(())
41 }
42
43 #[inline]
45 pub fn read_byte(&mut self) -> Result<u8, spi::Error> {
46 self.transfer_byte(0x00)
47 }
48
49 pub fn transfer_in_place(&mut self, buf: &mut [u8]) -> Result<(), spi::Error> {
51 for b in buf.iter_mut() {
52 *b = self.transfer_byte(*b)?;
53 }
54 Ok(())
55 }
56
57 pub fn free(self) -> Spi<I, P, Enabled<u8>> {
58 self.spi
59 }
60}
61
62pub trait CsControl {
64 fn select(&mut self);
65 fn deselect(&mut self);
66}
67
68pub struct NoChipSelect;
71
72impl CsControl for NoChipSelect {
73 fn select(&mut self) {
74 panic!("SPI chip select used on a driver constructed without one");
75 }
76 fn deselect(&mut self) {
77 panic!("SPI chip select used on a driver constructed without one");
78 }
79}
80
81pub struct ChipSelect<const P: char, const N: u8> {
83 pin: gpio::Pin<P, N, Output<PushPull>>,
84}
85
86impl<const P: char, const N: u8> ChipSelect<P, N> {
87 pub fn active_low<MODE>(pin: gpio::Pin<P, N, MODE>) -> Self {
89 let mut pin = pin.into_push_pull_output();
90 pin.set_state(PinState::High);
91 Self { pin }
92 }
93
94 #[inline]
96 pub fn select(&mut self) {
97 self.pin.set_low();
98 }
99
100 #[inline]
102 pub fn deselect(&mut self) {
103 self.pin.set_high();
104 }
105
106 pub fn free(self) -> gpio::Pin<P, N, Output<PushPull>> {
107 self.pin
108 }
109}
110
111impl<const P: char, const N: u8> CsControl for ChipSelect<P, N> {
112 #[inline]
113 fn select(&mut self) {
114 self.pin.set_low();
115 }
116 #[inline]
117 fn deselect(&mut self) {
118 self.pin.set_high();
119 }
120}