1use crate::error::Error;
2use crate::{FtInner, PinUse};
3use ftdi_mpsse::{ClockData, ClockDataOut, MpsseCmdBuilder, MpsseCmdExecutor};
4use std::sync::{Arc, Mutex, MutexGuard};
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10pub struct Polarity {
11 clk: ClockData,
15 clk_out: ClockDataOut,
19}
20
21impl From<eh0::spi::Polarity> for Polarity {
22 fn from(cpol: eh0::spi::Polarity) -> Self {
23 match cpol {
24 eh0::spi::Polarity::IdleLow => Polarity {
25 clk: ClockData::MsbPosIn,
26 clk_out: ClockDataOut::MsbNeg,
27 },
28 eh0::spi::Polarity::IdleHigh => Polarity {
29 clk: ClockData::MsbNegIn,
30 clk_out: ClockDataOut::MsbPos,
31 },
32 }
33 }
34}
35
36impl From<eh1::spi::Polarity> for Polarity {
37 fn from(cpol: eh1::spi::Polarity) -> Self {
38 match cpol {
39 eh1::spi::Polarity::IdleLow => Polarity {
40 clk: ClockData::MsbPosIn,
41 clk_out: ClockDataOut::MsbNeg,
42 },
43 eh1::spi::Polarity::IdleHigh => Polarity {
44 clk: ClockData::MsbNegIn,
45 clk_out: ClockDataOut::MsbPos,
46 },
47 }
48 }
49}
50
51impl Default for Polarity {
52 fn default() -> Self {
53 Self {
54 clk: ClockData::MsbPosIn,
55 clk_out: ClockDataOut::MsbNeg,
56 }
57 }
58}
59
60#[derive(Debug)]
68pub struct Spi<Device: MpsseCmdExecutor> {
69 mtx: Arc<Mutex<FtInner<Device>>>,
71 pol: Polarity,
73}
74
75impl<Device, E> Spi<Device>
76where
77 Device: MpsseCmdExecutor<Error = E>,
78 E: std::error::Error,
79 Error<E>: From<E>,
80{
81 pub(crate) fn new(mtx: Arc<Mutex<FtInner<Device>>>) -> Result<Spi<Device>, Error<E>> {
82 {
83 let mut lock = mtx.lock().expect("Failed to aquire FTDI mutex");
84 lock.allocate_pin(0, PinUse::Spi);
85 lock.allocate_pin(1, PinUse::Spi);
86 lock.allocate_pin(2, PinUse::Spi);
87
88 lock.direction &= !0x07;
90 lock.direction |= 0x03;
92
93 let cmd: MpsseCmdBuilder = MpsseCmdBuilder::new()
95 .set_gpio_lower(lock.value, lock.direction)
96 .send_immediate();
97 lock.ft.send(cmd.as_slice())?;
98 }
99
100 Ok(Spi {
101 mtx,
102 pol: Default::default(),
103 })
104 }
105
106 pub fn set_clock_polarity<P: Into<Polarity>>(&mut self, cpol: P) -> Result<(), Error<E>> {
128 self.pol = cpol.into();
129 let mut lock = self.mtx.lock().unwrap();
130 match self.pol.clk {
131 ClockData::MsbNegIn | ClockData::LsbNegIn => {
132 lock.lower.value |= 1;
133 }
134 ClockData::MsbPosIn | ClockData::LsbPosIn => {
135 lock.lower.value &= !1;
136 }
137 }
138 let cmd: MpsseCmdBuilder = MpsseCmdBuilder::new()
139 .set_gpio_lower(lock.value, lock.direction)
140 .send_immediate();
141 lock.ft.send(cmd.as_slice())?;
142 Ok(())
143 }
144}
145
146impl<Device, E> eh0::blocking::spi::Write<u8> for Spi<Device>
147where
148 Device: MpsseCmdExecutor<Error = E>,
149 E: std::error::Error,
150 Error<E>: From<E>,
151{
152 type Error = Error<E>;
153
154 fn write(&mut self, words: &[u8]) -> Result<(), Error<E>> {
155 let cmd: MpsseCmdBuilder = MpsseCmdBuilder::new()
156 .clock_data_out(self.pol.clk_out, words)
157 .send_immediate();
158
159 let mut lock = self.mtx.lock().expect("Failed to aquire FTDI mutex");
160 lock.ft.send(cmd.as_slice())?;
161
162 Ok(())
163 }
164}
165
166impl<Device, E> eh0::blocking::spi::Transfer<u8> for Spi<Device>
167where
168 Device: MpsseCmdExecutor<Error = E>,
169 E: std::error::Error,
170 Error<E>: From<E>,
171{
172 type Error = Error<E>;
173
174 fn transfer<'w>(&mut self, words: &'w mut [u8]) -> Result<&'w [u8], Error<E>> {
175 let cmd: MpsseCmdBuilder = MpsseCmdBuilder::new()
176 .clock_data(self.pol.clk, words)
177 .send_immediate();
178
179 let mut lock = self.mtx.lock().expect("Failed to aquire FTDI mutex");
180 lock.ft.send(cmd.as_slice())?;
181 lock.ft.recv(words)?;
182
183 Ok(words)
184 }
185}
186
187impl<Device, E> eh0::spi::FullDuplex<u8> for Spi<Device>
188where
189 Device: MpsseCmdExecutor<Error = E>,
190 E: std::error::Error,
191 Error<E>: From<E>,
192{
193 type Error = Error<E>;
194
195 fn read(&mut self) -> nb::Result<u8, Error<E>> {
196 let mut buf: [u8; 1] = [0];
197 let cmd: MpsseCmdBuilder = MpsseCmdBuilder::new()
198 .clock_data(self.pol.clk, &buf)
199 .send_immediate();
200
201 let mut lock = self.mtx.lock().expect("Failed to aquire FTDI mutex");
202 match lock.ft.xfer(cmd.as_slice(), &mut buf) {
203 Ok(()) => Ok(buf[0]),
204 Err(e) => Err(nb::Error::Other(Error::from(e))),
205 }
206 }
207
208 fn send(&mut self, byte: u8) -> nb::Result<(), Error<E>> {
209 let cmd: MpsseCmdBuilder = MpsseCmdBuilder::new()
210 .clock_data_out(self.pol.clk_out, &[byte])
211 .send_immediate();
212
213 let mut lock = self.mtx.lock().expect("Failed to aquire FTDI mutex");
214 match lock.ft.send(cmd.as_slice()) {
215 Ok(()) => Ok(()),
216 Err(e) => Err(nb::Error::Other(Error::from(e))),
217 }
218 }
219}
220
221impl<E> eh1::spi::Error for Error<E>
222where
223 E: std::error::Error,
224 Error<E>: From<E>,
225{
226 fn kind(&self) -> eh1::spi::ErrorKind {
227 eh1::spi::ErrorKind::Other
228 }
229}
230
231impl<Device, E> eh1::spi::ErrorType for Spi<Device>
232where
233 Device: MpsseCmdExecutor<Error = E>,
234 E: std::error::Error,
235 Error<E>: From<E>,
236{
237 type Error = Error<E>;
238}
239
240impl<Device, E> eh1::spi::SpiBus<u8> for Spi<Device>
241where
242 Device: MpsseCmdExecutor<Error = E>,
243 E: std::error::Error,
244 Error<E>: From<E>,
245{
246 fn read(&mut self, words: &mut [u8]) -> Result<(), Self::Error> {
247 let data_out: Vec<u8> = vec![0; words.len()];
248 let cmd: MpsseCmdBuilder = MpsseCmdBuilder::new()
249 .clock_data(self.pol.clk, &data_out)
250 .send_immediate();
251
252 let mut lock = self.mtx.lock().expect("Failed to aquire FTDI mutex");
253 lock.ft.send(cmd.as_slice())?;
254 lock.ft.recv(words)?;
255
256 Ok(())
257 }
258
259 fn write(&mut self, words: &[u8]) -> Result<(), Error<E>> {
260 let cmd: MpsseCmdBuilder = MpsseCmdBuilder::new()
261 .clock_data_out(self.pol.clk_out, words)
262 .send_immediate();
263
264 let mut lock = self.mtx.lock().expect("Failed to aquire FTDI mutex");
265 lock.ft.send(cmd.as_slice())?;
266
267 Ok(())
268 }
269
270 fn flush(&mut self) -> Result<(), Self::Error> {
271 Ok(())
272 }
273
274 fn transfer_in_place(&mut self, words: &mut [u8]) -> Result<(), Error<E>> {
275 let cmd: MpsseCmdBuilder = MpsseCmdBuilder::new()
276 .clock_data(self.pol.clk, words)
277 .send_immediate();
278
279 let mut lock = self.mtx.lock().expect("Failed to aquire FTDI mutex");
280
281 lock.ft.send(cmd.as_slice())?;
282 lock.ft.recv(words)?;
283
284 Ok(())
285 }
286
287 fn transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Error<E>> {
288 let cmd: MpsseCmdBuilder = MpsseCmdBuilder::new()
289 .clock_data(self.pol.clk, write)
290 .send_immediate();
291
292 let mut lock = self.mtx.lock().expect("Failed to aquire FTDI mutex");
293 lock.ft.send(cmd.as_slice())?;
294 lock.ft.recv(read)?;
295
296 let remain: usize = write.len().saturating_sub(read.len());
297 if remain != 0 {
298 let mut remain_buf: Vec<u8> = vec![0; remain];
299 lock.ft.recv(&mut remain_buf)?;
300 }
301
302 Ok(())
303 }
304}
305
306impl<Device, E> ehnb1::spi::FullDuplex<u8> for Spi<Device>
307where
308 Device: MpsseCmdExecutor<Error = E>,
309 E: std::error::Error,
310 Error<E>: From<E>,
311{
312 fn read(&mut self) -> nb::Result<u8, Error<E>> {
313 let mut buf: [u8; 1] = [0];
314 let cmd: MpsseCmdBuilder = MpsseCmdBuilder::new()
315 .clock_data(self.pol.clk, &buf)
316 .send_immediate();
317
318 let mut lock = self.mtx.lock().expect("Failed to aquire FTDI mutex");
319 match lock.ft.xfer(cmd.as_slice(), &mut buf) {
320 Ok(()) => Ok(buf[0]),
321 Err(e) => Err(nb::Error::Other(Error::from(e))),
322 }
323 }
324
325 fn write(&mut self, byte: u8) -> nb::Result<(), Error<E>> {
326 let cmd: MpsseCmdBuilder = MpsseCmdBuilder::new()
327 .clock_data_out(self.pol.clk_out, &[byte])
328 .send_immediate();
329
330 let mut lock = self.mtx.lock().expect("Failed to aquire FTDI mutex");
331 match lock.ft.send(cmd.as_slice()) {
332 Ok(()) => Ok(()),
333 Err(e) => Err(nb::Error::Other(Error::from(e))),
334 }
335 }
336}
337
338pub struct SpiDeviceBus<'a, Device: MpsseCmdExecutor> {
339 lock: MutexGuard<'a, FtInner<Device>>,
340 pol: Polarity,
341}
342
343impl<Device, E> eh1::spi::ErrorType for SpiDeviceBus<'_, Device>
344where
345 Device: MpsseCmdExecutor<Error = E>,
346 E: std::error::Error,
347 Error<E>: From<E>,
348{
349 type Error = Error<E>;
350}
351
352impl<Device, E> eh1::spi::SpiBus<u8> for SpiDeviceBus<'_, Device>
353where
354 Device: MpsseCmdExecutor<Error = E>,
355 E: std::error::Error,
356 Error<E>: From<E>,
357{
358 fn read(&mut self, words: &mut [u8]) -> Result<(), Self::Error> {
359 self.lock.ft.xfer(
360 MpsseCmdBuilder::new()
361 .clock_data(self.pol.clk, words)
362 .send_immediate()
363 .as_slice(),
364 words,
365 )?;
366 Ok(())
367 }
368
369 fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> {
370 self.lock.ft.send(
371 MpsseCmdBuilder::new()
372 .clock_data_out(self.pol.clk_out, words)
373 .send_immediate()
374 .as_slice(),
375 )?;
376 Ok(())
377 }
378
379 fn flush(&mut self) -> Result<(), Self::Error> {
380 Ok(())
381 }
382
383 fn transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Self::Error> {
384 self.lock.ft.xfer(
385 MpsseCmdBuilder::new()
386 .clock_data(self.pol.clk, write)
387 .send_immediate()
388 .as_slice(),
389 read,
390 )?;
391 Ok(())
392 }
393
394 fn transfer_in_place(&mut self, words: &mut [u8]) -> Result<(), Self::Error> {
395 self.lock.ft.xfer(
396 MpsseCmdBuilder::new()
397 .clock_data(self.pol.clk, words)
398 .send_immediate()
399 .as_slice(),
400 words,
401 )?;
402 Ok(())
403 }
404}
405
406#[derive(Debug)]
414pub struct SpiDevice<Device: MpsseCmdExecutor> {
415 mtx: Arc<Mutex<FtInner<Device>>>,
417 pol: Polarity,
419 cs_idx: u8,
421}
422
423impl<Device, E> SpiDevice<Device>
424where
425 Device: MpsseCmdExecutor<Error = E>,
426 E: std::error::Error,
427 Error<E>: From<E>,
428{
429 pub(crate) fn new(
430 mtx: Arc<Mutex<FtInner<Device>>>,
431 cs_idx: u8,
432 ) -> Result<SpiDevice<Device>, Error<E>> {
433 {
434 let mut lock = mtx.lock().expect("Failed to aquire FTDI mutex");
435 lock.allocate_pin(0, PinUse::Spi);
436 lock.allocate_pin(1, PinUse::Spi);
437 lock.allocate_pin(2, PinUse::Spi);
438 lock.allocate_pin(cs_idx, PinUse::Output);
439
440 let cs_mask: u8 = 1 << cs_idx;
441
442 lock.direction &= !(0x07 | cs_mask);
444 lock.direction |= 0x03 | cs_mask;
446 lock.value |= cs_mask;
448
449 let cmd: MpsseCmdBuilder = MpsseCmdBuilder::new()
451 .set_gpio_lower(lock.value, lock.direction)
452 .send_immediate();
453 lock.ft.send(cmd.as_slice())?;
454 }
455
456 Ok(Self {
457 mtx,
458 pol: Default::default(),
459 cs_idx,
460 })
461 }
462
463 pub(crate) fn cs_mask(&self) -> u8 {
464 1 << self.cs_idx
465 }
466
467 pub fn set_clock_polarity<P: Into<Polarity>>(&mut self, cpol: P) -> Result<(), Error<E>> {
489 self.pol = cpol.into();
490 let mut lock = self.mtx.lock().unwrap();
491 match self.pol.clk {
492 ClockData::MsbNegIn | ClockData::LsbNegIn => {
493 lock.lower.value |= 1;
494 }
495 ClockData::MsbPosIn | ClockData::LsbPosIn => {
496 lock.lower.value &= !1;
497 }
498 }
499 let cmd: MpsseCmdBuilder = MpsseCmdBuilder::new()
500 .set_gpio_lower(lock.value, lock.direction)
501 .send_immediate();
502 lock.ft.send(cmd.as_slice())?;
503 Ok(())
504 }
505}
506
507impl<Device, E> eh1::spi::ErrorType for SpiDevice<Device>
508where
509 Device: MpsseCmdExecutor<Error = E>,
510 E: std::error::Error,
511 Error<E>: From<E>,
512{
513 type Error = Error<E>;
514}
515
516impl<Device, E> eh1::spi::SpiDevice for SpiDevice<Device>
517where
518 Device: MpsseCmdExecutor<Error = E>,
519 E: std::error::Error,
520 Error<E>: From<E>,
521{
522 fn transaction(
523 &mut self,
524 operations: &mut [eh1::spi::Operation<'_, u8>],
525 ) -> Result<(), Self::Error> {
526 let mut lock: MutexGuard<FtInner<Device>> =
528 self.mtx.lock().expect("Failed to aquire FTDI mutex");
529 let direction: u8 = lock.direction;
530
531 let mut value_cs_asserted: u8 = lock.value & !self.cs_mask();
533
534 match self.pol.clk {
537 ClockData::MsbNegIn | ClockData::LsbNegIn => {
538 value_cs_asserted |= 1;
539 }
540 ClockData::MsbPosIn | ClockData::LsbPosIn => {
541 value_cs_asserted &= !1;
542 }
543 }
544
545 lock.ft.send(
546 MpsseCmdBuilder::new()
547 .set_gpio_lower(value_cs_asserted, direction)
548 .send_immediate()
549 .as_slice(),
550 )?;
551
552 let mut bus: SpiDeviceBus<Device> = SpiDeviceBus {
553 lock,
554 pol: self.pol,
555 };
556
557 for op in operations {
558 match op {
559 eh1::spi::Operation::Read(buffer) => {
560 eh1::spi::SpiBus::read(&mut bus, buffer)?;
561 }
562 eh1::spi::Operation::Write(buffer) => {
563 eh1::spi::SpiBus::write(&mut bus, buffer)?;
564 }
565 eh1::spi::Operation::Transfer(read, write) => {
566 eh1::spi::SpiBus::transfer(&mut bus, read, write)?;
567 }
568 eh1::spi::Operation::TransferInPlace(buffer) => {
569 eh1::spi::SpiBus::transfer_in_place(&mut bus, buffer)?;
570 }
571 eh1::spi::Operation::DelayNs(micros) => {
572 std::thread::sleep(std::time::Duration::from_nanos((*micros).into()));
573 }
574 }
575 }
576
577 {
579 use eh1::spi::SpiBus;
580 bus.flush()?;
581 }
582
583 let mut lock: MutexGuard<FtInner<Device>> = bus.lock;
584
585 let mut value_cs_deasserted: u8 = lock.value | self.cs_mask();
587
588 match self.pol.clk {
591 ClockData::MsbNegIn | ClockData::LsbNegIn => {
592 value_cs_deasserted |= 1;
593 }
594 ClockData::MsbPosIn | ClockData::LsbPosIn => {
595 value_cs_deasserted &= !1;
596 }
597 }
598
599 lock.ft.send(
600 MpsseCmdBuilder::new()
601 .set_gpio_lower(value_cs_deasserted, direction)
602 .send_immediate()
603 .as_slice(),
604 )?;
605
606 Ok(())
608 }
609}