2020-08-07 13:36:00 +08:00
|
|
|
#![no_main]
|
|
|
|
#![no_std]
|
|
|
|
|
|
|
|
use panic_semihosting as _;
|
|
|
|
|
|
|
|
use stm32h7xx_hal::hal::digital::v2::{
|
|
|
|
InputPin,
|
|
|
|
OutputPin,
|
|
|
|
};
|
|
|
|
use stm32h7xx_hal::{pac, prelude::*, spi};
|
|
|
|
|
|
|
|
use cortex_m;
|
|
|
|
use cortex_m::asm::nop;
|
|
|
|
use cortex_m_rt::entry;
|
|
|
|
use cortex_m_semihosting::hprintln;
|
|
|
|
|
|
|
|
use core::ptr;
|
|
|
|
use nb::block;
|
|
|
|
|
2020-08-11 00:07:07 +08:00
|
|
|
use firmware;
|
|
|
|
use firmware::{
|
|
|
|
CPLD,
|
|
|
|
attenuator::Attenuator,
|
2020-08-12 11:50:24 +08:00
|
|
|
config_register::{
|
|
|
|
ConfigRegister,
|
|
|
|
CFGMask,
|
2020-08-23 17:17:09 +08:00
|
|
|
StatusMask,
|
2020-08-12 11:50:24 +08:00
|
|
|
},
|
2020-08-17 12:15:11 +08:00
|
|
|
dds::DDS,
|
2020-08-11 00:07:07 +08:00
|
|
|
};
|
2020-08-07 13:36:00 +08:00
|
|
|
|
|
|
|
#[entry]
|
|
|
|
fn main() -> ! {
|
|
|
|
|
|
|
|
let 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
|
|
|
|
.sys_ck(400.mhz())
|
|
|
|
.pll1_q_ck(48.mhz())
|
|
|
|
.freeze(vos, &dp.SYSCFG);
|
|
|
|
|
|
|
|
let mut delay = cp.SYST.delay(ccdr.clocks);
|
|
|
|
|
|
|
|
let gpioa = dp.GPIOA.split(ccdr.peripheral.GPIOA);
|
|
|
|
let gpiob = dp.GPIOB.split(ccdr.peripheral.GPIOB);
|
2020-08-09 18:46:06 +08:00
|
|
|
let gpioc = dp.GPIOC.split(ccdr.peripheral.GPIOC);
|
2020-08-07 13:36:00 +08:00
|
|
|
let gpiod = dp.GPIOD.split(ccdr.peripheral.GPIOD);
|
2020-08-21 14:18:33 +08:00
|
|
|
let gpioe = dp.GPIOE.split(ccdr.peripheral.GPIOE);
|
2020-08-07 13:36:00 +08:00
|
|
|
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) => hprintln!("FPGA is ready."),
|
|
|
|
Ok(_) => hprintln!("FPGA is in reset state."),
|
|
|
|
Err(_) => hprintln!("Error: Cannot read C_DONE"),
|
|
|
|
}.unwrap();
|
|
|
|
|
2020-08-09 13:42:18 +08:00
|
|
|
/*
|
|
|
|
* 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();
|
2020-08-24 10:57:37 +08:00
|
|
|
|
2020-08-09 13:42:18 +08:00
|
|
|
|
2020-08-24 17:03:44 +08:00
|
|
|
let (cs0, cs1, cs2) = (
|
2020-08-11 00:07:07 +08:00
|
|
|
gpiob.pb12.into_push_pull_output(),
|
|
|
|
gpioa.pa15.into_push_pull_output(),
|
|
|
|
gpioc.pc7.into_push_pull_output(),
|
|
|
|
);
|
|
|
|
|
2020-08-24 10:57:37 +08:00
|
|
|
/*
|
|
|
|
* I/O_Update -> PB13
|
|
|
|
*/
|
2020-08-24 17:03:44 +08:00
|
|
|
// TODO: Incoporate io_update into DDS
|
2020-08-24 10:57:37 +08:00
|
|
|
let mut io_update = gpiob.pb15.into_push_pull_output();
|
|
|
|
|
2020-08-24 17:03:44 +08:00
|
|
|
let spi = dp.SPI1.spi(
|
2020-08-09 13:42:18 +08:00
|
|
|
(sclk, miso, mosi),
|
|
|
|
spi::MODE_0,
|
2020-08-21 14:18:33 +08:00
|
|
|
3.mhz(),
|
2020-08-09 13:42:18 +08:00
|
|
|
ccdr.peripheral.SPI1,
|
|
|
|
&ccdr.clocks,
|
|
|
|
);
|
2020-08-24 10:57:37 +08:00
|
|
|
|
2020-08-24 17:03:44 +08:00
|
|
|
let mut switch = CPLD::new(spi, (cs0, cs1, cs2), io_update);
|
2020-08-11 00:07:07 +08:00
|
|
|
let parts = switch.split();
|
|
|
|
|
2020-08-11 16:51:17 +08:00
|
|
|
let mut config = ConfigRegister::new(parts.spi1);
|
2020-08-21 14:18:33 +08:00
|
|
|
let mut att = Attenuator::new(parts.spi2);
|
2020-08-23 17:17:09 +08:00
|
|
|
let mut dds0 = DDS::new(parts.spi4);
|
2020-08-24 10:57:37 +08:00
|
|
|
|
2020-08-24 17:03:44 +08:00
|
|
|
// 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, 1)
|
|
|
|
]).unwrap();
|
|
|
|
|
|
|
|
dds0.write_register(0x00, &mut[
|
|
|
|
0x00, 0x00, 0x00, 0x02
|
|
|
|
]).unwrap();
|
|
|
|
|
|
|
|
// io_update.set_high().unwrap();
|
|
|
|
// io_update.set_low().unwrap();
|
|
|
|
// switch.issue_io_update();
|
|
|
|
|
|
|
|
dds0.write_register(0x02, &mut[
|
|
|
|
0x01F, 0x3F, 0xC0, 0x00
|
|
|
|
]).unwrap();
|
|
|
|
|
|
|
|
// io_update.set_high().unwrap();
|
|
|
|
// io_update.set_low().unwrap();
|
|
|
|
// switch.issue_io_update();
|
|
|
|
|
|
|
|
hprintln!("{:#X?}", dds0.read_register(0x00, &mut[
|
|
|
|
0x00, 0x00, 0x00, 0x00
|
|
|
|
]).unwrap()).unwrap();
|
|
|
|
|
|
|
|
// Calculate FTW
|
|
|
|
let f_out = 10_000_000;
|
|
|
|
let f_sclk = 100_000_000;
|
|
|
|
let resolution :u64 = 1 << 32;
|
|
|
|
let ftw = (resolution * f_out / f_sclk) as u32;
|
|
|
|
|
|
|
|
hprintln!("{}", ftw);
|
|
|
|
|
|
|
|
// Read single-tone profile 0
|
|
|
|
let mut profile :[u8; 8] = [0; 8];
|
|
|
|
dds0.read_register(0x0E, &mut profile).unwrap();
|
|
|
|
|
|
|
|
// Overwrite FTW on profile
|
|
|
|
profile[4] = ((ftw >> 24) & 0xFF) as u8;
|
|
|
|
profile[5] = ((ftw >> 16) & 0xFF) as u8;
|
|
|
|
profile[6] = ((ftw >> 8 ) & 0xFF) as u8;
|
|
|
|
profile[7] = ((ftw >> 0 ) & 0xFF) as u8;
|
2020-08-17 12:15:11 +08:00
|
|
|
|
2020-08-24 17:03:44 +08:00
|
|
|
dds0.write_register(0x0E, &mut profile).unwrap();
|
|
|
|
// io_update.set_high().unwrap();
|
|
|
|
// io_update.set_low().unwrap();
|
|
|
|
// switch.issue_io_update();
|
|
|
|
|
|
|
|
hprintln!("{:#X?}", dds0.read_register(0x0E, &mut profile).unwrap()).unwrap();
|
|
|
|
|
|
|
|
/*
|
2020-08-21 14:18:33 +08:00
|
|
|
cs0.set_low().unwrap();
|
|
|
|
cs1.set_low().unwrap();
|
|
|
|
cs2.set_low().unwrap();
|
2020-08-23 17:17:09 +08:00
|
|
|
|
2020-08-24 10:57:37 +08:00
|
|
|
io_update.set_low().unwrap();
|
|
|
|
|
|
|
|
let mut dummy :[u8;1] = [0];
|
|
|
|
spi.transfer(&mut dummy);
|
|
|
|
|
|
|
|
// Master reset DDS_0 through CPLD, with LED at 3
|
|
|
|
cs0.set_high().unwrap();
|
|
|
|
spi.transfer(&mut [
|
|
|
|
0x08, 0x00, 0x03
|
|
|
|
]).unwrap();
|
|
|
|
cs0.set_low().unwrap();
|
|
|
|
|
|
|
|
// Perform I/O Reset through CPLD, with LED at 4
|
|
|
|
cs0.set_high().unwrap();
|
|
|
|
spi.transfer(&mut [
|
|
|
|
0x10, 0x00, 0x04
|
|
|
|
]).unwrap();
|
|
|
|
cs0.set_low().unwrap();
|
2020-08-23 17:17:09 +08:00
|
|
|
|
2020-08-24 10:57:37 +08:00
|
|
|
// Release reset, control I/O Update through EEM
|
2020-08-24 17:03:44 +08:00
|
|
|
// Relay clock signal from internal OSC (CLK_SEL = 0)
|
|
|
|
// Enable Switch 0
|
2020-08-24 10:57:37 +08:00
|
|
|
cs0.set_high().unwrap();
|
|
|
|
spi.transfer(&mut [
|
2020-08-24 17:03:44 +08:00
|
|
|
0x00, 0x00, 0x01
|
2020-08-24 10:57:37 +08:00
|
|
|
]).unwrap();
|
|
|
|
cs0.set_low().unwrap();
|
|
|
|
|
|
|
|
cs0.set_low().unwrap();
|
2020-08-23 17:17:09 +08:00
|
|
|
cs1.set_low().unwrap();
|
2020-08-24 10:57:37 +08:00
|
|
|
cs2.set_high().unwrap();
|
2020-08-24 17:03:44 +08:00
|
|
|
|
|
|
|
// Configure SDIO to be input only, enable 3-wires communication
|
|
|
|
spi.transfer(&mut [
|
2020-08-24 10:57:37 +08:00
|
|
|
0x00, 0x00, 0x00, 0x00, 0x02
|
2020-08-24 17:03:44 +08:00
|
|
|
]).unwrap();
|
|
|
|
|
|
|
|
// IO Update after every SPI transfer
|
|
|
|
io_update.set_high().unwrap();
|
|
|
|
delay.delay_ms(1_u16);
|
|
|
|
io_update.set_low().unwrap();
|
|
|
|
|
|
|
|
// Bypass PLL, bypass divisor
|
|
|
|
spi.transfer(&mut [
|
|
|
|
0x02, 0x1F, 0x3F, 0xC0, 0x00
|
|
|
|
]).unwrap();
|
2020-08-23 17:17:09 +08:00
|
|
|
|
2020-08-24 10:57:37 +08:00
|
|
|
io_update.set_high().unwrap();
|
|
|
|
delay.delay_ms(1_u16);
|
|
|
|
io_update.set_low().unwrap();
|
|
|
|
|
2020-08-24 17:03:44 +08:00
|
|
|
hprintln!("{:#X?}", spi.transfer(&mut [
|
|
|
|
0x82, 0x00, 0x00, 0x00, 0x00
|
2020-08-24 10:57:37 +08:00
|
|
|
]).unwrap()).unwrap();
|
2020-08-24 17:03:44 +08:00
|
|
|
|
|
|
|
let f_out = 10_000_000.0;
|
|
|
|
let f_sclk = 100_000_000.0;
|
|
|
|
let resolution :u64 = 1 << 32;
|
|
|
|
let ftw = ((resolution as f32) * f_out / f_sclk) as u32;
|
|
|
|
hprintln!("{:#X}", ftw);
|
|
|
|
|
|
|
|
// Read profile 0
|
|
|
|
let mut profile_arr_0 :[u8; 9] = [0; 9];
|
|
|
|
profile_arr_0[0] = 0x8E;
|
|
|
|
hprintln!("{:#X?}", spi.transfer(&mut profile_arr_0).unwrap()).unwrap();
|
|
|
|
|
|
|
|
// Write FTW to profile 0
|
|
|
|
profile_arr_0[0] = 0x0E;
|
|
|
|
profile_arr_0[5] = ((ftw >> 24) & 0xFF) as u8;
|
|
|
|
profile_arr_0[6] = ((ftw >> 16) & 0xFF) as u8;
|
|
|
|
profile_arr_0[7] = ((ftw >> 8 ) & 0xFF) as u8;
|
|
|
|
profile_arr_0[8] = ((ftw >> 0 ) & 0xFF) as u8;
|
2020-08-24 10:57:37 +08:00
|
|
|
|
2020-08-24 17:03:44 +08:00
|
|
|
hprintln!("{:#X?}", profile_arr_0).unwrap();
|
|
|
|
spi.transfer(&mut profile_arr_0).unwrap();
|
|
|
|
|
|
|
|
// Update after write
|
|
|
|
io_update.set_high().unwrap();
|
|
|
|
delay.delay_ms(1_u16);
|
|
|
|
io_update.set_low().unwrap();
|
2020-08-24 10:57:37 +08:00
|
|
|
|
2020-08-24 17:03:44 +08:00
|
|
|
// Read profile again, new value should be present
|
|
|
|
profile_arr_0[0] = 0x8E;
|
|
|
|
hprintln!("{:#X?}", spi.transfer(&mut profile_arr_0).unwrap()).unwrap();
|
|
|
|
*/
|
|
|
|
|
2020-08-24 10:57:37 +08:00
|
|
|
loop {}
|
2020-08-07 13:36:00 +08:00
|
|
|
}
|
|
|
|
|