forked from stm32-rs/stm32h7xx-hal
-
Notifications
You must be signed in to change notification settings - Fork 1
/
spi_hardware_cs.rs
93 lines (79 loc) · 2.86 KB
/
spi_hardware_cs.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
//! This example shows off how the hardware chip select is implemented in the HAL.
//!
//! There are 4 modes:
//! - Disabled (default)
//! - EndlessTransaction
//! - WordTransaction
//! - FrameTransaction
//!
//! For more docs, see https://docs.rs/stm32h7xx-hal/latest/stm32h7xx_hal/spi/index.html
//!
#![deny(warnings)]
#![no_main]
#![no_std]
use cortex_m_rt::entry;
#[macro_use]
mod utilities;
use stm32h7xx_hal::{pac, prelude::*, spi};
use log::info;
use nb::block;
#[entry]
fn main() -> ! {
utilities::logger::init();
let dp = pac::Peripherals::take().unwrap();
// Constrain and Freeze power
info!("Setup PWR... ");
let pwr = dp.PWR.constrain();
let pwrcfg = example_power!(pwr).freeze();
// Constrain and Freeze clock
info!("Setup RCC... ");
let rcc = dp.RCC.constrain();
let ccdr = rcc
.sys_ck(96.mhz())
.pll1_q_ck(48.mhz())
.freeze(pwrcfg, &dp.SYSCFG);
// Acquire the GPIOA peripheral. This also enables the clock for
// GPIOA in the RCC register.
let gpioa = dp.GPIOA.split(ccdr.peripheral.GPIOA);
let sck = gpioa.pa5.into_alternate_af5();
let miso = gpioa.pa6.into_alternate_af5();
let mosi = gpioa.pa7.into_alternate_af5();
// Because we want to use the hardware chip select, we need to provide that too
let hcs = gpioa.pa4.into_alternate_af5();
info!("");
info!("stm32h7xx-hal example - SPI");
info!("");
// Initialise the SPI peripheral.
let mut spi = dp.SPI1.spi(
// Give ownership of the pins
(sck, miso, mosi, hcs),
// Create a config with the hardware chip select given
spi::Config::new(spi::MODE_0)
// Put 1 us idle time between every word sent. (the max is 15 spi peripheral ticks)
.inter_word_delay(0.000001)
// Specify that we use the hardware cs
.hardware_cs(spi::HardwareCS {
// See the docs of the HardwareCSMode to see what the different modes do
mode: spi::HardwareCSMode::EndlessTransaction,
// Put 1 us between the CS being asserted and the first clock
assertion_delay: 0.000001,
// Our CS should be high when not active and low when asserted
polarity: spi::Polarity::IdleHigh,
}),
3.mhz(),
ccdr.peripheral.SPI1,
&ccdr.clocks,
);
// Write fixed data.
// The CS will automatically be pulled low before the data is sent.
// Because the SPI is in EndlessTransaction mode, the CS will never be de-asserted.
spi.write(&[0x11u8, 0x22, 0x33]).unwrap();
// The CS can be de-asserted manually, though
spi.end_transaction().unwrap();
// Echo what is received on the SPI
let mut received = 0;
loop {
block!(spi.send(received)).ok();
received = block!(spi.read()).unwrap();
}
}