class Axi4SignalPattern(object): def __init__(self, name): self.name = name self.reg_num = 256 self.__axi4_clk_frequency = 125000000 self.__axi4lite = Axi4lite(self.name, self.reg_num) if self.__axi4lite.open() is False: logger.error('open %s device register number %d fail' % (self.name, self.reg_num)) self.__data_deal = DataOperate() self.__data_width = 4 def disable(self): """disable function""" self.__axi4lite.write(0x10, [0x00], 1) return None def enable(self): """enable function""" self.__axi4lite.write(0x10, [0x00], 1) self.__axi4lite.write(0x10, [0x01], 1) return None def config_calibration(self, gain, offset): """ config calibration Args: gain(float): 0~1.9999, Linear calibration gain parameter, offset(float): -0.9999~0.9999, the ratio of the output range Linear calibration offset parameter Returns: None """ wr_data = self.__data_deal.int_2_list(int(gain * pow(2, 17)), 3) self.__axi4lite.write(0x20, wr_data, len(wr_data)) wr_data = self.__data_deal.int_2_list(int(-offset * pow(2, 17)), 3) self.__axi4lite.write(0x24, wr_data, len(wr_data)) return None def pattern_output_enable(self, pattern_len, delay_time, timeout=10000): """ pattern signal output enable Args: pattern_len(int): pattern data length delay_time(int): 0~500us, After the signal is triggered, the delay time of the output pattern signal. Returns: None """ self.enable() wr_data = self.__data_deal.int_2_list(int(pattern_len), 4) self.__axi4lite.write(0x30, wr_data, len(wr_data)) wr_data = self.__data_deal.int_2_list(int(delay_time * 1000 / 8), 2) self.__axi4lite.write(0x34, wr_data, len(wr_data)) # detect start and wait triggered self.__axi4lite.write(0x11, [0x01], 1) return None def pattern_output_state(self, timeout=10000): """ query pattern signal output state Args: timeout(int): ms, Timeout waiting for the trigger signal. Returns: True | False """ # query state timeout_cnt = 0 rd_data = self.__axi4lite.read(0x13, 1) while (rd_data[0] != 0x01) and (timeout_cnt < (timeout + 1000)): time.sleep(0.001) rd_data = self.__axi4lite.read(0x13, 1) timeout_cnt = timeout_cnt + 1 # read pattern count # time.sleep(0.100) # rd_data = self.__axi4lite.read(0x30,4) # print("pattern len:", rd_data) # rd_data = self.__axi4lite.read(0x3C,4) # print("pattern cnt:", rd_data) # if(rd_data != [0, 80, 8, 0]): # exit(0) if (timeout_cnt == (timeout + 1000)): logger.error('@%s: Measure time out' % (self.name)) return False return True
class Axi4SignalSource(object): def __init__(self,name): self.name = name self.reg_num = 1024 self.__axi4lite=Axi4lite(self.name,self.reg_num) if self.__axi4lite.open() is False: logger.error('open %s device register number %d fail'%(self.name, self.reg_num)) self.__data_deal = DataOperate() self.__step_index = 0 def enable(self): """enable function""" rd_data = self.__axi4lite.read(0x10,1) wr_data = (rd_data[0] & 0xFE) | 0x00 self.__axi4lite.write(0x10, [wr_data],1) wr_data = (rd_data[0] & 0xFE) | 0x01 self.__axi4lite.write(0x10, [wr_data],1) return None def disable(self): """disable function""" rd_data = self.__axi4lite.read(0x10,1) wr_data = (rd_data[0] & 0xFE) | 0x00 self.__axi4lite.write(0x10, [wr_data],1) return None def signal_type_set(self,signal_type): """ set output signal type Args: signal_type(str): 'sine'--sine wave output 'square' -- square output 'AWG' -- arbitrary waveform output Returns: True | False """ self.__axi4lite.write(0x11, [0x00],1) rd_data = self.__axi4lite.read(0x10,1) if(signal_type == 'sine'): signal_type_flag = 0x10 elif(signal_type == 'square'): signal_type_flag = 0x00 elif(signal_type == 'AWG'): signal_type_flag = 0x40 else: logger.error('@%s: signal type set error'%(self.name)) return False wr_data = (rd_data[0] & 0x0F) | signal_type_flag; self.__axi4lite.write(0x10, [wr_data],1) return True def signal_time_set(self,signal_time): """ set output signal duration Args: signal_time(int): signal output duration, unit is us Returns: True | False """ self.__axi4lite.write(0x11, [0x00],1) wr_data = self.__data_deal.int_2_list(signal_time, 4) self.__axi4lite.write(0x40,wr_data,len(wr_data)) return True def swg_paramter_set(self,sample_rate,signal_frequency,vpp_scale,square_duty,offset_volt = 0): """ set standard waveform(sine or square) parameter Args: sample_rate(int): external DAC sample rate, unit is SPS signal_frequency(int): output signal frequency, unit is Hz vpp_scale(float): full scale ratio, (0.000~0.999) square_duty(float): duty of square, (0.001~0.999) offset_volt(flaot): offset volt,(-0.99999~0.99999) Returns: None """ self.__axi4lite.write(0x11, [0x00],1) freq_ctrl = int(pow(2,32) * signal_frequency / sample_rate) wr_data = self.__data_deal.int_2_list(freq_ctrl, 4) self.__axi4lite.write(0x20,wr_data,len(wr_data)) vpp_ctrl = int((pow(2,16)-1) * vpp_scale) wr_data = self.__data_deal.int_2_list(vpp_ctrl, 2) self.__axi4lite.write(0x24,wr_data,len(wr_data)) duty_ctrl = int((sample_rate/signal_frequency)*square_duty) wr_data = self.__data_deal.int_2_list(duty_ctrl, 4) self.__axi4lite.write(0x28,wr_data,len(wr_data)) offset_volt_hex = int(offset_volt*pow(2,23)) wr_data = self.__data_deal.int_2_list(offset_volt_hex, 3) self.__axi4lite.write(0x2C, wr_data, len(wr_data)) return None def signal_output(self): """signal output enable""" self.__axi4lite.write(0x11, [0x01],1) return None def _awg_step_set(self,sample_rate,start_volt,stop_volt,duration_ms): self.__axi4lite.write(0x11, [0x00],1) sample_cycle = 1000/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 = self.__data_deal.int_2_list(step_duration_temp, 2) wr_data.extend(wr_list) wr_list = self.__data_deal.int_2_list(step_ovlt_hex, 4) wr_data.extend(wr_list) wr_list = self.__data_deal.int_2_list(start_volt_hex, 2) wr_data.extend(wr_list) wr_data.append(self.__step_index) self.__axi4lite.write(0x30, wr_data, len(wr_data)) self.__axi4lite.write(0x39, [0x01], 1) self.__step_index = self.__step_index + 1 return None def awg_parameter_set(self,sample_rate,awg_step): """ set arbitrary waveform parameter Args: sample_rate(int): external DAC sample rate, unit is SPS awg_step(list): arbitrary waveform step, list unit is (start_volt,stop_volt,duration_ms) start_volt(float) -- step start volt (-1 ~ +1) stop_volt(float) -- step stop volt (-1 ~ +1) duration_ms(float) -- durarion time Returns: None """ self.__step_index = 0 for awg_step_temp in awg_step: self._awg_step_set(sample_rate, awg_step_temp[0], awg_step_temp[1], awg_step_temp[2]) self.__axi4lite.write(0x3A, [(self.__step_index - 1)], 1) return None def _test_register(self,test_data): wr_data = self.__data_deal.int_2_list(test_data,4) self.__axi4lite.write(0x00,wr_data,len(wr_data)) rd_data = self.__axi4lite.read(0x00,len(wr_data)) test_out = self.__data_deal.list_2_int(rd_data) if(test_out != test_data): logger.error('@%s: Test Register read data error. '%(self.name)) return False return None
class Axi4SwdCore(): def __init__(self, name): self.name = name self.reg_num = 8192 self.__axi4lite = Axi4lite(self.name, self.reg_num) if self.__axi4lite.open() is False: logger.error('open %s device register number %d fail' % (self.name, self.reg_num)) self.__data_deal = DataOperate() def enable(self): """Enable this FPGA function""" rd_data = self.__axi4lite.read(0x10, 1) rd_data[0] = rd_data[0] | 0x01 self.__axi4lite.write(0x10, rd_data, 1) return None def disable(self): """Disable this FPGA function""" rd_data = self.__axi4lite.read(0x10, 1) rd_data[0] = rd_data[0] & 0xFE self.__axi4lite.write(0x10, rd_data, 1) return None def swd_freq_set(self, freq_data): """ Set swd clk freq parameter Args: freq_data(int): swd bus clock frequency, unit is Hz Returns: None """ # read base clk freq: KHz rd_data = self.__axi4lite.read(0x01, 3) base_clk_freq = self.__data_deal.list_2_int(rd_data) # set swd freq swd_freq_div = int(((base_clk_freq * 1000) / (freq_data * 2)) - 2) if (swd_freq_div < 0): swd_freq_div = 0 wr_data = self.__data_deal.int_2_list(swd_freq_div, 2) self.__axi4lite.write(0x04, wr_data, len(wr_data)) return None def swd_rst_pin_ctrl(self, level): """ swd debug rst ctrl Args: level(string): 'L'--Low level,'H'--High level Returns: None """ # 0x12--bit7: rst_pin_level_ctrl, 0--high level; 1--low level rd_data = self.__axi4lite.read(0x12, 1) if level == 'H': rd_data[0] = rd_data[0] & 0x7F else: rd_data[0] = rd_data[0] | 0x80 self.__axi4lite.write(0x12, rd_data, 1) return None def swd_switch_timing_gen(self, timing_data): """ swd_switch_timing_gen Args: timing_data(list): timing_data, bit order: first_byte_bit0-->bit7,second_byte_bit0-->bit7,...,last_byte_bit0-->bit7 Returns: False | True """ # 0x30--wr switch timing data self.__axi4lite.write_array(0x30, timing_data, len(timing_data), 8) # 0x12--bit0 = 1 : start switch timing output rd_data = self.__axi4lite.read(0x12, 1) rd_data[0] = rd_data[0] | 0x01 self.__axi4lite.write(0x12, rd_data, 1) # query state timeout_cnt = 0 rd_data = self.__axi4lite.read(0x14, 1) while (rd_data[0] == 0x00) and timeout_cnt < 100: time.sleep(0.001) rd_data = self.__axi4lite.read(0x14, 1) timeout_cnt = timeout_cnt + 1 if (timeout_cnt == 100): logger.error('swd switch timing wait time out\n') return False return True def swd_wr_operate(self, swd_req_data, swd_wr_data): """ swd_wr_operate Args: swd_req_data(byte): swd_req_data swd_wr_data(list): swd_wr_data Returns: False | SWD RETURN ACK DATA(byte) """ # wr req data self.__axi4lite.write(0x23, [swd_req_data], 1) # wr wr_data self.__axi4lite.write(0x24, swd_wr_data, 4) # start swd wr operate self.__axi4lite.write(0x11, [0x01], 1) # query state timeout_cnt = 0 rd_data = self.__axi4lite.read(0x14, 1) while (rd_data[0] == 0x00) and timeout_cnt < 100: time.sleep(0.001) rd_data = self.__axi4lite.read(0x14, 1) timeout_cnt = timeout_cnt + 1 if (timeout_cnt == 100): logger.error('swd wr operate wait time out\n') return False # return ACK data(addr: 0x2C): rd_data = self.__axi4lite.read(0x2C, 1) return rd_data[0] def swd_rd_operate(self, swd_req_data): """ swd_rd_operate Args: swd_req_data(byte): swd_req_data Returns: False | swd_rd_data(list): Format, five bytes in total, the first four bytes are swd rd data, the last byte is ack data in bit0~bit2, and bit7 is swd rd data parity bit. """ # rd req data self.__axi4lite.write(0x23, [swd_req_data], 1) # start swd rd operate self.__axi4lite.write(0x11, [0x01], 1) # query state timeout_cnt = 0 rd_data = self.__axi4lite.read(0x14, 1) while (rd_data[0] == 0x00) and timeout_cnt < 100: time.sleep(0.001) rd_data = self.__axi4lite.read(0x14, 1) timeout_cnt = timeout_cnt + 1 if (timeout_cnt == 100): logger.error('swd rd operate wait time out\n') return False # return rd_data(addr: 0x28~0x2B) + ACK data(addr: 0x2C, [2:0]--ack data, [7]--swd rd data parity bit) swd_rd_data = self.__axi4lite.read(0x28, 5) return swd_rd_data
class Axi4SpiProgCore(): def __init__(self, name): self.name = name self.reg_num = 8192 self.__axi4lite = Axi4lite(self.name, self.reg_num) if self.__axi4lite.open() is False: logger.error('open %s device register number %d fail' % (self.name, self.reg_num)) self.__data_deal = DataOperate() def enable(self): """Enable this FPGA function""" rd_data = self.__axi4lite.read(0x10, 1) rd_data[0] = rd_data[0] | 0x01 self.__axi4lite.write(0x10, rd_data, 1) return None def disable(self): """Disable this FPGA function""" rd_data = self.__axi4lite.read(0x10, 1) rd_data[0] = rd_data[0] & 0xFE self.__axi4lite.write(0x10, rd_data, 1) return None def spi_module_config(self, spi_clk_mode, spi_clk_freq): """ jtag tck freq set Args: spi_clk_mode(int): 0~3 ==> SPI MODE 0~3 spi_clk_freq(int): 2000~62500000 Hz Returns: None """ # spi_mode_reg addr: 0x10--bit4 CPHA;0x10--bit5 CPOL; # Mode 0: CPOL=0,CPHA=0; Mode 1: CPOL=0,CPHA=1;Mode 2: CPOL=1,CPHA=0; Mode 3: CPOL=1,CPHA=1 # spi_clk_freq_reg addr: 0x20~0x21 # set spi clk mode reg rd_data = self.__axi4lite.read(0x10, 1) rd_data[0] = (rd_data[0] & 0xCF) | ((spi_clk_mode & 0x03) << 4) self.__axi4lite.write(0x10, rd_data, 1) # set spi clk freq reg rd_data = self.__axi4lite.read(0x01, 3) base_clk_freq = self.__data_deal.list_2_int(rd_data) freq_div = int(((base_clk_freq * 1000) / (spi_clk_freq * 2)) - 2) if (freq_div < 0): freq_div = 0 wr_data = self.__data_deal.int_2_list(freq_div, 2) self.__axi4lite.write(0x20, wr_data, 2) return None def spi_normal_fifo_clr(self): """ spi_normal_fifo_clr, clear spi normal fifo data. Args: None Returns: None """ # fifo clr addr: 0x12--bit0 self.__axi4lite.write(0x12, [0x01], 1) return None def spi_dma_fifo_clr(self): """ spi_dma_fifo_clr, Reserved function, Don't use it temporarily. Args: None Returns: None """ # fifo clr addr: 0x12--bit1 self.__axi4lite.write(0x12, [0x02], 1) return None def spi_cs_ctrl(self, cs_ch, level): """ spi_cs_ctrl Args: cs_ch(int): 0~7 -- cs channel level(string): 'L' or 'H' ~~ 'L'--low level,'H'~high level Returns: None """ # cs reg addr: 0x13,bit0~bit7 ==> cs0~cs7 rd_data = self.__axi4lite.read(0x13, 1) if level == 'L': rd_data[0] = rd_data[0] & (~(0x01 << cs_ch)) else: rd_data[0] = rd_data[0] | (0x01 << cs_ch) self.__axi4lite.write(0x13, rd_data, 1) read_data = self.__axi4lite.read(0x13, 1) print("CS_CFG_DATA:", read_data) return None def spi_extend_io_ctrl(self, ext_io_ch, level): """ spi_extend_io_ctrl Args: ext_io_ch(int): 0~7 -- ext_io channel level(string): 'L' or 'H' ~~ 'L'--low level,'H'~high level Returns: None """ # extend_io reg addr: 0x15,bit0~bit7 ==> ext_io0~ext_io7 rd_data = self.__axi4lite.read(0x15, 1) if level == 'L': rd_data[0] = rd_data[0] & (~(0x01 << ext_io_ch)) else: rd_data[0] = rd_data[0] | (0x01 << ext_io_ch) self.__axi4lite.write(0x15, rd_data, 1) return None def spi_arbitrary_n_clk(self, clk_cycle_num): """ spi_arbitrary_n_clk Args: clk_cycle_num(int): 1~8 level(string): 'L' or 'H' ~~ 'L'--low level,'H'~high level Returns: None """ # n clk & spi operate mode addr: 0x16 # [0]--arbitrary_n_clk enable bit, [3:1]--clk_cycle_num rd_data = self.__axi4lite.read(0x16, 1) rd_data[0] = (rd_data[0] & 0xF0) | (0x01 | ((clk_cycle_num - 1) << 1)) self.__axi4lite.write(0x16, rd_data, 1) return None def spi_normal_write(self, wr_data): """ spi_normal_write Args: wr_data(list): spi write data list(byte), len 1~2048 Returns: True | False """ # wr data addr: 0x80 # spi_ctrl addr: 0x16_bit4--spi operate mode sel, 0--normal operate mdoe,1--dma operate mode # spi_ctrl addr: 0x16_bit5--varify mode en bit, 0--enable,1--disable # config to spi normal operate mode self.__axi4lite.write(0x16, [0x00], 1) # wr data to normal wr_fifo # self.__axi4lite.write_byte_array(0x80, wr_data, len(wr_data), 8) self.__axi4lite.write_array(0x80, wr_data, len(wr_data), 8) # spi tran start self.__axi4lite.write(0x11, [0x01], 1) # query state timeout_cnt = 0 rd_data = self.__axi4lite.read(0x14, 1) while (rd_data[0] == 0x00) and timeout_cnt < 100000: rd_data = self.__axi4lite.read(0x14, 1) timeout_cnt = timeout_cnt + 1 if (timeout_cnt == 100000): return False # spi fifo clr self.spi_normal_fifo_clr() return True def spi_normal_read(self, read_len): """ spi_normal_read Args: read_len(int): 1~2048 Returns: spi_read_data(list): spi read data list(byte), len 1~2048 """ # rd data addr:0x80 # spi_ctrl addr: 0x16_bit4--spi operate mode sel, 0--normal operate mdoe,1--dma operate mode # spi_ctrl addr: 0x16_bit5--varify mode en bit, 0--enable,1--disable # config to spi normal operate mode self.__axi4lite.write(0x16, [0x00], 1) # wr data to normal wr_fifo, invalid data wr_data = [] for i in range(read_len): wr_data.append(0xAA) # wr_data.append([0xAA]) # self.__axi4lite.write_byte_array(0x80, wr_data, read_len, 8) self.__axi4lite.write_array(0x80, wr_data, read_len, 8) # spi tran start self.__axi4lite.write(0x11, [0x01], 1) # query state timeout_cnt = 0 rd_data = self.__axi4lite.read(0x14, 1) while (rd_data[0] == 0x00) and timeout_cnt < 100000: rd_data = self.__axi4lite.read(0x14, 1) timeout_cnt = timeout_cnt + 1 if (timeout_cnt == 100000): return False # spi rd data ==> rd data addr:0x80 # spi_read_data = self.__axi4lite.read_byte_array(0x80, read_len, 8) spi_read_data = self.__axi4lite.read_array(0x80, read_len, 8) return spi_read_data def spi_normal_write_read(self, wr_data): """ spi_normal_write_read Args: wr_data(list): spi write data list(byte), len 1~2048 Returns: spi_read_data(list): spi read data list(byte), len 1~2048 """ # rd data addr:0x80 # spi_ctrl addr: 0x16_bit4--spi operate mode sel, 0--normal operate mdoe,1--dma operate mode # spi_ctrl addr: 0x16_bit5--varify mode en bit, 0--enable,1--disable # config to spi normal operate mode self.__axi4lite.write(0x16, [0x00], 1) # wr data to normal wr_fifo # self.__axi4lite.write_byte_array(0x80, wr_data, len(wr_data), 8) self.__axi4lite.write_array(0x80, wr_data, len(wr_data), 8) # spi tran start self.__axi4lite.write(0x11, [0x01], 1) # query state timeout_cnt = 0 rd_data = self.__axi4lite.read(0x14, 1) while (rd_data[0] == 0x00) and timeout_cnt < 100000: rd_data = self.__axi4lite.read(0x14, 1) timeout_cnt = timeout_cnt + 1 if (timeout_cnt == 100000): return False # spi rd data ==> rd data addr:0x80 # spi_read_data = self.__axi4lite.read_byte_array(0x80, len(wr_data), 8) spi_read_data = self.__axi4lite.read_array(0x80, len(wr_data), 8) return spi_read_data def spi_dma_write(self, write_len): """ spi_dma_write,Reserved function, Don't use it temporarily. Args: write_len(int): 1~256 Returns: True | False """ # write_len: 1~256 # operate len addr: 0x24 # spi_ctrl addr: 0x16_bit4--spi operate mode sel, 0--normal operate mdoe,1--dma operate mode # spi_ctrl addr: 0x16_bit5--varify mode en bit, 0--enable,1--disable # config to spi dma operate mode self.__axi4lite.write(0x16, [0x10], 1) # config dma mode operate len self.__axi4lite.write(0x24, [(write_len - 1)], 1) # spi tran start self.__axi4lite.write(0x11, [0x01], 1) # query state timeout_cnt = 0 rd_data = self.__axi4lite.read(0x14, 1) while (rd_data[0] == 0x00) and timeout_cnt < 100000: rd_data = self.__axi4lite.read(0x14, 1) timeout_cnt = timeout_cnt + 1 if (timeout_cnt == 100000): return False return True def spi_dma_varify(self, varify_len): """ spi_dma_write,Reserved function, Don't use it temporarily. Args: varify_len(int): 1~256 Returns: True | False """ # operate len addr: 0x24 # spi_ctrl addr: 0x16_bit4--spi operate mode sel, 0--normal operate mdoe,1--dma operate mode # spi_ctrl addr: 0x16_bit5--varify mode en bit, 0--enable,1--disable # config to spi dma operate mode and enable varify mode self.__axi4lite.write(0x16, [0x30], 1) # config dma mode operate len self.__axi4lite.write(0x24, [varify_len - 1], 1) # spi tran start self.__axi4lite.write(0x11, [0x01], 1) # query state timeout_cnt = 0 rd_data = self.__axi4lite.read(0x14, 1) while (rd_data[0] == 0x00) and timeout_cnt < 100000: rd_data = self.__axi4lite.read(0x14, 1) timeout_cnt = timeout_cnt + 1 if (timeout_cnt == 100000): return False if ((rd_data[0] & 0x02) == 0x02): return False return True
class Axi4SignalMeter(object): def __init__(self, name): self.name = name self.reg_num = 1024 self.__axi4lite = Axi4lite(self.name, self.reg_num) if self.__axi4lite.open() is False: logger.error('open %s device register number %d fail' % (self.name, self.reg_num)) self.__data_deal = DataOperate() self.__measure_state = 0 self.__sample_rate = 125000000 def enable(self): """ Enable function """ rd_data = self.__axi4lite.read(0x10, 1) wr_data = (rd_data[0] & 0xFE) | 0x00 self.__axi4lite.write(0x10, [wr_data], 1) wr_data = (rd_data[0] & 0xFE) | 0x01 self.__axi4lite.write(0x10, [wr_data], 1) return None def disable(self): """ Disable function """ rd_data = self.__axi4lite.read(0x10, 1) wr_data = (rd_data[0] & 0xFE) | 0x00 self.__axi4lite.write(0x10, [wr_data], 1) return None def amplitude_interval_set(self, test_interval_ms): """ when measuring VPP, test_interval_ms is the measured time period for each measuring Args: test_interval_ms(int): the time of measured time period Returns: None """ wr_data = self.__data_deal.int_2_list(test_interval_ms, 2) self.__axi4lite.write(0x18, wr_data, len(wr_data)) return None def upframe_enable(self, frame_type, frame_channel, sample_rate_khz): """ set the parameter of data frame, and enable frame upload function Args: frame_type(int): the type of frame, 0~255 frame_channel(int): the channel of frame 0~15 sample_rate_khz(int): the sample rate of frame data Returns: None """ wr_data = [frame_type] self.__axi4lite.write(0xF4, wr_data, len(wr_data)) wr_data = self.__data_deal.int_2_list(sample_rate_khz, 3) wr_data.append(frame_channel * 16) self.__axi4lite.write(0xF0, wr_data, len(wr_data)) rd_data = self.__axi4lite.read(0x10, 1) wr_data = (rd_data[0] & 0xFD) | 0x02 self.__axi4lite.write(0x10, [wr_data], 1) return None def upframe_disable(self): """ disable frame upload function Args: None Returns: None """ rd_data = self.__axi4lite.read(0x10, 1) wr_data = (rd_data[0] & 0xFD) | 0x00 self.__axi4lite.write(0x10, [wr_data], 1) return None def measure_start(self, time_ms, sample_rate): """ start measure access Args: time_ms(int): measure time, unit is ms sample_rate(int): data sample rate, unit is SPS Returns: True | False """ self.__sample_rate = sample_rate wr_data = self.__data_deal.int_2_list(time_ms, 2) self.__axi4lite.write(0x11, wr_data, len(wr_data)) self.__axi4lite.write(0x14, [0x00], 1) self.__axi4lite.write(0x13, [0x01], 1) rd_data = self.__axi4lite.read(0x14, 1) timeout = 0 while (rd_data[0] != 0x01) and (timeout < (time_ms + 1000)): time.sleep(0.001) rd_data = self.__axi4lite.read(0x14, 1) timeout = timeout + 1 if (timeout == (time_ms + 1000)): logger.error('@%s: Measure time out' % (self.name)) self.__measure_state = 0 return False self.__measure_state = 1 return True def uploade_start(self, time_ms, sample_rate): wr_data = self.__data_deal.int_2_list(time_ms, 2) self.__axi4lite.write(0x11, wr_data, len(wr_data)) self.__axi4lite.write(0x14, [0x00], 1) self.__axi4lite.write(0x13, [0x01], 1) def frequency_measure(self, measure_type): """ get the frequency of input signal Args: measure_type(str): select the method of frequency measurent 'HP' is high precision measurement, it can be use when FPGA IP enable the frequency measurent function 'LP' is low precision measurement, it can be use when FPGA IP enable the duty measurent function Returns: freq(float): the frequency of input signal, unit is Hz """ if (self.__measure_state == 0): return (0, 'Hz') if (measure_type == 'HP'): freq = self._frequency_hp_measure() elif (measure_type == 'LP'): freq = self._frequency_lp_measure() else: logger.error('@%s: Measure type error' % (self.name)) return False return (freq, 'Hz') def duty_measure(self): """ get the duty of input signal Args: None Returns: duty(float): the duty of input signal, unit is %, 1%~99% """ if (self.__measure_state == 0): rd_data = self.__axi4lite.read(0x10, 1) if (rd_data[0] & 0x04 == 0x04): return (100, '%') else: return (0, '%') rd_data = self.__axi4lite.read(0x50, 8) duty_all = self.__data_deal.list_2_int(rd_data) rd_data = self.__axi4lite.read(0x58, 8) duty_high = self.__data_deal.list_2_int(rd_data) duty = (duty_high / duty_all) * 100 return (duty, '%') def amplitude_measure(self): """ get the amplitude of input signal Args: None Returns: amp_data(float): the normalized average amplitude of input signal, unit is V, 0V~2V max_data(float): the normalized max level of input signal, unit is V,-1V ~ +1V min_data(float): the normalized min level of input signal, unit is V,-1V ~ +1V """ rd_data = self.__axi4lite.read(0x70, 8) amp_max = self.__data_deal.list_2_int(rd_data) rd_data = self.__axi4lite.read(0x78, 8) amp_min = self.__data_deal.list_2_int(rd_data) rd_data = self.__axi4lite.read(0x80, 4) amp_cnt = self.__data_deal.list_2_int(rd_data) max_data = amp_max / (amp_cnt * pow(2, 15)) min_data = amp_min / (amp_cnt * pow(2, 15)) amp_data = max_data - min_data return (amp_data, 'V', max_data, 'V', min_data, 'V') def rms_measure(self): """ get the RMS of input signal Args: None Returns: rms_data(float): the normalized rms of input signal, unit is V, 0V~1V max_data(float): the normalized average level of input signal, unit is V, -1V~+1V """ rd_data = self.__axi4lite.read(0x90, 8) rms_square_sum = self.__data_deal.list_2_int(rd_data) rd_data = self.__axi4lite.read(0x98, 8) rms_sum = self.__data_deal.list_2_int(rd_data) rd_data = self.__axi4lite.read(0xA0, 4) rms_cnt = self.__data_deal.list_2_int(rd_data) rms_data = math.sqrt(rms_square_sum / rms_cnt) / pow(2, 15) avg_data = (rms_sum / rms_cnt) / pow(2, 15) return (rms_data, 'V', avg_data, 'V') def _test_register(self, test_data): wr_data = self.__data_deal.int_2_list(test_data, 4) self.__axi4lite.write(0x00, wr_data, len(wr_data)) rd_data = self.__axi4lite.read(0x00, len(wr_data)) test_out = self.__data_deal.list_2_int(rd_data) if (test_out != test_data): logger.error('@%s: Test Register read data error. ' % (self.name)) return False return None def _frequency_hp_measure(self): rd_data = self.__axi4lite.read(0x15, 2) sys_divide = self.__data_deal.list_2_int(rd_data) if (sys_divide == 0): sys_divide = 1 rd_data = self.__axi4lite.read(0x20, 8) freq_x_sum = self.__data_deal.list_2_int(rd_data) rd_data = self.__axi4lite.read(0x28, 8) freq_y_sum = self.__data_deal.list_2_int(rd_data) rd_data = self.__axi4lite.read(0x30, 8) freq_xy_sum = self.__data_deal.list_2_int(rd_data) rd_data = self.__axi4lite.read(0x38, 8) freq_xx_sum = self.__data_deal.list_2_int(rd_data) rd_data = self.__axi4lite.read(0x40, 4) freq_N = self.__data_deal.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 = sys_divide * self.__sample_rate * k_2 / k_1 return freq def _frequency_lp_measure(self): rd_data = self.__axi4lite.read(0x50, 8) duty_all = self.__data_deal.list_2_int(rd_data) rd_data = self.__axi4lite.read(0x60, 4) duty_N = self.__data_deal.list_2_int(rd_data) freq = duty_N * self.__sample_rate / duty_all return freq
class Axi4Gpio(object): def __init__(self, name): self.name = name self.reg_num = 256 self.__axi4lite = Axi4lite(self.name, self.reg_num) if self.__axi4lite.open() is False: logger.error('open %s device register number %d fail' % (self.name, self.reg_num)) self.__data_deal = DataOperate() def reset(self): """ All gpio reset to 0 """ wr_data = [0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF] reg_addr = 0x10 self.__axi4lite.write(reg_addr, wr_data, len(wr_data)) reg_addr = 0x20 self.__axi4lite.write(reg_addr, wr_data, len(wr_data)) reg_addr = 0x30 self.__axi4lite.write(reg_addr, wr_data, len(wr_data)) reg_addr = 0x40 self.__axi4lite.write(reg_addr, wr_data, len(wr_data)) def gpio_set(self, gpio_out): """ set gpio level Args: gpio_out(list): the unit of list is (gpio_number,gpio_level) gpio_number for 0 to 127 set gpio_level to 1, the gpio output high level set gpio_level to 0, the gpio output low level Returns: NONE """ ch0_data = [] ch1_data = [] ch2_data = [] ch3_data = [] for gpio_out_temp in gpio_out: gpio_out_temp = list(gpio_out_temp) if (gpio_out_temp[0] < 32): ch0_data.append(gpio_out_temp) elif (gpio_out_temp[0] < 64): gpio_out_temp[0] = gpio_out_temp[0] - 32 ch1_data.append(gpio_out_temp) elif (gpio_out_temp[0] < 96): gpio_out_temp[0] = gpio_out_temp[0] - 64 ch2_data.append(gpio_out_temp) else: gpio_out_temp[0] = gpio_out_temp[0] - 96 ch3_data.append(gpio_out_temp) if (len(ch0_data) > 0): self._gpio_output_set('ch0', ch0_data) if (len(ch1_data) > 0): self._gpio_output_set('ch1', ch1_data) if (len(ch2_data) > 0): self._gpio_output_set('ch2', ch2_data) if (len(ch3_data) > 0): self._gpio_output_set('ch3', ch3_data) return None def gpio_ctrl(self, gpio_ctrl): """ set gpio to input or output Args: gpio_ctrl(list): the unit of list is (gpio_number,gpio_ctrl) gpio_number for 0 to 127 set gpio_ctrl to 1, the gpio is set to input set gpio_ctrl to 0, the gpio is set to output Returns: NONE """ ch0_data = [] ch1_data = [] ch2_data = [] ch3_data = [] for gpio_out_temp in gpio_ctrl: gpio_out_temp = list(gpio_out_temp) if (gpio_out_temp[0] < 32): ch0_data.append(gpio_out_temp) elif (gpio_out_temp[0] < 64): gpio_out_temp[0] = gpio_out_temp[0] - 32 ch1_data.append(gpio_out_temp) elif (gpio_out_temp[0] < 96): gpio_out_temp[0] = gpio_out_temp[0] - 64 ch2_data.append(gpio_out_temp) else: gpio_out_temp[0] = gpio_out_temp[0] - 96 ch3_data.append(gpio_out_temp) if (len(ch0_data) > 0): self._gpio_ctrl_set('ch0', ch0_data) if (len(ch1_data) > 0): self._gpio_ctrl_set('ch1', ch1_data) if (len(ch2_data) > 0): self._gpio_ctrl_set('ch2', ch2_data) if (len(ch3_data) > 0): self._gpio_ctrl_set('ch3', ch3_data) return None def gpio_get(self, gpio_input, gpio_type='in'): """ get gpio state Args: gpio_input(list) : the unit of list is (gpio_number,gpio_level) gpio_number for 0 to 127 set gpio_level to 255 gpio_type(str) : select the gpio type 'in' --- select input gpio 'out' --- select output gpio Returns: gpio_input_data(list) : the unit of list is (gpio_number,gpio_level) gpio_number for 0 to 127 when gpio is high level, the gpio_level is 1 when gpio is low level, the gpio_level is 0 """ ch0_data = [] ch1_data = [] ch2_data = [] ch3_data = [] for gpio_out_temp in gpio_input: gpio_out_temp = list(gpio_out_temp) if (gpio_out_temp[0] < 32): ch0_data.append(gpio_out_temp) elif (gpio_out_temp[0] < 64): gpio_out_temp[0] = gpio_out_temp[0] - 32 ch1_data.append(gpio_out_temp) elif (gpio_out_temp[0] < 96): gpio_out_temp[0] = gpio_out_temp[0] - 64 ch2_data.append(gpio_out_temp) else: gpio_out_temp[0] = gpio_out_temp[0] - 96 ch3_data.append(gpio_out_temp) gpio_input_data = [] if (len(ch0_data) > 0): ch0_data_get = self._gpio_input_get('ch0', ch0_data) gpio_input_data.extend(ch0_data_get) if (len(ch1_data) > 0): ch1_data_get = self._gpio_input_get('ch1', ch1_data) gpio_input_data.extend(ch1_data_get) if (len(ch2_data) > 0): ch2_data_get = self._gpio_input_get('ch2', ch2_data) gpio_input_data.extend(ch2_data_get) if (len(ch3_data) > 0): ch3_data_get = self._gpio_input_get('ch3', ch3_data) gpio_input_data.extend(ch3_data_get) return gpio_input_data def _gpio_output_set(self, gpio_channel, gpio_out): if (gpio_channel == 'ch0'): reg_addr = 0x10 elif (gpio_channel == 'ch1'): reg_addr = 0x20 elif (gpio_channel == 'ch2'): reg_addr = 0x30 elif (gpio_channel == 'ch3'): reg_addr = 0x40 else: logger.error('@%s: GPIO Channel set rror' % (self.name)) return False rd_data = self.__axi4lite.read(reg_addr, 4) reg_data_int = self.__data_deal.list_2_int(rd_data) if (reg_data_int < 0): reg_data_int = reg_data_int + pow(2, 32) reg_data_int_shift = reg_data_int for gpio_out_temp in gpio_out: reg_data_int_shift = self.__data_deal.cyclic_shift( 'R', reg_data_int_shift, 32, gpio_out_temp[0]) if (gpio_out_temp[1] == 1): reg_data_int_shift = reg_data_int_shift & 0xFFFFFFFE | 0x00000001 elif (gpio_out_temp[1] == 0): reg_data_int_shift = reg_data_int_shift & 0xFFFFFFFE else: logger.error('@%s: GPIO output set error' % (self.name)) return False reg_data_int_shift = self.__data_deal.cyclic_shift( 'L', reg_data_int_shift, 32, gpio_out_temp[0]) wr_data = self.__data_deal.int_2_list(reg_data_int_shift, 4) self.__axi4lite.write(reg_addr, wr_data, len(wr_data)) def _gpio_ctrl_set(self, gpio_channel, gpio_ctrl): if (gpio_channel == 'ch0'): reg_addr = 0x14 elif (gpio_channel == 'ch1'): reg_addr = 0x24 elif (gpio_channel == 'ch2'): reg_addr = 0x34 elif (gpio_channel == 'ch3'): reg_addr = 0x44 else: logger.error('@%s: GPIO Channel set error' % (self.name)) return False rd_data = self.__axi4lite.read(reg_addr, 4) reg_data_int = self.__data_deal.list_2_int(rd_data) if (reg_data_int < 0): reg_data_int = reg_data_int + pow(2, 32) reg_data_int_shift = reg_data_int for gpio_ctrl_temp in gpio_ctrl: reg_data_int_shift = self.__data_deal.cyclic_shift( 'R', reg_data_int_shift, 32, gpio_ctrl_temp[0]) if (gpio_ctrl_temp[1] == 1): reg_data_int_shift = reg_data_int_shift & 0xFFFFFFFE | 0x00000001 elif (gpio_ctrl_temp[1] == 0): reg_data_int_shift = reg_data_int_shift & 0xFFFFFFFE else: logger.error('@%s: GPIO control set error' % (self.name)) return False reg_data_int_shift = self.__data_deal.cyclic_shift( 'L', reg_data_int_shift, 32, gpio_ctrl_temp[0]) wr_data = self.__data_deal.int_2_list(reg_data_int_shift, 4) self.__axi4lite.write(reg_addr, wr_data, len(wr_data)) def _gpio_input_get(self, gpio_channel, gpio_input, gpio_type='in'): if (gpio_type == 'in'): if (gpio_channel == 'ch0'): reg_addr = 0x18 elif (gpio_channel == 'ch1'): reg_addr = 0x28 elif (gpio_channel == 'ch2'): reg_addr = 0x38 elif (gpio_channel == 'ch3'): reg_addr = 0x48 else: logger.error('@%s: GPIO Channel set error' % (self.name)) return False else: if (gpio_channel == 'ch0'): reg_addr = 0x10 elif (gpio_channel == 'ch1'): reg_addr = 0x20 elif (gpio_channel == 'ch2'): reg_addr = 0x30 elif (gpio_channel == 'ch3'): reg_addr = 0x40 else: logger.error('@%s: GPIO Channel set error' % (self.name)) return False rd_data = self.__axi4lite.read(reg_addr, 4) reg_data_int = self.__data_deal.list_2_int(rd_data) if (reg_data_int < 0): reg_data_int = reg_data_int + pow(2, 32) if (len(gpio_input) > 32): logger.error('@%s: GPIO number set error' % (self.name)) return False for gpio_input_index in range(0, len(gpio_input)): reg_data_int_shift = self.__data_deal.cyclic_shift( 'R', reg_data_int, 32, gpio_input[gpio_input_index][0]) if ((reg_data_int_shift & 0x00000001) == 0x00000001): gpio_input[gpio_input_index] = ( gpio_input[gpio_input_index][0], 1) else: gpio_input[gpio_input_index] = ( gpio_input[gpio_input_index][0], 0) reg_data_int_shift = self.__data_deal.cyclic_shift( 'L', reg_data_int, 32, gpio_input[gpio_input_index][0]) return gpio_input
class Axi4AudioAnalyzer(object): def __init__(self, name): self.name = name self.reg_num = 65536 self.__axi4lite = Axi4lite(self.name, self.reg_num) if self.__axi4lite.open() is False: logger.error('open %s device register number %d fail' % (self.name, self.reg_num)) self.__data_deal = DataOperate() self.__k1_index = 0 self.__k1_data = 0 self.__k2_index = 0 self.__k2_data = 0 self.__decimation_data = 1 self.__base_frequency = 1000 def enable(self): """enable function""" self.disable() rd_data = self.__axi4lite.read(0x10, 1) rd_data[0] = rd_data[0] | 0x01 self.__axi4lite.write(0x10, rd_data, 1) return None def disable(self): """disable function""" rd_data = self.__axi4lite.read(0x10, 1) rd_data[0] = rd_data[0] & 0xFE self.__axi4lite.write(0x10, rd_data, 1) return None def upload_enable(self): """enable data upload function""" rd_data = self.__axi4lite.read(0x10, 1) rd_data[0] = rd_data[0] | 0x02 self.__axi4lite.write(0x10, rd_data, 1) return None def upload_disable(self): """disbale data upload function""" rd_data = self.__axi4lite.read(0x10, 1) rd_data[0] = rd_data[0] & 0xFD self.__axi4lite.write(0x10, rd_data, 1) return None def measure_paramter_set(self, bandwidth_hz, sample_rate, decimation_type, signal_source): """ Set measure paramter Args: bandwidth_hz(int): Bandwidth limit, unit is Hz sample_rate(int): signal sample rate, unit is Hz decimation_type(str): signal decimation type 'auto' -- automatic detection '1'/'2'/........ signal_source(str): 'IIS'/'PDM'/'SPDIF' Returns: False | True """ wr_data = self.__data_deal.int_2_list(int(sample_rate / 1000), 3) self.__axi4lite.write(0xF0, wr_data, len(wr_data)) rd_data = self.__axi4lite.read(0x16, 1) freq_resolution = sample_rate / (8192 * rd_data[0]) bandwidth_index = int(bandwidth_hz / freq_resolution) if (signal_source == 'IIS'): source_data = 0x10 elif (signal_source == 'SPDIF'): source_data = 0x20 elif (signal_source == 'PDM'): source_data = 0x30 else: logger.error('@%s: Signal Source Error' % (self.name)) return False wr_data = self.__data_deal.int_2_list(bandwidth_index, 2) wr_data[1] = (wr_data[1] & 0x0F) | source_data self.__axi4lite.write(0x11, wr_data, len(wr_data)) self._decimation_factor_set(decimation_type) return True def measure_start(self): """ start measure Args: None Returns: False | True """ self.__axi4lite.write(0x14, [0x00], 1) self.__axi4lite.write(0x13, [0x01], 1) rd_data = [0] timeout_cnt = 0 while (rd_data[0] == 0x00) and timeout_cnt < 3000: sleep(0.001) rd_data = self.__axi4lite.read(0x14, 1) timeout_cnt = timeout_cnt + 1 if (timeout_cnt == 3000): logger.error('@%s: wait time out' % (self.name)) return False self._base_index_find() return True def _decimation_factor_set(self, decimation_type): if (decimation_type is 'auto'): decimation_type_data = 0xFF else: decimation_type_data = int(decimation_type) self.__axi4lite.write(0x15, [decimation_type_data], 1) self.__axi4lite.write(0x17, [0x01], 1) rd_data = [0] timeout_cnt = 0 while (rd_data[0] == 0x00) and timeout_cnt < 3000: sleep(0.001) rd_data = self.__axi4lite.read(0x17, 1) timeout_cnt = timeout_cnt + 1 if (timeout_cnt == 3000): logger.error('@%s: wait time out' % (self.name)) return False rd_data = self.__axi4lite.read(0x16, 1) self.__decimation_data = rd_data[0] return True def _max_index_find(self): rd_data = self.__axi4lite.read(0x20, 4) max_index = self.__data_deal.list_2_int(rd_data) rd_addr = 32768 + max_index * 8 rd_data = self.__axi4lite.read(rd_addr, 8) max_data = self.__data_deal.list_2_int(rd_data) return (max_index, max_data) def _base_index_find(self): (max_index, max_data) = self._max_index_find() max_left_index = max_index - 1 max_right_index = max_index + 1 rd_addr = 32768 + max_left_index * 8 rd_data = self.__axi4lite.read(rd_addr, 8) max_left_data = self.__data_deal.list_2_int(rd_data) rd_addr = 32768 + max_right_index * 8 rd_data = self.__axi4lite.read(rd_addr, 8) max_right_data = self.__data_deal.list_2_int(rd_data) if (max_left_data > max_right_data): second_index = max_left_index second_data = max_left_data else: second_index = max_right_index second_data = max_right_data if (max_index > second_index): self.__k1_index = second_index self.__k1_data = second_data self.__k2_index = max_index self.__k2_data = max_data else: self.__k2_index = second_index self.__k2_data = second_data self.__k1_index = max_index self.__k1_data = max_data return None def _get_fft_data(self, data_cnt): fft_data = [] for i in range(0, data_cnt): rd_addr = 32768 + i * 8 rd_data = self.__axi4lite.read(rd_addr, 8) rd_data_int = self.__data_deal.list_2_int(rd_data) fft_data.append(rd_data_int) return fft_data def _test_register(self, test_data): wr_data = self.__data_deal.int_2_list(test_data, 4) self.__axi4lite.write(0x00, wr_data, len(wr_data)) rd_data = self.__axi4lite.read(0x00, len(wr_data)) test_out = self.__data_deal.list_2_int(rd_data) if (test_out != test_data): logger.error('@%s: Test Register read data error. ' % (self.name)) return False return None
class Axi4AskEncode(): def __init__(self, name): self.name = name self.reg_num = 8192 self.__axi4lite = Axi4lite(self.name, self.reg_num) if self.__axi4lite.open() is False: logger.error('open %s device register number %d fail' % (self.name, self.reg_num)) self.__data_deal = DataOperate() def enable(self): """Enable this FPGA function""" self.__axi4lite.write(0x10, [0x01], 1) return None def disable(self): """Disable this FPGA function""" self.__axi4lite.write(0x10, [0x00], 1) return None def set_ask_data_frequency(self, ask_data_freq): """ set_ask_date_frequency Args: ask_data_freq(int): ask data frequency,100~100000Hz Returns: None """ rd_data = self.__axi4lite.read(0x04, 4) base_freq = self.__data_deal.list_2_int(rd_data) data_freq_cnt = int(base_freq / ask_data_freq / 2) - 2 wr_data = self.__data_deal.int_2_list(data_freq_cnt, 3) self.__axi4lite.write(0x14, wr_data, len(wr_data)) return None def send_ask_decode_data(self, ask_send_data): """ send_ask_decode_data, include checksum data Args: ask_send_data(list): ask send data Returns: True | False """ # 0x12-[0]: ask_encode_start 1 -- valid # 0x13-[0]: ask_encode_state 0--busy,1--ready # 0x20: ask_fifo_wr & ask_fifo_wdata # 0x21~0x22: ask_wr_data_len ask_data_len = len(ask_send_data) if (ask_data_len == 0): return False # send ask data to ask data_fifo self.__axi4lite.write_array(0x20, ask_send_data, ask_data_len, 8) # ask encode start self.__axi4lite.write(0x12, [0x01], 1) # query state timeout_cnt = 0 rd_data = self.__axi4lite.read(0x13, 1) while (rd_data[0] == 0x00) and timeout_cnt < 1000: time.sleep(0.01) rd_data = self.__axi4lite.read(0x13, 1) timeout_cnt = timeout_cnt + 1 if (timeout_cnt == 1000): return False return True
class Axi4AidSlave(): def __init__(self,name): self.name = name self.reg_num = 8192 self.__axi4lite=Axi4lite(self.name,self.reg_num) if self.__axi4lite.open() is False: logger.error('open %s device register number %d fail'%(self.name, self.reg_num)) self.__data_deal = DataOperate() def enable(self): """Enable this FPGA function""" self.__axi4lite.write(0x10,[0x01],1) return None def disable(self): """Disable this FPGA function""" self.__axi4lite.write(0x10,[0x00],1) return None def cfg_aid_data(self,aid_index,aid_req_data,aid_req_data_mask,aid_resp_data): """ cfg aid slave module aid command data, include request and response command data. Args: aid_index(int): 0~63, up to 64 AID commands are supported, this parameter is the index number, and just a number, aid_req_data(list): use for match aid master req commamd(include CRC data), len 1~27 aid_req_data_mask(int): aid master req commamd byte data mask, used to indicate the bytes that need to be detected. bit0--byte0,bit1--byte1,...bit_n--byte_n; 0--ineffectual,1--effective aid_resp_data(list): use for resp aid master aid command(except CRC data), len 1~31 Returns: None """ # 0x20: aid_req_ram_wr # 0x21~0x22: aid_req_ram_addr # 0x23: wr--aid_req_ram_wdata & rd--aid_req_ram_rdata # 0x24~0x27: aid_rece_timeout_cnt # 0x30: aid_resp_ram_wr # 0x31~0x32: aid_resp_ram_addr # 0x33: wr--aid_resp_ram_wdata & rd--aid_resp_ram_rdata # aid_buff_num=64, aid_buff_len_max=32, aid_buff_content = 1_byte_len + 31_byte_aid_data; first byte is len info aid_req_len = len(aid_req_data) aid_resp_len = len(aid_resp_data)-1 req_data_mask_data = self.__data_deal.int_2_list(aid_req_data_mask, 4) # cfg aid req len aid_req_addr = aid_index * 32; wr_data = self.__data_deal.int_2_list(aid_req_addr, 2) self.__axi4lite.write(0x21, wr_data, len(wr_data)) wr_data = self.__data_deal.int_2_list(aid_req_len, 1) self.__axi4lite.write(0x23, [wr_data[0]], 1) self.__axi4lite.write(0x20, [0x01], 1) # cfg aid req mask for i in range(0, 4): aid_req_addr = aid_req_addr + 1 wr_data = self.__data_deal.int_2_list(aid_req_addr, 2) self.__axi4lite.write(0x21, wr_data, len(wr_data)) wr_data[0] = req_data_mask_data[i] self.__axi4lite.write(0x23, [wr_data[0]], 1) self.__axi4lite.write(0x20, [0x01], 1) # cfg aid req data for i in range(0, aid_req_len): aid_req_addr = aid_req_addr + 1 wr_data = self.__data_deal.int_2_list(aid_req_addr, 2) self.__axi4lite.write(0x21, wr_data, len(wr_data)) wr_data[0] = aid_req_data[i] self.__axi4lite.write(0x23, [wr_data[0]], 1) self.__axi4lite.write(0x20, [0x01], 1) # rece aid req cfg data from req ram # rece_aid_req_data = [] # aid_req_addr = aid_index * 32; # for i in range(0, aid_req_len+1): # wr_data = self.__data_deal.int_2_list(aid_req_addr, 2) # self.__axi4lite.write(0x21, wr_data, len(wr_data)) # rd_data = self.__axi4lite.read(0x23,1) # rece_aid_req_data = rece_aid_req_data + rd_data; # aid_req_addr = aid_req_addr + 1 # print('AID_REQ_RAM_INDEX:', aid_index, 'AID_REQ_RAM_DATA:', aid_req_data, 'AID_REQ_RAM_DATA_LEN:', len(aid_req_data)) # print('AID_REQ_RAM_INDEX:', aid_index, 'RECE_AID_REQ_RAM_DATA:', rece_aid_req_data) # cfg aid resp len aid_resp_addr = aid_index * 32; wr_data = self.__data_deal.int_2_list(aid_resp_addr, 2) self.__axi4lite.write(0x31, wr_data, len(wr_data)) wr_data = self.__data_deal.int_2_list(aid_resp_len, 1) self.__axi4lite.write(0x33, [wr_data[0]], 1) self.__axi4lite.write(0x30, [0x01], 1) # cfg aid resp data for i in range(0, aid_resp_len): aid_resp_addr = aid_resp_addr + 1 wr_data = self.__data_deal.int_2_list(aid_resp_addr, 2) self.__axi4lite.write(0x31, wr_data, len(wr_data)) wr_data[0] = aid_resp_data[i] self.__axi4lite.write(0x33, [wr_data[0]], 1) self.__axi4lite.write(0x30, [0x01], 1) # rece aid resp cfg data from resp ram # rece_aid_resp_data = [] # aid_resp_addr = aid_index * 32; # for i in range(0, aid_resp_len+1): # wr_data = self.__data_deal.int_2_list(aid_resp_addr, 2) # self.__axi4lite.write(0x31, wr_data, len(wr_data)) # rd_data = self.__axi4lite.read(0x33,1) # rece_aid_resp_data = rece_aid_resp_data + rd_data # aid_resp_addr = aid_resp_addr + 1 # print('AID_RESP_RAM_INDEX:', aid_index, 'AID_RESP_RAM_DATA:', aid_resp_data, 'AID_RESP_RAM_DATA_LEN:', len(aid_resp_data)) # print('AID_RESP_RAM_INDEX:', aid_index, 'RECE_AID_RESP_RAM_DATA:', rece_aid_resp_data) return None def aid_slave_init(self): """ init aid slave module request and response command data, last byte is CRC Args: None Returns: None """ aid_req_dict = { 0:[0x74,0x00,0x02,0x1F]}; # 1:[0x74,0x00,0x01,0xFD], # 2:[0xE0,0x04,0x01,0x00,0x00,0xEE,0x01,0x01,0xC4], # 3:[0xE0,0x04,0x01,0x00,0x00,0x02,0x06,0x04,0xF1,0x00,0x00,0x00,0x00,0x42], # 4:[0x70,0x00,0x00,0x3D], # 5:[0x74,0x00,0x02,0x1F], # 6:[0x76,0x10]}; aid_resp_dict = { 0:[0x75,0x20,0x0A,0x00,0x00,0x00,0x00,0x17]}; # 1:[0x75,0x04,0xF1,0x00,0x00,0x00,0x00,0xAB], # 2:[0xE1,0xAA,0xE1], # 3:[0xE1,0x55,0xD4], # 4:[0x71,0x93], # 5:[0x75,0x20,0x0A,0x00,0x00,0x00,0x00,0x17], # Tristar MUX configured to debug ports (USB+UART0) # 5:[0x75,0xE0,0x00,0x00,0x00,0x00,0x00,0x35], # pad reboot cmd # 5:[0x75,0xE0,0x08,0x00,0x00,0x00,0x00,0x0B], # Tristar reset - we’ve done this and verified # 5:[0x75,0xA0,0x08,0x00,0x00,0x00,0x00,0x7E], # Tristar MUX configured to SWD DFU + debug ports (SWD + USB + UART0) # 6:[0x77,0x02,0x01,0x02,0x80,0x60,0x00,0xE0,0x87,0x75,0x6B,0x37]}; for i in range(0,1): # print(i,aid_req_dict[i],aid_resp_dict[i]) self.cfg_aid_data(i,aid_req_dict[i],0x00000003,aid_resp_dict[i]) return None
class Axi4HdmiRreceiver(object): def __init__(self, name): self.name = name self.reg_num = 256 self.__axi4_clk_frequency = 125000000 self.__axi4lite = Axi4lite(self.name, self.reg_num) if self.__axi4lite.open() is False: logger.error('open %s device register number %d fail' % (self.name, self.reg_num)) self.__data_deal = DataOperate() self.__data_width = 4 def disable(self): """disable function""" self.__axi4lite.write(0x10, [0x00], 1) return None def enable(self): """enable function""" self.__axi4lite.write(0x10, [0x00], 1) self.__axi4lite.write(0x10, [0x01], 1) return None def initialize(self): """ initialize the edid of hdmi receiver ddc. Args: None Returns: None """ self.disable() # config ddc port paramer------------------------------------------ # bit_rate_hz = 100000 bit_clk_count = self.__axi4_clk_frequency / 100000 bit_clk_delay = int(bit_clk_count / 4) # byte_ctrl = address_bytes * 16 +data_bytes byte_ctrl = 1 * 16 + 1 self.__data_width = 1 # slave_address = 0x50 wr_data = [0x50, byte_ctrl] bit_clk_delay_temp = self.__data_deal.int_2_list(bit_clk_delay, 2) wr_data.extend(bit_clk_delay_temp) self.__axi4lite.write(0x30, wr_data, len(wr_data)) # config edid data------------------------------------------------ edid_720p_data = [ 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x10, 0xEC, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x1A, 0x01, 0x03, 0xA1, 0x33, 0x1D, 0x78, 0x0A, 0xEC, 0x18, 0xA3, 0x54, 0x46, 0x98, 0x25, 0x0F, 0x48, 0x4C, 0x21, 0x08, 0x00, 0xB3, 0x00, 0xD1, 0xC0, 0x81, 0x80, 0x81, 0xC0, 0xA9, 0xC0, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x1D, 0x00, 0x72, 0x51, 0xD0, 0x1E, 0x20, 0x6E, 0x28, 0x55, 0x00, 0x00, 0xD0, 0x52, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0xFC, 0x20, 0x44, 0x69, 0x67, 0x69, 0x6C, 0x65, 0x6E, 0x74, 0x44, 0x56, 0x49, 0x2D, 0x32, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEE ] self._register_write(0, edid_720p_data) self.enable() return None def _register_read(self, address, read_length): read_data = [] for i in range(0, read_length): wr_data = self.__data_deal.int_2_list(address, 2) self.__axi4lite.write(0x38, wr_data, len(wr_data)) rd_data = self.__axi4lite.read(0x3C, 4) read_data_temp = self.__data_deal.list_2_int(rd_data) if (read_data_temp < 0): read_data_temp = read_data_temp + pow(2, 32) read_data_temp = read_data_temp >> 8 * (4 - self.__data_width) read_data.append(read_data_temp) address = address + 1 return read_data def _register_write(self, address, write_data): for i in range(0, len(write_data)): write_data_temp = write_data[i] << 8 * (4 - self.__data_width) wr_data = self.__data_deal.int_2_list(write_data_temp, 4) self.__axi4lite.write(0x34, wr_data, len(wr_data)) wr_data = self.__data_deal.int_2_list(address, 2) self.__axi4lite.write(0x38, wr_data, len(wr_data)) self.__axi4lite.write(0x3A, [0x01], 1) address = address + 1 return None def _axi4_clk_frequency_set(self, clk_frequency): self.__axi4_clk_frequency = clk_frequency
class Axi4Ad717x(object): def __init__(self, name): self.name = name self.reg_num = 8192 self.__axi4lite = Axi4lite(self.name, self.reg_num) if self.__axi4lite.open() is False: logger.error('open %s device register number %d fail' % (self.name, self.reg_num)) self.__data_deal = DataOperate() def enable(self): """Enable this FPGA function""" self.__axi4lite.write(0x10, [0x01], 1) def disable(self): """Disable this FPGA function""" self.__axi4lite.write(0x10, [0x00], 1) def register_read(self, reg_addr): """ Read value from ADC chip register Args: reg_addr: ADC chip register address(0x00-0xff) Returns: register value: (0x00-0xffffffff) """ rd_data = self.__axi4lite.read(0x26, 1) if (rd_data[0] & 0x01 == 0x00): logger.warning('AD717X Bus is busy now') return False com_data = (0x3F & reg_addr) | 0x40 wr_data = [com_data, 0x01] self.__axi4lite.write(0x24, wr_data, len(wr_data)) rd_data = [0x00] timeout_cnt = 0 while (rd_data[0] & 0x01 == 0x00) and (timeout_cnt < 1000): time.sleep(0.001) timeout_cnt = timeout_cnt + 1 rd_data = self.__axi4lite.read(0x26, 1) if (timeout_cnt == 1000): logger.warning('AD717X read register wait timeout') return False rd_data = self.__axi4lite.read(0x28, 4) rd_data = rd_data[0] | (rd_data[1] << 8) | (rd_data[2] << 16) |\ (rd_data[3] << 24) return rd_data def register_write(self, reg_addr, reg_data): """ Write value to ADC chip register Args: reg_addr: ADC chip reg (0x00-0xff) reg_data: register value(0x00-0xffffffff) Returns: True | False """ rd_data = self.__axi4lite.read(0x26, 1) if (rd_data[0] & 0x01 == 0x00): logger.warning('AD717X Bus is busy now') return False wr_data = self.__data_deal.int_2_list(reg_data, 4) com_data = (0x3F & reg_addr) wr_data.append(com_data) wr_data.append(0x01) self.__axi4lite.write(0x20, wr_data, len(wr_data)) rd_data = [0x00] timeout_cnt = 0 while (rd_data[0] & 0x01 == 0x00) and (timeout_cnt < 1000): time.sleep(0.001) rd_data = self.__axi4lite.read(0x26, 1) timeout_cnt = timeout_cnt + 1 if (timeout_cnt == 1000): logger.warning('AD717X write register wait finish timeout') return False return True def single_sample_code_get(self): """ ADC chip single sample Returns: (channel,sample_code) """ rd_data = self.register_read(0x01) wr_data = rd_data & 0xFF0F | 0x0000 self.register_write(0x01, wr_data) rd_data = self.register_read(0x01) if ((rd_data & 0x00F0) != 0): logger.warning("AXI4 AD717X 0x01 ==%s" % (hex(rd_data))) return False wr_data = rd_data & 0xFF0F | 0x0010 self.register_write(0x01, wr_data) reg_data = self.register_read(0x04) rd_data = self.__axi4lite.read(0x26, 1) if (rd_data[0] & 0x08 == 0x08): sample_channel = (reg_data & 0x0000000F) sample_data = (reg_data & (0xFFFFFF00)) >> 8 else: sample_channel = 'Null' sample_data = reg_data & (0x00FFFFFF) #logger.info('channel: ',sample_channel,'rd_data: 0x%08x 0x%06x'%(reg_data,sample_data)) return (sample_channel, sample_data) def code_2_mvolt(self, code, mvref, bits): """ Adc sample code conversion to mVolt Args: code: sample code mvref:(value,unit) bits: ADC sample bits AD7175: 24 or 16 bits AD7177: 32 or 24 bits Returns: volt: (value,uinit) """ volt = code volt -= 0x800000 bits = bits - 1 volt /= 1 << bits volt *= mvref[0] return (volt, mvref[1]) def continue_sample_mode(self): """ ADC chip work in continue sample mode,cpu can not control the bus Returns: True | False """ rd_data = self.register_read(0x01) wr_data = rd_data & 0xFF0F | 0x0000 self.register_write(0x01, wr_data) rd_data = self.register_read(0x02) reg_data = rd_data & 0xFF7F | 0x0080 rd_data = self.__axi4lite.read(0x26, 1) if (rd_data[0] & 0x01 == 0x00): logger.warning('Error: AD717X Bus is busy now') return False wr_data = self.__data_deal.int_2_list(reg_data, 4) com_data = (0x3F & 0x02) wr_data.append(com_data) wr_data.append(0x01) self.__axi4lite.write(0x20, wr_data, len(wr_data)) return True def single_sample_mode(self): """ ADC chip exit continue sample mode,cpu can control the bus """ wr_data = [0x44, 0x01] state = self.__axi4lite.write(0x24, wr_data, len(wr_data)) return state def reset(self): """ Reset ADC chip """ wr_data = [0xFF, 0x01] state = self.__axi4lite.write(0x24, wr_data, len(wr_data)) return state def frame_channel_and_samplerate_set(self, channel_no, samplerate): """ Frame channel number and sample rate set. Only used in continue sample wor mode Args: channel_no: channel number samplerate: ADC sample rate """ wr_data = [0, 0, 0, 0] wr_data[0] = samplerate % 256 wr_data[1] = (samplerate >> 8) % 256 wr_data[2] = (samplerate >> 16) % 256 wr_data[3] = channel_no * 16 state = self.__axi4lite.write(0xF0, wr_data, len(wr_data)) return state def data_analysis(self, data_count): """ Adc sample data analysis Args: data_count(int): sample data count Returns: get_data(list): sample data list """ rd_data = self.__axi4lite.read(0x26, 1) if ((rd_data[0] & 0x04) != 0x04): logger.warning('AD717X is not in continuous sample mode') return False wr_data = self.__data_deal.int_2_list(data_count, 2) self.__axi4lite.write(0x61, wr_data, len(wr_data)) self.__axi4lite.write(0x60, [0x01], 1) rd_data = [0x00] while (rd_data[0] & 0x01 == 0x00): time.sleep(0.001) rd_data = self.__axi4lite.read(0x63, 1) get_data = [] for i in range(0, data_count): #rw_addr = i + 0x1000; rw_addr = i * 4 + 0x1000 rd_data = self.__axi4lite.read(rw_addr, 4) #rd_int = self.__data_deal.list_2_int(rd_data) rd_int = rd_data[0] | (rd_data[1] << 8) | (rd_data[2] << 16) |\ (rd_data[3] << 24) #rd_int = rd_int - 0x8000 get_data.append(rd_int) return get_data def _test_register(self, test_data): wr_data = self.__data_deal.int_2_list(test_data, 4) self.__axi4lite.write(0x00, wr_data, len(wr_data)) rd_data = self.__axi4lite.read(0x00, len(wr_data)) test_out = self.__data_deal.list_2_int(rd_data) if (test_out != test_data): logger.error('Register test failure') return False return True
class Axi4Uart(object): def __init__(self,name): self.name = name self.reg_num = 256 self.__axi4lite=Axi4lite(self.name,self.reg_num) self.__axi4_clk_frequency = 125000000 if self.__axi4lite.open() is False: logger.error('open %s device register number %d fail'%(self.name, self.reg_num)) self.__data_deal = DataOperate() rd_data = self.__axi4lite.read(0x0C,2) self._tx_cache = self.__data_deal.list_2_int(rd_data) def enable(self): """ Enable function """ self.__axi4lite.write(0x10, [0x00], 1) self.__axi4lite.write(0x10, [0x01], 1) return None def disable(self): """ Disable function """ self.__axi4lite.write(0x10, [0x00], 1) return None def config(self,baud_rate=115200,data_bits=8,parity_type='NONE',stop_bits=1, time_insert='NONE'): """ Set uart bus parameter Args: baud_rate(int) : UART baud rate data_bits(int) : Data width 5/6/7/8 parity_type(str) : parity type. "ODD"/"EVNE"/"NONE" stop_bits(float) : stop bit width. 1/1.5/2 time_insert(str) : Insert timestamp Control, "TS"/"NONE" Returns: None """ logger.info("%s set baud_rate: %s ; data_bits: %s; stop_bits : %s ;parity: %s; time_insert: %s;"\ %(self.name, baud_rate, data_bits,stop_bits,parity_type,time_insert)) baud_rate_temp = int(pow(2,32)*baud_rate/self.__axi4_clk_frequency) wr_data = self.__data_deal.int_2_list(baud_rate_temp, 4) self.__axi4lite.write(0x20, wr_data, len(wr_data)) if(parity_type == 'ODD'): parity_data = 0x01 elif(parity_type == 'EVNE'): parity_data = 0x00 else: parity_data = 0x02 if(stop_bits == 1): stop_bits_data = 0x04 elif(stop_bits == 1.5): stop_bits_data = 0x08 else: stop_bits_data = 0x0C data_bits_data = (data_bits-1)<<4 wr_data_temp = parity_data | stop_bits_data | data_bits_data self.__axi4lite.write(0x24, [wr_data_temp], 1) if(time_insert == "TS"): self.__axi4lite.write(0x25, [0x01], 1) else: self.__axi4lite.write(0x25, [0x00], 1) self.__axi4lite.write(0x26, [0x11], 1) return None def write(self,wr_data,block='non-block'): """ uart write access Args: write_data(bytes): uart send bytearray Returns: NONE """ i = len(wr_data) wr_data_index = 0 while(i > 0): rd_data = self.__axi4lite.read(0x35,2) cache_deep = self.__data_deal.list_2_int(rd_data) if(cache_deep > i): send_cnt = i else: send_cnt = cache_deep -3 self.__axi4lite.write_byte_array(0x34, wr_data[wr_data_index:wr_data_index+send_cnt], send_cnt, 8) wr_data_index += send_cnt i -= send_cnt if block is 'block': i = 0 while( i < self._tx_cache): rd_data = self.__axi4lite.read(0x35,2) cache_deep = self.__data_deal.list_2_int(rd_data) sleep(10) return None def read(self): """ uart read access Args: NONE Returns: receive_str(bytes): uart receive bytearray """ rd_data = self.__axi4lite.read(0x31, 2) cache_deep = self.__data_deal.list_2_int(rd_data) if cache_deep != 0: rd_data = self.__axi4lite.read_byte_array(0x30, cache_deep, 8) return rd_data else: return None
class Axi4Ad760x(): def __init__(self, name): self.name = name self.reg_num = 8192 self.__axi4lite = Axi4lite(self.name, self.reg_num) if self.__axi4lite.open() is False: logger.error('open %s device register number %d fail' % (self.name, self.reg_num)) self.__data_deal = DataOperate() def enable(self): """Enable this FPGA function""" self.__axi4lite.write(0x10, [0x01], 1) return None def disable(self): """Disable this FPGA function""" self.__axi4lite.write(0x10, [0x00], 1) return None def ad760x_reset(self): """ad760x reset function""" rd_data = self.__axi4lite.read(0x10, 1) rd_data[0] = rd_data[0] | 0x80 self.__axi4lite.write(0x11, rd_data, 1) time.sleep(0.001) rd_data[0] = rd_data[0] & 0x7F self.__axi4lite.write(0x11, rd_data, 1) return None def ad760x_single_sample(self, os, v_range): """ ad760x single sample Args: os(int): Oversampling set(0~7) v_range(string): adc reference voltage set('5V' or '10V') Returns: voltages(list): [ch0_volt,ch1_volt,...,ch7_volt], unit is V """ # ctrl reg cfg # 0x10 [0]--module_en;[4]--continuous_sample_en # 0x11 [2:0]--os;[3]--v_range;[7]--rst_pin_ctrl rd_data = self.__axi4lite.read(0x10, 2) self.__axi4lite.write(0x10, [0x00], 1) rd_data[0] = 0x01 if (v_range == '10V'): rd_data[1] = (rd_data[1] & 0xF0) | ((1 << 3) | os) else: rd_data[1] = (rd_data[1] & 0xF0) | os self.__axi4lite.write(0x10, rd_data, 2) # start sample self.__axi4lite.write(0x12, [0x01], 1) # query state timeout_cnt = 0 rd_data = self.__axi4lite.read(0x13, 1) while (rd_data[0] == 0x00) and timeout_cnt < 100: time.sleep(0.00001) rd_data = self.__axi4lite.read(0x13, 1) timeout_cnt = timeout_cnt + 1 if (timeout_cnt == 100): logger.error('ad760x sample timeout') return False #ch0:0x20-0x23;ch1:0x24-0x27;ch2:0x28-0x2B;ch3:0x2C-0x2Fch4:0x30-0x33;ch5:0x34-0x37;ch6:0x38-0x3B;ch7:0x3C-0x3F voltages = [] volt_reg_addr = 0x20 for i in range(8): rd_data = self.__axi4lite.read(volt_reg_addr, 4) volt_temp = self.__data_deal.list_2_int(rd_data) if (v_range == '10V'): volt_temp = volt_temp / pow(2, 32) * 20 else: volt_temp = volt_temp / pow(2, 32) * 10 volt_reg_addr = volt_reg_addr + 0x04 voltages.append(volt_temp) return voltages def ad760x_continuous_sample(self, os, v_range, sample_rate): """ ad760x_continuous_sample enable, and it must invoking the "disable" function to stop the ad760x_continuous_sample. When this function enable, the "ad760x_single_sample" function can't used. os & sample_rate limit description: os == 0: sample_rate 2000~200000Hz os == 1: sample_rate 2000~100000Hz os == 2: sample_rate 2000~50000Hz os == 3: sample_rate 2000~25000Hz os == 4: sample_rate 2000~12500Hz os == 5: sample_rate 2000~6250Hz os == 6: sample_rate 2000~3125Hz os == 7: invalid, out of commission Args: os(int): Oversampling set(0~7) v_range(string): adc reference voltage set('5V' or '10V') sample_rate(int): sample_rate set, 2000~200000Hz Returns: None """ # ctrl reg cfg # 0x10 [0]--module_en;[4]--continuous_sample_en # 0x11 [2:0]--os;[3]--v_range;[7]--rst_pin_ctrl # 0x14~0x15 [15:0] -- sample_rate rd_data = self.__axi4lite.read(0x10, 2) self.__axi4lite.write(0x10, [0x00], 1) rd_data[0] = 0x11 if (v_range == '10V'): rd_data[1] = (rd_data[1] & 0xF0) | ((1 << 3) | os) else: rd_data[1] = (rd_data[1] & 0xF0) | os self.__axi4lite.write(0x10, rd_data, 2) # cfg sample rate wr_data = self.__data_deal.int_2_list( int((125000000 / sample_rate) - 2), 2) self.__axi4lite.write(0x14, wr_data, 2) # start sample self.__axi4lite.write(0x12, [0x01], 1) # Until use disable function to stop continuous sample mode. return None
class Axi4JtagCore(): def __init__(self, name): self.name = name self.reg_num = 8192 self.__axi4lite = Axi4lite(self.name, self.reg_num) if self.__axi4lite.open() is False: logger.error('open %s device register number %d fail' % (self.name, self.reg_num)) self.__data_deal = DataOperate() def enable(self): """Enable this FPGA function""" self.__axi4lite.write(0x10, [0x01], 1) return None def disable(self): """Disable this FPGA function""" self.__axi4lite.write(0x10, [0x00], 1) return None def jtag_freq_set(self, freq_data): """ jtag tck freq set Args: freq_data(int): jtag tck freq set,Hz(1000~25000000) Returns: None """ rd_data = self.__axi4lite.read(0x01, 3) base_clk_freq = self.__data_deal.list_2_int(rd_data) # set jtag freq jtag_freq_div = int(((base_clk_freq * 1000) / (freq_data * 2)) - 2) if (jtag_freq_div < 0): jtag_freq_div = 0 wr_data = self.__data_deal.int_2_list(jtag_freq_div, 2) self.__axi4lite.write(0x04, wr_data, len(wr_data)) return None def jtag_rst_pin_ctrl(self, level): """ jtag rst pin ctrl Args: level(string): 'H'--high level,'L'--low level Returns: None """ rd_data = self.__axi4lite.read(0x13, 1) if level == 'H': rd_data[0] = rd_data[0] & 0x7F else: rd_data[0] = rd_data[0] | 0x80 self.__axi4lite.write(0x13, rd_data, 1) return None def jtag_logic_rst(self): """ jtag_logic_rst, the JTAG state machine reset logic. Args: None Returns: None """ rd_data = self.__axi4lite.read(0x13, 1) rd_data[0] = rd_data[0] | 0x01 self.__axi4lite.write(0x13, rd_data, 1) rd_data[0] = rd_data[0] & 0xFE self.__axi4lite.write(0x13, rd_data, 1) return None def jtag_tran_operate(self, ir_bit_len, ir_data, dr_bit_len, dr_data): """ jtag tran operate, shift IR&DR Args: ir_bit_len(int): 0~32, when ir_bit_len is 0, no ir operation. ir_data(list): ir shift data, at most 4 byte data. Shift starts at first byte bit0. dr_bit_len(int): 0~16384, when dr_bit_len is 0, no dr operation. dr_data(list): dr shift data, at most 2048 bytes. Shift starts at first byte bit0. Returns: dr_shift_in_data(list): dr_bit_len valid bits, start first byte bit0. """ # ir_len(0x20~0x21),dr_len(0x22~0x23) ir_bit_len_list = self.__data_deal.int_2_list(ir_bit_len, 2) dr_bit_len_list = self.__data_deal.int_2_list(dr_bit_len, 2) self.__axi4lite.write(0x20, ir_bit_len_list + dr_bit_len_list, 4) # ir_data(0x24~0x27) if (ir_bit_len != 0): self.__axi4lite.write(0x24, ir_data, len(ir_data)) # start jtag tran operate self.__axi4lite.write(0x11, [0x01], 1) # dr_data(0x28~0x2B) dr_data_len = len(dr_data) wr_data_len = 0 wr_data = [] if (dr_bit_len != 0): if ((dr_data_len % 4) != 0): wr_data = ((4 - (dr_data_len % 4)) * [0x00]) wr_data = dr_data + wr_data wr_data_len = len(wr_data) self.__axi4lite.write_array(0x28, wr_data, wr_data_len, 32) # query state timeout_cnt = 0 rd_data = self.__axi4lite.read(0x14, 1) while (rd_data[0] == 0x00) and timeout_cnt < 10000: time.sleep(0.001) rd_data = self.__axi4lite.read(0x14, 1) timeout_cnt = timeout_cnt + 1 if (timeout_cnt == 10000): logger.error('jtag tran operate wait time out') return False # rd dr data(0x28~0x2B) # wr_dr_dcnt(0x2C~0x2D),rd_dr_dcnt(0x2E~0x2F) dr_shift_in_data = [] if (dr_bit_len != 0): dr_shift_in_data = self.__axi4lite.read_array( 0x28, wr_data_len, 32) return dr_shift_in_data[0:dr_data_len]
class Axi4Spi(object): def __init__(self,name): self.name = name self.reg_num = 256 self.__axi4lite=Axi4lite(self.name,self.reg_num) if self.__axi4lite.open() is False: logger.error('open %s device register number %d fail'%(self.name, self.reg_num)) self.__axi4_clk_frequency = 125000000 self.__data_deal = DataOperate() self.__cache_size = 0 def enable(self): """ Enable function """ rd_data = self.__axi4lite.read(0x10, 1) wr_data_temp = rd_data[0] & 0xF0 self.__axi4lite.write(0x10, [wr_data_temp], 1) wr_data_temp = rd_data[0] & 0xF0 | 0x01 self.__axi4lite.write(0x10, [wr_data_temp], 1) return None def disable(self): """ Disable function """ rd_data = self.__axi4lite.read(0x10, 1) wr_data_temp = rd_data[0] & 0xF0 self.__axi4lite.write(0x10, [wr_data_temp], 1) return None def config(self,spi_clk_frequency = 500000,spi_clk_type = 'neg',wait_time_us = 1,spi_clk_polarity = 'high',cache_size=64): """ Set spi bus parameter Args: spi_clk_frequency(int): spi bus clock frequency, unit is Hz spi_clk_type(str): 'pos' --sclk posedge send data, sclk negedge receive data 'neg' --sclk negedge send data, sclk posedge receive data wait_time_us(float): the wait time for new spi access spi_clk_polarity(str): 'high' --when CS is high, the SCLK is high 'low' --when CS is high, the SCLK is low cache_size(int): data cache depth Returns: None """ rd_data = self.__axi4lite.read(0x10,1); if(spi_clk_type == 'pos'): set_data = rd_data[0] | 0x10 elif(spi_clk_type == 'neg'): set_data = rd_data[0] & 0xEF else: logger.error('@%s: sclk edge select error'%(self.name)) return False if(spi_clk_polarity == 'high'): set_data = set_data | 0x20 elif(spi_clk_polarity == 'low'): set_data = set_data & 0xDF else: logger.error('@%s: sclk polarity select error'%(self.name)) return False self.__axi4lite.write(0x10, [set_data], 1) freq_ctrl = int(spi_clk_frequency * pow(2,32)/self.__axi4_clk_frequency) wr_data = self.__data_deal.int_2_list(freq_ctrl, 4) self.__axi4lite.write(0x14, wr_data, len(wr_data)) wait_cnt = int(wait_time_us * self.__axi4_clk_frequency/1000000) wr_data = self.__data_deal.int_2_list(wait_cnt, 3) self.__axi4lite.write(0x11, wr_data, len(wr_data)) self.__cache_size = cache_size return None def write(self,write_data,cs_extend = 0): """ SPI write access Args: write_data(list): write data list cs_extend(float): The extend CS low when SPI access over, cs_extend is 0 to 8, min resolution is 0.5 Returns: False | True """ send_cache_depth = self.__axi4lite.read(0x28,1) last_append = (int(cs_extend)*16 + 5) if(cs_extend > int(cs_extend)): last_append = last_append + 8 if(self.__cache_size < (send_cache_depth[0] + len(write_data))): logger.error('@%s: send cache not enough') return False write_data_temp = [] for i in range(0,len(write_data)): write_data_temp.append(write_data[i]) if(i == (len(write_data)-1)): write_data_temp.append(last_append) else: write_data_temp.append(0x04) self.__axi4lite.write_array(0x20, write_data_temp, len(write_data_temp), 16) return True def read(self,read_length,cs_extend = 0): """ SPI read access Args: read_length(int): number of read data cs_extend(float): The extend CS low when SPI access over, cs_extend is 0 to 8, min resolution is 0.5 Returns: receive_data(list): read data list if error ,return False """ send_cache_depth = self.__axi4lite.read(0x28,1) last_append = (int(cs_extend)*16 + 3) if(cs_extend > int(cs_extend)): last_append = last_append + 8 if(send_cache_depth[0] + read_length > self.__cache_size): logger.error('@%s: send cache not enough'%(self.name)) return False recieve_cache_depth = self.__axi4lite.read(0x29,1) if(recieve_cache_depth[0] > 0): logger.error('@%s: receive cache not empty'%(self.name)) receive_data_temp = self.__axi4lite.read_array(0x24, 2*recieve_cache_depth[0], 16) return False tx_data_temp = [] for i in range(0,read_length): tx_data_temp.append(0x00) if(i == (read_length-1)): tx_data_temp.append(last_append) else: tx_data_temp.append(0x02) self.__axi4lite.write_array(0x20, tx_data_temp, len(tx_data_temp), 16) time_out = 0 while time_out < 3000 : recieve_cache_depth = self.__axi4lite.read(0x29,1) if(recieve_cache_depth[0] < read_length): time.sleep(0.001) time_out = time_out + 1 else: break if(time_out == 3000): logger.error('@%s: receive data time out'%(self.name)) return False receive_data_temp = self.__axi4lite.read_array(0x24, 2*read_length, 16) receive_data = [] i = 0 while i < 2*read_length : receive_data.append(receive_data_temp[i]) i = i+2 return receive_data def write_and_read(self,write_data,cs_extend = 0): """ SPI write and read access Args: write_data(list): write data list cs_extend(float): The extend CS low when SPI access over, cs_extend is 0 to 8, min resolution is 0.5 Returns: receive_data(list): read data list if error ,return False """ send_cache_depth = self.__axi4lite.read(0x28,1) last_append = (int(cs_extend)*16 + 7) if(cs_extend > int(cs_extend)): last_append = last_append + 8 if(send_cache_depth[0] > self.__cache_size): logger.error('@%s: send cache not enough'%(self.name)) return False recieve_cache_depth = self.__axi4lite.read(0x29,1) if(recieve_cache_depth[0] > 0): logger.error('@%s: receive cache not empty'%(self.name)) receive_data_temp = self.__axi4lite.read_array(0x24, 2*recieve_cache_depth[0], 16) return False tx_data_temp = [] for i in range(0,len(write_data)): tx_data_temp.append(write_data[i]) if(i == (len(write_data)-1)): tx_data_temp.append(last_append) else: tx_data_temp.append(0x06) self.__axi4lite.write_array(0x20, tx_data_temp, len(tx_data_temp), 16) time_out = 0 while time_out < 3000 : recieve_cache_depth = self.__axi4lite.read(0x29,1) if(recieve_cache_depth[0] < len(write_data)): time.sleep(0.001) time_out = time_out + 1 else: break if(time_out == 3000): logger.error('@%s: receive data time out'%(self.name)) return False receive_data_temp = self.__axi4lite.read_array(0x24, 2*recieve_cache_depth[0], 16) receive_data = [] i = 0 while i < 2*recieve_cache_depth[0] : receive_data.append(receive_data_temp[i]) i = i+2 return receive_data def write_to_read(self,write_data,read_length,cs_extend = 0): """ SPI write to read access Args: write_data(list): write data list read_length(int): number of read data cs_extend(float): The extend CS low when SPI access over, cs_extend is 0 to 8, min resolution is 0.5 Returns: receive_data(list): read data list if error ,return False """ send_cache_depth = self.__axi4lite.read(0x28,1) last_append = (int(cs_extend)*16 + 3) if(cs_extend > int(cs_extend)): last_append = last_append + 8 if(send_cache_depth[0] + read_length > self.__cache_size): logger.error('@%s: send cache not enough'%(self.name)) return False recieve_cache_depth = self.__axi4lite.read(0x29,1) if(recieve_cache_depth[0] > 0): logger.error('@%s: receive cache not empty'%(self.name)) receive_data_temp = self.__axi4lite.read_array(0x24, 2*recieve_cache_depth[0], 16) return False tx_data_temp = [] for i in range(0,len(write_data)): tx_data_temp.append(write_data[i]) tx_data_temp.append(0x04) for i in range(0,read_length): tx_data_temp.append(0x00) if(i == (read_length-1)): tx_data_temp.append(last_append) else: tx_data_temp.append(0x02) self.__axi4lite.write_array(0x20, tx_data_temp, len(tx_data_temp), 16) time_out = 0 while time_out < 3000 : recieve_cache_depth = self.__axi4lite.read(0x29,1) if(recieve_cache_depth[0] < read_length): time.sleep(0.001) time_out = time_out + 1 else: break if(time_out == 3000): logger.error('@%s: receive data time out'%(self.name)) return False i = 0 receive_data = [] receive_data_temp = self.__axi4lite.read_array(0x24, 2*recieve_cache_depth[0], 16) while i < 2*read_length : receive_data.append(receive_data_temp[i]) i = i+2 return receive_data
class Axi4SpiAdc(object): def __init__(self,name): self.name = name self.reg_num = 256 self.__axi4_clk_frequency = 125000000 self.__axi4lite=Axi4lite(self.name,self.reg_num) if self.__axi4lite.open() is False: logger.error('open %s device register number %d fail'%(self.name, self.reg_num)) self.__data_deal = DataOperate() def enable(self): """enable function""" self.__axi4lite.write(0x10, [0x00], 1) self.__axi4lite.write(0x10, [0x01], 1) return None def disable(self): """disable function""" self.__axi4lite.write(0x10, [0x00], 1) return None def sample_rate_set(self,sample_rate): """ set adc sample rate Args: sample_rate(int): ADC sample rate, unit is SPS Returns: None """ freq_hz_ctrl = int(sample_rate*pow(2,32)/self.__axi4_clk_frequency) wr_data = self.__data_deal.int_2_list(freq_hz_ctrl, 4) self.__axi4lite.write(0x20, wr_data, len(wr_data)) return None def sample_data_get(self): """ get sample data Args: None Returns: sample_volt(float): normalize volt (-1~+1) """ rd_data = self.__axi4lite.read(0x24,4) sample_data = self.__data_deal.list_2_int(rd_data) sample_volt = sample_data/pow(2,31) return sample_volt def _test_register(self,test_data): wr_data = self.__data_deal.int_2_list(test_data,4) self.__axi4lite.write(0x00,wr_data,len(wr_data)) rd_data = self.__axi4lite.read(0x00,len(wr_data)) test_out = self.__data_deal.list_2_int(rd_data) if(test_out != test_data): logger.error('@%s: Test Register read data error. '%(self.name)) return False return None def _set_axi4_clk_frequency(self,clk_frequency): self.__axi4_clk_frequency = clk_frequency return None
class Axi4Ad717x(object): def __init__(self, name): self.name = name self.reg_num = 8192 self.__axi4lite = Axi4lite(self.name, self.reg_num) if self.__axi4lite.open() is False: logger.error('open %s device register number %d fail' % (self.name, self.reg_num)) self.__data_deal = DataOperate() def enable(self): """Enable this FPGA function""" self.__axi4lite.write(0x10, [0x00], 1) self.__axi4lite.write(0x10, [0x01], 1) def disable(self): """Disable this FPGA function""" self.__axi4lite.write(0x10, [0x00], 1) def register_read(self, reg_addr): """ Read value from ADC chip register Args: reg_addr: ADC chip register address(0x00-0xff) Returns: register value: (0x00-0xffffffff) """ rd_data = self.__axi4lite.read(0x26, 1) if (rd_data[0] & 0x01 == 0x00): logger.warning('AD717X Bus is busy now') return False com_data = (0x3F & reg_addr) | 0x40 wr_data = [com_data, 0x01] self.__axi4lite.write(0x24, wr_data, len(wr_data)) rd_data = [0x00] timeout_cnt = 0 while (rd_data[0] & 0x01 == 0x00) and (timeout_cnt < 1000): time.sleep(0.001) timeout_cnt = timeout_cnt + 1 rd_data = self.__axi4lite.read(0x26, 1) if (timeout_cnt == 1000): logger.warning('AD717X read register wait timeout') return False rd_data = self.__axi4lite.read(0x28, 4) rd_data = rd_data[0] | (rd_data[1] << 8) | (rd_data[2] << 16) |\ (rd_data[3] << 24) return rd_data def register_write(self, reg_addr, reg_data): """ Write value to ADC chip register Args: reg_addr: ADC chip reg (0x00-0xff) reg_data: register value(0x00-0xffffffff) Returns: True | False """ rd_data = self.__axi4lite.read(0x26, 1) if (rd_data[0] & 0x01 == 0x00): logger.warning('AD717X Bus is busy now') return False wr_data = self.__data_deal.int_2_list(reg_data, 4) com_data = (0x3F & reg_addr) wr_data.append(com_data) wr_data.append(0x01) self.__axi4lite.write(0x20, wr_data, len(wr_data)) rd_data = [0x00] timeout_cnt = 0 while (rd_data[0] & 0x01 == 0x00) and (timeout_cnt < 1000): time.sleep(0.001) rd_data = self.__axi4lite.read(0x26, 1) timeout_cnt = timeout_cnt + 1 if (timeout_cnt == 1000): logger.warning('AD717X write register wait finish timeout') return False return True def single_sample_code_get(self): """ ADC chip single sample Returns: (channel,sample_code) """ rd_data = self.register_read(0x01) wr_data = rd_data & 0xFF0F | 0x0000 self.register_write(0x01, wr_data) rd_data = self.register_read(0x01) if ((rd_data & 0x00F0) != 0): logger.warning("AXI4 AD717X 0x01 ==%s" % (hex(rd_data))) return False wr_data = rd_data & 0xFF0F | 0x0010 self.register_write(0x01, wr_data) reg_data = self.register_read(0x04) rd_data = self.__axi4lite.read(0x26, 1) if (rd_data[0] & 0x08 == 0x08): sample_channel = (reg_data & 0x0000000F) sample_data = (reg_data & (0xFFFFFF00)) >> 8 else: sample_channel = 'Null' sample_data = reg_data & (0x00FFFFFF) return (sample_channel, sample_data) def continue_sample_mode(self): """ ADC chip work in continue sample mode,cpu can not control the bus Returns: True | False """ rd_data = self.register_read(0x01) wr_data = rd_data & 0xFF0F | 0x0000 self.register_write(0x01, wr_data) rd_data = self.register_read(0x02) reg_data = rd_data & 0xFF7F | 0x0080 rd_data = self.__axi4lite.read(0x26, 1) if (rd_data[0] & 0x01 == 0x00): logger.warning('Error: AD717X Bus is busy now') return False wr_data = self.__data_deal.int_2_list(reg_data, 4) com_data = (0x3F & 0x02) wr_data.append(com_data) wr_data.append(0x01) self.__axi4lite.write(0x20, wr_data, len(wr_data)) return True def single_sample_mode(self): """ ADC chip exit continue sample mode,cpu can control the bus """ wr_data = [0x44, 0x01] state = self.__axi4lite.write(0x24, wr_data, len(wr_data)) return state def reset(self): """ Reset ADC chip """ wr_data = [0xFF, 0x01] state = self.__axi4lite.write(0x24, wr_data, len(wr_data)) return state def chip_id_set(self, chip_id): """ set chip_id Args: chip_id(int): chip id, 0~8 Returns: True|False """ wr_data = [chip_id] state = self.__axi4lite.write(0x13, wr_data, len(wr_data)) return state def continue_sample_capture(self): """ read continue sampld data Args: None Returns: sample_data(list): sample data """ rd_data = self.__axi4lite.read(0x26, 1) sample_state = rd_data[0] & 0x04 if (sample_state == 0): logger.warning('AD717X not in continue sample mode') return False self.__axi4lite.write(0x11, [0x01], 1) rd_data = self.__axi4lite.read(0x12, 1) if (rd_data[0] & 0x02 == 0x00): logger.warning('AD717X capture fifo reset failt') return False self.__axi4lite.write(0x11, [0x00], 1) time_out = 0 while time_out < 300: rd_data = self.__axi4lite.read(0x12, 1) if rd_data[0] & 0x01 == 0x01: break else: time_out = time_out + 1 time.sleep(0.01) if time_out == 3000: logger.error('@%s: capture data time out' % (self.name)) return False receive_list = self.__axi4lite.read_array(0x60, 2048, 32) return receive_list
class Axi4SpiSlave(object): def __init__(self, name): self.name = name self.reg_num = 256 self.__axi4lite = Axi4lite(self.name, self.reg_num) if self.__axi4lite.open() is False: logger.error('open %s device register number %d fail' % (self.name, self.reg_num)) self.__axi4_clk_frequency = 125000000 self.__data_deal = DataOperate() self.__data_width = 4 def disable(self): """ Disable function """ rd_data = self.__axi4lite.read(0x10, 1) wr_data = rd_data[0] & 0xF0 self.__axi4lite.write(0x10, [wr_data], 1) return None def enable(self): """ Enable function """ rd_data = self.__axi4lite.read(0x10, 1) wr_data = rd_data[0] & 0xF0 self.__axi4lite.write(0x10, [wr_data], 1) wr_data = rd_data[0] & 0xF0 | 0x01 self.__axi4lite.write(0x10, [wr_data], 1) return None def config(self, spi_clk_cpha_cpol='Mode_0', spi_byte_cfg='1'): """ Set spi bus parameter Args: spi_byte_cfg(str): '1' --spi slave receive data or send data is 1byte '2' --spi slave receive data or send data is 2byte '3' --spi slave receive data or send data is 3byte '4' --spi slave receive data or send data is 4byte spi_clk_cpha_cpol(str): 'Mode_0' --CPHA=0, CPOL=0, when CS is high, the SCLK is low, first edge sample 'Mode_1' --CPHA=0, CPOL=1, when CS is high, the SCLK is high, first edge sample 'Mode_2' --CPHA=1, CPOL=0, when CS is high, the SCLK is low, second edge sample 'Mode_3' --CPHA=1, CPOL=1, when CS is high, the SCLK is high, second edge sample Returns: None """ mode_set_data = self.__axi4lite.write(0x11, [0x00], 1) if (spi_clk_cpha_cpol == 'Mode_0'): mode_set_data = 0x00 elif (spi_clk_cpha_cpol == 'Mode_1'): mode_set_data = 0x01 elif (spi_clk_cpha_cpol == 'Mode_2'): mode_set_data = 0x02 elif (spi_clk_cpha_cpol == 'Mode_3'): mode_set_data = 0x03 else: logger.error('@%s: Mode select error' % (self.name)) return False self.__axi4lite.write(0x11, [mode_set_data], 1) self.__axi4lite.write(0x12, [0x01], 1) if (spi_byte_cfg == '1'): set_byte = 0x01 elif (spi_byte_cfg == '2'): set_byte = 0x02 elif (spi_byte_cfg == '3'): set_byte = 0x03 elif (spi_byte_cfg == '4'): set_byte = 0x04 else: logger.error('@%s: byte select error' % (self.name)) return False self.__axi4lite.write(0x12, [set_byte], 1) self.__data_width = set_byte return None def register_read(self, address, read_length): read_data = [] for i in range(0, read_length): wr_data = self.__data_deal.int_2_list(address, 2) self.__axi4lite.write(0x14, wr_data, len(wr_data)) rd_data = self.__axi4lite.read(0x24, 4) read_data_temp = self.__data_deal.list_2_int(rd_data) if (read_data_temp < 0): read_data_temp = read_data_temp + pow(2, 32) read_data_temp = read_data_temp >> 8 * (4 - self.__data_width) read_data.append(read_data_temp) address = address + 1 return read_data def register_write(self, address, write_data): for i in range(0, len(write_data)): write_data_temp = write_data[i] << 8 * (4 - self.__data_width) wr_data = self.__data_deal.int_2_list(write_data_temp, 4) self.__axi4lite.write(0x20, wr_data, len(wr_data)) wr_data = self.__data_deal.int_2_list(address, 2) self.__axi4lite.write(0x14, wr_data, len(wr_data)) self.__axi4lite.write(0x16, [0x01], 1) address = address + 1 return None
class Axi4SampleMultiplex(object): def __init__(self, name): self.name = name self.reg_num = 1024 self.__axi4lite = Axi4lite(self.name, self.reg_num) if self.__axi4lite.open() is False: logger.error('open %s device register number %d fail' % (self.name, self.reg_num)) self.__data_deal = DataOperate() def enable(self): """ Enable function """ self.__axi4lite.write(0x10, [0x00], 1) self.__axi4lite.write(0x10, [0x01], 1) return None def disable(self): """ Disable function """ self.__axi4lite.write(0x10, [0x00], 1) return None def measure_time_set(self, time_ms): """ Set measure time Args: time_ms(int): mircosecond of measure Returns: None """ wr_data = self.__data_deal.int_2_list(time_ms, 2) self.__axi4lite.write(0x11, wr_data, len(wr_data)) return None def measure_state_get(self): """ Get measure state Args: None Returns: measure_state(str): 'BUSY' | 'IDLE' """ rd_data = self.__axi4lite.read(0x13, 1) if (rd_data[0] & 0x10 == 0x00): measure_state = 'BUSY' else: measure_state = 'IDLE' return measure_state def measure_start(self): """ Start measure Args: None Returns: False | True """ measure_state = self.measure_state_get() if (measure_state == 'BUSY'): logger.error('@%s: bus busy...' % (self.name)) return False self.__axi4lite.write(0x13, [0x01], 1) return True def sample_parameter_set(self, sample_rate, switch_wait_ns, switch_sample_count, frame_type=0x20, frame_channel=0x0): """ Set sample parameter Args: sample_rate(int): ADC Chip sample rate, unit is Hz switch_wait_ns(int): The waiting time after switching the sampling channel, unit is ns switch_sample_count(int): The number of sampled data after switching the sampling channel frame_type(int): The upload frame type. frame_channel(int): freame channel (0~15) Returns: None """ sample_cycle = 1000000000 / sample_rate ch_wait = int(switch_wait_ns / sample_cycle) - 3 data_temp = ch_wait + switch_sample_count * pow( 2, 16) + frame_channel * pow(2, 28) wr_data = self.__data_deal.int_2_list(data_temp, 4) self.__axi4lite.write(0x1c, wr_data, len(wr_data)) frame_sample_rate = int(1000000 / ((ch_wait + 3) * sample_cycle)) wr_data = self.__data_deal.int_2_list(frame_sample_rate, 3) wr_data.append(frame_type) self.__axi4lite.write(0x14, wr_data, len(wr_data)) return None def sample_channel_set(self, ch_sel): """ Set sample channel Args: ch_sel(list): select the sample channle Returns: None """ if (len(ch_sel) == 0): logger.error('@%s: CH Sel Error' % (self.name)) return wr_data = [(len(ch_sel) - 1)] self.__axi4lite.write(0x18, wr_data, len(wr_data)) rw_addr = 0x40 for i in ch_sel: wr_data = [i] self.__axi4lite.write(rw_addr, wr_data, len(wr_data)) rw_addr = rw_addr + 1 return None def channel_attached_set(self, ch_attached): """ Set extra information for each sample channel Args: ch_attached(list): extra information for each sample channel Returns: None """ if (len(ch_attached) == 0): logger.error('@%s: CH Sel Error' % (self.name)) return rw_addr = 0x80 for i in ch_attached: wr_data = [i] self.__axi4lite.write(rw_addr, wr_data, len(wr_data)) rw_addr = rw_addr + 1 return None def interrupt_time_get(self, clk_freq, ch_num): """ get the posedge time and negedge time of trigger signal Args: clk_freq(int): the frequency of reference clock, unit is Hz ch_num(int): the channel number of trigger Returns: pos_time(int): trigger posedge time neg_time(int): trigger negedge time """ if ((ch_num > 64) | (ch_num < 0)): logger.error('@%s: CH Num Error' % (self.name)) return clk_cycle = 1000000000 / clk_freq wr_data = self.__data_deal.int_2_list(ch_num, 1) self.__axi4lite.write(0x20, wr_data, len(wr_data)) rd_data = [0, 0, 0, 0] rd_data = self.__axi4lite.read(0x24, len(rd_data)) pos_time = self.__data_deal.list_2_int(rd_data) * clk_cycle rd_data = self.__axi4lite.read(0x28, len(rd_data)) neg_time = self.__data_deal.list_2_int(rd_data) * clk_cycle return (pos_time, neg_time) def trigger_clear(self): """ clear the trigger for signal """ self.__axi4lite.write(0x2C, [0x0, 0x0], 2) return None def posedge_trigger_set(self): """ set the posedge trigger for signal """ rd_data = self.__axi4lite.read(0x2C, 1) rd_data[0] = rd_data[0] | 0x01 self.__axi4lite.write(0x2C, rd_data, 1) return None def negedge_trigger_set(self): """ set the negedge trigger for signal """ rd_data = self.__axi4lite.read(0x2C, 1) rd_data[0] = rd_data[0] | 0x02 self.__axi4lite.write(0x2C, rd_data, 1) return None def high_spread_trigger_set(self): """ set the high level insufficient trigger for signal """ rd_data = self.__axi4lite.read(0x2C, 1) rd_data[0] = rd_data[0] | 0x04 self.__axi4lite.write(0x2C, rd_data, 1) def low_spread_trigger_set(self): """ set the low level insufficient trigger for signal """ rd_data = self.__axi4lite.read(0x2C, 1) rd_data[0] = rd_data[0] | 0x08 self.__axi4lite.write(0x2C, rd_data, 1) def high_thresdhold_level_set(self, normalize_volt): """ set the threasdhold for posedge triggger Args: normalize_volt(long): normalize volt. -1 ~ +1 Returns: None """ threshold_level = int(normalize_volt * pow(2, 15)) if (threshold_level < 0): threshold_level = threshold_level + pow(2, 16) wr_data = self.__data_deal.int_2_list(threshold_level, 2) self.__axi4lite.write(0x30, wr_data, 2) return None def volt_normalize(self, signal_volt, signal_full_scale): """ Calculate VPP normalization Args: signal_volt(float): the volt of signal, unit is mv signal_full_scale(float): the full scale vpp of signal output, unit is mv Returns: volt_scale(float): normalized volt, (-1.00 ~ +1.00) """ volt_scale = signal_volt * 2 / signal_full_scale return (volt_scale) def set_low_thresdhold_level(self, normalize_volt): """ set the threasdhold for negedge triggger Args: normalize_volt(long): normalize volt. -1 ~ +1 Returns: None """ threshold_level = int(normalize_volt * pow(2, 15)) if (threshold_level < 0): threshold_level = threshold_level + pow(2, 16) wr_data = self.__data_deal.int_2_list(threshold_level, 2) self.__axi4lite.write(0x34, wr_data, 2) return None def set_high_spread_time(self, spread_ms): """ set the threasdhold for high level insufficient triggger Args: normalize_volt(long): normalize volt. -1 ~ +1 Returns: None """ read_data = self.__axi4lite.read(0x14, 3) sample_rate = self.__data_deal.list_2_int(read_data) sample_cycle = 1000000 / sample_rate spread_cnt = int(spread_ms * 1000000 / sample_cycle) wr_data = self.__data_deal.int_2_list(spread_cnt, 2) self.__axi4lite.write(0x32, wr_data, 2) return None def set_low_spread_time(self, spread_ms): """ set the threasdhold for low level insufficient triggger Args: normalize_volt(long): normalize volt. -1 ~ +1 Returns: None """ read_data = self.__axi4lite.read(0x14, 3) sample_rate = self.__data_deal.list_2_int(read_data) sample_cycle = 1000000 / sample_rate spread_cnt = int(spread_ms * 1000000 / sample_cycle) wr_data = self.__data_deal.int_2_list(spread_cnt, 2) self.__axi4lite.write(0x36, wr_data, 2) return None def trigger_state_get(self, channel_num): """ get trigger state of each channel Args: channel_num(list): the number of channel Returns: state_out(list): the state of channel """ read_data = self.__axi4lite.read(0x38, 2) state_data = self.__data_deal.list_2_int(read_data) state_out = [] for i in range(channel_num): state_temp = state_data >> i if ((state_temp % 2) == 1): state_out.append('T') else: state_out.append('N') return state_out def _test_register(self, test_data): wr_data = self.__data_deal.int_2_list(test_data, 4) self.__axi4lite.write(0x00, wr_data, len(wr_data)) rd_data = self.__axi4lite.read(0x00, len(wr_data)) test_out = self.__data_deal.list_2_int(rd_data) if (test_out != test_data): logger.error('@%s: Test Register read data error. ' % (self.name)) return False return None
class AXI4_Frame_Test(object): def __init__(self, name): self.name = name self.reg_num = 256 self.__axi4lite = Axi4lite(self.name, self.reg_num) if self.__axi4lite.open() is False: logger.error('open %s device register number %d fail' % (self.name, self.reg_num)) self.__data_deal = DataOperate() def _test_register(self, test_data): wr_data = self.__data_deal.int_2_list(test_data, 16) self.__axi4lite.write(0x00, wr_data, len(wr_data)) rd_data = self.__axi4lite.read(0x00, 8) check_data = self.__data_deal.list_2_int(rd_data) if (check_data != test_data): logger.error('@ %s: Test Register read data error.' % (self.name)) return False #print('Peripherals register test pass') return True def enable(self): self.__axi4lite.write(0x10, [0x00], 1) self.__axi4lite.write(0x10, [0x01], 1) return True def disbale(self): self.__axi4lite.write(0x10, [0x00], 1) return True def frame_gen_set(self, frame_id, frame_length): wr_data_int = frame_length * pow(2, 16) + frame_id wr_data = self.__data_deal.int_2_list(wr_data_int, 4) self.__axi4lite.write(0x2C, wr_data, len(wr_data)) return True def frame_test_start(self): self.__axi4lite.write(0x11, [0x01], 1) return True def frame_test_stop(self): self.__axi4lite.write(0x11, [0x00], 1) return True def tx_state_get(self): rd_data = self.__axi4lite.read(0x20, 4) frame_count = self.__data_deal.list_2_int(rd_data) rd_data = self.__axi4lite.read(0x24, 8) frame_time_cnt = self.__data_deal.list_2_int(rd_data) frame_time = float(frame_time_cnt) * 8 / 1000000000 return (frame_time, frame_count) def rx_state_get(self): rd_data = self.__axi4lite.read(0x30, 4) frame_count = self.__data_deal.list_2_int(rd_data) rd_data = self.__axi4lite.read(0x34, 8) frame_time_cnt = self.__data_deal.list_2_int(rd_data) frame_time = float(frame_time_cnt) * 8 / 1000000000 rd_data = self.__axi4lite.read(0x3C, 4) error_count = self.__data_deal.list_2_int(rd_data) return (frame_time, frame_count, error_count)
class Axi4I2cSlave(object): def __init__(self, name): self.name = name self.reg_num = 256 self.__axi4_clk_frequency = 125000000 self.__axi4lite = Axi4lite(self.name, self.reg_num) if self.__axi4lite.open() is False: logger.error('open %s device register number %d fail' % (self.name, self.reg_num)) self.__data_deal = DataOperate() self.__data_width = 4 def enable(self): """enable function""" self.__axi4lite.write(0x10, [0x00], 1) self.__axi4lite.write(0x10, [0x01], 1) return None def disable(self): """disable function""" self.__axi4lite.write(0x10, [0x00], 1) return None def config(self, bit_rate_hz=400000, slave_address=0x48, address_bytes=1, data_bytes=1): """ config ii2 slave Args: bit_rate_hz(int): iic bus bit rate, unit is Hz slave_address(int): iic slave device address address_bytes(int): iic register addresss bytes data_bytes(int): iic register data bytes Returns: None """ self.disable() bit_clk_count = self.__axi4_clk_frequency / bit_rate_hz bit_clk_delay = int(bit_clk_count / 8) byte_ctrl = address_bytes * 16 + data_bytes wr_data = [slave_address, byte_ctrl] bit_clk_delay_temp = self.__data_deal.int_2_list(bit_clk_delay, 2) wr_data.extend(bit_clk_delay_temp) self.__axi4lite.write(0x30, wr_data, len(wr_data)) self.__data_width = data_bytes self.enable() return None def register_read(self, address, read_length): read_data = [] for i in range(0, read_length): wr_data = self.__data_deal.int_2_list(address, 2) self.__axi4lite.write(0x38, wr_data, len(wr_data)) rd_data = self.__axi4lite.read(0x3C, 4) read_data_temp = self.__data_deal.list_2_int(rd_data) if (read_data_temp < 0): read_data_temp = read_data_temp + pow(2, 32) read_data_temp = read_data_temp >> 8 * (4 - self.__data_width) read_data.append(read_data_temp) address = address + 1 return read_data def register_write(self, address, write_data): for i in range(0, len(write_data)): write_data_temp = write_data[i] << 8 * (4 - self.__data_width) wr_data = self.__data_deal.int_2_list(write_data_temp, 4) self.__axi4lite.write(0x34, wr_data, len(wr_data)) wr_data = self.__data_deal.int_2_list(address, 2) self.__axi4lite.write(0x38, wr_data, len(wr_data)) self.__axi4lite.write(0x3A, [0x01], 1) address = address + 1 return None def _axi4_clk_frequency_set(self, clk_frequency): self.__axi4_clk_frequency = clk_frequency
class Axi4FftAnalyzer(object): def __init__(self, name): self.name = name self.reg_num = 65536 self.__axi4lite = Axi4lite(self.name, self.reg_num) if self.__axi4lite.open() is False: logger.error('open %s device register number %d fail' % (self.name, self.reg_num)) self.__data_deal = DataOperate() self.__k1_index = 0 self.__k1_data = 0 self.__k2_index = 0 self.__k2_data = 0 self.__all_power = 0 self.__fft_power_data = [] self.__sample_rate = 0 self.__freq_resolution = 0 self.__bandwidth_index = 0 self.__decimation_data = 1 self.__base_frequency = 1000 def enable(self): """enable function""" self.disable() rd_data = self.__axi4lite.read(0x10, 1) rd_data[0] = rd_data[0] | 0x01 self.__axi4lite.write(0x10, rd_data, 1) return None def disable(self): """disable function""" rd_data = self.__axi4lite.read(0x10, 1) rd_data[0] = rd_data[0] & 0xFE self.__axi4lite.write(0x10, rd_data, 1) return None def upload_enable(self): """enable data upload function""" rd_data = self.__axi4lite.read(0x10, 1) rd_data[0] = rd_data[0] | 0x02 self.__axi4lite.write(0x10, rd_data, 1) return None def upload_disable(self): """disbale data upload function""" rd_data = self.__axi4lite.read(0x10, 1) rd_data[0] = rd_data[0] & 0xFD self.__axi4lite.write(0x10, rd_data, 1) return None def measure_paramter_set(self, bandwidth_hz, sample_rate, decimation_type): """ Set measure paramter Args: bandwidth_hz(int): Bandwidth limit, unit is Hz sample_rate(int): signal sample rate, unit is Hz decimation_type(str): signal decimation type 'auto' -- automatic detection '1'/'2'/........ Returns: False | True """ self._decimation_factor_set(decimation_type) self.__sample_rate = sample_rate / self.__decimation_data self.__freq_resolution = sample_rate / (8192 * self.__decimation_data) self.__bandwidth_index = int(bandwidth_hz / self.__freq_resolution) return True def measure_start(self): """ start measure Args: None Returns: False | True """ self.__axi4lite.write(0x14, [0x00], 1) self.__axi4lite.write(0x13, [0x01], 1) rd_data = [0] timeout_cnt = 0 while (rd_data[0] == 0x00) and timeout_cnt < 3000: sleep(0.001) rd_data = self.__axi4lite.read(0x14, 1) timeout_cnt = timeout_cnt + 1 if (timeout_cnt == 3000): logger.error('@%s: wait time out' % (self.name)) return False self._get_fft_data() self._base_index_find() return True def thdn_measure(self): """ measure thd+n Args: None Returns: thdn_data(float): thd+n """ fundamental_power = 0 for i in range(self.__k1_index - 4, self.__k2_index + 4): fundamental_power = fundamental_power + self.__fft_power_data[i] thdn_data = 10 * math.log10( (self.__all_power - fundamental_power) / fundamental_power) return (thdn_data, 'dB') def singal_measure(self): """ measure frequency and vpp Args: None Returns: amp_data(float): Normalized amplitude (0.000~0.999) freq_data(float): signal frequency, unit is Hz """ k1_data = math.sqrt(self.__k1_data) k2_data = math.sqrt(self.__k2_data) b_data = (k2_data - k1_data) / (k2_data + k1_data) a_data = 2.95494514 * pow(b_data, 1) + 0.17671943 * pow( b_data, 3) + 0.09230694 * pow(b_data, 5) amp_data = (k1_data + k2_data) * (3.20976143 + 0.9187393 * pow(a_data, 2) + 0.14734229 * pow(a_data, 4)) / 8192 amp_data = amp_data / 4096 freq_data = (0.5 + a_data + self.__k1_index) * (self.__sample_rate / 8192) self.__base_frequency = freq_data return (amp_data, 'V', freq_data, 'Hz') def vpp_measure(self, signal_frequency): """ measure the amplitude of the input frequency signal Args: signal_frequency(int): measure signal frequency, unit is hz Returns: amp_data(float): Normalized amplitude (0.000~0.999) """ k1_index = int(signal_frequency / self.__freq_resolution) k2_index = k1_index + 1 k1_data = self.__fft_power_data[k1_index] k2_data = self.__fft_power_data[k2_index] k1_data = math.sqrt(k1_data) k2_data = math.sqrt(k2_data) b_data = (k2_data - k1_data) / (k2_data + k1_data) a_data = 2.95494514 * pow(b_data, 1) + 0.17671943 * pow( b_data, 3) + 0.09230694 * pow(b_data, 5) amp_data = (k1_data + k2_data) * (3.20976143 + 0.9187393 * pow(a_data, 2) + 0.14734229 * pow(a_data, 4)) / 8192 amp_data = amp_data / 4096 return (amp_data, "V") def thd_measure(self, harmonic_num): """ measure thd Args: harmonic_num(int): harmonic num, <11 Returns: amp_data(float): Normalized amplitude (0.000~0.999) thd_data(float): thd data """ harmonic_freq = [] harmonic_vpp = [] harmonic_power = [] harmonic_all_power = 0 for i in range(1, harmonic_num): freq_data = i * self.__base_frequency harmonic_freq.append(freq_data) k1_index = int(freq_data / self.__freq_resolution) k2_index = k1_index + 1 power_temp = 0 for j in range(k1_index - 4, k2_index + 4): power_temp = power_temp + self.__fft_power_data[j] harmonic_power.append(power_temp) harmonic_all_power = harmonic_all_power + power_temp k1_data = self.__fft_power_data[k1_index] k2_data = self.__fft_power_data[k2_index] if ((k1_data != 0) or (k2_data != 0)): k1_data = math.sqrt(k1_data) k2_data = math.sqrt(k2_data) b_data = (k2_data - k1_data) / (k2_data + k1_data) a_data = 2.95494514 * pow(b_data, 1) + 0.17671943 * pow( b_data, 3) + 0.09230694 * pow(b_data, 5) amp_data = (k1_data + k2_data) * ( 3.20976143 + 0.9187393 * pow(a_data, 2) + 0.14734229 * pow(a_data, 4)) / 8192 else: amp_data = 0 harmonic_vpp.append(amp_data) thd_data = 10 * math.log10( (harmonic_all_power - harmonic_power[0]) / harmonic_power[0]) harmonic_all_amp_square = 0 for i in range(1, harmonic_num - 1): harmonic_all_amp_square = harmonic_all_amp_square + pow( harmonic_vpp[i], 2) thd_data1 = 20 * math.log10( math.sqrt(harmonic_all_amp_square) / harmonic_vpp[0]) return (thd_data, 'dB', thd_data1, 'dB') def _decimation_factor_set(self, decimation_type): if (decimation_type is 'auto'): decimation_type_data = 0xFF else: decimation_type_data = int(decimation_type) self.__axi4lite.write(0x15, [decimation_type_data], 1) self.__axi4lite.write(0x17, [0x01], 1) rd_data = [0] timeout_cnt = 0 while (rd_data[0] == 0x00) and timeout_cnt < 3000: sleep(0.001) rd_data = self.__axi4lite.read(0x17, 1) timeout_cnt = timeout_cnt + 1 if (timeout_cnt == 3000): logger.error('@%s: wait time out' % (self.name)) return False rd_data = self.__axi4lite.read(0x16, 1) self.__decimation_data = rd_data[0] return True def _base_index_find(self): max_data = max(self.__fft_power_data) max_index = self.__fft_power_data.index(max_data) max_left_index = max_index - 1 max_left_data = self.__fft_power_data[max_left_index] max_right_index = max_index + 1 max_right_data = self.__fft_power_data[max_right_index] if (max_left_data > max_right_data): second_index = max_left_index second_data = max_left_data else: second_index = max_right_index second_data = max_right_data if (max_index > second_index): self.__k1_index = second_index self.__k1_data = second_data self.__k2_index = max_index self.__k2_data = max_data else: self.__k2_index = second_index self.__k2_data = second_data self.__k1_index = max_index self.__k1_data = max_data self.__all_power = sum(self.__fft_power_data[8:self.__bandwidth_index]) return None def _get_fft_data(self): fft_data = [] self.__fft_power_data = [] rd_data = self.__axi4lite.read(0x84, 4) fft_data_cnt = self.__data_deal.list_2_int(rd_data) if (fft_data_cnt != 0): fft_data = self.__axi4lite.read_array(0x80, fft_data_cnt * 4, 32) for i in range(int(fft_data_cnt / 2)): self.__fft_power_data.append( self.__data_deal.list_2_int(fft_data[i * 8:i * 8 + 6])) # print(self.__fft_power_data) return self.__fft_power_data def _test_register(self, test_data): wr_data = self.__data_deal.int_2_list(test_data, 4) self.__axi4lite.write(0x00, wr_data, len(wr_data)) rd_data = self.__axi4lite.read(0x00, len(wr_data)) test_out = self.__data_deal.list_2_int(rd_data) if (test_out != test_data): logger.error('@%s: Test Register read data error. ' % (self.name)) return False return None
class Axi4Sysreg(object): def __init__(self, name): self.name = name self.reg_num = 256 self.__axi4lite = Axi4lite(self.name, self.reg_num) if self.__axi4lite.open() is False: logger.error('open %s device register number %d fail' % (self.name, self.reg_num)) self.__data_deal = DataOperate() def version_get(self): """ Get FPGA version Args: None Returns: fpga_version(str): fpga version(0.0~15.15) """ rd_data = self.__axi4lite.read(0x10, 1) if (rd_data == False): return False fpga_version_h = (rd_data[0] & 0xF0) >> 4 if (fpga_version_h < 10): fpga_version_h_str = '0' + str(fpga_version_h) else: fpga_version_h_str = str(fpga_version_h) fpga_version_l = (rd_data[0] & 0x0F) if (fpga_version_l < 10): fpga_version_l_str = '0' + str(fpga_version_l) else: fpga_version_l_str = str(fpga_version_l) fpga_version = fpga_version_h_str + '.' + fpga_version_l_str return fpga_version def uct_set(self, uct_second, uct_mircosecond): """ Set uct Args: uct_second(int): second time uct_mircosecond(int): mircosecond time(0~999) Returns: None """ uct_1 = self.__data_deal.int_2_list(uct_mircosecond, 2) uct_2 = self.__data_deal.int_2_list(uct_second, 4) wr_data = uct_1 + uct_2 self.__axi4lite.write(0x40, wr_data, len(wr_data)) self.__axi4lite.write(0x46, [0x01], 1) return None def uct_get(self): """ Get uct Args: None Returns: uct_second(int): second time uct_mircosecond(int): mircosecond time """ self.__axi4lite.write(0x47, [0x01], 1) rw_addr = 0x48 rd_data = self.__axi4lite.read(rw_addr, 6) print(rd_data) if (rd_data == False): return False uct_mircosecond = self.__data_deal.list_2_int(rd_data[0:1]) uct_second = self.__data_deal.list_2_int(rd_data[2:5]) return (uct_second, uct_mircosecond) def external_register_write(self, reg_addr, reg_data): """ write external register Args: reg_addr(int): register address, 0x80~0x9F reg_data(list): register write data Returns: None """ self.__axi4lite.write(reg_addr, reg_data, len(reg_data)) return None def external_register_read(self, reg_addr, read_length): """ write external register Args: reg_addr(int): register address, 0x80~0x9F read_length(int): read data bytes Returns: reg_data(list): register read data """ reg_data = self.__axi4lite.read(reg_addr, read_length) return reg_data
class Axi4SpiDac(object): def __init__(self, name): self.name = name self.reg_num = 256 self.__axi4_clk_frequency = 125000000 self.__axi4lite = Axi4lite(self.name, self.reg_num) if self.__axi4lite.open() is False: logger.error('open %s device register number %d fail' % (self.name, self.reg_num)) self.__data_deal = DataOperate() self.__sclk_frequency = 10000000 def enable(self): """enable function""" self.__axi4lite.write(0x10, [0x00], 1) self.__axi4lite.write(0x10, [0x01], 1) return None def disable(self): """disable function""" self.__axi4lite.write(0x10, [0x00], 1) return None def dac_mode_set(self, dac_mode): """ set dac mode data Args: dac_mode(int): dac mode data Returns: None """ wr_data = [dac_mode] self.__axi4lite.write(0x11, wr_data, len(wr_data)) return None def spi_sclk_frequency_set(self, sclk_freq_hz): """ set spi bus sclk frequency Args: sclk_freq_hz(int): spi bus sclk frequency, unit is Hz Returns: None """ self.__sclk_frequency = sclk_freq_hz freq_hz_ctrl = int(sclk_freq_hz * pow(2, 32) / self.__axi4_clk_frequency) wr_data = self.__data_deal.int_2_list(freq_hz_ctrl, 4) self.__axi4lite.write(0x24, wr_data, len(wr_data)) return None def sample_rate_set(self, sample_rate): """ set dac sample rate Args: sample_rate(int): DAC sample rate, unit is SPS Returns: None """ freq_hz_ctrl = int(sample_rate * pow(2, 32) / self.__sclk_frequency) wr_data = self.__data_deal.int_2_list(freq_hz_ctrl, 4) self.__axi4lite.write(0x20, wr_data, len(wr_data)) return None def _test_register(self, test_data): wr_data = self.__data_deal.int_2_list(test_data, 4) self.__axi4lite.write(0x00, wr_data, len(wr_data)) rd_data = self.__axi4lite.read(0x00, len(wr_data)) test_out = self.__data_deal.list_2_int(rd_data) if (test_out != test_data): logger.error('@%s: Test Register read data error. ' % (self.name)) return False return None def _set_axi4_clk_frequency(self, clk_frequency): self.__axi4_clk_frequency = clk_frequency return None
class Axi4I2c(object): def __init__(self, name): self.name = name self.reg_num = 256 self.__axi4_clk_frequency = 125000000 self.__axi4lite = Axi4lite(self.name, self.reg_num) if self.__axi4lite.open() is False: logger.error('open %s device register number %d fail' % (self.name, self.reg_num)) self.__data_deal = DataOperate() self.config() rd_data = self.__axi4lite.read(0x12, 2) self._cache_size = self.__data_deal.list_2_int(rd_data) def config(self, bit_rate_hz=400000): """ config ii2 master Args: bit_rate_hz(int): iic bus bit rate, unit is Hz Returns: None """ self.disable() bit_rate_ctrl = bit_rate_hz * 8 * pow(2, 32) / self.__axi4_clk_frequency wr_data = self.__data_deal.int_2_list(int(bit_rate_ctrl), 4) self.__axi4lite.write(0x20, wr_data, len(wr_data)) self.enable() return None def write(self, dev_addr, data): """ iis write Args: dev_addr(int): iic slave address data(list): iic write data, length < 65 Returns: False | True """ op_code = dev_addr * 2 send_data = [op_code] + data send_list = [] for i in range(0, len(send_data)): send_list.append(send_data[i]) if i == 0: send_list.append(0x80) elif i == (len(send_data) - 1): send_list.append(0x20) else: send_list.append(0x00) receive_list = self._iic_control(send_list) if receive_list == False: self.enable() return False i = 0 while (i < len(receive_list)): if (receive_list[i + 1] & 0x01 == 0x01): logger.error('@%s: receive no ACK' % (self.name)) return False i = i + 2 return True def read(self, dev_addr, length): """ iis read Args: dev_addr(int): iic slave address length(int): iic read data length, length < 65 Returns: receive_list_out(list): iic read data if error, return False """ op_code = dev_addr * 2 + 0x01 send_list = [op_code, 0x80] for i in range(0, length): send_list.append(0x00) if i == (length - 1): send_list.append(0x70) else: send_list.append(0x40) receive_list = self._iic_control(send_list) if receive_list == False: self.enable() return False i = 0 receive_list_out = [] while i < len(receive_list): receive_list_out.append(receive_list[i]) if (i != len(receive_list) - 2): if (receive_list[i + 1] & 0x01) == 0x01: logger.error('@%s: receive no ACK' % (self.name)) return False i = i + 2 i = 0 while i >= 0: del receive_list_out[i] i = i - 1 return receive_list_out def rdwr(self, dev_addr, write_data_list, read_length): """ iis write and read Args: dev_addr(int): iic slave address write_data_list(list): iic write data, length < 65 read_length(int): iic read data length, length < 65 the length of write_data_list + read_length < 65 Returns: receive_list_out(list): iic read data if error, return False """ op_code = dev_addr * 2 send_data = [op_code] + write_data_list send_list = [] for i in range(0, len(send_data)): send_list.append(send_data[i]) if i == 0: send_list.append(0x80) else: send_list.append(0x00) op_code = dev_addr * 2 + 0x1 send_list.append(op_code) send_list.append(0x80) for i in range(0, read_length): send_list.append(0x00) if i == (read_length - 1): send_list.append(0x70) else: send_list.append(0x40) receive_list = self._iic_control(send_list) if receive_list == False: self.enable() return False i = 0 receive_list_out = [] while i < len(receive_list) - 1: receive_list_out.append(receive_list[i]) if (i != len(receive_list) - 2): if (receive_list[i + 1] & 0x01) == 0x01: logger.error('@%s: receive no ACK' % (self.name)) return False i = i + 2 i = 1 + len(write_data_list) while i >= 0: del receive_list_out[i] i = i - 1 return receive_list_out def _iic_control(self, send_list): time_out = 0 send_cache_depth = self.__axi4lite.read(0x1C, 1) if (send_cache_depth[0] > 0): logger.error('@%s: send cache not empty' % (self.name)) return False recieve_cache_depth = self.__axi4lite.read(0x1E, 1) if (recieve_cache_depth[0] > 0): logger.error('@%s: receive cache not empty' % (self.name)) return False if (len(send_list) > self._cache_size * 2): logger.error('@%s: send data too much' % (self.name)) return False self.__axi4lite.write_array(0x14, send_list, len(send_list), 16) while time_out < 3000: recieve_cache_depth = self.__axi4lite.read(0x1E, 1) if recieve_cache_depth[0] == (len(send_list)) / 2: break else: time_out = time_out + 1 time.sleep(0.001) if time_out == 3000: logger.error('@%s: receive data enough' % (self.name)) return False receive_bytes_cnt = 2 * recieve_cache_depth[0] receive_list = self.__axi4lite.read_array(0x18, receive_bytes_cnt, 16) return receive_list def _axi4_clk_frequency_set(self, clk_frequency): self.__axi4_clk_frequency = clk_frequency def enable(self): """enable function""" self.__axi4lite.write(0x10, [0x00], 1) self.__axi4lite.write(0x10, [0x01], 1) return None def disable(self): """disable function""" self.__axi4lite.write(0x10, [0x00], 1) return None
class Axi4PowerPwmCore(): def __init__(self, name): self.name = name self.reg_num = 8192 self.__axi4lite = Axi4lite(self.name, self.reg_num) if self.__axi4lite.open() is False: logger.error('open %s device register number %d fail' % (self.name, self.reg_num)) self.__data_deal = DataOperate() def read_adc_sample_data(self): """ read_adc_sample_data Args: None Returns: adc_value: the normalized min level of input signal, unit is V,-1V ~ +1V the true voltage value needs to be multiplied by the reference range. """ # 0x38~0x3B [31:0]--adc_data: rd_data = self.__axi4lite.read(0x38, 4) adc_value = self.__data_deal.list_2_int(rd_data) / pow(2, 31) return adc_value def power_pwm_output_disable(self): """Disable this FPGA function""" self.__axi4lite.write(0x10, [0x00], 1) return None def power_pwm_output_enable(self, pwm_mode, pid_en, adc_dec_param, p_param, i_param, d_param, pwm0_duty, pwm1_duty, pwm_minimum_duty=0.05, pwm_maximum_duty=0.95, pwm_error_duty=0.01, adc_tran_pwm_param=72): """ power_pwm_en Args: pwm_mode(bool): 0-singal,1-double pid_en(bool): For enable PID modulation. adc_dec_param(int): 0~65535, ADC sampling decimation coefficient. p_param(float): -0.9999~+0.9999, PID proportional parameters. i_param(float): -0.9999~+0.9999, PID integral parameter. d_param(float): -0.9999~+0.9999, PID differential parameter. pwm0_duty(float): 0.05~0.95, pwm0_param = pwm0_duty * 624, pwm0 duty parameter. pwm1_duty(float): 0.05~0.95, pwm0_param = pwm0_duty * 624, pwm1 duty parameter. pwm_minimum_duty(float): 0.05~0.95, pwm_minimum_param = pwm_minimum_duty * 624, for PID modulation, limit minimum PWM duty output pwm_maximum_duty(float): 0.05~0.95, pwm_minimum_param = pwm_maximum_duty * 624, for PID modulation, limit maximum PWM duty output pwm_error_duty(float): 0.05~0.95, pwm_error_param = pwm_maximum_duty * 624, For PID modulation, The error exceeding this value will start the PID modulation adc_tran_pwm_param(int): (3.5*5/24)*(adc/2^15)*(125000/200) ≈> adc/72 => adc_tran_pwm_param = 72 3.5 => Attenuation coefficient, 5 => ADC input range,+-5V 24 => Voltage output range 125000 => FPGA IP base frequency, KHZ 200 => PWM frequency, KHZ Returns: None """ self.power_pwm_output_disable() # cfg param wr_data = self.__data_deal.int_2_list(int(adc_dec_param), 2) self.__axi4lite.write(0x20, wr_data, 2) wr_data = self.__data_deal.int_2_list(int(p_param * pow(2, 17)), 3) self.__axi4lite.write(0x24, wr_data, 3) wr_data = self.__data_deal.int_2_list(int(i_param * pow(2, 17)), 3) self.__axi4lite.write(0x28, wr_data, 3) wr_data = self.__data_deal.int_2_list(int(d_param * pow(2, 17)), 3) self.__axi4lite.write(0x2C, wr_data, 3) wr_data = self.__data_deal.int_2_list(int(pwm0_duty * 624), 2) self.__axi4lite.write(0x30, wr_data, 2) wr_data = self.__data_deal.int_2_list(int(pwm1_duty * 624), 2) self.__axi4lite.write(0x34, wr_data, 2) wr_data = self.__data_deal.int_2_list(int(pwm_minimum_duty * 624), 2) self.__axi4lite.write(0x40, wr_data, 2) wr_data = self.__data_deal.int_2_list(int(pwm_maximum_duty * 624), 2) self.__axi4lite.write(0x44, wr_data, 2) wr_data = self.__data_deal.int_2_list(int(pwm_error_duty * 624), 2) self.__axi4lite.write(0x48, wr_data, 2) # # start pwm # self.__axi4lite.write(0x11,[0x01],1) # cfg mode info wr_data = 0x01 | pwm_mode << 4 | pid_en << 5 self.__axi4lite.write(0x10, [wr_data], 1) return None
class Axi4AidMaster(): def __init__(self, name): self.name = name self.reg_num = 8192 self.__axi4lite = Axi4lite(self.name, self.reg_num) if self.__axi4lite.open() is False: logger.error('open %s device register number %d fail' % (self.name, self.reg_num)) self.__data_deal = DataOperate() def enable(self): """Enable this FPGA function""" self.__axi4lite.write(0x10, [0x01], 1) return None def disable(self): """Disable this FPGA function""" self.__axi4lite.write(0x10, [0x00], 1) return None def aid_switch_on(self): """Release aid bus, allow aid communication""" # 0x11 [0]--vdg_switch; [4]--vdg_poll_en rd_data = self.__axi4lite.read(0x11, 1) rd_data[0] = rd_data[0] & 0xFE self.__axi4lite.write(0x11, rd_data, 1) return None def aid_switch_off(self): """Force the aid bus to be low level, forbade aid communication""" # 0x11 [0]--vdg_switch; [4]--vdg_poll_en rd_data = self.__axi4lite.read(0x11, 1) rd_data[0] = rd_data[0] | 0x01 self.__axi4lite.write(0x11, rd_data, 1) return None def aid_detect_poll_on(self): """enable aid detect poll mode, that is the 70ms loop sends a "74 00 01" request command(otpID)""" # 0x11 [0]--vdg_switch; [4]--vdg_poll_en rd_data = self.__axi4lite.read(0x11, 1) rd_data[0] = rd_data[0] | 0x10 self.__axi4lite.write(0x11, rd_data, 1) return None def aid_detect_poll_off(self): """disable aid detect poll mode""" # 0x11 [0]--vdg_switch; [4]--vdg_poll_en rd_data = self.__axi4lite.read(0x11, 1) rd_data[0] = rd_data[0] & 0xEF self.__axi4lite.write(0x11, rd_data, 1) return None def aid_cmd(self, cmd_req_data): """ signal aid cmd communication Args: cmd_req_data(list): aid request command data(except CRC data),len 1~512 Returns: aid_resp_data(list): aid response command data(include CRC data),len 0~512(len=0 --> no aid response data) """ # ctrl reg cfg # 0x10 [0]--module_en # 0x11 [0]--vdg_switch; [4]--vdg_poll_en # 0x12 [0]--start # 0x13 [0]--state # 0x20~0x21 aid_req_len # 0x22~0x23 aid_resp_len # 0x24~0x27 aid_rece_timeout_cnt # 0x80 wr--wr_req_data; rd--rd_resp_data # wait detect poll over rd_data = self.__axi4lite.read(0x11, 1) vdg_poll_en_flag = (rd_data[0] & 0x10) >> 4 if (vdg_poll_en_flag == 0x01): rd_data[0] = rd_data[0] & 0xEF self.__axi4lite.write(0x11, rd_data, 1) timeout_cnt = 0 rd_data = self.__axi4lite.read(0x13, 1) while (rd_data[0] == 0x00) and timeout_cnt < 1000: time.sleep(0.001) rd_data = self.__axi4lite.read(0x13, 1) timeout_cnt = timeout_cnt + 1 if (timeout_cnt == 1000): logger.error('wait poll detct timeout') return False # cfg req len aid_req_len = len(cmd_req_data) wr_data = self.__data_deal.int_2_list(aid_req_len, 2) self.__axi4lite.write(0x20, wr_data, len(wr_data)) # wr cmd_req_data to req_fifo self.__axi4lite.write_array(0x80, cmd_req_data, aid_req_len, 8) # start aid communication self.__axi4lite.write(0x12, [0x01], 1) # query state timeout_cnt = 0 rd_data = self.__axi4lite.read(0x13, 1) while (rd_data[0] == 0x00) and timeout_cnt < 10000: time.sleep(0.001) rd_data = self.__axi4lite.read(0x13, 1) timeout_cnt = timeout_cnt + 1 if (timeout_cnt == 10000): logger.error('aid communication timeout') return False # rece cmd_resp_data len rd_data = self.__axi4lite.read(0x22, 2) resp_len = self.__data_deal.list_2_int(rd_data) # rece cmd_resp_data from resp_fifo aid_resp_data = [] if (resp_len != 0): aid_resp_data = self.__axi4lite.read_array(0x80, resp_len, 8) if (vdg_poll_en_flag == 0x01): rd_data = self.__axi4lite.read(0x11, 1) rd_data[0] = rd_data[0] | 0x10 self.__axi4lite.write(0x11, rd_data, 1) return aid_resp_data