This repository has been archived on 2024-06-16. You can view files and clone it, but cannot push or open issues or pull requests.
Robin Mueller 3886e2f11f First I2C implementation
Initial I2C HAL implementation.
Only the I2cMaster was tested so far, I2cSlave will be tested next.

Master side was tested with a temerature sensor example application
in the vorago-reb1 crate
2021-12-02 12:05:24 +01:00

190 lines
6.6 KiB
Rust

//! SPI example application
#![no_main]
#![no_std]
use core::cell::RefCell;
use cortex_m_rt::entry;
use embedded_hal::spi::{Mode, MODE_0};
use panic_rtt_target as _;
use rtt_target::{rprintln, rtt_init_print};
use va108xx_hal::{
gpio::{PinsA, PinsB},
pac::{self, SPIA, SPIB},
prelude::*,
spi::{self, Spi, SpiBase, TransferConfig},
timer::CountDownTimer,
};
#[derive(PartialEq, Debug)]
pub enum ExampleSelect {
// Enter loopback mode. It is not necessary to tie MOSI/MISO together for this
Loopback,
// Send a test buffer and print everything received
TestBuffer,
}
#[derive(PartialEq, Debug)]
pub enum SpiBusSelect {
SpiAPortA,
SpiAPortB,
SpiBPortB,
}
const EXAMPLE_SEL: ExampleSelect = ExampleSelect::TestBuffer;
const SPI_BUS_SEL: SpiBusSelect = SpiBusSelect::SpiBPortB;
const SPI_SPEED_KHZ: u32 = 1000;
const SPI_MODE: Mode = MODE_0;
const BLOCKMODE: bool = true;
#[entry]
fn main() -> ! {
rtt_init_print!();
rprintln!("-- VA108xx SPI example application--");
let mut dp = pac::Peripherals::take().unwrap();
let spia_ref: RefCell<Option<SpiBase<SPIA, u8>>> = RefCell::new(None);
let spib_ref: RefCell<Option<SpiBase<SPIB, u8>>> = RefCell::new(None);
let pinsa = PinsA::new(&mut dp.SYSCONFIG, None, dp.PORTA);
let pinsb = PinsB::new(&mut dp.SYSCONFIG, Some(dp.IOCONFIG), dp.PORTB);
let mut spi_cfg = spi::SpiConfig::default();
if EXAMPLE_SEL == ExampleSelect::Loopback {
spi_cfg = spi_cfg.loopback(true)
}
// Set up the SPI peripheral
match SPI_BUS_SEL {
SpiBusSelect::SpiAPortA => {
let (sck, mosi, miso) = (
pinsa.pa31.into_funsel_1(),
pinsa.pa30.into_funsel_1(),
pinsa.pa29.into_funsel_1(),
);
spia_ref.borrow_mut().replace(
Spi::spia(
dp.SPIA,
(sck, miso, mosi),
50.mhz(),
spi_cfg,
Some(&mut dp.SYSCONFIG),
None,
)
.downgrade(),
);
}
SpiBusSelect::SpiAPortB => {
let (sck, mosi, miso) = (
pinsb.pb9.into_funsel_2(),
pinsb.pb8.into_funsel_2(),
pinsb.pb7.into_funsel_2(),
);
spia_ref.borrow_mut().replace(
Spi::spia(
dp.SPIA,
(sck, miso, mosi),
50.mhz(),
spi_cfg,
Some(&mut dp.SYSCONFIG),
None,
)
.downgrade(),
);
}
SpiBusSelect::SpiBPortB => {
let (sck, mosi, miso) = (
pinsb.pb5.into_funsel_1(),
pinsb.pb4.into_funsel_1(),
pinsb.pb3.into_funsel_1(),
);
spib_ref.borrow_mut().replace(
Spi::spib(
dp.SPIB,
(sck, miso, mosi),
50.mhz(),
spi_cfg,
Some(&mut dp.SYSCONFIG),
None,
)
.downgrade(),
);
}
}
// Configure transfer specific properties here
match SPI_BUS_SEL {
SpiBusSelect::SpiAPortA | SpiBusSelect::SpiAPortB => {
if let Some(ref mut spi) = *spia_ref.borrow_mut() {
let transfer_cfg = TransferConfig::new_no_hw_cs(
SPI_SPEED_KHZ.khz().into(),
SPI_MODE,
BLOCKMODE,
false,
);
spi.cfg_transfer(&transfer_cfg);
}
}
SpiBusSelect::SpiBPortB => {
if let Some(ref mut spi) = *spib_ref.borrow_mut() {
let hw_cs_pin = pinsb.pb2.into_funsel_1();
let transfer_cfg = TransferConfig::new(
SPI_SPEED_KHZ.khz().into(),
SPI_MODE,
Some(hw_cs_pin),
BLOCKMODE,
false,
);
spi.cfg_transfer(&transfer_cfg);
}
}
}
// Application logic
let mut delay_tim = CountDownTimer::tim1(&mut dp.SYSCONFIG, 50.mhz().into(), dp.TIM1);
loop {
match SPI_BUS_SEL {
SpiBusSelect::SpiAPortA | SpiBusSelect::SpiAPortB => {
if let Some(ref mut spi) = *spia_ref.borrow_mut() {
if EXAMPLE_SEL == ExampleSelect::Loopback {
nb::block!(spi.send(0x42_u8)).unwrap();
let word = nb::block!(spi.read()).unwrap();
assert_eq!(word, 0x42);
delay_tim.delay_ms(500_u32);
let mut send_buf: [u8; 3] = [0x03, 0x02, 0x01];
let reply = spi.transfer(&mut send_buf).unwrap();
rprintln!("Received reply: {}, {}, {}", reply[0], reply[1], reply[2]);
assert_eq!(reply, &[0x03, 0x02, 0x01]);
delay_tim.delay_ms(500_u32);
} else {
let mut send_buf: [u8; 3] = [0x01, 0x02, 0x03];
let reply = spi.transfer(&mut send_buf).unwrap();
rprintln!("Received reply: {}, {}, {}", reply[0], reply[1], reply[2]);
delay_tim.delay_ms(1000_u32);
}
}
}
SpiBusSelect::SpiBPortB => {
if let Some(ref mut spi) = *spib_ref.borrow_mut() {
if EXAMPLE_SEL == ExampleSelect::Loopback {
nb::block!(spi.send(0x42_u8)).unwrap();
let word = nb::block!(spi.read()).unwrap();
assert_eq!(word, 0x42);
delay_tim.delay_ms(500_u32);
let mut send_buf: [u8; 3] = [0x03, 0x02, 0x01];
let reply = spi.transfer(&mut send_buf).unwrap();
rprintln!("Received reply: {}, {}, {}", reply[0], reply[1], reply[2]);
assert_eq!(reply, &[0x03, 0x02, 0x01]);
delay_tim.delay_ms(500_u32);
} else {
let mut send_buf: [u8; 3] = [0x01, 0x02, 0x03];
let reply = spi.transfer(&mut send_buf).unwrap();
rprintln!("Received reply: {}, {}, {}", reply[0], reply[1], reply[2]);
delay_tim.delay_ms(1000_u32);
}
}
}
}
}
}