jtag_scanner/protocols/
spi.rs1use embedded_hal::spi::{Mode, Phase, Polarity, SpiBus};
2
3use crate::{Error, PinGroup, PinId};
4
5pub struct Spi {
6 pin_group: PinGroup,
7 sck: PinId,
8 mosi: PinId,
9 miso: PinId,
10 mode: Mode,
11 lsb_first: bool,
12}
13
14impl Spi {
15 pub fn new(mut pin_group: PinGroup, mode: Mode) -> Result<Self, Error> {
20 let sck = pin_group.get_pin_id("SCK")?;
21 let mosi = pin_group.get_pin_id("MOSI")?;
22 let miso = pin_group.get_pin_id("MISO")?;
23 if !sck.is_output()
24 || !pin_group.pin_writable(&sck)?
25 || !mosi.is_output()
26 || !pin_group.pin_writable(&mosi)?
27 || !miso.is_input()
28 {
29 return Error::result(crate::ErrorKind::WrongPinType, "bad SPI pin config");
30 }
31 pin_group.set_pin_state(&sck, Some(mode.polarity == Polarity::IdleHigh))?;
32 if miso.is_output() && pin_group.pin_writable(&miso)? {
33 pin_group.set_pin_state(&miso, None)?;
34 }
35 pin_group.write_update()?;
36 Ok(Self {
37 pin_group,
38 sck,
39 miso,
40 mosi,
41 mode,
42 lsb_first: false,
43 })
44 }
45
46 pub fn set_lsb_first(&mut self, val: bool) {
49 self.lsb_first = val;
50 }
51}
52
53impl embedded_hal::spi::Error for Error {
54 fn kind(&self) -> embedded_hal::spi::ErrorKind {
55 embedded_hal::spi::ErrorKind::Other
56 }
57}
58
59impl embedded_hal::spi::ErrorType for Spi {
60 type Error = Error;
61}
62
63impl SpiBus for Spi {
64 fn transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Self::Error> {
65 let len = read.len().max(write.len());
66 if len == 0 {
67 return Ok(());
68 }
69 let cpha = self.mode.phase == Phase::CaptureOnSecondTransition;
70 let cpol = self.mode.polarity == Polarity::IdleHigh;
71
72 let mut set_bit = |bit_index: usize, val: bool| {
73 let i_byte = bit_index / 8;
74 if i_byte >= read.len() {
75 return; }
77 let i_bit = if self.lsb_first {
78 bit_index % 8
79 } else {
80 7 - bit_index % 8
81 };
82 if val {
83 read[i_byte] |= 1 << i_bit;
84 } else {
85 read[i_byte] &= 0xFF ^ (1 << i_bit);
86 }
87 };
88
89 let get_bit = |bit_index: usize| -> bool {
90 let i_byte = bit_index / 8;
91 if i_byte >= write.len() {
92 return false; }
94 let i_bit = if self.lsb_first {
95 bit_index % 8
96 } else {
97 7 - bit_index % 8
98 };
99 ((write[i_byte] >> i_bit) & 1) == 1
100 };
101
102 self.pin_group.batch(
105 len * 8 * 2,
106 |i, edit| {
107 if i % 2 == 0 {
108 let bit_index = i / 2;
109 edit.set(&self.mosi, Some(get_bit(bit_index)))?;
110 let sck_val = if cpha { !cpol } else { cpol };
111 edit.set(&self.sck, Some(sck_val))?;
112 } else {
113 let sck_val = if cpha { cpol } else { !cpol };
114 edit.set(&self.sck, Some(sck_val))?;
115 }
116 Ok(())
117 },
118 |i, view| {
119 if i % 2 != 0 {
120 let bit_index = i / 2;
121 let bit_read = view.get(&self.miso)?.input().unwrap();
122 set_bit(bit_index, bit_read);
123 }
124 Ok(())
125 },
126 )?;
127 if !cpha {
128 self.pin_group.set_pin_state(&self.sck, Some(cpol))?;
129 self.pin_group.write_update()?;
130 }
131 Ok(())
132 }
133
134 fn read(&mut self, words: &mut [u8]) -> Result<(), Self::Error> {
135 for w in words.iter_mut() {
136 *w = 0x00;
137 }
138 self.transfer_in_place(words)
139 }
140 fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> {
141 let mut buf_read = vec![0x00; words.len()];
142 self.transfer(&mut buf_read, words)
143 }
144 fn transfer_in_place(&mut self, words: &mut [u8]) -> Result<(), Self::Error> {
145 let buf_write = Vec::from(&mut *words);
146 self.transfer(words, &buf_write)
147 }
148 fn flush(&mut self) -> Result<(), Self::Error> {
149 Ok(())
150 }
151}