def vpp(self): ''' mix signal meter measure vpp Returns: list, include vpp_data(0 ~ +2), max_data(-1 ~ +1), min_data(-1 ~ +1). Examples: result = self.axi4_bus.vpp result is list ''' rd_data = self.axi4_bus.read_8bit_inc( MIXSignalMeterSGDef.MAX_REGISTER, 8) vpp_max = DataOperate.list_2_int(rd_data) rd_data = self.axi4_bus.read_8bit_inc( MIXSignalMeterSGDef.MIN_REGISTER, 8) vpp_min = DataOperate.list_2_int(rd_data) rd_data = self.axi4_bus.read_8bit_inc( MIXSignalMeterSGDef.VPP_REGISTER, 4) vpp_cnt = DataOperate.list_2_int(rd_data) max = float(vpp_max) / (float(vpp_cnt) * pow(2, 15)) min = float(vpp_min) / (float(vpp_cnt) * pow(2, 15)) vpp = max - min return [max, min, vpp]
def init_sys(self): ''' initialize the system :example: mix_timer.init_sys() ''' # set MODE regiter: IDLE MODE self.axi4_bus.write_32bit_inc(PLTimerDef.MODE, [0x00000000]) # set CFG regiter: extclk_en = 0, Prescaler = 0 (125MHz), trigger = 0 self.axi4_bus.write_32bit_inc(PLTimerDef.CFG, [0x00000000]) # set LEN register: gate length = 1s self.axi4_bus.write_32bit_inc(PLTimerDef.LEN_L, [0x07735940, 0x00000000] ) # set SYSCTRL register: IPrst = 0, enable = 0 self.axi4_bus.write_32bit_inc(PLTimerDef.SYSCTRL, [0x00000000]) # check default value of all read-only registers rd_data = DataOperate.list_2_int(self.axi4_bus.read_8bit_inc(PLTimerDef.CCR_L, 8)) try: assert rd_data == 0 except AssertionError: print(self.dev_name, "reset value wrong for CCR!\nTips: try reset again, if this error still occurs, contact IP design team") return False rd_data = DataOperate.list_2_int(self.axi4_bus.read_8bit_inc(PLTimerDef.CNT_L, 8)) try: assert rd_data == 0 except AssertionError: print(self.dev_name, "reset value wrong for CNT!\nTips: try reset again, if this error still occurs, contact IP design team") return False rd_data = DataOperate.list_2_int(self.axi4_bus.read_8bit_inc(PLTimerDef.STATUS, 4)) try: assert rd_data == 0 except AssertionError: print(self.dev_name, "reset value wrong for STATUS!\nTips: try reset again, if this error still occurs, contact IP design team") return False return True
def get_frequency(self, extclk_freq=10000000): ''' return measured signal frequency in unit of Hz when in correct function mode need to implement software timeout when apply the function :param extclk_freq int specify the external reference clock frequency in unit of Hz if used :example: mix_timer.get_frequency() ''' this_mode = self.axi4_bus.read_8bit_inc(PLTimerDef.MODE, 1)[0] if this_mode != PLTimerDef.FREQ_M : print("this function is only valid in frequency measurement mode! currently in mode %d") % (this_mode) return 0 print("in frequency measurement\n") if self.enable_proc(): # get register value and calculate frequency CCR = DataOperate.list_2_int(self.axi4_bus.read_8bit_inc(PLTimerDef.CCR_L, 8)) CNT = DataOperate.list_2_int(self.axi4_bus.read_8bit_inc(PLTimerDef.CNT_L, 8)) print('CCR=',CCR,' CNT=', CNT) prescaler = self.axi4_bus.read_8bit_inc(PLTimerDef.REG_FREQ, 1)[0] % 8 extclk_en = self.axi4_bus.read_8bit_inc(PLTimerDef.REG_EXCLK_EN, 1)[0] freq_res = CCR * ( extclk_freq if extclk_en else ( PLTimerDef.SYS_CLK_FREQ / (1 if prescaler == 0 else prescaler * 2) ) )/ CNT # get result done, clear enable bit self.axi4_bus.write_8bit_inc(PLTimerDef.REG_ENABLE, [PLTimerDef.STOP_FUNC]) return freq_res else: raise PLTimerException(self.dev_name, "overflow or timeout, need to reset IP ... ")
def rd_all_regs(self): ''' print all register values for debug purpose :example: mix_timer.rd_all_regs() ''' rd_data = self.axi4_bus.read_8bit_inc(PLTimerDef.MODE, 1)[0] print("MODE reg value = ", hex(rd_data)) rd_data = self.axi4_bus.read_8bit_inc(PLTimerDef.REG_EXCLK_EN, 1)[0] print("EXCLK_EN reg value = ", hex(rd_data)) rd_data = self.axi4_bus.read_8bit_inc(PLTimerDef.REG_TRIGGER, 1)[0] print("Trigger_ctrl reg value = ", hex(rd_data)) rd_data = self.axi4_bus.read_8bit_inc(PLTimerDef.REG_FREQ, 1)[0] print("Freq_prescaler reg value = ", hex(rd_data % 8)) rd_data = self.axi4_bus.read_16bit_inc(PLTimerDef.REG_FREQ, 1)[0] print("edge_cnt reg value = ", hex(rd_data >> 4)) rd_data = DataOperate.list_2_int(self.axi4_bus.read_8bit_inc(PLTimerDef.LEN_L, 8)) print("LEN reg value = ", rd_data) rd_data = self.axi4_bus.read_8bit_inc(PLTimerDef.REG_ENABLE, 1)[0] print("Enable reg value = ", hex(rd_data)) rd_data = self.axi4_bus.read_8bit_inc(PLTimerDef.REG_IP_RST, 1)[0] print("IP_rst reg value = ", hex(rd_data)) rd_data = DataOperate.list_2_int(self.axi4_bus.read_8bit_inc(PLTimerDef.CCR_L, 8)) print("CCR reg value = ", rd_data) rd_data = DataOperate.list_2_int(self.axi4_bus.read_8bit_inc(PLTimerDef.CNT_L, 8)) print("CNT reg value = ", rd_data) rd_data = self.axi4_bus.read_8bit_inc(PLTimerDef.REG_FLAG, 1)[0] print("Exception_flag reg value = ", hex(rd_data)) rd_data = self.axi4_bus.read_8bit_inc(PLTimerDef.REG_DONE, 1)[0] print("Complete reg value = ", hex(rd_data))
def duty(self): ''' mix signal meter measure duty Returns: float, [0~100]. Examples: duty = self.axi4_bus.duty duty = 10 ''' if(self._measure_state == 0): rd_data = self.axi4_bus.read_8bit_inc( MIXSignalMeterSGDef.CONFIG_REGISTER, 1) if(rd_data[0] & 0x04 == 0x04): return(100, '%') else: return(0, '%') rd_data = self.axi4_bus.read_8bit_inc( MIXSignalMeterSGDef.DUTY_ALL_REGISTER, 8) duty_all = DataOperate.list_2_uint(rd_data) rd_data = self.axi4_bus.read_8bit_inc( MIXSignalMeterSGDef.DUTY_HIGH_REGISTER, 8) duty_high = DataOperate.list_2_uint(rd_data) duty = (float(duty_high) / duty_all) * 100 return duty
def __init__(self, axi4_bus=None): if isinstance(axi4_bus, basestring): self.axi4_bus = AXI4LiteBus(axi4_bus, MIXASKLinkPingPongSGDef.REG_SIZE) else: self.axi4_bus = axi4_bus self.__data_deal = DataOperate()
def __init__(self, axi4_bus=None): if isinstance(axi4_bus, basestring): self._axi4_bus = AXI4LiteBus(axi4_bus, PLSPIDef.REG_SIZE) else: self._axi4_bus = axi4_bus self._dev_name = self._axi4_bus._dev_name self.__data_deal = DataOperate() self._timeout = AXI4Def.AXI4_TIMEOUT self._spi_speed = PLSPIDef.DEFAULT_SPEED self._spi_work_mode = PLSPIDef.SPI_MODE self.open()
def _measure_frequency_lp(self): ''' measure frequency in low-precision Returns: float, value, unit Hz. ''' rd_data = self.axi4_bus.read_8bit_inc( MIXSquareMeterSGDef.DUTY_ALL_REGISTER, 8) duty_all = DataOperate.list_2_int(rd_data) rd_data = self.axi4_bus.read_8bit_inc( MIXSquareMeterSGDef.DUTY_N_REGISTER, 4) duty_N = DataOperate.list_2_int(rd_data) freq = float(duty_N) * self.__sample_rate / duty_all return freq
def _read_fifo(self, rd_len): ''' Read data from receiving fifo Args: rd_len: int, Length of read data. Returns: list, [value], Data to be read, the list element is an integer, bit width: 8 bits. ''' assert isinstance(rd_len, int) assert (rd_len > 0) rd_cnt = rd_len / PLSPIDef.BYTE_ALIGNMENT_LENGTH rd_remain = rd_len % PLSPIDef.BYTE_ALIGNMENT_LENGTH rd_data = [] if rd_cnt: datas = self._axi4_bus.read_32bit_fix(PLSPIDef.WDATA_REGISTER, rd_cnt) for _data in datas: rd_data += DataOperate.int_2_list(_data, PLSPIDef.INT_TO_LIST_LEN_4) if rd_remain: rd_data += self._axi4_bus.read_8bit_inc(PLSPIDef.WDATA_REGISTER, rd_remain) return rd_data
def get_pulseWidth_unblocking(self): ''' return measured pulse width in unit of us when in correct function mode need to implement software timeout when apply the function :example: mix_timer.get_pulseWidth_unblocking() ''' this_mode = self.axi4_bus.read_8bit_inc(PLTimerDef.MODE, 1)[0] if ((this_mode != PLTimerDef.PULSE_M_S) and (this_mode != PLTimerDef.PULSE_M_D) ): print("this function is only valid in pulse width measurement mode! currently in mode %d") % (this_mode) return 0 done = 0 Exception_flag = 0 # check Complete register until it is asserted while done == 0 : done = self.axi4_bus.read_8bit_inc(PLTimerDef.REG_DONE, 1)[0] Exception_flag = self.axi4_bus.read_8bit_inc(PLTimerDef.REG_FLAG, 1)[0] flag_ovf = Exception_flag & PLTimerDef.BIT_OVF flag_timeout = Exception_flag & PLTimerDef.BIT_TIMEOUT if (flag_timeout != 0): raise PLTimerException(self.dev_name, "timeout exception! please check input signal, need to reset IP ... ") if (flag_ovf != 0): raise PLTimerException(self.dev_name, "overflow exception! measured signal out of spec, need to reset IP ... ") #Complete flag check done CNT = DataOperate.list_2_int(self.axi4_bus.read_8bit_inc(PLTimerDef.CNT_L, 8)) prescaler = self.axi4_bus.read_8bit_inc(PLTimerDef.REG_FREQ, 1)[0] % 8 res = CNT * (1000000.0 / (PLTimerDef.SYS_CLK_FREQ / (1 if prescaler == 0 else prescaler * 2) ) ) # get result done, clear enable bit self.axi4_bus.write_8bit_inc(PLTimerDef.REG_ENABLE, [PLTimerDef.STOP_FUNC]) return res
def start_measure(self, time_ms, sample_rate, measure_mask=0x00): ''' mix signal meter start measure Args: time_ms: int, [1~2000], unit ms. sample_rate: int, [1~125000000], unit SPS. measure_mask: int, [1~0xff], bit set means mask the function. Examples: self.axi4_bus.start_measure(2000, 150000) +---------------+-------------------+ | measure_mask | function | +===============+===================+ | bit[0:3] | Reserved | +---------------+-------------------+ | bit[4] | Frequency mask | +---------------+-------------------+ | bit[5] | Duty mask | +---------------+-------------------+ | bit[6] | Vpp mask | +---------------+-------------------+ | bit[7] | rms mask | +---------------+-------------------+ ''' assert isinstance(time_ms, int) assert isinstance(sample_rate, int) assert 1 <= sample_rate <= 125000000 self.axi4_bus.write_8bit_inc(MIXSignalMeterSGDef.MEASURE_MASK_REGISTER, [measure_mask]) self.__sample_rate = sample_rate # fpga count the time from 0, need to minus 1 wr_data = DataOperate.int_2_list(time_ms - 1, 2) self.axi4_bus.write_8bit_inc( MIXSignalMeterSGDef.WAIT_TIME_REGISTER, wr_data) self.axi4_bus.write_8bit_inc(MIXSignalMeterSGDef.FREQ_REGISTER, [0x00]) self.axi4_bus.write_8bit_inc( MIXSignalMeterSGDef.SET_MEASURE_REGISTER, [0x01]) rd_data = self.axi4_bus.read_8bit_inc( MIXSignalMeterSGDef.FREQ_REGISTER, 1) last_time = time.time() # time.time() unit needs to be converted to ms while ((rd_data[0] != 0x01) and ((time.time() - last_time) * 1000 < (time_ms + MIXSignalMeterSGDef.DEFAULT_TIMEOUT))): time.sleep(MIXSignalMeterSGDef.DEFAULT_DELAY) rd_data = self.axi4_bus.read_8bit_inc( MIXSignalMeterSGDef.FREQ_REGISTER, 1) if((time.time() - last_time) * 1000 >= (time_ms + MIXSignalMeterSGDef.DEFAULT_TIMEOUT)): raise MIXSignalMeterSGException('SignalMeter Measure time out') self._measure_state = 0 self._measure_state = 1 return "done"
def test_register(self, test_data): ''' Test_register Args: sample_rate: int, test data Examples: signal_source.test_register(0xffff) ''' wr_data = DataOperate.int_2_list(test_data, 4) self.axi4_bus.write_8bit_inc(MIXSignalSourceSGDef.TEST_REGISTER, wr_data) rd_data = self.axi4_bus.read_8bit_inc( MIXSignalSourceSGDef.TEST_REGISTER, len(wr_data)) test_out = DataOperate.list_2_int(rd_data) return None
def test_register(self, test_data): ''' mix signal meter test register Args: test_data: int, [0x23], test data. Examples: self.test_register(0x23) ''' wr_data = DataOperate.int_2_list(test_data, 4) self.axi4_bus.write_8bit_inc( MIXSignalMeterSGDef.OUTPUT_REGISTERS, wr_data) rd_data = self.axi4_bus.read_8bit_inc( MIXSignalMeterSGDef.OUTPUT_REGISTERS, len(wr_data)) test_out = DataOperate.list_2_int(rd_data) if(test_out != test_data): raise MIXSignalMeterSGException( 'SignalMeter Test Register read data error')
def set_awg_step(self, sample_rate, start_volt, stop_volt, duration_ms): ''' Set awg step Args: sample_rate: int, external DAC sample rate, unit is SPS start_volt: float, step start volt (-0.99999~0.99999) stop_volt: float, step start volt (-0.99999~0.99999) duration_ms: float, duration time Examples: signal_source.set_awg_step(1000, 0.5, 0.5, 0.5) ''' self.axi4_bus.write_8bit_inc(MIXSignalSourceSGDef.SIGNAL_REGISTER, [0x00]) sample_cycle = 1000.0 / sample_rate duration_step = duration_ms / sample_cycle duration_step_cnt = int(duration_step / pow(2, 16)) + 1 volt_step = (stop_volt - start_volt) / duration_step_cnt for i in range(0, duration_step_cnt): wr_data = [] start_volt_temp = i * volt_step + start_volt step_duration_temp = int(duration_step / duration_step_cnt) step_ovlt_temp = volt_step * pow(2, 16) / step_duration_temp start_volt_hex = int(start_volt_temp * pow(2, 15)) step_ovlt_hex = int(step_ovlt_temp * pow(2, 15)) wr_list = DataOperate.int_2_list(step_duration_temp - 1, 2) wr_data.extend(wr_list) wr_list = DataOperate.int_2_list(step_ovlt_hex, 4) wr_data.extend(wr_list) wr_list = DataOperate.int_2_list(start_volt_hex, 2) wr_data.extend(wr_list) wr_data.append(self.step_index) self.axi4_bus.write_8bit_inc(MIXSignalSourceSGDef.RX_BUF_REGISTER, wr_data) self.axi4_bus.\ write_8bit_inc(MIXSignalSourceSGDef.AWG_START_REGISYER, [0x01]) self.step_index = self.step_index + 1 return None
def _measure_frequency_hp(self): ''' measure frequency in high-precision Returns: float, value, unit Hz. ''' rd_data = self.axi4_bus.read_8bit_inc(MIXSquareMeterSGDef.HP_REGISTER, 2) sys_divide = DataOperate.list_2_int(rd_data) if (sys_divide == 0): sys_divide = 1 rd_data = self.axi4_bus.read_8bit_inc( MIXSquareMeterSGDef.FREQ_X_REGISTER, 8) freq_x_sum = DataOperate.list_2_int(rd_data) rd_data = self.axi4_bus.read_8bit_inc( MIXSquareMeterSGDef.FREQ_Y_REGISTER, 8) freq_y_sum = DataOperate.list_2_int(rd_data) rd_data = self.axi4_bus.read_8bit_inc( MIXSquareMeterSGDef.FREQ_XY_REGISTER, 8) freq_xy_sum = DataOperate.list_2_int(rd_data) rd_data = self.axi4_bus.read_8bit_inc( MIXSquareMeterSGDef.FREQ_XX_REGISTER, 8) freq_xx_sum = DataOperate.list_2_int(rd_data) rd_data = self.axi4_bus.read_8bit_inc( MIXSquareMeterSGDef.FREQ_N_REGISTER, 4) freq_N = DataOperate.list_2_int(rd_data) k_1 = freq_N * freq_xy_sum - freq_y_sum * freq_x_sum k_2 = freq_N * freq_xx_sum - freq_x_sum * freq_x_sum freq = float(sys_divide) * self.__sample_rate * k_2 / k_1 return freq
def set_swg_paramter(self, sample_rate, signal_frequency, vpp_scale, square_duty, offset_volt=0): ''' Set swg paramter Args: sample_rate: int, unit SPS, external DAC sample rate. signal_frequency: int, unit Hz, output signal frequency. vpp_scale: float, [0.000~0.999, full scale ratio. square_duty: float, [0.001~0.999], duty of square. offset_volt: float, [-0.99999~0.99999], offset volt. Examples: signal_source.set_swg_paramter(1000, 1000, 0.5, 0.5, 0.5) ''' self.axi4_bus.write_8bit_inc(MIXSignalSourceSGDef.SIGNAL_REGISTER, [0x00]) freq_ctrl = int(pow(2, 32) * signal_frequency / sample_rate) wr_data = DataOperate.int_2_list(freq_ctrl, 4) self.axi4_bus.write_8bit_inc(MIXSignalSourceSGDef.FREQUENCY_REGISTER, wr_data) vpp_ctrl = int((pow(2, 16) - 1) * vpp_scale) wr_data = DataOperate.int_2_list(vpp_ctrl, 2) self.axi4_bus.write_8bit_inc(MIXSignalSourceSGDef.VPP_SCALE_REGISTER, wr_data) duty_ctrl = int((sample_rate / signal_frequency) * square_duty) wr_data = DataOperate.int_2_list(duty_ctrl, 4) self.axi4_bus.write_8bit_inc(MIXSignalSourceSGDef.DUTY_REGISTER, wr_data) offset_volt_hex = int(offset_volt * pow(2, 23)) wr_data = DataOperate.int_2_list(offset_volt_hex, 3) self.axi4_bus.write_8bit_inc(MIXSignalSourceSGDef.OFFSET_VOLT_REGISTER, wr_data)
def measure_time(self, time_ms): ''' power sequence set measure time, Set the ipcore to measure the duration of the trigger voltage Args: time_ms: int,[0~65535], unit ms. Examples: power_sequence.measure_time = 3000 ''' assert time_ms > 0 and time_ms <= 65535 self.sample_time = time_ms times = DataOperate.int_2_list(time_ms, 2) self.axi4_bus.write_8bit_inc(MIXPowerSequenceSGDef.TIME_REGISTER, times)
def rms(self): ''' mix signal meter measure rms Returns: list, include rms_data(0 ~ +1), avg_data(-1 ~ +1). Examples: result = self.axi4_bus.rms result is list ''' rd_data = self.axi4_bus.read_8bit_inc( MIXSignalMeterSGDef.RMS_SQUARE_REGISTER, 8) rms_square_sum = DataOperate.list_2_int(rd_data) rd_data = self.axi4_bus.read_8bit_inc( MIXSignalMeterSGDef.RMS_SUM_REGISTER, 8) rms_sum = DataOperate.list_2_int(rd_data) rd_data = self.axi4_bus.read_8bit_inc( MIXSignalMeterSGDef.RMS_CNT_REGISTER, 4) rms_cnt = DataOperate.list_2_int(rd_data) rms = math.sqrt(rms_square_sum / rms_cnt) / pow(2, 15) avg = (float(rms_sum) / rms_cnt) / pow(2, 15) return [rms, avg]
def measure_rising_edge_count(self): ''' mix signal meter measure rising edge count in low-precision if want to get accurate count, measure time must minus 1. Returns: int, value. Examples: self.measure_rising_edge_count() ''' rd_data = self.axi4_bus.read_8bit_inc( MIXSignalMeterSGDef.DUTY_N_REGISTER, 4) return DataOperate.list_2_uint(rd_data)
def duty(self): ''' Measure input signal duty Returns: float, [0~100], signal duty. ''' if (self.__measure_state == 0): rd_data = self.axi4_bus.read_8bit_inc( MIXSquareMeterSGDef.CONFIG_REGISTER, 1) if (rd_data[0] & 0x04 == 0x04): return (100, '%') else: return (0, '%') rd_data = self.axi4_bus.read_8bit_inc( MIXSquareMeterSGDef.DUTY_ALL_REGISTER, 8) duty_all = DataOperate.list_2_int(rd_data) rd_data = self.axi4_bus.read_8bit_inc( MIXSquareMeterSGDef.DUTY_HIGH_REGISTER, 8) duty_high = DataOperate.list_2_int(rd_data) duty = (float(duty_high) / duty_all) * 100 return duty
def func_select(self, mode, extclk_en=0, trigger=0, edge_cnt=2048, prescaler=0, gate_len=1000000, extclk_freq=10): ''' select Timer function with configuration parameters :param mode: int (0 ~ 6) funcitonal mode :param extclk_en: int (0 ~ 1) (optional, default 0, using system clock) enable external source as reference clock :param trigger: int (0 ~ 3) (optional, default 0) trigger status, refer to IP spec :param edge_cnt: int (1 ~ 2048) (optional, default 2048) edge cnt, only used for mode 6 :param prescaler: int (0 ~ 7) (optional, default no prescale) reference clock prescaler control, only valid when extclk_en is set to 0 :param gate_len: long int (optional, default 1s) gate length in unit of us :param extclk_freq: long int (optional, default 10MHz) external clock frequency, used for frequency calculation, only valid when extclk_en is set to 1 :example: mix_timer.func_select(mode=FREQ_M, extclk=0, prescale = 1, gate_len=1000000) mix_timer.func_select(mode=FREQ_M, extclk=1, gate_len=1000000, extclk_freq = 10) ''' mode_dict = { PLTimerDef.IDLE_MODE: 'in idle mode', PLTimerDef.FREQ_M: 'in frequency measurement', PLTimerDef.PULSE_M_S: 'in single-line pulse measurement', PLTimerDef.PULSE_M_D: 'in dual-line pulse measurement', PLTimerDef.EDGE_C: 'in edge counting', PLTimerDef.PULSE_G: 'in pulse generation', PLTimerDef.EDGE_M: 'in edge time measurement', } # check invalid input assert mode in mode_dict, 'wrong mode {}; expecting int (0 - 6)'.format(mode) assert 0 <= trigger <= 3, 'trigger out of range, expecting int (0 - 3)' assert 1 <= edge_cnt <= 2048, 'egde count out of range, expecting int (1 - 2048)' assert 0 <= prescaler <= 7, 'prescaler out of range, expecting int (0 - 7)' # set MODE register self.axi4_bus.write_8bit_inc(PLTimerDef.MODE, [mode]) mode_info = mode_dict[mode] print(mode_info) # calculate LEN register value to be written based on user configuration if extclk_en: real_len = int(gate_len * extclk_freq) elif prescaler == 0: real_len = int(gate_len * 125) else : real_len = int(gate_len * 125 / 2 / prescaler) # configure registers according to function input self.axi4_bus.write_8bit_inc(PLTimerDef.REG_EXCLK_EN, [extclk_en]) self.axi4_bus.write_8bit_inc(PLTimerDef.REG_TRIGGER, [trigger]) edge_cnt_and_prescaler = edge_cnt << 4 + prescaler self.axi4_bus.write_16bit_inc(PLTimerDef.REG_FREQ, [edge_cnt_and_prescaler]) self.axi4_bus.write_8bit_inc(PLTimerDef.LEN_L, DataOperate.int_2_list(real_len, 8)) return True
def set_vpp_interval(self, test_interval_ms): ''' mix signal meter set the vpp interval Args: test_interval_ms: int, [1~10000], unit ms. Examples: self.axi4_bus.set_vpp_interval(1000) ''' assert isinstance(test_interval_ms, int) config_data = DataOperate.int_2_list(test_interval_ms, 2) self.axi4_bus.write_8bit_inc( MIXSignalMeterSGDef.VPP_INTERVAL_REGISTER, config_data) return "done"
def set_signal_time(self, signal_time): ''' Set output signal time Args: signal_time: int, unit us, signal time of signal source. Examples: signalsource.set_signal_time(10000) ''' self.axi4_bus.write_8bit_inc(MIXSignalSourceSGDef.SIGNAL_REGISTER, [0x00]) wr_data = DataOperate.int_2_list(signal_time, 4) self.axi4_bus.write_8bit_inc(MIXSignalSourceSGDef.DURATION_REGISTER, wr_data)
def __init__(self, axi4_bus=None): if isinstance(axi4_bus, basestring): self.axi4_bus = AXI4LiteBus(axi4_bus, MIXWidthMeasureSGDef.REG_SIZE) else: self.axi4_bus = axi4_bus self.dev_name = self.axi4_bus._dev_name self.data_deal = DataOperate() rd_data = self.axi4_bus.read_32bit_inc( MIXWidthMeasureSGDef.BASE_CLK_FREQUENCY, MIXWidthMeasureSGDef.READ_FREQUENCY_DATA_LEN) self.clk_frequency = rd_data[0] # rd_data: type: int unit: KHz # disable all register and clear buffer cache,then all registers work self.stop_measure() # enable all register, then all registers work self.axi4_bus.write_8bit_inc(MIXWidthMeasureSGDef.MODULE_EN, [MIXWidthMeasureSGDef.ENABLE])
def get_edgeCount(self): ''' return the number of edges when in correct function mode need to implement software timeout when apply the function :example: mix_timer.get_edgeCount() ''' this_mode = self.axi4_bus.read_8bit_inc(PLTimerDef.MODE, 1)[0] if this_mode != PLTimerDef.EDGE_C : print("this function is only valid in edge counter mode! currently in mode %d") % (this_mode) return 0 if self.enable_proc() : CCR = DataOperate.list_2_int(self.axi4_bus.read_8bit_inc(PLTimerDef.CCR_L, 8)) # get result done, clear enable bit self.axi4_bus.write_8bit_inc(PLTimerDef.REG_ENABLE, [PLTimerDef.STOP_FUNC]) return CCR else : raise PLTimerException(self.dev_name, "overflow or timeout, need to reset IP ... ")
def start_measure(self, time_ms, sample_rate): ''' Start measure input signal Args: time_ms: int, [1~2000], unit ms, the total time in ms to measure. sample_rate: int, [1~125000000], unit SPS, ADC sample rate in SPS. Returns: string, 'done', return 'done', if execute successfully. ''' assert isinstance(time_ms, int) assert 1 <= time_ms <= 2000 assert isinstance(sample_rate, int) assert 1 <= sample_rate <= 125000000 self.__sample_rate = sample_rate wr_data = DataOperate.int_2_list(time_ms, 2) self.axi4_bus.write_8bit_inc(MIXSquareMeterSGDef.WAIT_TIME_REGISTER, wr_data) self.axi4_bus.write_8bit_inc(MIXSquareMeterSGDef.FREQ_REGISTER, [0x00]) self.axi4_bus.write_8bit_inc(MIXSquareMeterSGDef.SET_MEASURE_REGISTER, [0x01]) rd_data = self.axi4_bus.read_8bit_inc( MIXSquareMeterSGDef.FREQ_REGISTER, 1) last_time = time.time() # time.time() unit needs to be converted to ms while ((rd_data[0] != 0x01) and ((time.time() - last_time) * 1000 < (time_ms + MIXSquareMeterSGDef.DEFAULT_TIMEOUT))): time.sleep(MIXSquareMeterSGDef.DEFAULT_DELAY) rd_data = self.axi4_bus.read_8bit_inc( MIXSquareMeterSGDef.FREQ_REGISTER, 1) if ((time.time() - last_time) * 1000 >= (time_ms + MIXSquareMeterSGDef.DEFAULT_TIMEOUT)): raise MIXSquareMeterSGException('SignalMeter Measure time out') self.__measure_state = 0 self.__measure_state = 1 return "done"
def get_pulseWidth(self): ''' return measured pulse width in unit of us when in correct function mode need to implement software timeout when apply the function :example: mix_timer.get_pulseWidth() ''' this_mode = self.axi4_bus.read_8bit_inc(PLTimerDef.MODE, 1)[0] if ((this_mode != PLTimerDef.PULSE_M_S) and (this_mode != PLTimerDef.PULSE_M_D) ): print("this function is only valid in pulse width measurement mode! currently in mode %d") % (this_mode) return 0 if self.enable_proc(): CNT = DataOperate.list_2_int(self.axi4_bus.read_8bit_inc(PLTimerDef.CNT_L, 8)) prescaler = self.axi4_bus.read_8bit_inc(PLTimerDef.REG_FREQ, 1)[0] % 8 res = CNT * (1000000.0 / (PLTimerDef.SYS_CLK_FREQ / (1 if prescaler == 0 else prescaler * 2) ) ) # get result done, clear enable bit self.axi4_bus.write_8bit_inc(PLTimerDef.REG_ENABLE, [PLTimerDef.STOP_FUNC]) return res else: raise PLTimerException(self.dev_name, "overflow or timeout, need to reset IP ... ")
def get_edgeTime(self): ''' return the The period of time beginning from the first edge and stopping at the predefined number of edge when in correct function mode in unit of us need to implement software timeout when apply the function :example: mix_timer.get_edgeTime() ''' this_mode = self.axi4_bus.read_8bit_inc(PLTimerDef.MODE, 1)[0] if this_mode != PLTimerDef.EDGE_M : print("this function is only valid in edge time measurement mode! currently in mode %d") % (this_mode) return 0 if self.enable_proc(): CNT = DataOperate.list_2_int(self.axi4_bus.read_8bit_inc(PLTimerDef.CNT_L, 8)) prescaler = self.axi4_bus.read_8bit_inc(PLTimerDef.REG_FREQ, 1)[0] % 8 res = CNT * (1000000.0 / (PLTimerDef.SYS_CLK_FREQ / (1 if prescaler == 0 else prescaler * 2) ) ) # get result done, clear enable bit # self.axi4_bus.write_8bit_inc(PLTimerDef.REG_ENABLE, [PLTimerDef.STOP_FUNC]) return res else: raise PLTimerException(self.dev_name, "overflow or timeout, need to reset IP ... ")
class _MIXQSPISG(object): ''' The MIXQSPISG class provides an interface to the MIX QSPI IPcore. This class supports SPI and QPI mode. ClassType = SPI Args: axi4_bus: instance(AXI4LiteBus)/None, Class instance of axi4 bus, if not using this parameter, will create emulator Examples: axi4_bus = AXI4LiteBus('/dev/MIX_QSPI_SG', 8192) spi = MIXQSPISG(axi4_bus) ''' rpc_public_api = [ 'set_timeout', 'set_work_mode', 'get_work_mode', 'set_mode', 'get_mode', 'set_speed', 'get_speed', 'read', 'write', 'sync_transfer', 'async_transfer', 'transfer' ] def __init__(self, axi4_bus=None): if isinstance(axi4_bus, basestring): self._axi4_bus = AXI4LiteBus(axi4_bus, PLSPIDef.REG_SIZE) else: self._axi4_bus = axi4_bus self._dev_name = self._axi4_bus._dev_name self.__data_deal = DataOperate() self._timeout = AXI4Def.AXI4_TIMEOUT self._spi_speed = PLSPIDef.DEFAULT_SPEED self._spi_work_mode = PLSPIDef.SPI_MODE self.open() def __del__(self): self.close() def _wait_for_ready(self): ''' Waiting for ipcore status to be ready or timeout Returns: boolean, [True, False], True is ready,Fasle is timeout. ''' ret = 0 start = time.time() while (time.time() < (start + self._timeout)): ret = self._axi4_bus.read_8bit_inc(PLSPIDef.STATE_REGISTER, PLSPIDef.STATE_READY)[0] if ret == PLSPIDef.SPI_READY: return True time.sleep(PLSPIDef.DELAY_TIME) return False def _clear_fifo(self): ''' Clear fifo data. ''' self._axi4_bus.write_8bit_inc(PLSPIDef.FIFO_CLR_REGISTER, [PLSPIDef.CLEAR_FIFO]) def _assembly_data(self, wr_data): ''' 4-byte alignment operation, combining a 1-byte list of each element into a 4-byte list for each element Args: wr_data: list, 1-byte list of each element. Returns: list, [value], 4-byte list of each element. ''' assert isinstance(wr_data, list) data = [] offset = 0 wr_len = len(wr_data) if 0 <= wr_len < 4: data.append(self.__data_deal.list_2_int(wr_data[offset:])) return data for i in range(0, (wr_len / PLSPIDef.BYTE_ALIGNMENT_LENGTH + 1)): if wr_len - offset >= PLSPIDef.BYTE_ALIGNMENT_LENGTH: data.append( self.__data_deal.list_2_int( wr_data[offset:offset + PLSPIDef.BYTE_ALIGNMENT_LENGTH])) offset += PLSPIDef.BYTE_ALIGNMENT_LENGTH elif wr_len - offset > 0: data.append(self.__data_deal.list_2_int(wr_data[offset:])) return data def _read_fifo(self, rd_len): ''' Read data from receiving fifo Args: rd_len: int, Length of read data. Returns: list, [value], Data to be read, the list element is an integer, bit width: 8 bits. ''' assert isinstance(rd_len, int) assert (rd_len > 0) rd_cnt = rd_len / PLSPIDef.BYTE_ALIGNMENT_LENGTH rd_remain = rd_len % PLSPIDef.BYTE_ALIGNMENT_LENGTH rd_data = [] if rd_cnt: datas = self._axi4_bus.read_32bit_fix(PLSPIDef.WDATA_REGISTER, rd_cnt) for _data in datas: rd_data += DataOperate.int_2_list(_data, PLSPIDef.INT_TO_LIST_LEN_4) if rd_remain: rd_data += self._axi4_bus.read_8bit_inc(PLSPIDef.WDATA_REGISTER, rd_remain) return rd_data def _write_fifo(self, wr_data): ''' Write data to transfer fifo Args: wr_data: list, Data to write, the list element is an integer, bit width: 8 bits. ''' wr_len = len(wr_data) wr_data = self._assembly_data(wr_data) # 'wr_len - 1': SPI operation byte length. SPI_BYTE_LEN = Actual byte length - 1 data = self.__data_deal.int_2_list(wr_len - 1, PLSPIDef.INT_TO_LIST_LEN_2) self._axi4_bus.write_8bit_inc(PLSPIDef.BYTE_LEN_REGISTER, data) self._axi4_bus.write_8bit_inc(PLSPIDef.TRANSMIT_START_REGISTER, [PLSPIDef.TRANSMIT_ENABLE]) self._axi4_bus.write_32bit_fix(PLSPIDef.WDATA_REGISTER, wr_data) if not self._wait_for_ready(): raise MIXQSPISGException(self._axi4_bus._dev_name, "timeout") def _only_read(self, rd_len): ''' Read rd_len bytes data from the spi bus Args: rd_len: int, Length of read data. Returns: list, [value], Data to be read, the list element is an integer, bit width: 8 bits. ''' assert isinstance(rd_len, int) assert rd_len > 0 data = [] reg_data = self._axi4_bus.read_8bit_inc( PLSPIDef.CONTROL_REGISTER, PLSPIDef.CONTROL_REGISTER_LEN)[0] reg_data &= ~PLSPIDef.WRITE_ENABLE reg_data |= PLSPIDef.READ_ENABLE self._axi4_bus.write_8bit_inc(PLSPIDef.CONTROL_REGISTER, [reg_data]) while (rd_len > 0): if PLSPIDef.MAX_FIFO_LEN <= rd_len: byte_len = PLSPIDef.MAX_FIFO_LEN rd_len -= PLSPIDef.MAX_FIFO_LEN else: byte_len = rd_len rd_len = 0 self._axi4_bus.write_16bit_inc(PLSPIDef.BYTE_LEN_REGISTER, [byte_len - 1]) self._axi4_bus.write_8bit_inc(PLSPIDef.TRANSMIT_START_REGISTER, [PLSPIDef.TRANSMIT_ENABLE]) if not self._wait_for_ready(): raise MIXQSPISGException(self._axi4_bus._dev_name, "timeout") data += self._read_fifo(byte_len) self._clear_fifo() return data def _only_write(self, wr_data): ''' Write data to spi bus Args: wr_data: list, Data to write, the list element is an integer, bit width: 8 bits. ''' assert isinstance(wr_data, list) offset = 0 data_len = len(wr_data) rd_data = self._axi4_bus.read_8bit_inc( PLSPIDef.CONTROL_REGISTER, PLSPIDef.CONTROL_REGISTER_LEN)[0] rd_data |= PLSPIDef.WRITE_ENABLE rd_data &= ~PLSPIDef.READ_ENABLE self._axi4_bus.write_8bit_inc(PLSPIDef.CONTROL_REGISTER, [rd_data]) while (data_len > 0): if data_len >= PLSPIDef.MAX_FIFO_LEN: data_len -= PLSPIDef.MAX_FIFO_LEN else: data_len = 0 data = wr_data[offset:(offset + PLSPIDef.MAX_FIFO_LEN)] self._write_fifo(data) self._clear_fifo() offset += PLSPIDef.MAX_FIFO_LEN def open(self): ''' Open the spi device, initialize the clock rate and the working mode Examples: axi4_bus = AXI4LiteBus('/dev/MIX_QSPI_SG', 8192) spi = PLSPIBus(axi4_bus) spi.open() ''' rd_conf_val = self._axi4_bus.read_8bit_inc( PLSPIDef.CONFIG_REGISTER, PLSPIDef.CONFIG_REGISTER_LEN)[0] config_data = rd_conf_val | PLSPIDef.MODULE_ENABLE self._axi4_bus.write_8bit_inc(PLSPIDef.CONFIG_REGISTER, [config_data]) self.set_speed(self._spi_speed) self.set_work_mode(self._spi_work_mode) def close(self): ''' Close the spi device Examples: axi4_bus = AXI4LiteBus('/dev/MIX_QSPI_SG', 8192) spi = PLSPIBus(axi4_bus) spi.close() ''' if not hasattr(self, '_axi4_bus'): return rd_conf_val = self._axi4_bus.read_8bit_inc( PLSPIDef.CONFIG_REGISTER, PLSPIDef.CONFIG_REGISTER_LEN)[0] config_data = rd_conf_val & ~PLSPIDef.MODULE_ENABLE self._axi4_bus.write_8bit_inc(PLSPIDef.CONFIG_REGISTER, [config_data]) def set_timeout(self, timeout): ''' Set the timeout for waiting for the ipcore state to be ready Args: timeout: float, unit s. Examples: axi4_bus = AXI4LiteBus('/dev/MIX_QSPI_SG', 8192) spi = PLSPIBus(axi4_bus) # set 0.1s timeout for polling the ipcore status register spi.set_timeout(0.1) ''' assert isinstance(timeout, float) assert timeout >= 0 self._timeout = timeout def set_work_mode(self, quad_mode): ''' Set the spi working mode. The MIX QSPI_SG IPcore supports SPI / QPI mode Args: quad_mode: int, [0, 1], 0: SPI mode, 1: QPI mode. Examples: axi4_bus = AXI4LiteBus('/dev/MIX_QSPI_SG', 8192) spi = PLSPIBus(axi4_bus) # set the spi working mode to SPI mode. spi.set_work_mode(PLSPIDef.SPI_MODE) ''' assert quad_mode in [PLSPIDef.SPI_MODE, PLSPIDef.QPI_MODE] rd_data = self._axi4_bus.read_8bit_inc( PLSPIDef.CONTROL_REGISTER, PLSPIDef.CONTROL_REGISTER_LEN)[0] rd_data &= PLSPIDef.SPI_MODE_CLEAR rd_data |= quad_mode self._axi4_bus.write_8bit_inc(PLSPIDef.CONTROL_REGISTER, [rd_data]) self._spi_work_mode = quad_mode def get_work_mode(self): ''' Get spi working mode Returns: int, [0, 1], 0: SPI mode, 1: QPI mode. Examples: axi4_bus = AXI4LiteBus('/dev/MIX_QSPI_SG', 8192) spi = PLSPIBus(axi4_bus) ret = spi.set_work_mode() # ret == 0 ''' rd_data = self._axi4_bus.read_8bit_inc( PLSPIDef.CONTROL_REGISTER, PLSPIDef.CONTROL_REGISTER_LEN)[0] return rd_data & PLSPIDef.SPI_MODE_BIT def set_mode(self, mode): ''' Set the spi bus clock polarity and phase mode Args: mode: string, ['MODE0', 'MODE1', 'MODE2', 'MODE3'], set mode. +---------+---------+----------+ | Mode | CPOL | CPHA | +=========+=========+==========+ | 0 | 0 | 0 | +---------+---------+----------+ | 1 | 0 | 1 | +---------+---------+----------+ | 2 | 1 | 0 | +---------+---------+----------+ | 3 | 1 | 1 | +---------+---------+----------+ Examples: # set polarity to 0, phase to 0. spi.set_mode("MODE0") ''' assert mode in PLSPIDef.SPI_MODES rd_data = self._axi4_bus.read_8bit_inc(PLSPIDef.CONFIG_REGISTER, PLSPIDef.CONFIG_REGISTER_LEN)[0] # 'rd_data & PLSPIDef.SPI_MODE_MASK' is to clear bit4 and bit5, # '(mode & 0x03) << 4' is write bit4 and bit 5 rd_data = (rd_data & PLSPIDef.SPI_MODE_MASK) | ( (PLSPIDef.SPI_MODES[mode] & 0x03) << 4) self._axi4_bus.write_8bit_inc(PLSPIDef.CONFIG_REGISTER, [rd_data]) def get_mode(self): ''' Get the spi bus clock polarity and phase mode Returns: string, ['MODE0', 'MODE1', 'MODE2', 'MODE3'], 'MODE0': CPOL=0, CPHA=0 'MODE1': CPOL=0, CPHA=1 'MODE2': CPOL=1, CPHA=0 'MODE3': CPOL=1, CPHA=1 Examples: axi4_bus = AXI4LiteBus('/dev/MIX_QSPI_SG', 8192) spi = PLSPIBus(axi4_bus) ret = spi.get_mode() # ret == "MODE0" ''' rd_data = self._axi4_bus.read_8bit_inc(PLSPIDef.CONFIG_REGISTER, PLSPIDef.CONFIG_REGISTER_LEN)[0] # get bit4 and bit 5 config_data = (rd_data & ~PLSPIDef.SPI_MODE_MASK) >> 4 for (key, value) in PLSPIDef.SPI_MODES.viewitems(): if value == config_data: return key def get_base_clock(self): ''' Get the ipcore base clock frequency Returns: int, value, unit kHz. Examples: axi4_bus = AXI4LiteBus('/dev/MIX_QSPI_SG', 8192) spi = PLSPIBus(axi4_bus) ret = spi.get_base_clock() # ret == 125000 ''' base_clk = self._axi4_bus.read_8bit_inc( PLSPIDef.BASE_CLOCK_FREQ_REGISTER, PLSPIDef.CLK_REGISTER_LEN) return self.__data_deal.list_2_int(base_clk) def set_speed(self, speed): ''' Set the spi bus clock speed Args: speed: int, [2~20000000], unit Hz, 1000000 means 1000000Hz. Examples: # set clock speed to 10MHz spi.set_speed(10000000) ''' assert (speed >= PLSPIDef.MIN_SPEED) assert (speed <= PLSPIDef.MAX_SPEED) # get bace clocek frequency base_clk_freq = self.get_base_clock() # SPI_CLK_DIV = BASE_CLK_FREQ / (SPI_CLK_FREQ * 2) - 2 freq_div = int(((base_clk_freq * PLSPIDef.KHZ) / (speed * 2)) - 2) if freq_div < 0: freq_div = 0 wr_data = self.__data_deal.int_2_list(freq_div, PLSPIDef.INT_TO_LIST_LEN_2) self._axi4_bus.write_8bit_inc(PLSPIDef.FREQ_REGISTER, wr_data) self._spi_speed = speed def get_speed(self): ''' Get the spi bus clock speed Returns: int, value, unit Hz. Examples: axi4_bus = AXI4LiteBus('/dev/MIX_QSPI_SG', 8192) spi = PLSPIBus(axi4_bus) ret = spi.get_speed() # ret == 10000000 ''' speed = self._axi4_bus.read_16bit_inc(PLSPIDef.FREQ_REGISTER, PLSPIDef.FREQ_REGISTER_LEN)[0] # get bace clocek frequency base_clk_freq = self.get_base_clock() # SPI_CLK_FREQ = BASE_CLK_FREQ / (SPEED + 2) * 2 return (base_clk_freq * PLSPIDef.KHZ) / ((speed + 2) * 2) def set_cs(self, cs_mode): ''' Set the chip select signal level Args: cs_mode: int, [0, 1], 0: CS_LOW, 1: CS_HIGH. Examples: axi4_bus = AXI4LiteBus('/dev/MIX_QSPI_SG', 8192) spi = PLSPIBus(axi4_bus) # set the chip select signal to low level. spi.set_cs(PLSPIDef.CS_LOW) ''' assert cs_mode in [PLSPIDef.CS_LOW, PLSPIDef.CS_HIGH] self._axi4_bus.write_8bit_inc(PLSPIDef.CS_REGISTER, [cs_mode]) def read(self, rd_len): ''' Read data from spi bus. This function will control the chip select signal Args: rd_len: int, (>0), Length of read data. Returns: list, [value], Data to be read, the list element is an integer, bit width: 8 bits. Examples: axi4_bus = AXI4LiteBus('/dev/MIX_QSPI_SG', 8192) spi = PLSPIBus(axi4_bus) spi.read(100) ''' assert isinstance(rd_len, int) assert rd_len > 0 self.set_cs(PLSPIDef.CS_LOW) rd_data = self._only_read(rd_len) self.set_cs(PLSPIDef.CS_HIGH) return rd_data def write(self, wr_data): ''' Write data to spi bus. This function will control the chip select signal Args: wr_data: list, Data to write, the list element is an integer, bit width: 8 bits. Examples: axi4_bus = AXI4LiteBus('/dev/MIX_QSPI_SG', 8192) spi = PLSPIBus(axi4_bus) spi.set_mode("MODE0") spi.write([0x01, 0x02, 0x03, 0x04, 0x05, 0x06]) ''' assert isinstance(wr_data, list) self.set_cs(PLSPIDef.CS_LOW) self._only_write(wr_data) self.set_cs(PLSPIDef.CS_HIGH) def sync_transfer(self, wr_data): ''' This function only supports standard spi mode Write data to the spi bus. At the same time, the same length of data is read Args: wr_data: list, Data to write, the list element is an integer, bit width: 8 bits. Returns: list, [value], Data to be read, the list element is an integer, bit width: 8 bits. Examples: axi4_bus = AXI4LiteBus('/dev/MIX_QSPI_SG', 8192) spi = PLSPIBus(axi4_bus) spi.set_mode("MODE0") spi.set_work_mode("SPI") to_send = [0x01, 0x03, 0x04, 0x06] ret = spi.sync_transfer(to_send) # len(ret) == len(to_send) ''' assert isinstance(wr_data, list) offset = 0 read_data = [] rd_len = len(wr_data) self.set_cs(PLSPIDef.CS_LOW) rd_data = self._axi4_bus.read_8bit_inc( PLSPIDef.CONTROL_REGISTER, PLSPIDef.CONTROL_REGISTER_LEN)[0] rd_data |= PLSPIDef.READ_WRITE_ENABLE self._axi4_bus.write_8bit_inc(PLSPIDef.CONTROL_REGISTER, [rd_data]) while (rd_len > 0): if rd_len >= PLSPIDef.MAX_FIFO_LEN: byte_len = PLSPIDef.MAX_FIFO_LEN rd_len -= PLSPIDef.MAX_FIFO_LEN else: byte_len = rd_len rd_len = 0 data = wr_data[offset:(offset + PLSPIDef.MAX_FIFO_LEN)] self._write_fifo(data) read_data += self._read_fifo(byte_len) offset += byte_len self._clear_fifo() self.set_cs(PLSPIDef.CS_HIGH) return read_data def async_transfer(self, wr_data, rd_len): ''' This function supports SPI and QPI mode First write data to the spi bus, then read data from the spi bus Args: wr_data: list, Data to write, the list element is an integer, bit width: 8 bits. rd_len: int, Length of read data. Returns: list, [value], Data to be read, the list element is an integer, bit width: 8 bits. Examples: axi4_bus = AXI4LiteBus('/dev/MIX_QSPI_SG', 8192) spi = PLSPIBus(axi4_bus) spi.set_mode("MODE0") spi.set_work_mode("QPI") ret = spi.async_transfer([0x01,0x02,0x03,0x04], 3) # len(ret) == 3 ''' assert isinstance(wr_data, list) assert rd_len > 0 self.set_cs(PLSPIDef.CS_LOW) # write operation self._only_write(wr_data) # read operation read_data = self._only_read(rd_len) self.set_cs(PLSPIDef.CS_HIGH) return read_data def transfer(self, wr_data, rd_len, sync=True): ''' This is the same as sync_transfer when sync is True, and the same as async_transfer when sync is False Args: wr_data: list, Data to write, the list element is an integer, bit width: 8 bits. rd_len: int, Length of read data. sync: boolean, [True, False], True for write and read synchronizily, False for write then read from spi bus. Returns: list, [value], Data to be read, the list element is an integer, bit width: 8 bits. Examples: axi4_bus = AXI4LiteBus('/dev/MIX_QSPI_SG', 8192) spi = PLSPIBus(axi4_bus) spi.set_mode("MODE0") spi.set_work_mode("QPI") # write [0x01,0x02,0x03] data to spi bus,then read 4 bytes from spi bus. ret = spi.transfer([0x01,0x02,0x03], 4, False) # len(ret) == 4 ''' assert isinstance(wr_data, list) assert rd_len > 0 assert sync in [True, False] if sync is True: return self.sync_transfer(wr_data) else: return self.async_transfer(wr_data, rd_len)
class MIXQIASKLinkEncodeSG(object): ''' MIX_QI_ASKLink_Encode_SG Driver Mainly used for wireless charging protocol QI, generating Ask signal (square wave). ClassType = ASKEncode Args: xi4_bus: instance(AXI4LiteBus)/None, axi4_lite_bus instance. Examples: ask_encode = MIXQIASKLinkCode('/dev/MIX_QI_ASKLink_Encode_SG') # Set Ask signal frequency ask_encode.set_frequency(2000) # Send Ask signal wr_data = [1,2,3] ask_encode.write_encode_data(wr_data) ''' rpc_public_api = ['get_base_clock', 'set_frequency', 'write_encode_data'] def __init__(self, axi4_bus=None): if isinstance(axi4_bus, basestring): self.axi4_bus = AXI4LiteBus(axi4_bus, MIXQIASKLinkEncodeSGDef.REG_SIZE) else: self.axi4_bus = axi4_bus self.__data_deal = DataOperate() self._enable() def __del__(self): self._disable() def _wait_for_ready(self): ''' Waiting for ipcore status to be ready or timeout. Returns: boolean, [True, False], True is ready,Fasle is timeout. ''' ret = 0 start = time.time() while (time.time() < (start + MIXQIASKLinkEncodeSGDef.DEFAULT_TIMEOUT)): ret = self.axi4_bus.read_8bit_inc( MIXQIASKLinkEncodeSGDef.STATE_REGISTER, MIXQIASKLinkEncodeSGDef.STATE_READY)[0] if ret == MIXQIASKLinkEncodeSGDef.STATE_READY: return True time.sleep(MIXQIASKLinkEncodeSGDef.DELAY_S) return False def _enable(self): ''' MIXQIASKLinkEncodeSG IP enable function. ''' reg_data = self.axi4_bus.read_8bit_inc( MIXQIASKLinkEncodeSGDef.MODULE_EN_REGISTER, 1)[0] reg_data &= ~MIXQIASKLinkEncodeSGDef.MODULE_ENABLE self.axi4_bus.write_8bit_inc( MIXQIASKLinkEncodeSGDef.MODULE_EN_REGISTER, [reg_data]) reg_data |= MIXQIASKLinkEncodeSGDef.MODULE_ENABLE self.axi4_bus.write_8bit_inc( MIXQIASKLinkEncodeSGDef.MODULE_EN_REGISTER, [reg_data]) def _disable(self): ''' MIXQIASKLinkEncodeSG IP disable function. ''' reg_data = self.axi4_bus.read_8bit_inc( MIXQIASKLinkEncodeSGDef.MODULE_EN_REGISTER, 1)[0] reg_data &= ~MIXQIASKLinkEncodeSGDef.MODULE_ENABLE self.axi4_bus.write_8bit_inc( MIXQIASKLinkEncodeSGDef.MODULE_EN_REGISTER, [reg_data]) def get_base_clock(self): ''' Get the ipcore base clock frequency. Returns: int, value, unit Hz. ''' base_clk = self.axi4_bus.read_8bit_inc( MIXQIASKLinkEncodeSGDef.BASE_CLOCK_FREQ_REGISTER, MIXQIASKLinkEncodeSGDef.CLK_REGISTER_LEN) return self.__data_deal.list_2_int(base_clk) * 1000 def set_frequency(self, freq): ''' Set the Ask signal frequency. Args: freq: int, [100~100000], unit Hz, 2000 means 2000Hz. ''' assert isinstance(freq, int) assert MIXQIASKLinkEncodeSGDef.MIN_FREQ <= freq <= MIXQIASKLinkEncodeSGDef.MAX_FREQ # get bace clocek frequency base_clk_freq = self.get_base_clock() # FREQ_DIV = BASE_CLK_FREQ / (FREQ * 2) - 2 freq_div = int((base_clk_freq / (freq * 2)) - 2) if freq_div < 0: freq_div = 0 wr_data = self.__data_deal.int_2_list( freq_div, MIXQIASKLinkEncodeSGDef.INT_TO_LIST_LEN_3) self.axi4_bus.write_8bit_inc(MIXQIASKLinkEncodeSGDef.FREQ_REGISTER, wr_data) def write_encode_data(self, wr_data): ''' Write Ask encoded signal data (square wave) to FIFO. Args: wr_data: list, Data to write, the list item is byte. Raises: MIXQIASKLinkEncodeSGException: Waiting for the ipcore state timeout. ''' assert isinstance(wr_data, list) and len(wr_data) > 0 # Write data to fifo self.axi4_bus.write_8bit_fix( MIXQIASKLinkEncodeSGDef.DATA_FIFO_REGISTER, wr_data) # Start Transmt self.axi4_bus.write_8bit_inc( MIXQIASKLinkEncodeSGDef.TRANSMIT_START_REGISTER, [MIXQIASKLinkEncodeSGDef.TRANSMIT_ENABLE]) if not self._wait_for_ready(): raise MIXQIASKLinkEncodeSGException("timeout")