forked from M-Labs/artiq
1
0
Fork 0

firmware, sayma: port converter_spi to spi2

* ksupport/nrt_bus
* port ad9154, hmc830, hmc7043
* port local_spi and drtio_spi
* port kernel_proto libdrtioaux, satman
* change sayma_rtm gateware over
* add spi2 NRTSPIMaster
* remove spi NRTSPIMaster
* change sayma device_db
* change HMC830 to open mode and explicitly sequence open mode
This commit is contained in:
Robert Jördens 2018-02-23 09:50:49 +00:00 committed by Robert Jordens
parent 68278e225d
commit a7720d05cd
16 changed files with 155 additions and 225 deletions

View File

@ -10,9 +10,8 @@ class AD9154:
self.chip_select = chip_select self.chip_select = chip_select
@kernel @kernel
def setup_bus(self, write_div=16, read_div=16): def setup_bus(self, div=16):
self.bus.set_config_mu(0, write_div, read_div) self.bus.set_config_mu(0, 24, div, self.chip_select)
self.bus.set_xfer(self.chip_select, 24, 0)
@kernel @kernel
def write(self, addr, data): def write(self, addr, data):

View File

@ -21,7 +21,7 @@ __all__ = [
"SPI_OFFLINE", "SPI_ACTIVE", "SPI_PENDING", "SPI_OFFLINE", "SPI_ACTIVE", "SPI_PENDING",
"SPI_CS_POLARITY", "SPI_CLK_POLARITY", "SPI_CLK_PHASE", "SPI_CS_POLARITY", "SPI_CLK_POLARITY", "SPI_CLK_PHASE",
"SPI_LSB_FIRST", "SPI_HALF_DUPLEX", "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, rtio_output(now_mu(), self.channel, SPI_CONFIG_ADDR | SPI_RT2WB_READ,
0) 0)
return rtio_input_data(self.channel) 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)

View File

@ -8,6 +8,7 @@ time is an error.
""" """
from artiq.language.core import syscall, kernel, portable, now_mu, delay_mu 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 from artiq.coredevice.rtio import rtio_output, rtio_input_data
@ -16,7 +17,7 @@ __all__ = [
"SPI_OFFLINE", "SPI_END", "SPI_INPUT", "SPI_OFFLINE", "SPI_END", "SPI_INPUT",
"SPI_CS_POLARITY", "SPI_CLK_POLARITY", "SPI_CLK_PHASE", "SPI_CS_POLARITY", "SPI_CLK_POLARITY", "SPI_CLK_PHASE",
"SPI_LSB_FIRST", "SPI_HALF_DUPLEX", "SPI_LSB_FIRST", "SPI_HALF_DUPLEX",
"SPIMaster" "SPIMaster", "NRTSPIMaster"
] ]
SPI_DATA_ADDR = 0 SPI_DATA_ADDR = 0
@ -205,3 +206,53 @@ class SPIMaster:
:return: SPI input data. :return: SPI input data.
""" """
return rtio_input_data(self.channel) 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)

View File

