diff --git a/artiq/coredevice/ad9154_spi.py b/artiq/coredevice/ad9154_spi.py index 0ebb77034..d83a85ff6 100644 --- a/artiq/coredevice/ad9154_spi.py +++ b/artiq/coredevice/ad9154_spi.py @@ -10,9 +10,8 @@ class AD9154: self.chip_select = chip_select @kernel - def setup_bus(self, write_div=16, read_div=16): - self.bus.set_config_mu(0, write_div, read_div) - self.bus.set_xfer(self.chip_select, 24, 0) + def setup_bus(self, div=16): + self.bus.set_config_mu(0, 24, div, self.chip_select) @kernel def write(self, addr, data): diff --git a/artiq/coredevice/spi.py b/artiq/coredevice/spi.py index 1d60722d5..b10d9dd0d 100644 --- a/artiq/coredevice/spi.py +++ b/artiq/coredevice/spi.py @@ -21,7 +21,7 @@ __all__ = [ "SPI_OFFLINE", "SPI_ACTIVE", "SPI_PENDING", "SPI_CS_POLARITY", "SPI_CLK_POLARITY", "SPI_CLK_PHASE", "SPI_LSB_FIRST", "SPI_HALF_DUPLEX", - "SPIMaster", "NRTSPIMaster" + "SPIMaster" ] @@ -284,65 +284,3 @@ class SPIMaster: rtio_output(now_mu(), self.channel, SPI_CONFIG_ADDR | SPI_RT2WB_READ, 0) return rtio_input_data(self.channel) - - -@syscall(flags={"nounwind", "nowrite"}) -def spi_set_config(busno: TInt32, flags: TInt32, write_div: TInt32, read_div: TInt32) -> TNone: - raise NotImplementedError("syscall not simulated") - - -@syscall(flags={"nounwind", "nowrite"}) -def spi_set_xfer(busno: TInt32, chip_select: TInt32, write_length: TInt32, read_length: TInt32) -> TNone: - raise NotImplementedError("syscall not simulated") - - -@syscall(flags={"nounwind", "nowrite"}) -def spi_write(busno: TInt32, data: TInt32) -> TNone: - raise NotImplementedError("syscall not simulated") - - -@syscall(flags={"nounwind", "nowrite"}) -def spi_read(busno: TInt32) -> TInt32: - raise NotImplementedError("syscall not simulated") - - -class NRTSPIMaster: - """Core device non-realtime Serial Peripheral Interface (SPI) bus master. - Owns one non-realtime SPI bus. - - With this driver, SPI transactions and are performed by the CPU without - involving RTIO. - - Realtime and non-realtime buses are separate and defined at bitstream - compilation time. - - See :class:`SPIMaster` for a description of the methods. - """ - def __init__(self, dmgr, busno=0, core_device="core"): - self.core = dmgr.get(core_device) - self.busno = busno - - @kernel - def set_config_mu(self, flags=0, write_div=6, read_div=6): - """Set the ``config`` register. - - Note that the non-realtime SPI cores are usually clocked by the system - clock and not the RTIO clock. In many cases, the SPI configuration is - already set by the firmware and you do not need to call this method. - - The offline bit cannot be set using this method. - The SPI bus is briefly taken offline when this method is called. - """ - spi_set_config(self.busno, flags, write_div, read_div) - - @kernel - def set_xfer(self, chip_select=0, write_length=0, read_length=0): - spi_set_xfer(self.busno, chip_select, write_length, read_length) - - @kernel - def write(self, data=0): - spi_write(self.busno, data) - - @kernel - def read(self): - return spi_read(self.busno) diff --git a/artiq/coredevice/spi2.py b/artiq/coredevice/spi2.py index ddf81d477..31e1effa2 100644 --- a/artiq/coredevice/spi2.py +++ b/artiq/coredevice/spi2.py @@ -8,6 +8,7 @@ time is an error. """ from artiq.language.core import syscall, kernel, portable, now_mu, delay_mu +from artiq.language.types import TInt32, TNone from artiq.coredevice.rtio import rtio_output, rtio_input_data @@ -16,7 +17,7 @@ __all__ = [ "SPI_OFFLINE", "SPI_END", "SPI_INPUT", "SPI_CS_POLARITY", "SPI_CLK_POLARITY", "SPI_CLK_PHASE", "SPI_LSB_FIRST", "SPI_HALF_DUPLEX", - "SPIMaster" + "SPIMaster", "NRTSPIMaster" ] SPI_DATA_ADDR = 0 @@ -205,3 +206,53 @@ class SPIMaster: :return: SPI input data. """ return rtio_input_data(self.channel) + + +@syscall(flags={"nounwind", "nowrite"}) +def spi_set_config(busno: TInt32, flags: TInt32, length: TInt32, div: TInt32, cs: TInt32) -> TNone: + raise NotImplementedError("syscall not simulated") + + +@syscall(flags={"nounwind", "nowrite"}) +def spi_write(busno: TInt32, data: TInt32) -> TNone: + raise NotImplementedError("syscall not simulated") + + +@syscall(flags={"nounwind", "nowrite"}) +def spi_read(busno: TInt32) -> TInt32: + raise NotImplementedError("syscall not simulated") + + +class NRTSPIMaster: + """Core device non-realtime Serial Peripheral Interface (SPI) bus master. + Owns one non-realtime SPI bus. + + With this driver, SPI transactions and are performed by the CPU without + involving RTIO. + + Realtime and non-realtime buses are separate and defined at bitstream + compilation time. + + See :class:`SPIMaster` for a description of the methods. + """ + def __init__(self, dmgr, busno=0, core_device="core"): + self.core = dmgr.get(core_device) + self.busno = busno + + @kernel + def set_config_mu(self, flags=0, length=8, div=6, cs=1): + """Set the ``config`` register. + + Note that the non-realtime SPI cores are usually clocked by the system + clock and not the RTIO clock. In many cases, the SPI configuration is + already set by the firmware and you do not need to call this method. + """ + spi_set_config(self.busno, flags, length, div, cs) + + @kernel + def write(self, data=0): + spi_write(self.busno, data) + + @kernel + def read(self): + return spi_read(self.busno) diff --git a/artiq/examples/sayma_drtio/device_db.py b/artiq/examples/sayma_drtio/device_db.py index 039efb6bd..92b7dd13d 100644 --- a/artiq/examples/sayma_drtio/device_db.py +++ b/artiq/examples/sayma_drtio/device_db.py @@ -95,7 +95,7 @@ device_db = { "converter_spi": { "type": "local", - "module": "artiq.coredevice.spi", + "module": "artiq.coredevice.spi2", "class": "NRTSPIMaster", }, "ad9154_spi0": { @@ -112,7 +112,7 @@ device_db = { }, "rconverter_spi": { "type": "local", - "module": "artiq.coredevice.spi", + "module": "artiq.coredevice.spi2", "class": "NRTSPIMaster", "arguments": {"busno": 0x010000} }, diff --git a/artiq/examples/sayma_standalone/device_db.py b/artiq/examples/sayma_standalone/device_db.py index 370b3f0a6..303fdce7e 100644 --- a/artiq/examples/sayma_standalone/device_db.py +++ b/artiq/examples/sayma_standalone/device_db.py @@ -21,7 +21,7 @@ device_db = { "converter_spi": { "type": "local", - "module": "artiq.coredevice.spi", + "module": "artiq.coredevice.spi2", "class": "NRTSPIMaster", }, "ad9154_spi0": { diff --git a/artiq/firmware/ksupport/api.rs b/artiq/firmware/ksupport/api.rs index 53736a0fa..b2d608b1f 100644 --- a/artiq/firmware/ksupport/api.rs +++ b/artiq/firmware/ksupport/api.rs @@ -118,7 +118,6 @@ static mut API: &'static [(&'static str, *const ())] = &[ api!(i2c_read = ::nrt_bus::i2c::read), api!(spi_set_config = ::nrt_bus::spi::set_config), - api!(spi_set_xfer = ::nrt_bus::spi::set_xfer), api!(spi_write = ::nrt_bus::spi::write), api!(spi_read = ::nrt_bus::spi::read), ]; diff --git a/artiq/firmware/ksupport/nrt_bus.rs b/artiq/firmware/ksupport/nrt_bus.rs index c847bcf82..9e226dd96 100644 --- a/artiq/firmware/ksupport/nrt_bus.rs +++ b/artiq/firmware/ksupport/nrt_bus.rs @@ -50,17 +50,9 @@ pub mod spi { use ::recv; use kernel_proto::*; - pub extern fn set_config(busno: i32, flags: i32, write_div: i32, read_div: i32) { + pub extern fn set_config(busno: i32, flags: i32, length: i32, div: i32, cs: i32) { send(&SpiSetConfigRequest { busno: busno as u32, flags: flags as u8, - write_div: write_div as u8, read_div: read_div as u8 }); - recv!(&SpiBasicReply { succeeded } => if !succeeded { - raise!("SPIError", "SPI bus could not be accessed"); - }); - } - - pub extern fn set_xfer(busno: i32, chip_select: i32, write_length: i32, read_length: i32) { - send(&SpiSetXferRequest { busno: busno as u32, chip_select: chip_select as u16, - write_length: write_length as u8, read_length: read_length as u8 }); + length: length as u8, div: div as u8, cs: cs as u8 }); recv!(&SpiBasicReply { succeeded } => if !succeeded { raise!("SPIError", "SPI bus could not be accessed"); }); diff --git a/artiq/firmware/libboard_artiq/ad9154.rs b/artiq/firmware/libboard_artiq/ad9154.rs index d00f2fc40..a50d55ab8 100644 --- a/artiq/firmware/libboard_artiq/ad9154.rs +++ b/artiq/firmware/libboard_artiq/ad9154.rs @@ -3,34 +3,33 @@ use ad9154_reg; fn spi_setup(dacno: u8) { unsafe { - csr::converter_spi::offline_write(1); + while csr::converter_spi::idle_read() == 0 {} + csr::converter_spi::offline_write(0); + csr::converter_spi::end_write(1); csr::converter_spi::cs_polarity_write(0b0001); csr::converter_spi::clk_polarity_write(0); csr::converter_spi::clk_phase_write(0); csr::converter_spi::lsb_first_write(0); csr::converter_spi::half_duplex_write(0); - csr::converter_spi::clk_div_write_write(16); - csr::converter_spi::clk_div_read_write(16); - csr::converter_spi::xfer_len_write_write(24); - csr::converter_spi::xfer_len_read_write(0); + csr::converter_spi::length_write(24 - 1); + csr::converter_spi::div_write(16 - 2); csr::converter_spi::cs_write(1 << (csr::CONFIG_CONVERTER_SPI_FIRST_AD9154_CS + dacno as u32)); - csr::converter_spi::offline_write(0); } } fn write(addr: u16, data: u8) { unsafe { - csr::converter_spi::data_write_write( + while csr::converter_spi::writable_read() == 0 {} + csr::converter_spi::data_write( ((addr as u32) << 16) | ((data as u32) << 8)); - while csr::converter_spi::pending_read() != 0 {} - while csr::converter_spi::active_read() != 0 {} + while csr::converter_spi::writable_read() == 0 {} } } fn read(addr: u16) -> u8 { unsafe { write((1 << 15) | addr, 0); - csr::converter_spi::data_read_read() as u8 + csr::converter_spi::data_read() as u8 } } diff --git a/artiq/firmware/libboard_artiq/hmc830_7043.rs b/artiq/firmware/libboard_artiq/hmc830_7043.rs index 80406251c..dc899ce15 100644 --- a/artiq/firmware/libboard_artiq/hmc830_7043.rs +++ b/artiq/firmware/libboard_artiq/hmc830_7043.rs @@ -51,16 +51,24 @@ mod hmc830 { fn spi_setup() { unsafe { - csr::converter_spi::offline_write(1); + while csr::converter_spi::idle_read() == 0 {} + csr::converter_spi::offline_write(0); + csr::converter_spi::end_write(1); csr::converter_spi::cs_polarity_write(0b0001); csr::converter_spi::clk_polarity_write(0); csr::converter_spi::clk_phase_write(0); csr::converter_spi::lsb_first_write(0); csr::converter_spi::half_duplex_write(0); - csr::converter_spi::clk_div_write_write(8); - csr::converter_spi::clk_div_read_write(8); + csr::converter_spi::div_write(16 - 2); csr::converter_spi::cs_write(1 << csr::CONFIG_CONVERTER_SPI_HMC830_CS); - csr::converter_spi::offline_write(0); + + // do a dummy cycle with cs still high to ensure Open mode + // (rising CLK before rising CS) + csr::converter_spi::length_write(0); + csr::converter_spi::data_write(0); + while csr::converter_spi::writable_read() == 0 {} + + csr::converter_spi::length_write(31 - 1); } } @@ -68,24 +76,17 @@ mod hmc830 { let cmd = (0 << 6) | addr; let val = ((cmd as u32) << 24) | data; unsafe { - csr::converter_spi::xfer_len_write_write(32); - csr::converter_spi::xfer_len_read_write(0); - csr::converter_spi::data_write_write(val << (32-31)); - while csr::converter_spi::pending_read() != 0 {} - while csr::converter_spi::active_read() != 0 {} + while csr::converter_spi::writable_read() == 0 {} + csr::converter_spi::data_write(val << 1); + while csr::converter_spi::writable_read() == 0 {} } } fn read(addr: u8) -> u32 { - let cmd = (1 << 6) | addr; - let val = (cmd as u32) << 24; + write(addr, 0); unsafe { - csr::converter_spi::xfer_len_write_write(7); - csr::converter_spi::xfer_len_read_write(25); - csr::converter_spi::data_write_write(val << (32-31)); - while csr::converter_spi::pending_read() != 0 {} - while csr::converter_spi::active_read() != 0 {} - csr::converter_spi::data_read_read() & 0xffffff + while csr::converter_spi::writable_read() == 0 {} + csr::converter_spi::data_read() & 0xffffff } } @@ -123,7 +124,7 @@ mod hmc830 { mod hmc7043 { use board::csr; - + // To do: check which output channels we actually need const DAC_CLK_DIV: u32 = 2; const FPGA_CLK_DIV: u32 = 8; @@ -150,16 +151,17 @@ mod hmc7043 { fn spi_setup() { unsafe { - csr::converter_spi::offline_write(1); + while csr::converter_spi::idle_read() == 0 {} + csr::converter_spi::offline_write(0); + csr::converter_spi::end_write(1); csr::converter_spi::cs_polarity_write(0b0001); csr::converter_spi::clk_polarity_write(0); csr::converter_spi::clk_phase_write(0); csr::converter_spi::lsb_first_write(0); - csr::converter_spi::half_duplex_write(1); - csr::converter_spi::clk_div_write_write(8); - csr::converter_spi::clk_div_read_write(8); + csr::converter_spi::half_duplex_write(0); // change mid-transaction for reads + csr::converter_spi::length_write(24 - 1); + csr::converter_spi::div_write(16 - 2); csr::converter_spi::cs_write(1 << csr::CONFIG_CONVERTER_SPI_HMC7043_CS); - csr::converter_spi::offline_write(0); } } @@ -167,24 +169,29 @@ mod hmc7043 { let cmd = (0 << 15) | addr; let val = ((cmd as u32) << 8) | data as u32; unsafe { - csr::converter_spi::xfer_len_write_write(24); - csr::converter_spi::xfer_len_read_write(0); - csr::converter_spi::data_write_write(val << (32-24)); - while csr::converter_spi::pending_read() != 0 {} - while csr::converter_spi::active_read() != 0 {} + while csr::converter_spi::writable_read() == 0 {} + csr::converter_spi::data_write(val << 8); + while csr::converter_spi::writable_read() == 0 {} } } fn read(addr: u16) -> u8 { let cmd = (1 << 15) | addr; - let val = (cmd as u32) << 8; + let val = cmd as u32; unsafe { - csr::converter_spi::xfer_len_write_write(16); - csr::converter_spi::xfer_len_read_write(8); - csr::converter_spi::data_write_write(val << (32-24)); - while csr::converter_spi::pending_read() != 0 {} - while csr::converter_spi::active_read() != 0 {} - csr::converter_spi::data_read_read() as u8 + while csr::converter_spi::writable_read() == 0 {} + csr::converter_spi::end_write(0); + csr::converter_spi::length_write(16 - 1); + csr::converter_spi::data_write(val << 16); + while csr::converter_spi::writable_read() == 0 {} + csr::converter_spi::end_write(1); + csr::converter_spi::half_duplex_write(1); + csr::converter_spi::length_write(8 - 1); + csr::converter_spi::data_write(0); + while csr::converter_spi::writable_read() == 0 {} + csr::converter_spi::half_duplex_write(0); + csr::converter_spi::length_write(24 - 1); + csr::converter_spi::data_read() as u8 } } @@ -233,7 +240,7 @@ mod hmc7043 { write(channel_base + 0x4, dphase & 0x1f); // No analog phase shift on clock channels - if (channel % 2) == 0 { write(channel_base + 0x7, 0x00); } + if (channel % 2) == 0 { write(channel_base + 0x7, 0x00); } else { write(channel_base + 0x7, 0x01); } write(channel_base + 0x8, 0x08) @@ -245,6 +252,7 @@ mod hmc7043 { pub fn init() -> Result<(), &'static str> { clock_mux::init(); + /* must be the first SPI init because of HMC830 SPI mode selection */ hmc830::init()?; hmc7043::init() } diff --git a/artiq/firmware/libboard_artiq/spi.rs b/artiq/firmware/libboard_artiq/spi.rs index 44aa0c729..94773b690 100644 --- a/artiq/firmware/libboard_artiq/spi.rs +++ b/artiq/firmware/libboard_artiq/spi.rs @@ -2,33 +2,24 @@ mod imp { use board::csr; - pub fn set_config(busno: u8, flags: u8, write_div: u8, read_div: u8) -> Result<(), ()> { + pub fn set_config(busno: u8, flags: u8, length: u8, div: u8, cs: u8) -> Result<(), ()> { if busno != 0 { return Err(()) } unsafe { - csr::converter_spi::offline_write(1); - csr::converter_spi::cs_polarity_write(flags >> 3 & 1); + while csr::converter_spi::idle_read() == 0 {} + csr::converter_spi::offline_write(flags >> 0 & 1); + csr::converter_spi::end_write(flags >> 1 & 1); + /* input (in RTIO): flags >> 2 & 1 */ + /* cs_polarity is a mask in the CSR interface */ + csr::converter_spi::cs_polarity_write(0xff & (flags >> 3 & 1)); csr::converter_spi::clk_polarity_write(flags >> 4 & 1); csr::converter_spi::clk_phase_write(flags >> 5 & 1); csr::converter_spi::lsb_first_write(flags >> 6 & 1); csr::converter_spi::half_duplex_write(flags >> 7 & 1); - csr::converter_spi::clk_div_write_write(write_div); - csr::converter_spi::clk_div_read_write(read_div); - csr::converter_spi::offline_write(0); - } - Ok(()) - } - - pub fn set_xfer(busno: u8, chip_select: u16, write_length: u8, read_length: u8) - -> Result<(), ()> { - if busno != 0 { - return Err(()) - } - unsafe { - csr::converter_spi::cs_write(chip_select as _); - csr::converter_spi::xfer_len_write_write(write_length); - csr::converter_spi::xfer_len_read_write(read_length); + csr::converter_spi::length_write(length - 1); + csr::converter_spi::div_write(div - 2); + csr::converter_spi::cs_write(cs); } Ok(()) } @@ -38,9 +29,9 @@ mod imp { return Err(()) } unsafe { - csr::converter_spi::data_write_write(data); - while csr::converter_spi::pending_read() != 0 {} - while csr::converter_spi::active_read() != 0 {} + while csr::converter_spi::writable_read() == 0 {} + csr::converter_spi::data_write(data); + while csr::converter_spi::writable_read() == 0 {} } Ok(()) } @@ -50,16 +41,14 @@ mod imp { return Err(()) } Ok(unsafe { - csr::converter_spi::data_read_read() + csr::converter_spi::data_read() }) } } #[cfg(not(has_converter_spi))] mod imp { - pub fn set_config(_busno: u8, _flags: u8, _write_div: u8, _read_div: u8) -> Result<(), ()> { Err(()) } - pub fn set_xfer(_busno: u8,_chip_select: u16, _write_length: u8, _read_length: u8) - -> Result<(), ()> { Err(()) } + pub fn set_config(_busno: u8, _flags: u8, _length: u8, _div: u8, _cs: u8) -> Result<(), ()> { Err(()) } pub fn write(_busno: u8,_data: u32) -> Result<(), ()> { Err(()) } pub fn read(_busno: u8,) -> Result { Err(()) } } diff --git a/artiq/firmware/libdrtioaux/lib.rs b/artiq/firmware/libdrtioaux/lib.rs index 927825630..bb4aa6dcc 100644 --- a/artiq/firmware/libdrtioaux/lib.rs +++ b/artiq/firmware/libdrtioaux/lib.rs @@ -41,8 +41,7 @@ pub enum Packet { I2cReadReply { succeeded: bool, data: u8 }, I2cBasicReply { succeeded: bool }, - SpiSetConfigRequest { busno: u8, flags: u8, write_div: u8, read_div: u8 }, - SpiSetXferRequest { busno: u8, chip_select: u16, write_length: u8, read_length: u8 }, + SpiSetConfigRequest { busno: u8, flags: u8, length: u8, div: u8, cs: u8 }, SpiWriteRequest { busno: u8, data: u32 }, SpiReadRequest { busno: u8 }, SpiReadReply { succeeded: bool, data: u32 }, @@ -123,15 +122,11 @@ impl Packet { 0x90 => Packet::SpiSetConfigRequest { busno: read_u8(reader)?, flags: read_u8(reader)?, - write_div: read_u8(reader)?, - read_div: read_u8(reader)? - }, - 0x91 => Packet::SpiSetXferRequest { - busno: read_u8(reader)?, - chip_select: read_u16(reader)?, - write_length: read_u8(reader)?, - read_length: read_u8(reader)? + length: read_u8(reader)?, + div: read_u8(reader)?, + cs: read_u8(reader)? }, + /* 0x91: was Packet::SpiSetXferRequest */ 0x92 => Packet::SpiWriteRequest { busno: read_u8(reader)?, data: read_u32(reader)? @@ -238,19 +233,13 @@ impl Packet { write_bool(writer, succeeded)?; }, - Packet::SpiSetConfigRequest { busno, flags, write_div, read_div } => { + Packet::SpiSetConfigRequest { busno, flags, length, div, cs } => { write_u8(writer, 0x90)?; write_u8(writer, busno)?; write_u8(writer, flags)?; - write_u8(writer, write_div)?; - write_u8(writer, read_div)?; - }, - Packet::SpiSetXferRequest { busno, chip_select, write_length, read_length } => { - write_u8(writer, 0x91)?; - write_u8(writer, busno)?; - write_u16(writer, chip_select)?; - write_u8(writer, write_length)?; - write_u8(writer, read_length)?; + write_u8(writer, length)?; + write_u8(writer, div)?; + write_u8(writer, cs)?; }, Packet::SpiWriteRequest { busno, data } => { write_u8(writer, 0x92)?; diff --git a/artiq/firmware/libproto/kernel_proto.rs b/artiq/firmware/libproto/kernel_proto.rs index 06e5473d0..babd9fbcf 100644 --- a/artiq/firmware/libproto/kernel_proto.rs +++ b/artiq/firmware/libproto/kernel_proto.rs @@ -85,8 +85,7 @@ pub enum Message<'a> { I2cReadReply { succeeded: bool, data: u8 }, I2cBasicReply { succeeded: bool }, - SpiSetConfigRequest { busno: u32, flags: u8, write_div: u8, read_div: u8 }, - SpiSetXferRequest { busno: u32, chip_select: u16, write_length: u8, read_length: u8 }, + SpiSetConfigRequest { busno: u32, flags: u8, length: u8, div: u8, cs: u8 }, SpiWriteRequest { busno: u32, data: u32 }, SpiReadRequest { busno: u32 }, SpiReadReply { succeeded: bool, data: u32 }, diff --git a/artiq/firmware/runtime/kern_hwreq.rs b/artiq/firmware/runtime/kern_hwreq.rs index 8eea9cd17..be1a380e8 100644 --- a/artiq/firmware/runtime/kern_hwreq.rs +++ b/artiq/firmware/runtime/kern_hwreq.rs @@ -194,25 +194,13 @@ mod drtio_spi { } } - pub fn set_config(nodeno: u8, busno: u8, flags: u8, write_div: u8, read_div: u8) -> Result<(), ()> { + pub fn set_config(nodeno: u8, busno: u8, flags: u8, length: u8, div: u8, cs: u8) -> Result<(), ()> { let request = drtioaux::Packet::SpiSetConfigRequest { busno: busno, flags: flags, - write_div: write_div, - read_div: read_div - }; - if drtioaux::hw::send(nodeno, &request).is_err() { - return Err(()) - } - basic_reply(nodeno) - } - - pub fn set_xfer(nodeno: u8, busno: u8, chip_select: u16, write_length: u8, read_length: u8) -> Result<(), ()> { - let request = drtioaux::Packet::SpiSetXferRequest { - busno: busno, - chip_select: chip_select, - write_length: write_length, - read_length: read_length + length: length, + div: div, + cs: cs }; if drtioaux::hw::send(nodeno, &request).is_err() { return Err(()) @@ -255,12 +243,7 @@ mod drtio_spi { #[cfg(not(has_drtio))] mod drtio_spi { pub fn set_config(_nodeno: u8, _busno: u8, _flags: u8, - _write_div: u8, _read_div: u8) -> Result<(), ()> { - Err(()) - } - - pub fn set_xfer(_nodeno: u8, _busno: u8, _chip_select: u16, - _write_length: u8, _read_length: u8) -> Result<(), ()> { + _length: u8, _div: u8, _cs: u8) -> Result<(), ()> { Err(()) } @@ -277,23 +260,13 @@ mod spi { use board_artiq::spi as local_spi; use super::drtio_spi; - pub fn set_config(busno: u32, flags: u8, write_div: u8, read_div: u8) -> Result<(), ()> { + pub fn set_config(busno: u32, flags: u8, length: u8, div: u8, cs: u8) -> Result<(), ()> { let nodeno = (busno >> 16) as u8; let node_busno = busno as u8; if nodeno == 0 { - local_spi::set_config(node_busno, flags, write_div, read_div) + local_spi::set_config(node_busno, flags, length, div, cs) } else { - drtio_spi::set_config(nodeno, node_busno, flags, write_div, read_div) - } - } - - pub fn set_xfer(busno: u32, chip_select: u16, write_length: u8, read_length: u8) -> Result<(), ()> { - let nodeno = (busno >> 16) as u8; - let node_busno = busno as u8; - if nodeno == 0 { - local_spi::set_xfer(node_busno, chip_select, write_length, read_length) - } else { - drtio_spi::set_xfer(nodeno, node_busno, chip_select, write_length, read_length) + drtio_spi::set_config(nodeno, node_busno, flags, length, div, cs) } } @@ -364,14 +337,10 @@ pub fn process_kern_hwreq(io: &Io, request: &kern::Message) -> io::Result } } - &kern::SpiSetConfigRequest { busno, flags, write_div, read_div } => { - let succeeded = spi::set_config(busno, flags, write_div, read_div).is_ok(); + &kern::SpiSetConfigRequest { busno, flags, length, div, cs } => { + let succeeded = spi::set_config(busno, flags, length, div, cs).is_ok(); kern_send(io, &kern::SpiBasicReply { succeeded: succeeded }) }, - &kern::SpiSetXferRequest { busno, chip_select, write_length, read_length } => { - let succeeded = spi::set_xfer(busno, chip_select, write_length, read_length).is_ok(); - kern_send(io, &kern::SpiBasicReply { succeeded: succeeded }) - } &kern::SpiWriteRequest { busno, data } => { let succeeded = spi::write(busno, data).is_ok(); kern_send(io, &kern::SpiBasicReply { succeeded: succeeded }) diff --git a/artiq/firmware/runtime/main.rs b/artiq/firmware/runtime/main.rs index 9cf3c11f3..3066ea9b3 100644 --- a/artiq/firmware/runtime/main.rs +++ b/artiq/firmware/runtime/main.rs @@ -94,6 +94,7 @@ fn startup() { #[cfg(si5324_as_synthesizer)] setup_si5324_as_synthesizer(); #[cfg(has_hmc830_7043)] + /* must be the first SPI init because of HMC830 SPI mode selection */ board_artiq::hmc830_7043::init().expect("cannot initialize HMC830/7043"); #[cfg(has_ad9154)] board_artiq::ad9154::init().expect("cannot initialize AD9154"); diff --git a/artiq/firmware/satman/main.rs b/artiq/firmware/satman/main.rs index 7744c65c0..195471457 100644 --- a/artiq/firmware/satman/main.rs +++ b/artiq/firmware/satman/main.rs @@ -144,14 +144,10 @@ fn process_aux_packet(p: &drtioaux::Packet) { }; } - drtioaux::Packet::SpiSetConfigRequest { busno, flags, write_div, read_div } => { - let succeeded = spi::set_config(busno, flags, write_div, read_div).is_ok(); + drtioaux::Packet::SpiSetConfigRequest { busno, flags, length, div, cs } => { + let succeeded = spi::set_config(busno, flags, length, div, cs).is_ok(); drtioaux::hw::send_link(0, &drtioaux::Packet::SpiBasicReply { succeeded: succeeded }).unwrap(); }, - drtioaux::Packet::SpiSetXferRequest { busno, chip_select, write_length, read_length } => { - let succeeded = spi::set_xfer(busno, chip_select, write_length, read_length).is_ok(); - drtioaux::hw::send_link(0, &drtioaux::Packet::SpiBasicReply { succeeded: succeeded }).unwrap(); - } drtioaux::Packet::SpiWriteRequest { busno, data } => { let succeeded = spi::write(busno, data).is_ok(); drtioaux::hw::send_link(0, &drtioaux::Packet::SpiBasicReply { succeeded: succeeded }).unwrap(); @@ -226,6 +222,7 @@ fn startup() { serwb::wait_init(); #[cfg(has_hmc830_7043)] + /* must be the first SPI init because of HMC830 SPI mode selection */ hmc830_7043::init().expect("cannot initialize HMC830/7043"); i2c::init(); si5324::setup(&SI5324_SETTINGS).expect("cannot initialize Si5324"); diff --git a/artiq/gateware/targets/sayma_rtm.py b/artiq/gateware/targets/sayma_rtm.py index 9a77a4694..4061320ed 100755 --- a/artiq/gateware/targets/sayma_rtm.py +++ b/artiq/gateware/targets/sayma_rtm.py @@ -10,7 +10,7 @@ from migen.build.platforms.sinara import sayma_rtm from misoc.interconnect import wishbone, stream from misoc.interconnect.csr import * from misoc.cores import identifier -from misoc.cores import spi +from misoc.cores import spi2 from misoc.cores import gpio from misoc.integration.wb_slaves import WishboneSlaveManager from misoc.integration.cpu_interface import get_csr_csv @@ -140,10 +140,10 @@ class SaymaRTM(Module): platform.request("ad9154_txen", 1).eq(0b11) ] - self.submodules.converter_spi = spi.SPIMaster([ + self.submodules.converter_spi = spi2.SPIMaster(spi2.SPIInterface( platform.request("hmc_spi"), platform.request("ad9154_spi", 0), - platform.request("ad9154_spi", 1)]) + platform.request("ad9154_spi", 1))) csr_devices.append("converter_spi") self.comb += platform.request("hmc7043_reset").eq(0)