diff --git a/litex/soc/cores/xadc.py b/litex/soc/cores/xadc.py index 0cea38bb7..b54db0fea 100644 --- a/litex/soc/cores/xadc.py +++ b/litex/soc/cores/xadc.py @@ -7,12 +7,42 @@ from litex.soc.interconnect.csr import * # XADC --------------------------------------------------------------------------------------------- +analog_layout = [("vauxp", 16), ("vauxn", 16), ("vp", 1), ("vn", 1)] + class XADC(Module, AutoCSR): - def __init__(self): + def __init__(self, analog=None): + # add a CSR bank for controlling the XADC DRP. Adds bloat to the gateware + # if you're not using this feature, but makes the code more elegant. + self.drp_enable = CSRStatus() # must set this to 1 to use DRP, otherwise auto-sample + self.drp_read = CSR() + self.drp_write = CSR() + self.drp_drdy = CSRStatus() + self.drp_adr = CSRStorage(7) + self.drp_dat_w = CSRStorage(16) + self.drp_dat_r = CSRStatus(16) + drp_drdy = Signal() + + if analog == None: + analog = Record(analog_layout) + self.comb += [ + analog.vauxp.eq(0), + analog.vauxn.eq(0), + analog.vp.eq(0), + analog.vn.eq(0), + ] + + self.sync += [ + If(self.drp_read.re | self.drp_write.re, + self.drp_drdy.status.eq(0) + ).Elif(drp_drdy, + self.drp_drdy.status.eq(1) + ) + ] + # Temperature(°C) = adc_value*503.975/4096 - 273.15 self.temperature = CSRStatus(12) - # Voltage(V) = adc_value*)/4096*3 + # Voltage(V) = as uadc_value*)/4096*3 self.vccint = CSRStatus(12) self.vccaux = CSRStatus(12) self.vccbram = CSRStatus(12) @@ -28,8 +58,17 @@ class XADC(Module, AutoCSR): eoc = Signal() eos = Signal() data = Signal(16) - drdy = Signal() + auto = Signal() + self.comb += auto.eq(~self.drp_enable.status) + adr = Signal(7) + self.comb += [ + If(auto, + adr.eq(channel), + ).Else( + adr.eq(self.drp_adr.storage) + ) + ] self.specials += Instance("XADC", # from ug480 p_INIT_40=0x9000, p_INIT_41=0x2ef0, p_INIT_42=0x0400, @@ -44,12 +83,14 @@ class XADC(Module, AutoCSR): p_INIT_58=0x5999, p_INIT_5C=0x5111, o_ALM=self.alarm, o_OT=self.ot, o_BUSY=busy, o_CHANNEL=channel, o_EOC=eoc, o_EOS=eos, - i_VAUXN=0, i_VAUXP=1, i_VN=0, i_VP=1, + i_VAUXN=analog.vauxn, i_VAUXP=analog.vauxp, i_VN=analog.vn, i_VP=analog.vp, i_CONVST=0, i_CONVSTCLK=0, i_RESET=ResetSignal(), - o_DO=data, o_DRDY=drdy, i_DADDR=channel, i_DCLK=ClockSignal(), - i_DEN=eoc, i_DI=0, i_DWE=0, + o_DO=data, o_DRDY=drp_drdy, i_DADDR=adr, i_DCLK=ClockSignal(), + i_DEN=(auto & eoc) | (~auto & (self.drp_read.re | self.drp_write.re)), + i_DI=self.drp_dat_w.storage, i_DWE=self.drp_write.re, # o_JTAGBUSY=, o_JTAGLOCKED=, o_JTAGMODIFIED=, o_MUXADDR=, ) + self.comb += self.drp_dat_r.status.eq(data) channels = { 0: self.temperature, @@ -59,7 +100,7 @@ class XADC(Module, AutoCSR): } self.sync += [ - If(drdy, + If(drp_drdy & auto, Case(channel, dict( (k, v.status.eq(data >> 4)) for k, v in channels.items()))