@ -95,7 +95,7 @@ device_db = {
"converter_spi": { "converter_spi": {
"type": "local", "type": "local",
"module": "artiq.coredevice.spi", "module": "artiq.coredevice.spi2",
"class": "NRTSPIMaster", "class": "NRTSPIMaster",
}, },
"ad9154_spi0": { "ad9154_spi0": {
@ -112,7 +112,7 @@ device_db = {
}, },
"rconverter_spi": { "rconverter_spi": {
"type": "local", "type": "local",
"module": "artiq.coredevice.spi", "module": "artiq.coredevice.spi2",
"class": "NRTSPIMaster", "class": "NRTSPIMaster",
"arguments": {"busno": 0x010000} "arguments": {"busno": 0x010000}
}, },

View File

@ -21,7 +21,7 @@ device_db = {
"converter_spi": { "converter_spi": {
"type": "local", "type": "local",
"module": "artiq.coredevice.spi", "module": "artiq.coredevice.spi2",
"class": "NRTSPIMaster", "class": "NRTSPIMaster",
}, },
"ad9154_spi0": { "ad9154_spi0": {

View File

@ -118,7 +118,6 @@ static mut API: &'static [(&'static str, *const ())] = &[
api!(i2c_read = ::nrt_bus::i2c::read), api!(i2c_read = ::nrt_bus::i2c::read),
api!(spi_set_config = ::nrt_bus::spi::set_config), 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_write = ::nrt_bus::spi::write),
api!(spi_read = ::nrt_bus::spi::read), api!(spi_read = ::nrt_bus::spi::read),
]; ];

View File

@ -50,17 +50,9 @@ pub mod spi {
use ::recv; use ::recv;
use kernel_proto::*; 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, send(&SpiSetConfigRequest { busno: busno as u32, flags: flags as u8,
write_div: write_div as u8, read_div: read_div 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");
});
}
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 });
recv!(&SpiBasicReply { succeeded } => if !succeeded { recv!(&SpiBasicReply { succeeded } => if !succeeded {
raise!("SPIError", "SPI bus could not be accessed"); raise!("SPIError", "SPI bus could not be accessed");
}); });

View File

@ -3,34 +3,33 @@ use ad9154_reg;
fn spi_setup(dacno: u8) { fn spi_setup(dacno: u8) {
unsafe { 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::cs_polarity_write(0b0001);
csr::converter_spi::clk_polarity_write(0); csr::converter_spi::clk_polarity_write(0);
csr::converter_spi::clk_phase_write(0); csr::converter_spi::clk_phase_write(0);
csr::converter_spi::lsb_first_write(0); csr::converter_spi::lsb_first_write(0);
csr::converter_spi::half_duplex_write(0); csr::converter_spi::half_duplex_write(0);
csr::converter_spi::clk_div_write_write(16); csr::converter_spi::length_write(24 - 1);
csr::converter_spi::clk_div_read_write(16); csr::converter_spi::div_write(16 - 2);
csr::converter_spi::xfer_len_write_write(24);
csr::converter_spi::xfer_len_read_write(0);
csr::converter_spi::cs_write(1 << (csr::CONFIG_CONVERTER_SPI_FIRST_AD9154_CS + dacno as u32)); 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) { fn write(addr: u16, data: u8) {
unsafe { 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)); ((addr as u32) << 16) | ((data as u32) << 8));
while csr::converter_spi::pending_read() != 0 {} while csr::converter_spi::writable_read() == 0 {}
while csr::converter_spi::active_read() != 0 {}
} }
} }
fn read(addr: u16) -> u8 { fn read(addr: u16) -> u8 {
unsafe { unsafe {
write((1 << 15) | addr, 0); write((1 << 15) | addr, 0);
csr::converter_spi::data_read_read() as u8 csr::converter_spi::data_read() as u8
} }
} }

View File

