forked from M-Labs/humpback-dds
attenuator: fix reverse data
This commit is contained in:
parent
29abca72cd
commit
181ef5c72a
@ -1,5 +1,5 @@
|
|||||||
[target.thumbv7em-none-eabihf]
|
[target.thumbv7em-none-eabihf]
|
||||||
runner = "gdb -q -x gdb_config/debug.gdb"
|
runner = "gdb -q -x gdb_config/openocd.gdb"
|
||||||
rustflags = [
|
rustflags = [
|
||||||
"-C", "link-arg=-Tlink.x",
|
"-C", "link-arg=-Tlink.x",
|
||||||
]
|
]
|
||||||
|
@ -17,11 +17,16 @@ where
|
|||||||
pub fn new(spi: SPI) -> Self {
|
pub fn new(spi: SPI) -> Self {
|
||||||
Attenuator {
|
Attenuator {
|
||||||
spi,
|
spi,
|
||||||
|
// data[y] refers to the yth byte for SPI communication
|
||||||
data: [0, 0, 0, 0],
|
data: [0, 0, 0, 0],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_attenuation(&mut self, att: [f32; 4]) -> Result<[u8; 4], Error<E>> {
|
/*
|
||||||
|
* Set attenuations of all attenuators
|
||||||
|
* att[x] refers to the attenuation for channel x
|
||||||
|
*/
|
||||||
|
pub fn set_attenuation(&mut self, att: [f32; 4]) -> Result<(), Error<E>> {
|
||||||
for i in 0..4 {
|
for i in 0..4 {
|
||||||
let mut atten = att[i];
|
let mut atten = att[i];
|
||||||
if att[i] > 31.5 {
|
if att[i] > 31.5 {
|
||||||
@ -30,48 +35,49 @@ where
|
|||||||
if att[i] < 0.0 {
|
if att[i] < 0.0 {
|
||||||
atten = 0.0;
|
atten = 0.0;
|
||||||
}
|
}
|
||||||
self.data[i] = (atten * 2.0) as u8;
|
// Set data as attenuation * 2
|
||||||
self.data[i] = self.data[i] << 2;
|
// Flip data using bitwise XOR, active low data
|
||||||
|
// Data is most signifant attenuator first
|
||||||
|
self.data[3-i] = (((atten * 2.0) as u8) ^ 0xFF) << 2
|
||||||
}
|
}
|
||||||
let mut clone = self.data.clone();
|
let mut clone = self.data.clone();
|
||||||
// Transmit SPI once to set attenuation
|
// Transmit SPI once to set attenuation
|
||||||
if self.spi.transfer(&mut clone).map_err(Error::SPI).is_err() {
|
|
||||||
return Err(Error::AttenuatorError);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Transmit the same data again, to get the return value
|
|
||||||
// Report the data returned by SPI, or an error
|
|
||||||
clone = self.data.clone();
|
|
||||||
match self.spi.transfer(&mut clone).map_err(Error::SPI) {
|
match self.spi.transfer(&mut clone).map_err(Error::SPI) {
|
||||||
Ok(arr) => {
|
Err(e) => Err(Error::AttenuatorError),
|
||||||
Ok([arr[0], arr[1], arr[2], arr[3]])
|
Ok(_) => Ok(()),
|
||||||
},
|
|
||||||
err => Err(Error::AttenuatorError)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_channel_attenuation(&mut self, channel: u8, attenuation: f32) -> Result<u8, Error<E>> {
|
pub fn set_channel_attenuation(&mut self, channel: u8, attenuation: f32) -> Result<(), Error<E>> {
|
||||||
assert!(channel < 4);
|
assert!(channel < 4);
|
||||||
let mut arr: [f32; 4] = self.get_attenuation();
|
let mut arr: [f32; 4] = self.get_attenuation()?;
|
||||||
arr[channel as usize] = attenuation;
|
arr[channel as usize] = attenuation;
|
||||||
match self.set_attenuation(arr) {
|
match self.set_attenuation(arr) {
|
||||||
Ok(v) => Ok(v[channel as usize]),
|
Ok(v) => Ok(()),
|
||||||
Err(e) => Err(e)
|
Err(e) => Err(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_channel_attenuation(&mut self, channel: u8) -> f32 {
|
pub fn get_channel_attenuation(&mut self, channel: u8) -> Result<f32, Error<E>> {
|
||||||
assert!(channel < 4);
|
assert!(channel < 4);
|
||||||
(self.data[channel as usize] as f32)/8.0
|
match self.get_attenuation() {
|
||||||
|
Ok(arr) => Ok(arr[channel as usize]),
|
||||||
|
Err(e) => Err(e),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_attenuation(&mut self) -> [f32; 4] {
|
pub fn get_attenuation(&mut self) -> Result<[f32; 4], Error<E>> {
|
||||||
[
|
let mut clone = self.data.clone();
|
||||||
self.get_channel_attenuation(0),
|
match self.spi.transfer(&mut clone).map_err(Error::SPI) {
|
||||||
self.get_channel_attenuation(1),
|
Ok(arr) => {
|
||||||
self.get_channel_attenuation(2),
|
let mut ret :[f32; 4] = [0.0; 4];
|
||||||
self.get_channel_attenuation(3),
|
for index in 0..4 {
|
||||||
]
|
ret[index] = ((arr[3 - index] ^ 0xFC) as f32) / 8.0;
|
||||||
|
}
|
||||||
|
Ok(ret)
|
||||||
|
},
|
||||||
|
Err(e) => Err(e),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
124
src/main.rs
124
src/main.rs
@ -84,8 +84,7 @@ fn main() -> ! {
|
|||||||
/*
|
/*
|
||||||
* I/O_Update -> PB13
|
* I/O_Update -> PB13
|
||||||
*/
|
*/
|
||||||
// TODO: Incoporate io_update into DDS
|
let io_update = gpiob.pb15.into_push_pull_output();
|
||||||
let mut io_update = gpiob.pb15.into_push_pull_output();
|
|
||||||
|
|
||||||
let spi = dp.SPI1.spi(
|
let spi = dp.SPI1.spi(
|
||||||
(sclk, miso, mosi),
|
(sclk, miso, mosi),
|
||||||
@ -94,7 +93,7 @@ fn main() -> ! {
|
|||||||
ccdr.peripheral.SPI1,
|
ccdr.peripheral.SPI1,
|
||||||
&ccdr.clocks,
|
&ccdr.clocks,
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut switch = CPLD::new(spi, (cs0, cs1, cs2), io_update);
|
let mut switch = CPLD::new(spi, (cs0, cs1, cs2), io_update);
|
||||||
let parts = switch.split();
|
let parts = switch.split();
|
||||||
|
|
||||||
@ -119,18 +118,10 @@ fn main() -> ! {
|
|||||||
0x00, 0x00, 0x00, 0x02
|
0x00, 0x00, 0x00, 0x02
|
||||||
]).unwrap();
|
]).unwrap();
|
||||||
|
|
||||||
// io_update.set_high().unwrap();
|
|
||||||
// io_update.set_low().unwrap();
|
|
||||||
// switch.issue_io_update();
|
|
||||||
|
|
||||||
dds0.write_register(0x02, &mut[
|
dds0.write_register(0x02, &mut[
|
||||||
0x01F, 0x3F, 0xC0, 0x00
|
0x01F, 0x3F, 0x41, 0x00
|
||||||
]).unwrap();
|
]).unwrap();
|
||||||
|
|
||||||
// io_update.set_high().unwrap();
|
|
||||||
// io_update.set_low().unwrap();
|
|
||||||
// switch.issue_io_update();
|
|
||||||
|
|
||||||
hprintln!("{:#X?}", dds0.read_register(0x00, &mut[
|
hprintln!("{:#X?}", dds0.read_register(0x00, &mut[
|
||||||
0x00, 0x00, 0x00, 0x00
|
0x00, 0x00, 0x00, 0x00
|
||||||
]).unwrap()).unwrap();
|
]).unwrap()).unwrap();
|
||||||
@ -148,109 +139,36 @@ fn main() -> ! {
|
|||||||
dds0.read_register(0x0E, &mut profile).unwrap();
|
dds0.read_register(0x0E, &mut profile).unwrap();
|
||||||
|
|
||||||
// Overwrite FTW on profile
|
// Overwrite FTW on profile
|
||||||
|
profile[0] = 0x20;
|
||||||
profile[4] = ((ftw >> 24) & 0xFF) as u8;
|
profile[4] = ((ftw >> 24) & 0xFF) as u8;
|
||||||
profile[5] = ((ftw >> 16) & 0xFF) as u8;
|
profile[5] = ((ftw >> 16) & 0xFF) as u8;
|
||||||
profile[6] = ((ftw >> 8 ) & 0xFF) as u8;
|
profile[6] = ((ftw >> 8 ) & 0xFF) as u8;
|
||||||
profile[7] = ((ftw >> 0 ) & 0xFF) as u8;
|
profile[7] = ((ftw >> 0 ) & 0xFF) as u8;
|
||||||
|
|
||||||
dds0.write_register(0x0E, &mut profile).unwrap();
|
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();
|
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();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
cs0.set_low().unwrap();
|
// Write to FTW register
|
||||||
cs1.set_low().unwrap();
|
dds0.write_register(0x07, &mut [
|
||||||
cs2.set_low().unwrap();
|
((ftw >> 24) & 0xFF) as u8,
|
||||||
|
((ftw >> 16) & 0xFF) as u8,
|
||||||
io_update.set_low().unwrap();
|
((ftw >> 8 ) & 0xFF) as u8,
|
||||||
|
((ftw >> 0 ) & 0xFF) as u8,
|
||||||
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();
|
|
||||||
|
|
||||||
// Release reset, control I/O Update through EEM
|
|
||||||
// Relay clock signal from internal OSC (CLK_SEL = 0)
|
|
||||||
// Enable Switch 0
|
|
||||||
cs0.set_high().unwrap();
|
|
||||||
spi.transfer(&mut [
|
|
||||||
0x00, 0x00, 0x01
|
|
||||||
]).unwrap();
|
|
||||||
cs0.set_low().unwrap();
|
|
||||||
|
|
||||||
cs0.set_low().unwrap();
|
|
||||||
cs1.set_low().unwrap();
|
|
||||||
cs2.set_high().unwrap();
|
|
||||||
|
|
||||||
// Configure SDIO to be input only, enable 3-wires communication
|
|
||||||
spi.transfer(&mut [
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x02
|
|
||||||
]).unwrap();
|
]).unwrap();
|
||||||
|
|
||||||
// IO Update after every SPI transfer
|
hprintln!("{:#X?}", dds0.read_register(0x07, &mut [
|
||||||
io_update.set_high().unwrap();
|
0x00, 0x00, 0x00, 0x00
|
||||||
delay.delay_ms(1_u16);
|
|
||||||
io_update.set_low().unwrap();
|
|
||||||
|
|
||||||
// Bypass PLL, bypass divisor
|
|
||||||
spi.transfer(&mut [
|
|
||||||
0x02, 0x1F, 0x3F, 0xC0, 0x00
|
|
||||||
]).unwrap();
|
|
||||||
|
|
||||||
io_update.set_high().unwrap();
|
|
||||||
delay.delay_ms(1_u16);
|
|
||||||
io_update.set_low().unwrap();
|
|
||||||
|
|
||||||
hprintln!("{:#X?}", spi.transfer(&mut [
|
|
||||||
0x82, 0x00, 0x00, 0x00, 0x00
|
|
||||||
]).unwrap()).unwrap();
|
]).unwrap()).unwrap();
|
||||||
|
*/
|
||||||
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;
|
|
||||||
|
|
||||||
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();
|
|
||||||
|
|
||||||
// Read profile again, new value should be present
|
|
||||||
profile_arr_0[0] = 0x8E;
|
|
||||||
hprintln!("{:#X?}", spi.transfer(&mut profile_arr_0).unwrap()).unwrap();
|
|
||||||
*/
|
|
||||||
|
|
||||||
loop {}
|
loop {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user