def io_init(self): gpio = GPIO() gpio.set_output(CLK_REF_SEL) gpio.set_output(PLL_POW_EN) gpio.set_value(CLK_REF_SEL, gpio.HIGH) gpio.set_value(PLL_POW_EN, gpio.HIGH)
def io_init(self): # configure spi pins self.spi = bitbang_spi(self.pins['lmx_le'], self.pins['lmx_data'], self.pins['lmx_lock'], self.pins['lmx_clk']) self.gpio = GPIO() # configure gpio pins self.gpio.set_output(self.pins['lmx_pow_en']) self.gpio.set_value(self.pins['lmx_pow_en'], self.gpio.HIGH) self.gpio.set_output(self.pins['lmx_ce']) #GPIO.setup(self.pins['lmx_lock'], GPIO.IN) if self.rf_board: self.gpio.set_output(self.pins['-5v_en']) self.gpio.set_value(self.pins['-5v_en'], self.gpio.HIGH) self.gpio.set_output(self.pins['amp_en']) # TODO: disable 5V rail until DAC is tested, active low self.gpio.set_output(self.pins['amp_en'], self.gpio.HIGH) self.dac_spi = bitbang_spi(self.pins['dac_cs'], self.pins['dac_data'], None, self.pins['dac_sck']) self.set_power_dac(500) time.sleep(.1)
def __init__(self, spi_cs, spi_mosi, spi_miso, spi_clk): self.gpio = GPIO() self.spi_cs = spi_cs self.spi_mosi = spi_mosi self.spi_miso = spi_miso self.spi_clk = spi_clk self.gpio.set_output(spi_cs) self.gpio.set_output(spi_mosi) self.gpio.set_output(spi_clk) if self.spi_miso != None: self.gpio.set_input(spi_miso) self.gpio.set_value(spi_cs, self.gpio.HIGH)
def __init__(self, spi_cs, spi_mosi, spi_miso, spi_clk, rising_data = True, latch = None, enable_low = True): self.gpio = GPIO() self.rising_data = rising_data self.enable_low = enable_low self.spi_cs = spi_cs self.spi_mosi = spi_mosi self.spi_miso = spi_miso self.spi_clk = spi_clk self.latch = latch self.gpio.set_output(spi_cs) self.gpio.set_output(spi_mosi) self.gpio.set_output(spi_clk) if self.spi_miso != None: self.gpio.set_input(spi_miso) if self.latch != None: self.gpio.set_output(latch) self.gpio.set_value(spi_cs, self.enable_low)
def io_init(self): # configure spi pins self.spi = bitbang_spi(self.pins['lmx_le'], self.pins['lmx_data'], self.pins['lmx_lock'], self.pins['lmx_clk']) self.gpio = GPIO() # configure gpio pins self.gpio.set_output(self.pins['lmx_pow_en']) self.gpio.set_value(self.pins['lmx_pow_en'], self.gpio.HIGH) self.gpio.set_output(self.pins['lmx_ce']) #GPIO.setup(self.pins['lmx_lock'], GPIO.IN) if self.rf_board: self.dac_spi = bitbang_spi(self.pins['dac_cs'], self.pins['dac_data'], None, self.pins['dac_sck']) self.set_power_dac(000) self.gpio.set_output(self.pins['amp_en']) self.gpio.set_value(self.pins['amp_en'], self.gpio.LOW) time.sleep(.1)
class synth_r1: def __init__(self, pins): self.pins = pins if 'filta' in self.pins: self.rf_board = True else: self.rf_board = False print("not an RF board..") self.io_init() self.current_channel = CHANNEL_BOTH self.current_freq = F_VCO_MAX self.current_filter = 0 self.channel_power = 0 self.lmx_init() def io_init(self): # configure spi pins self.spi = bitbang_spi(self.pins['lmx_le'], self.pins['lmx_data'], self.pins['lmx_lock'], self.pins['lmx_clk']) self.gpio = GPIO() # configure gpio pins self.gpio.set_output(self.pins['lmx_pow_en']) self.gpio.set_value(self.pins['lmx_pow_en'], self.gpio.HIGH) self.gpio.set_output(self.pins['lmx_ce']) #GPIO.setup(self.pins['lmx_lock'], GPIO.IN) if self.rf_board: self.gpio.set_output(self.pins['-5v_en']) self.gpio.set_value(self.pins['-5v_en'], self.gpio.HIGH) self.gpio.set_output(self.pins['amp_en']) # TODO: disable 5V rail until DAC is tested, active low self.gpio.set_output(self.pins['amp_en'], self.gpio.HIGH) self.dac_spi = bitbang_spi(self.pins['dac_cs'], self.pins['dac_data'], None, self.pins['dac_sck']) self.set_power_dac(500) time.sleep(.1) def lmx_powerdown(self): self._set_reg(0, REG0_POWERDOWN, defaults=False) def lmx_init(self): self.gpio.set_value(self.pins['lmx_ce'], self.gpio.HIGH) self.current_channel = CHANNEL_NONE if self.rf_board: self.gpio.set_value(self.pins['amp_en'], self.gpio.LOW) self.current_filter = 0 else: self.channel_power = 20 # channel power of 20 produces reasonable LO drive on demod board time.sleep(.05) self._set_reg(0, REG0_RESET, defaults=False) self._set_reg(0, DEFAULT) # load in register values generated by TICS Pro for i in range(112, -1, -1): self._set_reg(i, DEFAULT) self.set_freq(2.15e9) def set_power_dac(self, power): # assuming 10 bit ltc2630 # send write and update command self.dac_spi.transfer(0x03 << 20 | ((power & 0x3FF) << 6), bits=24) def set_power_lmx(self, power): # TODO: convert to use macom vga/dac.. # currently just output lmx2594 power units.. self.channel_power = power & 0x3F r44 = 0 r45 = 0 # keep mux for channel A on VCO if we're outputting the vco.. if self.current_freq > F_VCO_MIN: r45 = _bit(11) if self.current_channel == CHANNEL_BOTH: # enable channel A, enable channel B print('both channels active!') r45 |= self.channel_power # set channel B power r44 |= self.channel_power << 8 # set channel A power elif self.current_channel == CHANNELA: # enable channel A, disable channel B print('channel a active!') r44 |= _bit(7) # set OUTB_PD r44 |= self.channel_power << 8 # set channel A power elif self.current_channel == CHANNELB: # enable channel B, disable channel A print('channel b active!') r44 |= _bit(6) # set OUTA_PD r45 |= self.channel_power # set channel B power else: # disable channels A and B print('both channels inactive!') r44 |= _bit(7) # set OUTB_PD r44 |= _bit(6) # set OUTA_PD self._set_reg(45, r45) self._set_reg(44, r44) print('channel power: {}'.format(self.channel_power)) # set filter bank from frequency def set_filter_bank(self, freq): pass ''' fidx = 3 for (i, fc) in enumerate(FILTER_BANK_CUTOFFS): if(freq > fc): fidx = np.mod(i - 1, FILTER_BANK_SIZE) break print('setting filter bank to index {}'.format(fidx)) if fidx != self.current_filter: GPIO.output(self.pins['filta'], fidx & _bit(0)) GPIO.output(self.pins['filtb'], fidx & _bit(1)) self.current_filter = fidx if fidx > 1: self.current_channel = CHANNELA else: self.current_channel = CHANNELB ''' def _calc_n(self, f, n_step, div): return int(f / (n_step / div)) def _calc_frac(self, f, n, n_step, frac_step, div): return int((f - n * (n_step / div)) / (frac_step / div)) # set synth frequency def set_freq(self, freq): self.current_freq = freq n_step = PFD frac_step = n_step / FRAC_DENOM n = MIN_N f_vco = 0 frac = 0 if freq < F_VCO_MIN: for div_i in range(len(div_ratios)): if freq > F_VCO_MIN / div_ratios[div_i]: break n = self._calc_n(freq, n_step, div_ratios[div_i]) frac = self._calc_frac(freq, n, n_step, frac_step, div_ratios[div_i]) f_vco = freq / div_ratios[div_i] print('set n to {}, frac to {}, div to {}'.format( n, frac, div_ratios[div_i])) self._set_reg(75, div_i << 6) # set vco divider value self._set_reg(46, 0) # set OUTB_MUX to divider self._set_reg(45, self.channel_power ) # set OUTA_MUX to divider (preserve channel power) else: n = self._calc_n(freq, n_step, 1) frac = self._calc_frac(freq, n, n_step, frac_step, 1) f_vco = freq print('set n to {}, frac to {}'.format(n, frac)) # set mux to VCO self._set_reg(46, 1) # set OUTB_MUX to vco self._set_reg(45, _bit(11) | self.channel_power ) # set OUTA_MUX to vco (preserve channel power) # load new n and frac registers self._set_reg(36, n) self._set_reg(42, (frac >> 16) & 0xFFFF) self._set_reg(43, frac & 0xFFFF) # set PFD_DLY_SEL, assuming mash order 2 if f_vco < 10e9: self._set_reg(37, 3 << 8) else: self._set_reg(37, 4 << 8) # recalibrate VCO self._set_reg(0, REG0_FCAL_EN) if self.rf_board: # update filter bank, enable only one output channel self.set_filter_bank(freq) else: self.current_channel = CHANNEL_BOTH # update output channel self.set_power_lmx(self.channel_power) def wait_for_lock(self): # wait for pll lock while not self.gpio.read_value(self.pins['lmx_lock']): print('waiting for lock..') def _set_reg(self, reg, d, defaults=True): if defaults: d = d | LMX_REG_DEFAULTS[reg] payload = reg << 16 payload |= (d & 0xffff) #print('setting register {} to {:016b}'.format(reg, d)) self.spi.transfer(payload, bits=24) def _read_reg(self, reg): payload = (reg << 16) + (1 << 23) return self.spi.transfer(payload, bits=24)
spi, 0x07, 0x0e) # set decimation rate to 900, 60 * (M + 1) if K = 0, M = 14 # configure SSI ad9864_write_reg(spi, 0x1A, 0x07) # (clkout freq = adc clk / 7) ad9864_write_reg(spi, 0x18, 0x00) # take fs and clkout out of tristate # set doutb to tristate ad9864_write_reg(spi, 0x3B, 0x08) # disable mosi on doutb if __name__ == '__main__': from mmap_gpio import GPIO import time gpio = GPIO() SYNCB = PINS.AD_SYNCB V3_EN = PINS.PLL_3V3_EN gpio.set_output(SYNCB) gpio.set_output(V3_EN) gpio.set_output(ADC_CLK_EN) gpio.set_value(V3_EN, gpio.HIGH) gpio.set_value(SYNCB, gpio.HIGH) gpio.set_value(ADC_CLK_EN, gpio.HIGH) print("SYNCB HIGH") time.sleep(.5) spi1 = bitbang_spi(ADC_SPI_CS1, ADC_SPI_MOSI, ADC_SPI_MISO, ADC_SPI_CLK)
def _revbits(self, x, nbits = 11): return int(bin(x)[2:].zfill(nbits)[::-1], 2) def set_a(self, value): command = ((value & 0x1FF) << 2) command = self._revbits(command) self.spi.transfer(command, bits = 11) def set_b(self, value): command = (((value & 0x1FF)) << 2) + 1 command = self._revbits(command) self.spi.transfer(command, bits = 11) if __name__ == '__main__': gpio = GPIO() gpio.set_output(TRIG_SEL0) gpio.set_output(TRIG_SEL1) gpio.set_output(REF_SEL) gpio.set_input(COMP_OUT) gpio.set_input(REFCLK) delay = Delay(gpio) dac = Dac(gpio) NDELAYS = 1 << 9 NDACS = 1 << 12 BRUTE_FORCE_TRIG = False
class bitbang_spi: def __init__(self, spi_cs, spi_mosi, spi_miso, spi_clk): self.gpio = GPIO() self.spi_cs = spi_cs self.spi_mosi = spi_mosi self.spi_miso = spi_miso self.spi_clk = spi_clk self.gpio.set_output(spi_cs) self.gpio.set_output(spi_mosi) self.gpio.set_output(spi_clk) if self.spi_miso != None: self.gpio.set_input(spi_miso) self.gpio.set_value(spi_cs, self.gpio.HIGH) def transfer(self, payload, bits = 8): self.gpio.set_value(self.spi_cs, self.gpio.LOW) self.gpio.set_value(self.spi_clk, self.gpio.LOW) response = 0 for i in range(bits): response = response << 1 # data clocked in on clock rising edge self.gpio.set_value(self.spi_mosi, (payload >> (bits - (i + 1))) & 0x01) self.gpio.set_value(self.spi_clk, self.gpio.HIGH) if self.spi_miso != None: response |= self.gpio.read_value(self.spi_miso) self.gpio.set_value(self.spi_clk, self.gpio.LOW) self.gpio.set_value(self.spi_cs, self.gpio.HIGH) return response
def __init__(self, context, port): self.command_handlers = {\ VNA_SW_CMD: self._set_switch, \ MIX_EN_CMD: self._enable_mixer, \ MIX_MUL_CMD: self._set_multiplier, \ ADC_INIT_CMD : self._init_adc, \ ADC_SYNC_CMD: self._sync_adc,\ ADC_ATTEN_CMD : self._attenuate_adc} # init socket stuff self.context = context self.socket = context.socket(zmq.REP) print('binding socket..') self.socket.bind("tcp://*:{}".format(str(port))) print('binding complete') # init io stuff self.gpio = GPIO() print('bringing up 3.3V rail') self.gpio.set_output(V3_EN) self.gpio.set_value(V3_EN, self.gpio.HIGH) print('initializing reference clocks') self.synth = ad9577_synth() self.synth.lo_powerdown() print('setting up IO') self.gpio.set_output(DEMOD_3V3_EN) self.gpio.set_output(MIX_EN) self.gpio.set_output(MIX_X2) self.gpio.set_output(SW_PORT_SEL) self.gpio.set_output(ADC_CLK_EN) self.gpio.set_output(LO_BUF_AMP_EN) self.gpio.set_output(SYNCB) print('setting default values') self.gpio.set_value(DEMOD_3V3_EN, self.gpio.HIGH) self.gpio.set_value(MIX_EN, self.gpio.LOW) self.gpio.set_value(MIX_X2, self.gpio.LOW) self.gpio.set_value(LO_BUF_AMP_EN, self.gpio.LOW) self.gpio.set_value(ADC_CLK_EN, self.gpio.HIGH) self.gpio.set_value(SYNCB, self.gpio.HIGH) self.gpio.set_value(SW_PORT_SEL, self.gpio.HIGH) print('initalizing ADCs') self.adc_spi1 = bitbang_spi(ADC_SPI_CS1, ADC_SPI_MOSI, ADC_SPI_MISO, ADC_SPI_CLK) self.adc_spi2 = bitbang_spi(ADC_SPI_CS2, ADC_SPI_MOSI, ADC_SPI_MISO, ADC_SPI_CLK) self.adc_spi3 = bitbang_spi(ADC_SPI_CS3, ADC_SPI_MOSI, ADC_SPI_MISO, ADC_SPI_CLK) self.adc_spi4 = bitbang_spi(ADC_SPI_CS4, ADC_SPI_MOSI, ADC_SPI_MISO, ADC_SPI_CLK) self.adc_spis = [ self.adc_spi1, self.adc_spi2, self.adc_spi3, self.adc_spi4 ] for s in self.adc_spis: ad9864_tristate_miso(s) print('init complete')
class zmq_io_server: def __init__(self, context, port): self.command_handlers = {\ VNA_SW_CMD: self._set_switch, \ MIX_EN_CMD: self._enable_mixer, \ MIX_MUL_CMD: self._set_multiplier, \ ADC_INIT_CMD : self._init_adc, \ ADC_SYNC_CMD: self._sync_adc,\ ADC_ATTEN_CMD : self._attenuate_adc} # init socket stuff self.context = context self.socket = context.socket(zmq.REP) print('binding socket..') self.socket.bind("tcp://*:{}".format(str(port))) print('binding complete') # init io stuff self.gpio = GPIO() print('bringing up 3.3V rail') self.gpio.set_output(V3_EN) self.gpio.set_value(V3_EN, self.gpio.HIGH) print('initializing reference clocks') self.synth = ad9577_synth() self.synth.lo_powerdown() print('setting up IO') self.gpio.set_output(DEMOD_3V3_EN) self.gpio.set_output(MIX_EN) self.gpio.set_output(MIX_X2) self.gpio.set_output(SW_PORT_SEL) self.gpio.set_output(ADC_CLK_EN) self.gpio.set_output(LO_BUF_AMP_EN) self.gpio.set_output(SYNCB) print('setting default values') self.gpio.set_value(DEMOD_3V3_EN, self.gpio.HIGH) self.gpio.set_value(MIX_EN, self.gpio.LOW) self.gpio.set_value(MIX_X2, self.gpio.LOW) self.gpio.set_value(LO_BUF_AMP_EN, self.gpio.LOW) self.gpio.set_value(ADC_CLK_EN, self.gpio.HIGH) self.gpio.set_value(SYNCB, self.gpio.HIGH) self.gpio.set_value(SW_PORT_SEL, self.gpio.HIGH) print('initalizing ADCs') self.adc_spi1 = bitbang_spi(ADC_SPI_CS1, ADC_SPI_MOSI, ADC_SPI_MISO, ADC_SPI_CLK) self.adc_spi2 = bitbang_spi(ADC_SPI_CS2, ADC_SPI_MOSI, ADC_SPI_MISO, ADC_SPI_CLK) self.adc_spi3 = bitbang_spi(ADC_SPI_CS3, ADC_SPI_MOSI, ADC_SPI_MISO, ADC_SPI_CLK) self.adc_spi4 = bitbang_spi(ADC_SPI_CS4, ADC_SPI_MOSI, ADC_SPI_MISO, ADC_SPI_CLK) self.adc_spis = [ self.adc_spi1, self.adc_spi2, self.adc_spi3, self.adc_spi4 ] for s in self.adc_spis: ad9864_tristate_miso(s) print('init complete') def _set_switch(self, message): #sw = message[SW_IDX] state = int(message[SW_STATE]) #pin = SW_MAP[sw] self.gpio.set_value(SW_PORT_SEL, state) return message[COMMAND_INDEX] def _set_multiplier(self, message): mult_enable = int(message[1:]) if mult_enable: print('enabling multiplier') self.gpio.set_value(MIX_X2, self.gpio.HIGH) else: self.gpio.set_value(MIX_X2, self.gpio.LOW) return message[COMMAND_INDEX] def _enable_mixer(self, message): mixer_enable = int(message[1:]) print('enabling mixer') if mixer_enable: self.gpio.set_value(MIX_EN, self.gpio.HIGH) self.gpio.set_value(LO_BUF_AMP_EN, self.gpio.HIGH) else: self.gpio.set_value(MIX_EN, self.gpio.LOW) self.gpio.set_value(LO_BUF_AMP_EN, self.gpio.LOW) return message[COMMAND_INDEX] def _init_adc(self, message): self.gpio.set_value(MIX_EN, self.gpio.LOW) self.synth.lo_powerdown() time.sleep(.45) adc = int(message[1:]) if adc == int(ALL_ADC): for s in self.adc_spis: ad9864_init(s) else: ad9864_init(self.adc_spis[adc]) time.sleep(.05) self.synth.lo_powerup() return message[COMMAND_INDEX] def _attenuate_adc(self, message): adc = int(message[1:2]) state = int(message[2:3]) if adc == int(ALL_ADC): for s in self.adc_spis: ad9864_set_attenuation(s, state) else: ad9864_set_attenuation(self.adc_spis[adc], state) return message[COMMAND_INDEX] def _sync_adc(self, message): self.gpio.set_value(SYNCB, self.gpio.HIGH) self.gpio.set_value(SYNCB, self.gpio.LOW) time.sleep(.05) self.gpio.set_value(SYNCB, self.gpio.HIGH) return message[COMMAND_INDEX] def run(self): print('entering run loop') while True: print('waiting for command') message = self.socket.recv() command = message[COMMAND_INDEX] print('received {} command, message: {}'.format(command, message)) response = '' if command in self.command_handlers: response = self.command_handlers[command](message) else: print('unrecognized command: {}'.format(command)) pdb.set_trace() self.socket.send(response)
class bitbang_spi: def __init__(self, spi_cs, spi_mosi, spi_miso, spi_clk, rising_data = True, latch = None, enable_low = True): self.gpio = GPIO() self.rising_data = rising_data self.enable_low = enable_low self.spi_cs = spi_cs self.spi_mosi = spi_mosi self.spi_miso = spi_miso self.spi_clk = spi_clk self.latch = latch self.gpio.set_output(spi_cs) self.gpio.set_output(spi_mosi) self.gpio.set_output(spi_clk) if self.spi_miso != None: self.gpio.set_input(spi_miso) if self.latch != None: self.gpio.set_output(latch) self.gpio.set_value(spi_cs, self.enable_low) def transfer(self, payload, bits = 8): self.gpio.set_value(self.spi_cs, not self.enable_low) self.gpio.set_value(self.spi_clk, self.gpio.LOW) if self.latch != None: self.gpio.set_value(self.latch, self.gpio.LOW) response = 0 for i in range(bits): response = response << 1 # data clocked in on clock rising edge self.gpio.set_value(self.spi_mosi, (payload >> (bits - (i + 1))) & 0x01) self.gpio.set_value(self.spi_clk, self.gpio.HIGH) if self.spi_miso != None: response |= self.gpio.read_value(self.spi_miso) if self.latch!= None and i == bits - 1: self.gpio.set_value(self.latch, self.gpio.HIGH) self.gpio.set_value(self.spi_clk, self.gpio.LOW) if self.latch != None: self.gpio.set_value(self.latch, self.gpio.LOW) self.gpio.set_value(self.spi_cs, self.enable_low) return response