@ -51,16 +51,24 @@ mod hmc830 {
fn spi_setup() { fn spi_setup() {
unsafe { 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::cs_polarity_write(0b0001);
csr::converter_spi::clk_polarity_write(0); csr::converter_spi::clk_polarity_write(0);
csr::converter_spi::clk_phase_write(0); csr::converter_spi::clk_phase_write(0);
csr::converter_spi::lsb_first_write(0); csr::converter_spi::lsb_first_write(0);
csr::converter_spi::half_duplex_write(0); csr::converter_spi::half_duplex_write(0);
csr::converter_spi::clk_div_write_write(8); csr::converter_spi::div_write(16 - 2);
csr::converter_spi::clk_div_read_write(8);
csr::converter_spi::cs_write(1 << csr::CONFIG_CONVERTER_SPI_HMC830_CS); 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 cmd = (0 << 6) | addr;
let val = ((cmd as u32) << 24) | data; let val = ((cmd as u32) << 24) | data;
unsafe { unsafe {
csr::converter_spi::xfer_len_write_write(32); while csr::converter_spi::writable_read() == 0 {}
csr::converter_spi::xfer_len_read_write(0); csr::converter_spi::data_write(val << 1);
csr::converter_spi::data_write_write(val << (32-31)); while csr::converter_spi::writable_read() == 0 {}
while csr::converter_spi::pending_read() != 0 {}
while csr::converter_spi::active_read() != 0 {}
} }
} }
fn read(addr: u8) -> u32 { fn read(addr: u8) -> u32 {
let cmd = (1 << 6) | addr; write(addr, 0);
let val = (cmd as u32) << 24;
unsafe { unsafe {
csr::converter_spi::xfer_len_write_write(7); while csr::converter_spi::writable_read() == 0 {}
csr::converter_spi::xfer_len_read_write(25); csr::converter_spi::data_read() & 0xffffff
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
} }
} }
@ -123,7 +124,7 @@ mod hmc830 {
mod hmc7043 { mod hmc7043 {
use board::csr; use board::csr;
// To do: check which output channels we actually need // To do: check which output channels we actually need
const DAC_CLK_DIV: u32 = 2; const DAC_CLK_DIV: u32 = 2;
const FPGA_CLK_DIV: u32 = 8; const FPGA_CLK_DIV: u32 = 8;
@ -150,16 +151,17 @@ mod hmc7043 {
fn spi_setup() { fn spi_setup() {
unsafe { 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::cs_polarity_write(0b0001);
csr::converter_spi::clk_polarity_write(0); csr::converter_spi::clk_polarity_write(0);
csr::converter_spi::clk_phase_write(0); csr::converter_spi::clk_phase_write(0);
csr::converter_spi::lsb_first_write(0); csr::converter_spi::lsb_first_write(0);
csr::converter_spi::half_duplex_write(1); csr::converter_spi::half_duplex_write(0); // change mid-transaction for reads
csr::converter_spi::clk_div_write_write(8); csr::converter_spi::length_write(24 - 1);
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_HMC7043_CS); 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 cmd = (0 << 15) | addr;
let val = ((cmd as u32) << 8) | data as u32; let val = ((cmd as u32) << 8) | data as u32;
unsafe { unsafe {
csr::converter_spi::xfer_len_write_write(24); while csr::converter_spi::writable_read() == 0 {}
csr::converter_spi::xfer_len_read_write(0); csr::converter_spi::data_write(val << 8);
csr::converter_spi::data_write_write(val << (32-24)); while csr::converter_spi::writable_read() == 0 {}
while csr::converter_spi::pending_read() != 0 {}
while csr::converter_spi::active_read() != 0 {}
} }
} }
fn read(addr: u16) -> u8 { fn read(addr: u16) -> u8 {
let cmd = (1 << 15) | addr; let cmd = (1 << 15) | addr;
let val = (cmd as u32) << 8; let val = cmd as u32;
unsafe { unsafe {
csr::converter_spi::xfer_len_write_write(16); while csr::converter_spi::writable_read() == 0 {}
csr::converter_spi::xfer_len_read_write(8); csr::converter_spi::end_write(0);
csr::converter_spi::data_write_write(val << (32-24)); csr::converter_spi::length_write(16 - 1);
while csr::converter_spi::pending_read() != 0 {} csr::converter_spi::data_write(val << 16);
while csr::converter_spi::active_read() != 0 {} while csr::converter_spi::writable_read() == 0 {}
csr::converter_spi::data_read_read() as u8 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); write(channel_base + 0x4, dphase & 0x1f);
// No analog phase shift on clock channels // 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); } else { write(channel_base + 0x7, 0x01); }
write(channel_base + 0x8, 0x08) write(channel_base + 0x8, 0x08)
@ -245,6 +252,7 @@ mod hmc7043 {
pub fn init() -> Result<(), &'static str> { pub fn init() -> Result<(), &'static str> {
clock_mux::init(); clock_mux::init();
/* must be the first SPI init because of HMC830 SPI mode selection */
hmc830::init()?; hmc830::init()?;
hmc7043::init() hmc7043::init()
} }

View File

@ -2,33 +2,24 @@
mod imp { mod imp {
use board::csr; 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 { if busno != 0 {
return Err(()) return Err(())
} }
unsafe { unsafe {
csr::converter_spi::offline_write(1); while csr::converter_spi::idle_read() == 0 {}
csr::converter_spi::cs_polarity_write(flags >> 3 & 1); 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_polarity_write(flags >> 4 & 1);
csr::converter_spi::clk_phase_write(flags >> 5 & 1); csr::converter_spi::clk_phase_write(flags >> 5 & 1);
csr::converter_spi::lsb_first_write(flags >> 6 & 1); csr::converter_spi::lsb_first_write(flags >> 6 & 1);
csr::converter_spi::half_duplex_write(flags >> 7 & 1); csr::converter_spi::half_duplex_write(flags >> 7 & 1);
csr::converter_spi::clk_div_write_write(write_div); csr::converter_spi::length_write(length - 1);
csr::converter_spi::clk_div_read_write(read_div); csr::converter_spi::div_write(div - 2);
csr::converter_spi::offline_write(0); csr::converter_spi::cs_write(cs);
}
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);
} }
Ok(()) Ok(())
} }
@ -38,9 +29,9 @@ mod imp {
return Err(()) return Err(())
} }
unsafe { unsafe {
csr::converter_spi::data_write_write(data); while csr::converter_spi::writable_read() == 0 {}
while csr::converter_spi::pending_read() != 0 {} csr::converter_spi::data_write(data);
while csr::converter_spi::active_read() != 0 {} while csr::converter_spi::writable_read() == 0 {}
} }
Ok(()) Ok(())
} }
@ -50,16 +41,14 @@ mod imp {
return Err(()) return Err(())
} }
Ok(unsafe { Ok(unsafe {
csr::converter_spi::data_read_read() csr::converter_spi::data_read()
}) })
} }
} }
#[cfg(not(has_converter_spi))] #[cfg(not(has_converter_spi))]
mod imp { mod imp {
pub fn set_config(_busno: u8, _flags: u8, _write_div: u8, _read_div: u8) -> Result<(), ()> { Err(()) } pub fn set_config(_busno: u8, _flags: u8, _length: u8, _div: u8, _cs: u8) -> Result<(), ()> { Err(()) }
pub fn set_xfer(_busno: u8,_chip_select: u16, _write_length: u8, _read_length: u8)
-> Result<(), ()> { Err(()) }
pub fn write(_busno: u8,_data: u32) -> Result<(), ()> { Err(()) } pub fn write(_busno: u8,_data: u32) -> Result<(), ()> { Err(()) }
pub fn read(_busno: u8,) -> Result<u32, ()> { Err(()) } pub fn read(_busno: u8,) -> Result<u32, ()> { Err(()) }
} }

