imix/test/
spi_dummy.rs

1// Licensed under the Apache License, Version 2.0 or the MIT License.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// Copyright Tock Contributors 2022.
4
5//! A dummy SPI client to test the SPI implementation
6
7use core::ptr::addr_of_mut;
8
9use kernel::hil::gpio::Configure;
10use kernel::hil::spi::{self, SpiMaster};
11use kernel::utilities::leasable_buffer::SubSliceMut;
12use kernel::ErrorCode;
13
14#[allow(unused_variables, dead_code)]
15pub struct DummyCB {
16    val: u8,
17    spi: &'static sam4l::spi::SpiHw<'static>,
18}
19
20impl DummyCB {
21    pub fn new(spi: &'static sam4l::spi::SpiHw<'static>) -> Self {
22        Self { val: 0x55_u8, spi }
23    }
24}
25
26pub static mut FLOP: bool = false;
27pub static mut BUF1: [u8; 8] = [0, 0, 0, 0, 0, 0, 0, 0];
28pub static mut BUF2: [u8; 8] = [8, 7, 6, 5, 4, 3, 2, 1];
29pub static mut A5: [u8; 16] = [0xA5; 16];
30
31impl spi::SpiMasterClient for DummyCB {
32    #[allow(unused_variables, dead_code)]
33    fn read_write_done(
34        &self,
35        write: SubSliceMut<'static, u8>,
36        read: Option<SubSliceMut<'static, u8>>,
37        status: Result<usize, ErrorCode>,
38    ) {
39        unsafe {
40            // do actual stuff
41            // TODO verify SPI return value
42            let _ = self
43                .spi
44                .read_write_bytes((&mut *addr_of_mut!(A5) as &mut [u8]).into(), None);
45
46            // FLOP = !FLOP;
47            // let len: usize = BUF1.len();
48            // if FLOP {
49            //     sam4l::spi::SPI.read_write_bytes(&mut BUF1, Some(&mut BUF2), len);
50            // } else {
51            //     sam4l::spi::SPI.read_write_bytes(&mut BUF2, Some(&mut BUF1), len);
52            // }
53        }
54    }
55}
56
57// This test first turns on the Imix's User led, asserts pin D2 and then
58// initiates a continuous SPI transfer of 8 bytes.
59//
60// If the SPI transfer of multiple bytes fail, then the test will loop writing
61// 0xA5.
62//
63// The first SPI transfer outputs [8, 7, 6, 5, 4, 3, 2, 1] then echoes whatever
64// input it recieves from the slave on peripheral 1 continuously.
65//
66// To test with a logic analyzer, connect probes to pin D2 on the Imix, and
67// the SPI MOSI and CLK pins (exposed on the Imix's 20-pin header). Setup
68// the logic analyzer to trigger sampling on assertion of pin 2, then restart
69// the board.
70#[inline(never)]
71#[allow(unused_variables, dead_code)]
72pub unsafe fn spi_dummy_test(spi: &'static sam4l::spi::SpiHw<'static>) {
73    // set the LED to mark that we've programmed.
74    let pin = sam4l::gpio::GPIOPin::new(sam4l::gpio::Pin::PC10);
75    pin.make_output();
76    pin.set();
77
78    let pin2 = sam4l::gpio::GPIOPin::new(sam4l::gpio::Pin::PC31); // It's on D2 of the IMIX
79    pin2.make_output();
80    pin2.set();
81
82    let spicb = kernel::static_init!(DummyCB, DummyCB::new(spi));
83    spi.specify_chip_select(sam4l::spi::Peripheral::Peripheral0)
84        .unwrap();
85    spi.set_client(spicb);
86
87    spi.init().unwrap();
88    spi.set_baud_rate(200000);
89
90    let buf2 = &mut *addr_of_mut!(BUF2);
91    let len = buf2.len();
92    if spi.read_write_bytes(
93        (buf2 as &mut [u8]).into(),
94        Some((&mut *addr_of_mut!(BUF1) as &mut [u8]).into()),
95    ) != Ok(())
96    {
97        loop {
98            spi.write_byte(0xA5).unwrap();
99        }
100    }
101
102    pin2.clear();
103}