211 lines
4.4 KiB
Rust
211 lines
4.4 KiB
Rust
#![no_main]
|
|
#![no_std]
|
|
|
|
#[macro_use]
|
|
extern crate log;
|
|
|
|
use log::{trace, debug, info, warn};
|
|
|
|
use stm32h7xx_hal::hal::digital::v2::{
|
|
InputPin,
|
|
OutputPin,
|
|
};
|
|
use stm32h7xx_hal::{pac, prelude::*, spi};
|
|
|
|
use cortex_m;
|
|
use cortex_m_rt::entry;
|
|
|
|
use firmware;
|
|
use firmware::{
|
|
attenuator::Attenuator,
|
|
config_register::{
|
|
ConfigRegister,
|
|
CFGMask,
|
|
StatusMask,
|
|
},
|
|
dds::{
|
|
DDS,
|
|
DDSCFRMask,
|
|
},
|
|
cpld::{
|
|
CPLD,
|
|
}
|
|
};
|
|
|
|
#[path = "../examples/util/logger.rs"]
|
|
mod logger;
|
|
|
|
#[entry]
|
|
fn main() -> ! {
|
|
|
|
let mut cp = cortex_m::Peripherals::take().unwrap();
|
|
let dp = pac::Peripherals::take().unwrap();
|
|
|
|
let pwr = dp.PWR.constrain();
|
|
let vos = pwr.freeze();
|
|
|
|
let rcc = dp.RCC.constrain();
|
|
let ccdr = rcc
|
|
.use_hse(8.mhz())
|
|
.sys_ck(400.mhz())
|
|
.pll1_q_ck(48.mhz())
|
|
.pll1_r_ck(400.mhz())
|
|
.freeze(vos, &dp.SYSCFG);
|
|
|
|
unsafe {
|
|
logger::enable_itm(&dp.DBGMCU, &mut cp.DCB, &mut cp.ITM);
|
|
}
|
|
logger::init();
|
|
|
|
let mut delay = cp.SYST.delay(ccdr.clocks);
|
|
|
|
let gpioa = dp.GPIOA.split(ccdr.peripheral.GPIOA);
|
|
let gpiob = dp.GPIOB.split(ccdr.peripheral.GPIOB);
|
|
let gpioc = dp.GPIOC.split(ccdr.peripheral.GPIOC);
|
|
let gpiod = dp.GPIOD.split(ccdr.peripheral.GPIOD);
|
|
let gpioe = dp.GPIOE.split(ccdr.peripheral.GPIOE);
|
|
let gpiof = dp.GPIOF.split(ccdr.peripheral.GPIOF);
|
|
|
|
// Setup CDONE for checking
|
|
let fpga_cdone = gpiod.pd15.into_pull_up_input();
|
|
|
|
match fpga_cdone.is_high() {
|
|
Ok(true) => info!("FPGA is ready."),
|
|
Ok(_) => info!("FPGA is in reset state."),
|
|
Err(_) => info!("Error: Cannot read C_DONE"),
|
|
};
|
|
|
|
/*
|
|
* Using SPI1, AF5
|
|
* SCLK -> PA5
|
|
* MOSI -> PB5
|
|
* MISO -> PA6
|
|
* CS -> 0: PB12, 1: PA15, 2: PC7
|
|
*/
|
|
|
|
let sclk = gpioa.pa5.into_alternate_af5();
|
|
let mosi = gpiob.pb5.into_alternate_af5();
|
|
let miso = gpioa.pa6.into_alternate_af5();
|
|
|
|
|
|
let (cs0, cs1, cs2) = (
|
|
gpiob.pb12.into_push_pull_output(),
|
|
gpioa.pa15.into_push_pull_output(),
|
|
gpioc.pc7.into_push_pull_output(),
|
|
);
|
|
|
|
/*
|
|
* I/O_Update -> PB15
|
|
*/
|
|
let io_update = gpiob.pb15.into_push_pull_output();
|
|
|
|
let spi = dp.SPI1.spi(
|
|
(sclk, miso, mosi),
|
|
spi::MODE_0,
|
|
3.mhz(),
|
|
ccdr.peripheral.SPI1,
|
|
&ccdr.clocks,
|
|
);
|
|
|
|
let switch = CPLD::new(spi, (cs0, cs1, cs2), io_update);
|
|
let parts = switch.split();
|
|
|
|
let mut config = ConfigRegister::new(parts.spi1);
|
|
let mut att = Attenuator::new(parts.spi2);
|
|
let mut dds0 = DDS::new(parts.spi4, 25_000_000);
|
|
|
|
// Reset all DDS, set CLK_SEL to 0
|
|
config.set_configurations(&mut [
|
|
(CFGMask::RST, 1),
|
|
(CFGMask::IO_RST, 1),
|
|
(CFGMask::IO_UPDATE, 0)
|
|
]).unwrap();
|
|
|
|
config.set_configurations(&mut [
|
|
(CFGMask::IO_RST, 0),
|
|
(CFGMask::RST, 0),
|
|
(CFGMask::RF_SW, 13),
|
|
(CFGMask::DIV, 3)
|
|
]).unwrap();
|
|
|
|
dds0.init().unwrap();
|
|
|
|
dds0.set_configurations(&mut [
|
|
(DDSCFRMask::PDCLK_ENABLE, 0),
|
|
(DDSCFRMask::READ_EFFECTIVE_FTW, 1),
|
|
]).unwrap();
|
|
|
|
dds0.enable_pll(1_000_000_000).unwrap();
|
|
|
|
// Attenuator
|
|
att.set_attenuation([
|
|
0.0, 31.5, 24.0, 0.0
|
|
]).unwrap();
|
|
|
|
dds0.set_single_tone_profile(1, 10_000_000, 0.0, 0.5).unwrap();
|
|
config.set_configurations(&mut [
|
|
(CFGMask::PROFILE, 1),
|
|
]).unwrap();
|
|
|
|
// Setup RAM configuration
|
|
dds0.set_configurations(&mut [
|
|
(DDSCFRMask::RAM_ENABLE, 1),
|
|
(DDSCFRMask::RAM_PLAYBACK_DST, 2),
|
|
]).unwrap();
|
|
|
|
// Configure RAM profile 0
|
|
dds0.write_register(0x0E, &mut [
|
|
0x00, // Open
|
|
0x09, 0xC4, // Address step rate (2500)
|
|
0xFF, 0xC0, // End at address 1023
|
|
0x00, 0x00, // Start at address 0
|
|
0x04, // Recirculate mode
|
|
]).unwrap();
|
|
|
|
debug!("{:#X?}", dds0.read_register(0x0E, &mut[
|
|
0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00,
|
|
]).unwrap());
|
|
|
|
// Choose profile 0
|
|
config.set_configurations(&mut [
|
|
(CFGMask::PROFILE, 0),
|
|
]).unwrap();
|
|
|
|
// Set RAM to be amplitudes, disable RAM momentarily
|
|
dds0.set_configurations(&mut [
|
|
(DDSCFRMask::RAM_PLAYBACK_DST, 0),
|
|
(DDSCFRMask::RAM_ENABLE, 0),
|
|
]).unwrap();
|
|
|
|
let mut ram_data: [u8; ((1024 * 4) + 1)] = [0; (1024 * 4) + 1];
|
|
ram_data[0] = 0x16;
|
|
for index in 0..1024 {
|
|
if index % 2 == 1 {
|
|
ram_data[(index * 4) + 1] = 0x3F;
|
|
ram_data[(index * 4) + 2] = 0xFF;
|
|
} else {
|
|
ram_data[(index * 4) + 1] = 0x00;
|
|
ram_data[(index * 4) + 2] = 0x00;
|
|
}
|
|
// ram_data[(index * 4) + 1] = ((index >> 2) & 0xFF) as u8;
|
|
// ram_data[(index * 4) + 2] = ((index & 0x03) << 6) as u8;
|
|
}
|
|
dds0.transfer(&mut ram_data).unwrap();
|
|
|
|
config.set_configurations(&mut [
|
|
(CFGMask::PROFILE, 1),
|
|
]).unwrap();
|
|
|
|
config.set_configurations(&mut [
|
|
(CFGMask::PROFILE, 0),
|
|
]).unwrap();
|
|
|
|
dds0.set_configurations(&mut [
|
|
(DDSCFRMask::RAM_ENABLE, 1),
|
|
]).unwrap();
|
|
|
|
loop {}
|
|
}
|
|
|