Adding WIP updates to SPI functionality

This commit is contained in:
Ryan Summers 2020-04-22 13:36:51 +02:00
parent d700935246
commit 3962f7eb68
2 changed files with 51 additions and 129 deletions

View File

@ -1,77 +0,0 @@
use super::pac;
pub fn dma1_setup(
dma1: &pac::DMA1,
dmamux1: &pac::DMAMUX1,
ma: usize,
pa0: usize,
pa1: usize,
) {
dma1.st[0].cr.modify(|_, w| w.en().clear_bit());
while dma1.st[0].cr.read().en().bit_is_set() {}
dma1.st[0].par.write(|w| unsafe { w.bits(pa0 as u32) });
dma1.st[0].m0ar.write(|w| unsafe { w.bits(ma as u32) });
dma1.st[0].ndtr.write(|w| w.ndt().bits(1));
dmamux1.ccr[0].modify(|_, w| w.dmareq_id().tim2_up());
dma1.st[0].cr.modify(|_, w| {
w.pl()
.medium()
.circ()
.enabled()
.msize()
.bits32()
.minc()
.fixed()
.mburst()
.single()
.psize()
.bits32()
.pinc()
.fixed()
.pburst()
.single()
.dbm()
.disabled()
.dir()
.memory_to_peripheral()
.pfctrl()
.dma()
});
dma1.st[0].fcr.modify(|_, w| w.dmdis().clear_bit());
dma1.st[0].cr.modify(|_, w| w.en().set_bit());
dma1.st[1].cr.modify(|_, w| w.en().clear_bit());
while dma1.st[1].cr.read().en().bit_is_set() {}
dma1.st[1].par.write(|w| unsafe { w.bits(pa1 as u32) });
dma1.st[1].m0ar.write(|w| unsafe { w.bits(ma as u32) });
dma1.st[1].ndtr.write(|w| w.ndt().bits(1));
dmamux1.ccr[1].modify(|_, w| w.dmareq_id().tim2_up());
dma1.st[1].cr.modify(|_, w| {
w.pl()
.medium()
.circ()
.enabled()
.msize()
.bits32()
.minc()
.fixed()
.mburst()
.single()
.psize()
.bits32()
.pinc()
.fixed()
.pburst()
.single()
.dbm()
.disabled()
.dir()
.memory_to_peripheral()
.pfctrl()
.dma()
});
dma1.st[1].fcr.modify(|_, w| w.dmdis().clear_bit());
dma1.st[1].cr.modify(|_, w| w.en().set_bit());
}

View File

