From 38b1c7528c4747752078a27a3381e8fdaee63ff9 Mon Sep 17 00:00:00 2001 From: occheung Date: Wed, 26 Aug 2020 13:18:50 +0800 Subject: [PATCH] dds: add register io --- .cargo/config | 2 +- src/bitmask_macro.rs | 4 +- src/dds.rs | 102 ++++++++++++++++++++++++++++++++++++++++--- src/lib.rs | 1 + src/main.rs | 85 +++++++++++++++++++++++------------- 5 files changed, 155 insertions(+), 39 deletions(-) diff --git a/.cargo/config b/.cargo/config index 86b3292..c0ce242 100644 --- a/.cargo/config +++ b/.cargo/config @@ -1,5 +1,5 @@ [target.thumbv7em-none-eabihf] -runner = "gdb -q -x gdb_config/openocd.gdb" +runner = "gdb -q -x gdb_config/fpga_config.gdb" rustflags = [ "-C", "link-arg=-Tlink.x", ] diff --git a/src/bitmask_macro.rs b/src/bitmask_macro.rs index 4836f44..a72dabc 100644 --- a/src/bitmask_macro.rs +++ b/src/bitmask_macro.rs @@ -10,7 +10,7 @@ use core::mem::size_of; macro_rules! construct_bitmask { ($collection: ident; $unsigned_type: ty; $($name: ident, $shift: expr, $width: expr),+) => { - #[derive(Debug, Copy, Clone)] + #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub enum $collection { $( $name, @@ -41,7 +41,7 @@ macro_rules! construct_bitmask { } pub(crate) fn get_shifted_bits(self, arg: $unsigned_type) -> $unsigned_type { assert!(arg < (2 << self.get_width())); - (arg << self.get_shift()) + (arg << (self.get_shift() % ((size_of::<$unsigned_type>() as u8) * 8))) } pub(crate) fn set_data_by_arg(self, data: &mut $unsigned_type, arg: $unsigned_type) { // Clear bits in field, then insert shifted argument diff --git a/src/dds.rs b/src/dds.rs index fb0abaf..70df3b1 100644 --- a/src/dds.rs +++ b/src/dds.rs @@ -3,6 +3,9 @@ use cortex_m_semihosting::hprintln; use crate::Error; use core::mem::size_of; +/* + * Bitmask for all configurations (Order: CFR3, CFR2, CFR1) + */ construct_bitmask!(DDSCFRMask; u32; // CFR1 bitmasks LSB_FIRST, 0, 1, @@ -86,12 +89,99 @@ where } } -// impl DDS -// where -// SPI: Transfer -// { -// pub fn set_configuration -// } +/* + * Implement init + */ + impl DDS + where + SPI: Transfer + { + pub fn init(&mut self) -> Result<(), Error> { + match self.write_register(0x00, &mut [ + 0x00, 0x00, 0x00, 0x02 + ]) { + Ok(_) => Ok(()), + Err(e) => Err(e), + } + } + } + +/* + * Impleement configurations registers I/O through bitmasks + */ +impl DDS +where + SPI: Transfer +{ + /* + * Return (cfr1, cfr2, cfr3) contents + */ + fn get_all_configurations(&mut self) -> Result<[u32; 3], Error> { + let mut cfr_reg = [0; 12]; + self.read_register(0x00, &mut cfr_reg[0..4])?; + self.read_register(0x01, &mut cfr_reg[4..8])?; + self.read_register(0x02, &mut cfr_reg[8..12])?; + Ok([ + (cfr_reg[0] as u32) << 24 | (cfr_reg[1] as u32) << 16 | (cfr_reg[2] as u32) << 8 | (cfr_reg[3] as u32), + (cfr_reg[4] as u32) << 24 | (cfr_reg[5] as u32) << 16 | (cfr_reg[6] as u32) << 8 | (cfr_reg[7] as u32), + (cfr_reg[8] as u32) << 24 | (cfr_reg[9] as u32) << 16 | (cfr_reg[10] as u32) << 8 | (cfr_reg[11] as u32) + ]) + } + + /* + * Get a set of configurations using DDSCFRMask + */ + pub fn get_configurations<'w>(&mut self, mask_pairs: &'w mut[(DDSCFRMask, u32)]) -> Result<&'w [(DDSCFRMask, u32)], Error> { + let data_array = self.get_all_configurations()?; + for index in 0..mask_pairs.len() { + mask_pairs[index].1 = match mask_pairs[index].0.get_shift() { + 0..=31 => mask_pairs[index].0.get_filtered_content(data_array[0]), + 32..=63 => mask_pairs[index].0.get_filtered_content(data_array[1]), + 64..=95 => mask_pairs[index].0.get_filtered_content(data_array[2]), + _ => panic!("Invalid DDSCFRMask!"), + } + } + Ok(mask_pairs) + } + + /* + * Write (cfr1, cfr2, cfr3) contents + */ + fn set_all_configurations(&mut self, data_array: [u32; 3]) -> Result<(), Error> { + for register in 0x00..=0x02 { + self.write_register(register, &mut [ + ((data_array[register as usize] >> 24) & 0xFF) as u8, + ((data_array[register as usize] >> 16) & 0xFF) as u8, + ((data_array[register as usize] >> 8 ) & 0xFF) as u8, + ((data_array[register as usize] >> 0 ) & 0xFF) as u8 + ])?; + } + Ok(()) + } + + /* + * Set a set of configurations using DDSCFRMask + */ + pub fn set_configurations(&mut self, mask_pairs: &mut[(DDSCFRMask, u32)]) -> Result<(), Error> { + let mut data_array = self.get_all_configurations()?; + hprintln!("Initial array {:#X?}", data_array).unwrap(); + for index in 0..mask_pairs.len() { + // Reject any attempt to write LSB_FIRST and SBIO_INPUT_ONLY + if mask_pairs[index].0 == DDSCFRMask::LSB_FIRST || mask_pairs[index].0 == DDSCFRMask::SDIO_IN_ONLY { + continue; + } + match mask_pairs[index].0.get_shift() { + 0..=31 => mask_pairs[index].0.set_data_by_arg(&mut data_array[0], mask_pairs[index].1), + 32..=63 => mask_pairs[index].0.set_data_by_arg(&mut data_array[1], mask_pairs[index].1), + 64..=95 => mask_pairs[index].0.set_data_by_arg(&mut data_array[2], mask_pairs[index].1), + _ => panic!("Invalid DDSCFRMask!"), + }; + } + hprintln!("Modified array {:#X?}", data_array).unwrap(); + self.set_all_configurations(data_array.clone()) + } + +} macro_rules! impl_register_io { ($($reg_addr: expr, $reg_byte_size: expr),+) => { diff --git a/src/lib.rs b/src/lib.rs index d98182e..a0b3fa4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -32,6 +32,7 @@ pub enum Error { GetRefMutDataError, AttenuatorError, IOUpdateError, + DDSError, } /* diff --git a/src/main.rs b/src/main.rs index ddd11ba..9241f0d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -26,7 +26,10 @@ use firmware::{ CFGMask, StatusMask, }, - dds::DDS, + dds::{ + DDS, + DDSCFRMask, + }, }; #[entry] @@ -94,7 +97,7 @@ fn main() -> ! { &ccdr.clocks, ); - let mut switch = CPLD::new(spi, (cs0, cs1, cs2), io_update); + let switch = CPLD::new(spi, (cs0, cs1, cs2), io_update); let parts = switch.split(); let mut config = ConfigRegister::new(parts.spi1); @@ -111,35 +114,63 @@ fn main() -> ! { config.set_configurations(&mut [ (CFGMask::IO_RST, 0), (CFGMask::RST, 0), - (CFGMask::RF_SW, 1) + (CFGMask::RF_SW, 13), + (CFGMask::DIV, 2) ]).unwrap(); - dds0.write_register(0x00, &mut[ - 0x00, 0x00, 0x00, 0x02 + // dds0.write_register(0x00, &mut[ + // 0x00, 0x00, 0x00, 0x02 + // ]).unwrap(); + + // dds0.write_register(0x01, &mut[ + // 0x01, 0x01, 0x00, 0x20 + // ]).unwrap(); + + // dds0.write_register(0x02, &mut[ + // 0x05, 0x38, 0xC5, 0x28 + // ]).unwrap(); + + dds0.init().unwrap(); + + dds0.set_configurations(&mut [ + (DDSCFRMask::PDCLK_ENABLE, 0), + (DDSCFRMask::READ_EFFECTIVE_FTW, 1), + (DDSCFRMask::DIGITAL_RAMP_ENABLE, 0), + (DDSCFRMask::EN_AMP_SCALE_SINGLE_TONE_PRO, 1), + (DDSCFRMask::N, 0x14), + (DDSCFRMask::PLL_ENABLE, 1), + (DDSCFRMask::PFD_RESET, 1), + (DDSCFRMask::REFCLK_IN_DIV_BYPASS, 1), + (DDSCFRMask::I_CP, 7), + (DDSCFRMask::VCO_SEL, 5), + (DDSCFRMask::DRV0, 0), ]).unwrap(); - dds0.write_register(0x02, &mut[ - 0x01F, 0x3F, 0x41, 0x00 + hprintln!("{:#X?}", dds0.read_register(0x02, &mut[ + 0x00, 0x00, 0x00, 0x00 + ]).unwrap()).unwrap(); + + dds0.set_configurations(&mut [ + (DDSCFRMask::PFD_RESET, 0), ]).unwrap(); - hprintln!("{:#X?}", dds0.read_register(0x00, &mut[ + hprintln!("{:#X?}", dds0.read_register(0x02, &mut[ 0x00, 0x00, 0x00, 0x00 ]).unwrap()).unwrap(); // Calculate FTW - let f_out = 10_000_000; - let f_sclk = 100_000_000; + let f_out = 8_008_135; + let f_sclk = 100_000_000 / 2 * 20; 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[0] = 0x20; + // Overwrite FTW on profile 0 + profile[0] = 0x1F; + profile[1] = 0xFF; profile[4] = ((ftw >> 24) & 0xFF) as u8; profile[5] = ((ftw >> 16) & 0xFF) as u8; profile[6] = ((ftw >> 8 ) & 0xFF) as u8; @@ -147,28 +178,22 @@ fn main() -> ! { dds0.write_register(0x0E, &mut profile).unwrap(); - hprintln!("{:#X?}", dds0.read_register(0x0E, &mut profile).unwrap()).unwrap(); - // Attenuator att.set_attenuation([ 0.0, 31.5, 24.0, 0.0 ]).unwrap(); - hprintln!("{:#X?}", att.get_attenuation().unwrap()).unwrap(); + hprintln!("{:#X?}", dds0.get_configurations(&mut + [ + (DDSCFRMask::SDIO_IN_ONLY, 0), + (DDSCFRMask::LSB_FIRST, 0), + (DDSCFRMask::PROFILE_CTRL, 0), + (DDSCFRMask::EN_AMP_SCALE_SINGLE_TONE_PRO, 0), + (DDSCFRMask::DRV0, 0), + (DDSCFRMask::VCO_SEL, 0) + ] + ).unwrap()).unwrap(); -/* - // Write to FTW register - dds0.write_register(0x07, &mut [ - ((ftw >> 24) & 0xFF) as u8, - ((ftw >> 16) & 0xFF) as u8, - ((ftw >> 8 ) & 0xFF) as u8, - ((ftw >> 0 ) & 0xFF) as u8, - ]).unwrap(); - - hprintln!("{:#X?}", dds0.read_register(0x07, &mut [ - 0x00, 0x00, 0x00, 0x00 - ]).unwrap()).unwrap(); -*/ loop {} }