Adding WIP updates to SPI functionality
This commit is contained in:
parent
d700935246
commit
3962f7eb68
77
src/board.rs
77
src/board.rs
@ -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());
|
|
||||||
}
|
|
103
src/main.rs
103
src/main.rs
@ -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();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user