attenuator: fix reverse data

This commit is contained in:
occheung 2020-08-25 12:20:24 +08:00
parent 29abca72cd
commit 181ef5c72a
3 changed files with 54 additions and 130 deletions

View File

@ -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",
] ]

View File

@ -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),
}
} }
} }

View File

@ -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 {}
} }