diff --git a/litex/soc/cores/i2s.py b/litex/soc/cores/i2s.py index 2bffa7571..14ba84159 100644 --- a/litex/soc/cores/i2s.py +++ b/litex/soc/cores/i2s.py @@ -16,13 +16,17 @@ class I2S_FORMAT(Enum): I2S_LEFT_JUSTIFIED = 2 class S7I2S(Module, AutoCSR, AutoDoc): - def __init__(self, pads, fifo_depth=256, master=False, concatenate_channels=True, sample_width=16, frame_format=I2S_FORMAT.I2S_LEFT_JUSTIFIED, lrck_ref_freq=100e6, lrck_freq=44100, bits_per_channel=28): + def __init__(self, pads, fifo_depth=256, controller=False, master=False, concatenate_channels=True, sample_width=16, frame_format=I2S_FORMAT.I2S_LEFT_JUSTIFIED, lrck_ref_freq=100e6, lrck_freq=44100, bits_per_channel=28): + if master == True: + print("Master/slave terminology deprecated, please use controller/peripheral. Please see http://oshwa.org/a-resolution-to-redefine-spi-signal-names.") + controller = True + self.intro = ModuleDoc("""Intro - I2S master/slave creates a master/slave audio interface instance depending on a configured master variable. + I2S controller/peripheral creates a controller/peripheral audio interface instance depending on a configured controller variable. Tx and Rx interfaces are inferred based upon the presence or absence of the respective pins in the "pads" argument. - When device is configured as master you can manipulate LRCK and SCLK signals using below variables. + When device is configured as controller you can manipulate LRCK and SCLK signals using below variables. - lrck_ref_freq - is a reference signal that is required to achive desired LRCK and SCLK frequencies. Have be the same as your sys_clk. @@ -31,8 +35,8 @@ class S7I2S(Module, AutoCSR, AutoDoc): - bits_per_channel - defines SCLK frequency. Mind you, that based on sys_clk frequency, the requested amount of bits per channel may vary from configured. - When device is configured as slave I2S interface, sampling rate and framing is set by the - programming of the audio CODEC chip. A slave configuration defers the + When device is configured as peripheral I2S interface, sampling rate and framing is set by the + programming of the audio CODEC chip. A peripheral configuration defers the generation of audio clocks to the CODEC, which has PLLs specialized to generate the correct frequencies for audio sampling rates. @@ -163,7 +167,7 @@ class S7I2S(Module, AutoCSR, AutoDoc): ] - if master == True: + if controller == True: if bits_per_channel < sample_width and frame_format == I2S_FORMAT.I2S_STANDARD: bits_per_channel = sample_width + 1 print("I2S warning: bits per channel can't be smaller than sample_width. Setting bits per channel to {}".format(sample_width + 1)) diff --git a/litex/soc/cores/spi_opi.py b/litex/soc/cores/spi_opi.py index 8e87518f8..eddffd450 100644 --- a/litex/soc/cores/spi_opi.py +++ b/litex/soc/cores/spi_opi.py @@ -14,7 +14,7 @@ class S7SPIOPI(Module, AutoCSR, AutoDoc): dq_delay_taps = 31, sclk_name = "SCLK_ODDR", iddr_name = "SPI_IDDR", - miso_name = "MISO_FDRE", + cipo_name = "CIPO_FDRE", sim = False, spiread = False, prefetch_lines = 1): @@ -100,8 +100,8 @@ class S7SPIOPI(Module, AutoCSR, AutoDoc): self.di = Signal(16) # OPI data from SPI self.tx = Signal() # When asserted OPI is transmitting data to SPI, otherwise, receiving - self.mosi = Signal() # SPI data to SPI - self.miso = Signal() # SPI data from SPI + self.copi = Signal() # SPI data to SPI + self.cipo = Signal() # SPI data from SPI # Delay programming API self.delay_config = CSRStorage(fields=[ @@ -125,7 +125,7 @@ class S7SPIOPI(Module, AutoCSR, AutoDoc): self.comb += self.di.eq(Cat(di_fall, di_rise)) # OPI DDR registers - dq = TSTriple(7) # dq[0] is special because it is also MOSI + dq = TSTriple(7) # dq[0] is special because it is also copi dq_delayed = Signal(8) self.specials += dq.get_tristate(pads.dq[1:]) for i in range(1, 8): @@ -198,19 +198,19 @@ class S7SPIOPI(Module, AutoCSR, AutoDoc): ) # SPI SDR register self.specials += [ - Instance("FDRE", name="{}".format(miso_name), + Instance("FDRE", name="{}".format(cipo_name), i_C = ~ClockSignal("spinor"), i_CE = 1, i_R = 0, - o_Q = self.miso, + o_Q = self.cipo, i_D = dq_delayed[1], ) ] - # bit 0 (MOSI) is special-cased to handle SPI mode - dq_mosi = TSTriple(1) # this has similar structure but an independent "oe" signal - self.specials += dq_mosi.get_tristate(pads.dq[0]) - do_mux_rise = Signal() # mux signal for mosi/dq select of bit 0 + # bit 0 (copi) is special-cased to handle SPI mode + dq_copi = TSTriple(1) # this has similar structure but an independent "oe" signal + self.specials += dq_copi.get_tristate(pads.dq[0]) + do_mux_rise = Signal() # mux signal for copi/dq select of bit 0 do_mux_fall = Signal() self.specials += [ Instance("ODDR", @@ -221,7 +221,7 @@ class S7SPIOPI(Module, AutoCSR, AutoDoc): i_CE = 1, i_D1 = do_mux_rise, i_D2 = do_mux_fall, - o_Q = dq_mosi.o, + o_Q = dq_copi.o, ), Instance("IDDR", p_DDR_CLK_EDGE="SAME_EDGE_PIPELINED", @@ -253,11 +253,11 @@ class S7SPIOPI(Module, AutoCSR, AutoDoc): i_CE = 0, i_LD = self.delay_update, i_CNTVALUEIN = self.delay_config.fields.d, - i_IDATAIN = dq_mosi.i, + i_IDATAIN = dq_copi.i, o_DATAOUT = dq_delayed[0], ), else: - self.comb += dq_delayed[0].eq(dq_mosi.i) + self.comb += dq_delayed[0].eq(dq_copi.i) # Wire up SCLK interface clk_en = Signal() @@ -430,11 +430,11 @@ class S7SPIOPI(Module, AutoCSR, AutoDoc): # Tristate mux self.sync += [ dq.oe.eq(~spi_mode & self.tx), - dq_mosi.oe.eq(spi_mode | self.tx), + dq_copi.oe.eq(spi_mode | self.tx), ] # Data out mux (no data in mux, as we can just sample data in all the time without harm) - self.comb += do_mux_rise.eq(~spi_mode & do_rise[0] | spi_mode & self.mosi) - self.comb += do_mux_fall.eq(~spi_mode & do_fall[0] | spi_mode & self.mosi) + self.comb += do_mux_rise.eq(~spi_mode & do_rise[0] | spi_mode & self.copi) + self.comb += do_mux_fall.eq(~spi_mode & do_fall[0] | spi_mode & self.copi) # Indicates if the current "req" requires dummy cycles to be appended (used for both OPI/SPI) has_dummy = Signal() @@ -746,7 +746,7 @@ class S7SPIOPI(Module, AutoCSR, AutoDoc): # internal signals are: # selection - spi_mode # OPI - self.do(16), self.di(16), self.tx - # SPI - self.mosi, self.miso + # SPI - self.copi, self.cipo # cs_n - both # ecs_n - OPI # clk_en - both @@ -758,15 +758,15 @@ class S7SPIOPI(Module, AutoCSR, AutoDoc): spi_di_load = Signal() # spi_do load is pipelined back one cycle using this mechanism spi_di_load2 = Signal() spi_ack_pipe = Signal() - # Pipelining is required the MISO path is very slow (IOB->fabric FD), and a falling-edge + # Pipelining is required the cipo path is very slow (IOB->fabric FD), and a falling-edge # retiming reg is used to meet timing self.sync += [ spi_di_load2.eq(spi_di_load), - If(spi_di_load2, spi_di.eq(Cat(self.miso, spi_si[:-1]))).Else(spi_di.eq(spi_di)), + If(spi_di_load2, spi_di.eq(Cat(self.cipo, spi_si[:-1]))).Else(spi_di.eq(spi_di)), spi_ack.eq(spi_ack_pipe), ] - self.comb += self.mosi.eq(spi_so[7]) - self.sync += spi_si.eq(Cat(self.miso, spi_si[:-1])) + self.comb += self.copi.eq(spi_so[7]) + self.sync += spi_si.eq(Cat(self.cipo, spi_si[:-1])) self.submodules.spiphy = spiphy = FSM(reset_state="RESET") spiphy.act("RESET", If(spi_req, @@ -1056,7 +1056,7 @@ class S7SPIOPI(Module, AutoCSR, AutoDoc): NextValue(spi_req, 0), If(spi_ack, # Protect these in a spi_mode mux to prevent excess inference of logic to - # handle otherwise implicit dual-master situation + # handle otherwise implicit dual-controller situation If(spi_mode, NextValue(bus.dat_r, Cat(d_to_wb[8:],spi_di)), NextValue(bus.ack, 1),