diff --git a/Cargo.lock b/Cargo.lock index fcfc491..998e749 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -108,9 +108,9 @@ checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" [[package]] name = "cortex-m" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2be99930c99669a74d986f7fd2162085498b322e6daae8ef63a97cc9ac1dc73c" +checksum = "88cdafeafba636c00c467ded7f1587210725a1adfab0c24028a7844b87738263" dependencies = [ "aligned", "bare-metal 0.2.5", @@ -362,9 +362,9 @@ dependencies = [ [[package]] name = "proc-macro-hack" -version = "0.5.18" +version = "0.5.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99c605b9a0adc77b7211c6b1f722dcb613d68d66859a44f3d485a6da332b0598" +checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" [[package]] name = "proc-macro2" @@ -495,7 +495,7 @@ dependencies = [ "serde-json-core", "smoltcp", "stm32h7-ethernet", - "stm32h7xx-hal 0.7.1", + "stm32h7xx-hal 0.8.0", ] [[package]] @@ -557,8 +557,8 @@ dependencies = [ [[package]] name = "stm32h7xx-hal" -version = "0.7.1" -source = "git+https://github.com/stm32-rs/stm32h7xx-hal#f28cf3e66c7a7fe2bdd1518f06acbf680e9b9a11" +version = "0.8.0" +source = "git+https://github.com/quartiq/stm32h7xx-hal?branch=rs/issue-158/managed-spi#cc36bbbaa1bf21e53732cfc0f3dd7175c3ed6d44" dependencies = [ "bare-metal 1.0.0", "cast", diff --git a/Cargo.toml b/Cargo.toml index fe4cda3..0f2df5c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -58,9 +58,9 @@ branch = "master" features = ["stm32h743v"] [dependencies.stm32h7xx-hal] -features = ["stm32h743v", "rt", "unproven", "ethernet", "phy_lan8742a", "quadspi"] -git = "https://github.com/stm32-rs/stm32h7xx-hal" -# path = "../stm32h7xx-hal" +features = ["stm32h743v", "rt", "unproven", "ethernet", "quadspi"] +git = "https://github.com/quartiq/stm32h7xx-hal" +branch = "rs/issue-158/managed-spi" [features] semihosting = ["panic-semihosting", "cortex-m-log/semihosting"] diff --git a/ad9959/src/lib.rs b/ad9959/src/lib.rs index a3d42bf..6fdcefd 100644 --- a/ad9959/src/lib.rs +++ b/ad9959/src/lib.rs @@ -572,12 +572,17 @@ where / (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 // frequency tuning word and f_s is the system clock rate. - let tuning_word: u32 = - ((freq as f64 / self.system_clock_frequency()) - * 1u64.wrapping_shl(32) as f64) as u32; + let tuning_word: u32 = ((freq as f64 / self.system_clock_frequency()) + * 1u64.wrapping_shl(32) as f64) + as u32; 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[3] = Register::CFTW0 as u8; 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(()) } - fn modify_channel_closure(&mut self, channel: Channel, f: F) -> Result<(), Error> + fn modify_channel_closure( + &mut self, + channel: Channel, + f: F, + ) -> Result<(), Error> where F: FnOnce(&mut INTERFACE) -> Result<(), Error>, { diff --git a/src/main.rs b/src/main.rs index 3b5bfd1..61dcb7e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,3 @@ -#![deny(warnings)] #![allow(clippy::missing_safety_doc)] #![no_std] #![no_main] @@ -35,11 +34,12 @@ use stm32h7xx_hal::prelude::*; use embedded_hal::digital::v2::{InputPin, OutputPin}; -use smoltcp as net; use hal::{ + dma::{DmaChannel, DmaExt, DmaInternal}, ethernet, - dma::{DmaExt, DmaChannel, DmaInternal}, + rcc::rec::ResetEnable, }; +use smoltcp as net; use heapless::{consts::*, String}; @@ -92,7 +92,7 @@ static mut NET_STORE: NetStorage = NetStorage { 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); @@ -176,22 +176,13 @@ const APP: () = { timer: hal::timer::Timer, // 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 - // definition to: - // - // ```rust - // net_interface: net::iface::EthernetInterface< - // 'static, - // 'static, - // 'static, - // ethernet::EthernetDMA<'static>>, - // ``` + // results in GDB breakpoints being set improperly. + #[rustfmt::skip] net_interface: net::iface::EthernetInterface< 'static, 'static, 'static, - ethernet::EthernetDMA<'static>, - >, + ethernet::EthernetDMA<'static>>, eth_mac: ethernet::EthernetMAC, mac_addr: net::wire::EthernetAddress, @@ -256,6 +247,7 @@ const APP: () = { afe::ProgrammableGainAmplifier::new(a0_pin, a1_pin) }; + clocks.peripheral.DMA1.reset().enable(); let mut dma_channels = dp.DMA1.split(); // Configure the SPI interfaces to the ADCs and DACs. @@ -278,16 +270,34 @@ const APP: () = { phase: hal::spi::Phase::CaptureOnSecondTransition, }) .manage_cs() + .suspend_when_inactive() .cs_delay(220e-9); - dma_channels.0.set_peripheral_address(&dp.SPI2.cr1 as *const _ as u32, false); - dma_channels.0.set_memory_address(&SPI_START_CODE as *const _ as u32, false); - dma_channels.0.set_direction(hal::dma::Direction::MemoryToPeripherial); + dma_channels.0.set_peripheral_address( + &dp.SPI2.txdr as *const _ as u32, + 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.cr().modify(|_, w| w.circ().enabled()); - dma_channels.0.dmamux().modify(|_, w| - w.dmareq_id().variant(hal::stm32::dmamux1::ccr::DMAREQ_ID_A::TIM2_UP)); - dma_channels.0.start(); + dma_channels.0.cr().modify(|_, w| { + w.circ() + .enabled() + .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( (spi_sck, spi_miso, hal::spi::NoMosi), @@ -297,6 +307,10 @@ const APP: () = { &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 @@ -321,16 +335,34 @@ const APP: () = { phase: hal::spi::Phase::CaptureOnSecondTransition, }) .manage_cs() + .suspend_when_inactive() .cs_delay(220e-9); - dma_channels.1.set_peripheral_address(&dp.SPI3.cr1 as *const _ as u32, false); - dma_channels.1.set_memory_address(&SPI_START_CODE 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_peripheral_address( + &dp.SPI3.txdr as *const _ as u32, + false, + ); + 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.cr().modify(|_, w| w.circ().enabled()); - dma_channels.1.start(); + dma_channels.1.cr().modify(|_, w| { + w.circ() + .enabled() + .psize() + .bits16() + .msize() + .bits16() + .pfctrl() + .dma() + }); let mut spi: hal::spi::Spi<_, _, u16> = dp.SPI3.spi( (spi_sck, spi_miso, hal::spi::NoMosi), @@ -340,6 +372,9 @@ const APP: () = { &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 @@ -370,6 +405,8 @@ const APP: () = { phase: hal::spi::Phase::CaptureOnSecondTransition, }) .manage_cs() + .suspend_when_inactive() + .communication_mode(hal::spi::CommunicationMode::Transmitter) .swap_mosi_miso(); dp.SPI4.spi( @@ -400,6 +437,8 @@ const APP: () = { phase: hal::spi::Phase::CaptureOnSecondTransition, }) .manage_cs() + .suspend_when_inactive() + .communication_mode(hal::spi::CommunicationMode::Transmitter) .swap_mosi_miso(); dp.SPI5.spi( @@ -429,7 +468,6 @@ const APP: () = { let qspi_interface = { // Instantiate the QUADSPI pins and peripheral interface. let qspi_pins = { - let _qspi_ncs = gpioc .pc11 .into_alternate_af9() @@ -459,8 +497,13 @@ const APP: () = { (clk, io0, io1, io2, io3) }; - let qspi = hal::qspi::Qspi::bank2(dp.QUADSPI, qspi_pins, 11.mhz(), &clocks.clocks, - clocks.peripheral.QSPI); + let qspi = hal::qspi::Qspi::bank2( + dp.QUADSPI, + qspi_pins, + 11.mhz(), + &clocks.clocks, + clocks.peripheral.QSPI, + ); pounder::QspiInterface::new(qspi).unwrap() }; @@ -489,7 +532,12 @@ const APP: () = { let io_expander = { let sda = gpiob.pb7.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() }; @@ -524,7 +572,13 @@ const APP: () = { }; 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 = { adc1.calibrate(); @@ -561,7 +615,12 @@ const APP: () = { let mut eeprom_i2c = { let sda = gpiof.pf0.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. @@ -619,18 +678,18 @@ const APP: () = { let (network_interface, eth_mac) = { // Configure the ethernet controller - let (eth_dma, mut eth_mac) = unsafe { + let (eth_dma, eth_mac) = unsafe { ethernet::new_unchecked( dp.ETHERNET_MAC, dp.ETHERNET_MTL, dp.ETHERNET_DMA, &mut DES_RING, mac_addr.clone(), + clocks.peripheral.ETH1MAC, + &clocks.clocks, ) }; - eth_mac.block_until_link(); - unsafe { ethernet::enable_interrupt() }; let store = unsafe { &mut NET_STORE }; @@ -662,12 +721,18 @@ const APP: () = { cp.DWT.enable_cycle_counter(); // 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() }; t2_regs.dier.modify(|_, w| w.ude().set_bit()); } + // Start the SPI transfers. + dma_channels.0.start(); + dma_channels.1.start(); + init::LateResources { afe0: afe0, adc0: adc0_spi, diff --git a/src/pounder/mod.rs b/src/pounder/mod.rs index 489cc67..032b209 100644 --- a/src/pounder/mod.rs +++ b/src/pounder/mod.rs @@ -474,8 +474,13 @@ where channel: Channel, state: ChannelState, ) -> Result<(), Error> { - self.ad9959.write_profile(channel.into(), state.parameters.frequency, - state.parameters.phase_offset).map_err(|_| Error::Dds)?; + self.ad9959 + .write_profile( + channel.into(), + state.parameters.frequency, + state.parameters.phase_offset, + ) + .map_err(|_| Error::Dds)?; self.ad9959 .set_amplitude(channel.into(), state.parameters.amplitude) .map_err(|_| Error::Dds)?;