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()
Exemple #7
0
 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()
Exemple #8
0
    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
Exemple #9
0
    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
Exemple #10
0
    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
Exemple #15
0
    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)
Exemple #20
0
    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
Exemple #21
0
    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)
Exemple #24
0
    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])
Exemple #25
0
    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 ... ")
Exemple #26
0
    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"
Exemple #27
0
    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 ... ")
Exemple #28
0
    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 ... ")
Exemple #29
0
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)
Exemple #30
0
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")