View File

@ -41,8 +41,7 @@ pub enum Packet {
I2cReadReply { succeeded: bool, data: u8 }, I2cReadReply { succeeded: bool, data: u8 },
I2cBasicReply { succeeded: bool }, I2cBasicReply { succeeded: bool },
SpiSetConfigRequest { busno: u8, flags: u8, write_div: u8, read_div: u8 }, SpiSetConfigRequest { busno: u8, flags: u8, length: u8, div: u8, cs: u8 },
SpiSetXferRequest { busno: u8, chip_select: u16, write_length: u8, read_length: u8 },
SpiWriteRequest { busno: u8, data: u32 }, SpiWriteRequest { busno: u8, data: u32 },
SpiReadRequest { busno: u8 }, SpiReadRequest { busno: u8 },
SpiReadReply { succeeded: bool, data: u32 }, SpiReadReply { succeeded: bool, data: u32 },
@ -123,15 +122,11 @@ impl Packet {
0x90 => Packet::SpiSetConfigRequest { 0x90 => Packet::SpiSetConfigRequest {
busno: read_u8(reader)?, busno: read_u8(reader)?,
flags: read_u8(reader)?, flags: read_u8(reader)?,
write_div: read_u8(reader)?, length: read_u8(reader)?,
read_div: read_u8(reader)? div: read_u8(reader)?,
}, cs: 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)?
}, },
/* 0x91: was Packet::SpiSetXferRequest */
0x92 => Packet::SpiWriteRequest { 0x92 => Packet::SpiWriteRequest {
busno: read_u8(reader)?, busno: read_u8(reader)?,
data: read_u32(reader)? data: read_u32(reader)?
@ -238,19 +233,13 @@ impl Packet {
write_bool(writer, succeeded)?; 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, 0x90)?;
write_u8(writer, busno)?; write_u8(writer, busno)?;
write_u8(writer, flags)?; write_u8(writer, flags)?;
write_u8(writer, write_div)?; write_u8(writer, length)?;
write_u8(writer, read_div)?; write_u8(writer, div)?;
}, write_u8(writer, cs)?;
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)?;
}, },
Packet::SpiWriteRequest { busno, data } => { Packet::SpiWriteRequest { busno, data } => {
write_u8(writer, 0x92)?; write_u8(writer, 0x92)?;

View File

@ -85,8 +85,7 @@ pub enum Message<'a> {
I2cReadReply { succeeded: bool, data: u8 }, I2cReadReply { succeeded: bool, data: u8 },
I2cBasicReply { succeeded: bool }, I2cBasicReply { succeeded: bool },
SpiSetConfigRequest { busno: u32, flags: u8, write_div: u8, read_div: u8 }, SpiSetConfigRequest { busno: u32, flags: u8, length: u8, div: u8, cs: u8 },
SpiSetXferRequest { busno: u32, chip_select: u16, write_length: u8, read_length: u8 },
SpiWriteRequest { busno: u32, data: u32 }, SpiWriteRequest { busno: u32, data: u32 },
SpiReadRequest { busno: u32 }, SpiReadRequest { busno: u32 },
SpiReadReply { succeeded: bool, data: u32 }, SpiReadReply { succeeded: bool, data: u32 },

View File

@ -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 { let request = drtioaux::Packet::SpiSetConfigRequest {
busno: busno, busno: busno,
flags: flags, flags: flags,
write_div: write_div, length: length,
read_div: read_div div: div,
}; cs: cs
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
}; };
if drtioaux::hw::send(nodeno, &request).is_err() { if drtioaux::hw::send(nodeno, &request).is_err() {
return Err(()) return Err(())
@ -255,12 +243,7 @@ mod drtio_spi {
#[cfg(not(has_drtio))] #[cfg(not(has_drtio))]
mod drtio_spi { mod drtio_spi {
pub fn set_config(_nodeno: u8, _busno: u8, _flags: u8, pub fn set_config(_nodeno: u8, _busno: u8, _flags: u8,
_write_div: u8, _read_div: u8) -> Result<(), ()> { _length: u8, _div: u8, _cs: u8) -> Result<(), ()> {
Err(())
}
pub fn set_xfer(_nodeno: u8, _busno: u8, _chip_select: u16,
_write_length: u8, _read_length: u8) -> Result<(), ()> {
Err(()) Err(())
} }
@ -277,23 +260,13 @@ mod spi {
use board_artiq::spi as local_spi; use board_artiq::spi as local_spi;
use super::drtio_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 nodeno = (busno >> 16) as u8;
let node_busno = busno as u8; let node_busno = busno as u8;
if nodeno == 0 { 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 { } else {
drtio_spi::set_config(nodeno, node_busno, flags, write_div, read_div) drtio_spi::set_config(nodeno, node_busno, flags, length, div, cs)
}
}
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)
} }
} }
@ -364,14 +337,10 @@ pub fn process_kern_hwreq(io: &Io, request: &kern::Message) -> io::Result<bool>
} }
} }
&kern::SpiSetConfigRequest { busno, flags, write_div, read_div } => { &kern::SpiSetConfigRequest { busno, flags, length, div, cs } => {
let succeeded = spi::set_config(busno, flags, write_div, read_div).is_ok(); let succeeded = spi::set_config(busno, flags, length, div, cs).is_ok();
kern_send(io, &kern::SpiBasicReply { succeeded: succeeded }) 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 } => { &kern::SpiWriteRequest { busno, data } => {
let succeeded = spi::write(busno, data).is_ok(); let succeeded = spi::write(busno, data).is_ok();
kern_send(io, &kern::SpiBasicReply { succeeded: succeeded }) kern_send(io, &kern::SpiBasicReply { succeeded: succeeded })

View File

@ -94,6 +94,7 @@ fn startup() {
#[cfg(si5324_as_synthesizer)] #[cfg(si5324_as_synthesizer)]
setup_si5324_as_synthesizer(); setup_si5324_as_synthesizer();
#[cfg(has_hmc830_7043)] #[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"); board_artiq::hmc830_7043::init().expect("cannot initialize HMC830/7043");
#[cfg(has_ad9154)] #[cfg(has_ad9154)]
board_artiq::ad9154::init().expect("cannot initialize AD9154"); board_artiq::ad9154::init().expect("cannot initialize AD9154");

View File

@ -144,14 +144,10 @@ fn process_aux_packet(p: &drtioaux::Packet) {
}; };
} }
drtioaux::Packet::SpiSetConfigRequest { busno, flags, write_div, read_div } => { drtioaux::Packet::SpiSetConfigRequest { busno, flags, length, div, cs } => {
let succeeded = spi::set_config(busno, flags, write_div, read_div).is_ok(); let succeeded = spi::set_config(busno, flags, length, div, cs).is_ok();
drtioaux::hw::send_link(0, &drtioaux::Packet::SpiBasicReply { succeeded: succeeded }).unwrap(); 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 } => { drtioaux::Packet::SpiWriteRequest { busno, data } => {
let succeeded = spi::write(busno, data).is_ok(); let succeeded = spi::write(busno, data).is_ok();
drtioaux::hw::send_link(0, &drtioaux::Packet::SpiBasicReply { succeeded: succeeded }).unwrap(); drtioaux::hw::send_link(0, &drtioaux::Packet::SpiBasicReply { succeeded: succeeded }).unwrap();
@ -226,6 +222,7 @@ fn startup() {
serwb::wait_init(); serwb::wait_init();
#[cfg(has_hmc830_7043)] #[cfg(has_hmc830_7043)]
/* must be the first SPI init because of HMC830 SPI mode selection */
hmc830_7043::init().expect("cannot initialize HMC830/7043"); hmc830_7043::init().expect("cannot initialize HMC830/7043");
i2c::init(); i2c::init();
si5324::setup(&SI5324_SETTINGS).expect("cannot initialize Si5324"); si5324::setup(&SI5324_SETTINGS).expect("cannot initialize Si5324");

View File

@ -10,7 +10,7 @@ from migen.build.platforms.sinara import sayma_rtm
from misoc.interconnect import wishbone, stream from misoc.interconnect import wishbone, stream
from misoc.interconnect.csr import * from misoc.interconnect.csr import *
from misoc.cores import identifier from misoc.cores import identifier
from misoc.cores import spi from misoc.cores import spi2
from misoc.cores import gpio from misoc.cores import gpio
from misoc.integration.wb_slaves import WishboneSlaveManager from misoc.integration.wb_slaves import WishboneSlaveManager
from misoc.integration.cpu_interface import get_csr_csv from misoc.integration.cpu_interface import get_csr_csv
@ -140,10 +140,10 @@ class SaymaRTM(Module):
platform.request("ad9154_txen", 1).eq(0b11) 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("hmc_spi"),
platform.request("ad9154_spi", 0), platform.request("ad9154_spi", 0),
platform.request("ad9154_spi", 1)]) platform.request("ad9154_spi", 1)))
csr_devices.append("converter_spi") csr_devices.append("converter_spi")
self.comb += platform.request("hmc7043_reset").eq(0) self.comb += platform.request("hmc7043_reset").eq(0)