def __init__(self, dmgr, channel): self.core = dmgr.get("core") self.ref_period_mu = seconds_to_mu(self.core.coarse_ref_period, self.core) self.channel = channel self.write_period_mu = int(0, 64) self.read_period_mu = int(0, 64) self.xfer_period_mu = int(0, 64)
def __init__(self, dmgr, channel, core_device="core"): self.core = dmgr.get(core_device) self.ref_period_mu = seconds_to_mu(self.core.coarse_ref_period, self.core) self.channel = channel self.write_period_mu = int(0, 64) self.read_period_mu = int(0, 64) self.xfer_period_mu = int(0, 64)
def set_config_mu(self, flags=0, write_div=6, read_div=6): """Set the ``config`` register (in SPI bus machine units). .. seealso:: :meth:`set_config` :param write_div: Counter load value to divide the RTIO clock by to generate the SPI write clk. (minimum=2, reset=2) ``f_rtio_clk/f_spi_write == write_div``. If ``write_div`` is odd, the setup phase of the SPI clock is biased to longer lengths by one RTIO clock cycle. :param read_div: Ditto for the read clock. """ rtio_output(now_mu(), self.channel, SPI_CONFIG_ADDR, flags | ((write_div - 2) << 16) | ((read_div - 2) << 24)) self.write_period_mu = int(write_div * self.ref_period_mu) self.read_period_mu = int(read_div * self.ref_period_mu) delay_mu(3 * self.ref_period_mu)
def set_config_mu(self, flags=0, write_div=6, read_div=6): """Set the ``config`` register (in SPI bus machine units). .. seealso:: :meth:`set_config` :param write_div: Counter load value to divide the RTIO clock by to generate the SPI write clk. (minimum=2, reset=2) ``f_rtio_clk/f_spi_write == write_div``. If ``write_div`` is odd, the setup phase of the SPI clock is biased to longer lengths by one RTIO clock cycle. :param read_div: Ditto for the read clock. """ rtio_output(now_mu(), self.channel, SPI_CONFIG_ADDR, flags | ((write_div - 2) << 16) | ((read_div - 2) << 24)) self.write_period_mu = int(write_div*self.ref_period_mu) self.read_period_mu = int(read_div*self.ref_period_mu) delay_mu(3*self.ref_period_mu)
def set_xfer(self, chip_select=0, write_length=0, read_length=0): """Set the ``xfer`` register. * Every transfer consists of a write of ``write_length`` bits immediately followed by a read of ``read_length`` bits. * ``cs_n`` is asserted at the beginning and deasserted at the end of the transfer if there is no other transfer pending. * ``cs_n`` handling is agnostic to whether it is one-hot or decoded somewhere downstream. If it is decoded, "``cs_n`` all deasserted" should be handled accordingly (no slave selected). If it is one-hot, asserting multiple slaves should only be attempted if ``miso`` is either not connected between slaves, or open collector, or correctly multiplexed externally. * For 4-wire SPI only the sum of ``read_length`` and ``write_length`` matters. The behavior is the same (except for clock speeds) no matter how the total transfer length is divided between the two. For 3-wire SPI, the direction of ``mosi`` is switched from output to input after ``write_length`` bits. * Data output on ``mosi`` in 4-wire SPI during the read cycles is what is found in the data register at the time. Data in the ``data`` register outside the least/most (depending on ``config.lsb_first``) significant ``read_length`` bits is what is seen on ``miso`` (or ``mosi`` if ``config.half_duplex``) during the write cycles. * Writes to ``xfer`` are synchronized to the start of the next (possibly chained) transfer. This method advances the timeline by the duration of the RTIO-to-Wishbone bus transaction (three RTIO clock cycles). :param chip_select: Bit mask of chip selects to assert. Or number of the chip select to assert if ``cs`` is decoded downstream. (reset=0) :param write_length: Number of bits to write during the next transfer. (reset=0) :param read_length: Number of bits to read during the next transfer. (reset=0) """ rtio_output(now_mu(), self.channel, SPI_XFER_ADDR, chip_select | (write_length << 16) | (read_length << 24)) self.xfer_period_mu = int(write_length*self.write_period_mu + read_length*self.read_period_mu) delay_mu(3*self.ref_period_mu)
def frequency_to_div(self, f): return int(1 / (f * self.ref_period)) + 1
def frequency_to_div(self, f): return int(1/(f*mu_to_seconds(self.ref_period_mu))) + 1