Adding updates for 0.8.0 of the HAL

This commit is contained in:
Ryan Summers 2020-10-28 15:41:27 +01:00
parent 17c8e4d2e1
commit c058d4bcde
5 changed files with 139 additions and 58 deletions

14
Cargo.lock generated
View File

@ -108,9 +108,9 @@ checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
[[package]] [[package]]
name = "cortex-m" name = "cortex-m"
version = "0.6.3" version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2be99930c99669a74d986f7fd2162085498b322e6daae8ef63a97cc9ac1dc73c" checksum = "88cdafeafba636c00c467ded7f1587210725a1adfab0c24028a7844b87738263"
dependencies = [ dependencies = [
"aligned", "aligned",
"bare-metal 0.2.5", "bare-metal 0.2.5",
@ -362,9 +362,9 @@ dependencies = [
[[package]] [[package]]
name = "proc-macro-hack" name = "proc-macro-hack"
version = "0.5.18" version = "0.5.19"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "99c605b9a0adc77b7211c6b1f722dcb613d68d66859a44f3d485a6da332b0598" checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
@ -495,7 +495,7 @@ dependencies = [
"serde-json-core", "serde-json-core",
"smoltcp", "smoltcp",
"stm32h7-ethernet", "stm32h7-ethernet",
"stm32h7xx-hal 0.7.1", "stm32h7xx-hal 0.8.0",
] ]
[[package]] [[package]]
@ -557,8 +557,8 @@ dependencies = [
[[package]] [[package]]
name = "stm32h7xx-hal" name = "stm32h7xx-hal"
version = "0.7.1" version = "0.8.0"
source = "git+https://github.com/stm32-rs/stm32h7xx-hal#f28cf3e66c7a7fe2bdd1518f06acbf680e9b9a11" source = "git+https://github.com/quartiq/stm32h7xx-hal?branch=rs/issue-158/managed-spi#cc36bbbaa1bf21e53732cfc0f3dd7175c3ed6d44"
dependencies = [ dependencies = [
"bare-metal 1.0.0", "bare-metal 1.0.0",
"cast", "cast",

View File

@ -58,9 +58,9 @@ branch = "master"
features = ["stm32h743v"] features = ["stm32h743v"]
[dependencies.stm32h7xx-hal] [dependencies.stm32h7xx-hal]
features = ["stm32h743v", "rt", "unproven", "ethernet", "phy_lan8742a", "quadspi"] features = ["stm32h743v", "rt", "unproven", "ethernet", "quadspi"]
git = "https://github.com/stm32-rs/stm32h7xx-hal" git = "https://github.com/quartiq/stm32h7xx-hal"
# path = "../stm32h7xx-hal" branch = "rs/issue-158/managed-spi"
[features] [features]
semihosting = ["panic-semihosting", "cortex-m-log/semihosting"] semihosting = ["panic-semihosting", "cortex-m-log/semihosting"]

View File

@ -572,12 +572,17 @@ where
/ (1u64 << 32) as f64) / (1u64 << 32) as f64)
} }
pub fn write_profile(&mut self, channel: Channel, freq: f64, turns: f32) -> Result<(), Error> { pub fn write_profile(
&mut self,
channel: Channel,
freq: f64,
turns: f32,
) -> Result<(), Error> {
// The function for channel frequency is `f_out = FTW * f_s / 2^32`, where FTW is the // The function for channel frequency is `f_out = FTW * f_s / 2^32`, where FTW is the
// frequency tuning word and f_s is the system clock rate. // frequency tuning word and f_s is the system clock rate.
let tuning_word: u32 = let tuning_word: u32 = ((freq as f64 / self.system_clock_frequency())
((freq as f64 / self.system_clock_frequency()) * 1u64.wrapping_shl(32) as f64)
* 1u64.wrapping_shl(32) as f64) as u32; as u32;
let phase_offset: u16 = (turns * (1 << 14) as f32) as u16 & 0x3FFFu16; let phase_offset: u16 = (turns * (1 << 14) as f32) as u16 & 0x3FFFu16;
@ -586,13 +591,19 @@ where
data[0..2].copy_from_slice(&phase_offset.to_be_bytes()); data[0..2].copy_from_slice(&phase_offset.to_be_bytes());
data[3] = Register::CFTW0 as u8; data[3] = Register::CFTW0 as u8;
data[4..7].copy_from_slice(&tuning_word.to_be_bytes()); data[4..7].copy_from_slice(&tuning_word.to_be_bytes());
interface.write(Register::CPOW0 as u8, &data).map_err(|_| Error::Interface) interface
.write(Register::CPOW0 as u8, &data)
.map_err(|_| Error::Interface)
})?; })?;
Ok(()) Ok(())
} }
fn modify_channel_closure<F>(&mut self, channel: Channel, f: F) -> Result<(), Error> fn modify_channel_closure<F>(
&mut self,
channel: Channel,
f: F,
) -> Result<(), Error>
where where
F: FnOnce(&mut INTERFACE) -> Result<(), Error>, F: FnOnce(&mut INTERFACE) -> Result<(), Error>,
{ {

View File

@ -1,4 +1,3 @@
#![deny(warnings)]
#![allow(clippy::missing_safety_doc)] #![allow(clippy::missing_safety_doc)]
#![no_std] #![no_std]
#![no_main] #![no_main]
@ -35,11 +34,12 @@ use stm32h7xx_hal::prelude::*;
use embedded_hal::digital::v2::{InputPin, OutputPin}; use embedded_hal::digital::v2::{InputPin, OutputPin};
use smoltcp as net;
use hal::{ use hal::{
dma::{DmaChannel, DmaExt, DmaInternal},
ethernet, ethernet,
dma::{DmaExt, DmaChannel, DmaInternal}, rcc::rec::ResetEnable,
}; };
use smoltcp as net;
use heapless::{consts::*, String}; use heapless::{consts::*, String};
@ -92,7 +92,7 @@ static mut NET_STORE: NetStorage = NetStorage {
const SCALE: f32 = ((1 << 15) - 1) as f32; const SCALE: f32 = ((1 << 15) - 1) as f32;
const SPI_START_CODE: u32 = 0x201; const SPI_START: u32 = 0x00;
// static ETHERNET_PENDING: AtomicBool = AtomicBool::new(true); // static ETHERNET_PENDING: AtomicBool = AtomicBool::new(true);
@ -176,22 +176,13 @@ const APP: () = {
timer: hal::timer::Timer<hal::stm32::TIM2>, timer: hal::timer::Timer<hal::stm32::TIM2>,
// Note: It appears that rustfmt generates a format that GDB cannot recognize, which // Note: It appears that rustfmt generates a format that GDB cannot recognize, which
// results in GDB breakpoints being set improperly. To debug, redefine the following // results in GDB breakpoints being set improperly.
// definition to: #[rustfmt::skip]
//
// ```rust
// net_interface: net::iface::EthernetInterface<
// 'static,
// 'static,
// 'static,
// ethernet::EthernetDMA<'static>>,
// ```
net_interface: net::iface::EthernetInterface< net_interface: net::iface::EthernetInterface<
'static, 'static,
'static, 'static,
'static, 'static,
ethernet::EthernetDMA<'static>, ethernet::EthernetDMA<'static>>,
>,
eth_mac: ethernet::EthernetMAC, eth_mac: ethernet::EthernetMAC,
mac_addr: net::wire::EthernetAddress, mac_addr: net::wire::EthernetAddress,
@ -256,6 +247,7 @@ const APP: () = {
afe::ProgrammableGainAmplifier::new(a0_pin, a1_pin) afe::ProgrammableGainAmplifier::new(a0_pin, a1_pin)
}; };
clocks.peripheral.DMA1.reset().enable();
let mut dma_channels = dp.DMA1.split(); let mut dma_channels = dp.DMA1.split();
// Configure the SPI interfaces to the ADCs and DACs. // Configure the SPI interfaces to the ADCs and DACs.
@ -278,16 +270,34 @@ const APP: () = {
phase: hal::spi::Phase::CaptureOnSecondTransition, phase: hal::spi::Phase::CaptureOnSecondTransition,
}) })
.manage_cs() .manage_cs()
.suspend_when_inactive()
.cs_delay(220e-9); .cs_delay(220e-9);
dma_channels.0.set_peripheral_address(&dp.SPI2.cr1 as *const _ as u32, false); dma_channels.0.set_peripheral_address(
dma_channels.0.set_memory_address(&SPI_START_CODE as *const _ as u32, false); &dp.SPI2.txdr as *const _ as u32,
dma_channels.0.set_direction(hal::dma::Direction::MemoryToPeripherial); false,
);
dma_channels
.0
.set_memory_address(&SPI_START as *const _ as u32, false);
dma_channels
.0
.set_direction(hal::dma::Direction::MemoryToPeripherial);
dma_channels.0.set_transfer_length(1); dma_channels.0.set_transfer_length(1);
dma_channels.0.cr().modify(|_, w| w.circ().enabled()); dma_channels.0.cr().modify(|_, w| {
dma_channels.0.dmamux().modify(|_, w| w.circ()
w.dmareq_id().variant(hal::stm32::dmamux1::ccr::DMAREQ_ID_A::TIM2_UP)); .enabled()
dma_channels.0.start(); .psize()
.bits16()
.msize()
.bits16()
.pfctrl()
.dma()
});
dma_channels.0.dmamux().modify(|_, w| {
w.dmareq_id()
.variant(hal::stm32::dmamux1::ccr::DMAREQ_ID_A::TIM2_UP)
});
let mut spi: hal::spi::Spi<_, _, u16> = dp.SPI2.spi( let mut spi: hal::spi::Spi<_, _, u16> = dp.SPI2.spi(
(spi_sck, spi_miso, hal::spi::NoMosi), (spi_sck, spi_miso, hal::spi::NoMosi),
@ -297,6 +307,10 @@ const APP: () = {
&clocks.clocks, &clocks.clocks,
); );
// Kick-start the SPI transaction - we will add data to the TXFIFO to read from the ADC.
let spi_regs = unsafe { &*hal::stm32::SPI2::ptr() };
spi_regs.cr1.modify(|_, w| w.cstart().started());
spi.listen(hal::spi::Event::Rxp); spi.listen(hal::spi::Event::Rxp);
spi spi
@ -321,16 +335,34 @@ const APP: () = {
phase: hal::spi::Phase::CaptureOnSecondTransition, phase: hal::spi::Phase::CaptureOnSecondTransition,
}) })
.manage_cs() .manage_cs()
.suspend_when_inactive()
.cs_delay(220e-9); .cs_delay(220e-9);
dma_channels.1.set_peripheral_address(&dp.SPI3.cr1 as *const _ as u32, false); dma_channels.1.set_peripheral_address(
dma_channels.1.set_memory_address(&SPI_START_CODE as *const _ as u32, false); &dp.SPI3.txdr as *const _ as u32,
dma_channels.1.set_direction(hal::dma::Direction::MemoryToPeripherial); false,
dma_channels.1.dmamux().modify(|_, w| );
w.dmareq_id().variant(hal::stm32::dmamux1::ccr::DMAREQ_ID_A::TIM2_UP)); dma_channels
.1
.set_memory_address(&SPI_START as *const _ as u32, false);
dma_channels
.1
.set_direction(hal::dma::Direction::MemoryToPeripherial);
dma_channels.1.dmamux().modify(|_, w| {
w.dmareq_id()
.variant(hal::stm32::dmamux1::ccr::DMAREQ_ID_A::TIM2_UP)
});
dma_channels.1.set_transfer_length(1); dma_channels.1.set_transfer_length(1);
dma_channels.1.cr().modify(|_, w| w.circ().enabled()); dma_channels.1.cr().modify(|_, w| {
dma_channels.1.start(); w.circ()
.enabled()
.psize()
.bits16()
.msize()
.bits16()
.pfctrl()
.dma()
});
let mut spi: hal::spi::Spi<_, _, u16> = dp.SPI3.spi( let mut spi: hal::spi::Spi<_, _, u16> = dp.SPI3.spi(
(spi_sck, spi_miso, hal::spi::NoMosi), (spi_sck, spi_miso, hal::spi::NoMosi),
@ -340,6 +372,9 @@ const APP: () = {
&clocks.clocks, &clocks.clocks,
); );
let spi_regs = unsafe { &*hal::stm32::SPI3::ptr() };
spi_regs.cr1.modify(|_, w| w.cstart().started());
spi.listen(hal::spi::Event::Rxp); spi.listen(hal::spi::Event::Rxp);
spi spi
@ -370,6 +405,8 @@ const APP: () = {
phase: hal::spi::Phase::CaptureOnSecondTransition, phase: hal::spi::Phase::CaptureOnSecondTransition,
}) })
.manage_cs() .manage_cs()
.suspend_when_inactive()
.communication_mode(hal::spi::CommunicationMode::Transmitter)
.swap_mosi_miso(); .swap_mosi_miso();
dp.SPI4.spi( dp.SPI4.spi(
@ -400,6 +437,8 @@ const APP: () = {
phase: hal::spi::Phase::CaptureOnSecondTransition, phase: hal::spi::Phase::CaptureOnSecondTransition,
}) })
.manage_cs() .manage_cs()
.suspend_when_inactive()
.communication_mode(hal::spi::CommunicationMode::Transmitter)
.swap_mosi_miso(); .swap_mosi_miso();
dp.SPI5.spi( dp.SPI5.spi(
@ -429,7 +468,6 @@ const APP: () = {
let qspi_interface = { let qspi_interface = {
// Instantiate the QUADSPI pins and peripheral interface. // Instantiate the QUADSPI pins and peripheral interface.
let qspi_pins = { let qspi_pins = {
let _qspi_ncs = gpioc let _qspi_ncs = gpioc
.pc11 .pc11
.into_alternate_af9() .into_alternate_af9()
@ -459,8 +497,13 @@ const APP: () = {
(clk, io0, io1, io2, io3) (clk, io0, io1, io2, io3)
}; };
let qspi = hal::qspi::Qspi::bank2(dp.QUADSPI, qspi_pins, 11.mhz(), &clocks.clocks, let qspi = hal::qspi::Qspi::bank2(
clocks.peripheral.QSPI); dp.QUADSPI,
qspi_pins,
11.mhz(),
&clocks.clocks,
clocks.peripheral.QSPI,
);
pounder::QspiInterface::new(qspi).unwrap() pounder::QspiInterface::new(qspi).unwrap()
}; };
@ -489,7 +532,12 @@ const APP: () = {
let io_expander = { let io_expander = {
let sda = gpiob.pb7.into_alternate_af4().set_open_drain(); let sda = gpiob.pb7.into_alternate_af4().set_open_drain();
let scl = gpiob.pb8.into_alternate_af4().set_open_drain(); let scl = gpiob.pb8.into_alternate_af4().set_open_drain();
let i2c1 = dp.I2C1.i2c((scl, sda), 100.khz(), clocks.peripheral.I2C1, &clocks.clocks); let i2c1 = dp.I2C1.i2c(
(scl, sda),
100.khz(),
clocks.peripheral.I2C1,
&clocks.clocks,
);
mcp23017::MCP23017::default(i2c1).unwrap() mcp23017::MCP23017::default(i2c1).unwrap()
}; };
@ -524,7 +572,13 @@ const APP: () = {
}; };
let (adc1, adc2) = { let (adc1, adc2) = {
let (mut adc1, mut adc2) = hal::adc::adc12(dp.ADC1, dp.ADC2, &mut delay, clocks.peripheral.ADC12, &clocks.clocks); let (mut adc1, mut adc2) = hal::adc::adc12(
dp.ADC1,
dp.ADC2,
&mut delay,
clocks.peripheral.ADC12,
&clocks.clocks,
);
let adc1 = { let adc1 = {
adc1.calibrate(); adc1.calibrate();
@ -561,7 +615,12 @@ const APP: () = {
let mut eeprom_i2c = { let mut eeprom_i2c = {
let sda = gpiof.pf0.into_alternate_af4().set_open_drain(); let sda = gpiof.pf0.into_alternate_af4().set_open_drain();
let scl = gpiof.pf1.into_alternate_af4().set_open_drain(); let scl = gpiof.pf1.into_alternate_af4().set_open_drain();
dp.I2C2.i2c((scl, sda), 100.khz(), clocks.peripheral.I2C2, &clocks.clocks) dp.I2C2.i2c(
(scl, sda),
100.khz(),
clocks.peripheral.I2C2,
&clocks.clocks,
)
}; };
// Configure ethernet pins. // Configure ethernet pins.
@ -619,18 +678,18 @@ const APP: () = {
let (network_interface, eth_mac) = { let (network_interface, eth_mac) = {
// Configure the ethernet controller // Configure the ethernet controller
let (eth_dma, mut eth_mac) = unsafe { let (eth_dma, eth_mac) = unsafe {
ethernet::new_unchecked( ethernet::new_unchecked(
dp.ETHERNET_MAC, dp.ETHERNET_MAC,
dp.ETHERNET_MTL, dp.ETHERNET_MTL,
dp.ETHERNET_DMA, dp.ETHERNET_DMA,
&mut DES_RING, &mut DES_RING,
mac_addr.clone(), mac_addr.clone(),
clocks.peripheral.ETH1MAC,
&clocks.clocks,
) )
}; };
eth_mac.block_until_link();
unsafe { ethernet::enable_interrupt() }; unsafe { ethernet::enable_interrupt() };
let store = unsafe { &mut NET_STORE }; let store = unsafe { &mut NET_STORE };
@ -662,12 +721,18 @@ const APP: () = {
cp.DWT.enable_cycle_counter(); cp.DWT.enable_cycle_counter();
// Configure timer 2 to trigger conversions for the ADC // Configure timer 2 to trigger conversions for the ADC
let timer2 = dp.TIM2.timer(500.khz(), clocks.peripheral.TIM2, &clocks.clocks); let timer2 =
dp.TIM2
.timer(500.khz(), clocks.peripheral.TIM2, &clocks.clocks);
{ {
let t2_regs = unsafe { &*hal::stm32::TIM2::ptr() }; let t2_regs = unsafe { &*hal::stm32::TIM2::ptr() };
t2_regs.dier.modify(|_, w| w.ude().set_bit()); t2_regs.dier.modify(|_, w| w.ude().set_bit());
} }
// Start the SPI transfers.
dma_channels.0.start();
dma_channels.1.start();
init::LateResources { init::LateResources {
afe0: afe0, afe0: afe0,
adc0: adc0_spi, adc0: adc0_spi,

View File

@ -474,8 +474,13 @@ where
channel: Channel, channel: Channel,
state: ChannelState, state: ChannelState,
) -> Result<(), Error> { ) -> Result<(), Error> {
self.ad9959.write_profile(channel.into(), state.parameters.frequency, self.ad9959
state.parameters.phase_offset).map_err(|_| Error::Dds)?; .write_profile(
channel.into(),
state.parameters.frequency,
state.parameters.phase_offset,
)
.map_err(|_| Error::Dds)?;
self.ad9959 self.ad9959
.set_amplitude(channel.into(), state.parameters.amplitude) .set_amplitude(channel.into(), state.parameters.amplitude)
.map_err(|_| Error::Dds)?; .map_err(|_| Error::Dds)?;