@ -29,7 +29,6 @@ extern crate log;
// use core::sync::atomic::{AtomicU32, AtomicBool, Ordering}; // use core::sync::atomic::{AtomicU32, AtomicBool, Ordering};
use cortex_m_rt::exception; use cortex_m_rt::exception;
use rtfm::cyccnt::{U32Ext as _};
use stm32h7xx_hal as hal; use stm32h7xx_hal as hal;
use stm32h7xx_hal::{ use stm32h7xx_hal::{
prelude::*, prelude::*,
@ -53,7 +52,6 @@ mod eth;
mod iir; mod iir;
use iir::*; use iir::*;
mod board;
mod eeprom; mod eeprom;
#[cfg(not(feature = "semihosting"))] #[cfg(not(feature = "semihosting"))]
@ -103,9 +101,7 @@ macro_rules! create_socket {
} }
*/ */
static DAT: u32 = 0x30; // EN | CSTART #[rtfm::app(device = stm32h7xx_hal::stm32, peripherals = true)]
#[rtfm::app(device = stm32h7xx_hal::stm32, peripherals = true, monotonic = rtfm::cyccnt::CYCCNT)]
const APP: () = { const APP: () = {
struct Resources { struct Resources {
adc1: hal::spi::Spi<hal::stm32::SPI2>, adc1: hal::spi::Spi<hal::stm32::SPI2>,
@ -116,6 +112,10 @@ const APP: () = {
_eeprom_i2c: hal::i2c::I2c<hal::stm32::I2C2>, _eeprom_i2c: hal::i2c::I2c<hal::stm32::I2C2>,
dbg_pin: hal::gpio::gpioc::PC6<hal::gpio::Output<hal::gpio::PushPull>>,
dac_pin: hal::gpio::gpiob::PB15<hal::gpio::Output<hal::gpio::PushPull>>,
timer: hal::timer::Timer<hal::stm32::TIM2>,
// TODO: Add in pounder hardware resources. // TODO: Add in pounder hardware resources.
//ethernet_periph: //ethernet_periph:
@ -129,7 +129,7 @@ const APP: () = {
//ethernet: eth::Device, //ethernet: eth::Device,
} }
#[init(schedule = [tick])] #[init]
fn init(c: init::Context) -> init::LateResources { fn init(c: init::Context) -> init::LateResources {
let dp = c.device; let dp = c.device;
let mut cp = cortex_m::Peripherals::take().unwrap(); let mut cp = cortex_m::Peripherals::take().unwrap();
@ -139,6 +139,7 @@ const APP: () = {
let rcc = dp.RCC.constrain(); let rcc = dp.RCC.constrain();
let mut clocks = rcc let mut clocks = rcc
//TODO: Re-enable HSE for Stabilizer platform.
// .use_hse(8.mhz()) // .use_hse(8.mhz())
.sysclk(400.mhz()) .sysclk(400.mhz())
.hclk(200.mhz()) .hclk(200.mhz())
@ -160,7 +161,7 @@ const APP: () = {
let gpiog = dp.GPIOG.split(&mut clocks.ahb4); let gpiog = dp.GPIOG.split(&mut clocks.ahb4);
// Configure the SPI interfaces to the ADCs and DACs. // Configure the SPI interfaces to the ADCs and DACs.
let (adc1_spi, adc1_cr_address) = { let adc1_spi = {
let spi_miso = gpiob.pb14.into_alternate_af5(); let spi_miso = gpiob.pb14.into_alternate_af5();
let spi_sck = gpiob.pb10.into_alternate_af5(); let spi_sck = gpiob.pb10.into_alternate_af5();
let _spi_nss = gpiob.pb9.into_alternate_af5(); let _spi_nss = gpiob.pb9.into_alternate_af5();
@ -169,12 +170,11 @@ const APP: () = {
polarity: hal::spi::Polarity::IdleHigh, polarity: hal::spi::Polarity::IdleHigh,
phase: hal::spi::Phase::CaptureOnSecondTransition, phase: hal::spi::Phase::CaptureOnSecondTransition,
}) })
.communication_mode(hal::spi::CommunicationMode::Receiver)
.manage_cs() .manage_cs()
.cs_delay(220e-9) .cs_delay(220e-9)
.frame_size(16); .frame_size(16);
let cr_address = &dp.SPI2.cr1 as *const _ as usize;
let mut spi = dp.SPI2.spi( let mut spi = dp.SPI2.spi(
(spi_sck, spi_miso, hal::spi::NoMosi), (spi_sck, spi_miso, hal::spi::NoMosi),
hal::spi::MODE_0, //config, hal::spi::MODE_0, //config,
@ -183,38 +183,33 @@ const APP: () = {
spi.listen(hal::spi::Event::Rxp); spi.listen(hal::spi::Event::Rxp);
(spi, cr_address) spi
}; };
let (adc2_spi, adc2_cr_address) = { let adc2_spi = {
let spi_miso = gpiob.pb4.into_alternate_af6(); let spi_miso = gpiob.pb4.into_alternate_af6();
let spi_sck = gpioc.pc10.into_alternate_af6(); let spi_sck = gpioc.pc10.into_alternate_af6();
let _spi_nss = gpioa.pa15.into_alternate_af6();
let mut cs = gpioa.pa15.into_push_pull_output();
cs.set_high().unwrap();
let _spi_nss = cs.into_alternate_af6();
let config = hal::spi::Config::new(hal::spi::Mode{ let config = hal::spi::Config::new(hal::spi::Mode{
polarity: hal::spi::Polarity::IdleHigh, polarity: hal::spi::Polarity::IdleHigh,
phase: hal::spi::Phase::CaptureOnSecondTransition, phase: hal::spi::Phase::CaptureOnSecondTransition,
}) })
.communication_mode(hal::spi::CommunicationMode::Receiver)
.manage_cs() .manage_cs()
.frame_size(16) .frame_size(16)
.cs_delay(220e-9); .cs_delay(220e-9);
let cr_address = &dp.SPI3.cr1 as *const _ as usize;
let mut spi = dp.SPI3.spi( let mut spi = dp.SPI3.spi(
(spi_sck, spi_miso, hal::spi::NoMosi), (spi_sck, spi_miso, hal::spi::NoMosi),
config, config,
25.mhz(), 25.mhz(),
&clocks); &clocks);
spi.send(8_u8).unwrap();
spi.listen(hal::spi::Event::Rxp); spi.listen(hal::spi::Event::Rxp);
(spi, cr_address) spi
}; };
let dac1_spi = { let dac1_spi = {
@ -226,6 +221,7 @@ const APP: () = {
polarity: hal::spi::Polarity::IdleHigh, polarity: hal::spi::Polarity::IdleHigh,
phase: hal::spi::Phase::CaptureOnSecondTransition, phase: hal::spi::Phase::CaptureOnSecondTransition,
}) })
.communication_mode(hal::spi::CommunicationMode::Transmitter)
.manage_cs() .manage_cs()
.frame_size(16) .frame_size(16)
.swap_mosi_miso(); .swap_mosi_miso();
@ -242,6 +238,7 @@ const APP: () = {
polarity: hal::spi::Polarity::IdleHigh, polarity: hal::spi::Polarity::IdleHigh,
phase: hal::spi::Phase::CaptureOnSecondTransition, phase: hal::spi::Phase::CaptureOnSecondTransition,
}) })
.communication_mode(hal::spi::CommunicationMode::Transmitter)
.manage_cs() .manage_cs()
.frame_size(16) .frame_size(16)
.swap_mosi_miso(); .swap_mosi_miso();
@ -249,26 +246,6 @@ const APP: () = {
dp.SPI5.spi((spi_sck, spi_miso, hal::spi::NoMosi), config, 25.mhz(), &clocks) dp.SPI5.spi((spi_sck, spi_miso, hal::spi::NoMosi), config, 25.mhz(), &clocks)
}; };
// Configure timer 2 to trigger conversions for the ADC
let mut timer2 = hal::timer::Timer::tim2(dp.TIM2, 500.khz(), &mut clocks);
//timer2.listen(hal::timer::Event::TimeOut);
timer2.listen(hal::timer::Event::DmaRequest);
cortex_m::asm::dsb();
let dat_addr = &DAT as *const _ as usize;
cp.SCB.clean_dcache_by_address(dat_addr, 4);
// Enable the DMA.
// TODO: Refactor the DMA API to be a bit cleaner.
clocks.ahb1.enr().modify(|_, w| w.dma1en().set_bit());
board::dma1_setup(
&dp.DMA1,
&dp.DMAMUX1,
dat_addr,
adc1_cr_address,
adc2_cr_address,
);
// Instantiate the QUADSPI pins and peripheral interface. // Instantiate the QUADSPI pins and peripheral interface.
// TODO: Place these into a pins structure that is provided to the QSPI constructor. // TODO: Place these into a pins structure that is provided to the QSPI constructor.
@ -332,14 +309,24 @@ const APP: () = {
cp.SCB.enable_icache(); cp.SCB.enable_icache();
// The cycle counter is used for RTFM scheduling. // The cycle counter is used for RTFM scheduling.
cp.DWT.enable_cycle_counter(); //cp.DWT.enable_cycle_counter();
init_log(); init_log();
// info!("Version {} {}", build_info::PKG_VERSION, build_info::GIT_VERSION.unwrap()); // info!("Version {} {}", build_info::PKG_VERSION, build_info::GIT_VERSION.unwrap());
// info!("Built on {}", build_info::BUILT_TIME_UTC); // info!("Built on {}", build_info::BUILT_TIME_UTC);
// info!("{} {}", build_info::RUSTC_VERSION, build_info::TARGET); // info!("{} {}", build_info::RUSTC_VERSION, build_info::TARGET);
// c.schedule.tick(Instant::now()).unwrap(); let mut debug_pin = gpioc.pc6.into_push_pull_output();
debug_pin.set_low().unwrap();
let mut dac_pin = gpiob.pb15.into_push_pull_output();
dac_pin.set_low().unwrap();
// Configure timer 2 to trigger conversions for the ADC
let mut timer2 = dp.TIM2.timer(1.khz(), &mut clocks);
timer2.clear_uif_bit();
timer2.listen(hal::timer::Event::TimeOut);
init::LateResources { init::LateResources {
adc1: adc1_spi, adc1: adc1_spi,
@ -347,6 +334,10 @@ const APP: () = {
adc2: adc2_spi, adc2: adc2_spi,
dac2: dac2_spi, dac2: dac2_spi,
dbg_pin: debug_pin,
dac_pin: dac_pin,
timer: timer2,
_eeprom_i2c: i2c2, _eeprom_i2c: i2c2,
// ethernet_periph: ( // ethernet_periph: (
// dp.ETHERNET_MAC, // dp.ETHERNET_MAC,
@ -465,17 +456,19 @@ const APP: () = {
} }
*/ */
#[task(priority = 1, schedule = [tick])] #[task(binds = TIM2, resources = [dbg_pin, timer, adc1, adc2])]
fn tick(c: tick::Context) { fn tim2(mut c: tim2::Context) {
static mut TIME: u32 = 0; c.resources.timer.clear_uif_bit();
*TIME += 1;
const PERIOD: u32 = 200_000_000;
c.schedule.tick(c.scheduled + PERIOD.cycles()).unwrap();
}
#[task(binds = TIM2)] c.resources.dbg_pin.set_high().unwrap();
fn tim2(_c: tim2::Context) { c.resources.dbg_pin.set_low().unwrap();
info!("TIM2 interrupt"); c.resources.dbg_pin.set_high().unwrap();
c.resources.dbg_pin.set_low().unwrap();
// Start a SPI transaction on ADC0 and ADC1
// TODO: Stagger these requests.
c.resources.adc1.lock(|adc| adc.spi.cr1.modify(|_, w| w.cstart().set_bit()));
c.resources.adc2.lock(|adc| adc.spi.cr1.modify(|_, w| w.cstart().set_bit()));
} }
// seems to slow it down // seems to slow it down
@ -500,11 +493,13 @@ const APP: () = {
// TODO: Handle errors. // TODO: Handle errors.
dac.send(d).unwrap(); dac.send(d).unwrap();
} }
adc.spi.ifcr.write(|w| w.eotc().set_bit());
#[cfg(feature = "bkpt")] #[cfg(feature = "bkpt")]
cortex_m::asm::bkpt(); cortex_m::asm::bkpt();
} }
#[task(binds = SPI3, resources = [adc2, dac2, iir_state, iir_ch], priority = 2)] #[task(binds = SPI3, resources = [adc2, dac2, iir_state, iir_ch, dac_pin], priority = 2)]
fn spi3(c: spi3::Context) { fn spi3(c: spi3::Context) {
#[cfg(feature = "bkpt")] #[cfg(feature = "bkpt")]
cortex_m::asm::bkpt(); cortex_m::asm::bkpt();
@ -512,6 +507,7 @@ const APP: () = {
let dac = c.resources.dac2; let dac = c.resources.dac2;
let iir_ch = c.resources.iir_ch; let iir_ch = c.resources.iir_ch;
let iir_state = c.resources.iir_state; let iir_state = c.resources.iir_state;
c.resources.dac_pin.set_high().unwrap();
// TODO: Doesn't make sense if RXP is unset. // TODO: Doesn't make sense if RXP is unset.
if adc.is_rxp() { if adc.is_rxp() {
@ -524,6 +520,9 @@ const APP: () = {
// TODO: Handle errors. // TODO: Handle errors.
dac.send(d).unwrap(); dac.send(d).unwrap();
} }
adc.spi.ifcr.write(|w| w.eotc().set_bit());
c.resources.dac_pin.set_low().unwrap();
#[cfg(feature = "bkpt")] #[cfg(feature = "bkpt")]
cortex_m::asm::bkpt(); cortex_m::asm::bkpt();
} }