forked from M-Labs/artiq
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:
parent
68278e225d
commit
a7720d05cd
|
@ -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):
|
||||||
|
|
|
@ -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)
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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}
|
||||||
},
|
},
|
||||||
|
|
|
@ -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": {
|
||||||
|
|
|
@ -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),
|
||||||
];
|
];
|
||||||
|
|
|
@ -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");
|
||||||
});
|
});
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
|
|
|
@ -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(()) }
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)?;
|
||||||
|
|
|
@ -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 },
|
||||||
|
|
|
@ -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 })
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue