class MyMDIApp(QMainWindow): def __init__(self): super(MyMDIApp, self).__init__() self.setGeometry(50, 40, 1200, 960) # self.setAcceptDrops(True) self.filelist = [] # ==================================== # UIの生成 # ==================================== # :: MDIワークスペースのインスタンス化 self.workspace = QWorkspace() self.workspace.setWindowTitle("Simple WorkSpace Exmaple") # :: lite_listview self.lite_listview = LiteListView() self.lite_listview.addItems(["abc", "def", "ghi", "jkl"]) self.lite_listview.resize(150, 300) self.workspace.addWindow(self.lite_listview) # :: ボタンs layout = QHBoxLayout() self.btn_ana = QPushButton("Analysis") self.btn_plot = QPushButton("Plot") self.btn_save = QPushButton("Save") layout.addWidget(self.btn_ana) layout.addWidget(self.btn_plot) layout.addWidget(self.btn_save) self.btn_wid = QWidget() self.btn_wid.setWindowTitle("Feauters Analysis") self.btn_wid.setLayout(layout) self.workspace.addWindow(self.btn_wid) # :: Figure.FigureImapctAndHarmonic # : FIH用FigureCanvasグラフオブジェクト self.fig_impandharm = FigureImapctAndHarmonic() self.fig_impandharm.setWindowTitle("Figure Impact & Harmonic") self.workspace.addWindow(self.fig_impandharm) self.fig_impandharm.close() # : 以下コントローラ layout2 = QHBoxLayout() self.fih_label = QLabel() self.fih_label.setText(self.tr("Impact & Harm")) self.fih_btn_ana = QPushButton("Analysis") self.fih_btn_plot = QPushButton("Plot") self.fih_btn_save = QPushButton("Save") layout2.addWidget(self.fih_label) layout2.addWidget(self.fih_btn_ana) layout2.addWidget(self.fih_btn_plot) layout2.addWidget(self.fih_btn_save) self.btn_wid2 = QWidget() self.btn_wid2.setWindowTitle("Imapct & Harm") self.btn_wid2.setLayout(layout2) self.workspace.addWindow(self.btn_wid2) self.fih_btn_ana.clicked.connect(self.run_FIH_analysis) self.fih_btn_plot.clicked.connect(self.run_FIH_plot) self.fih_btn_save.clicked.connect(self.fig_impandharm.save) # :: キャンバス self.sig_canvas = SignalDataCanvas() # self.sig_canvas.setWindowTitle(self.tr(u"特徴量グラフ")) self.sig_canvas.setWindowTitle(u"特徴量グラフ") self.workspace.addWindow(self.sig_canvas) self.sig_canvas.close() # :: ステータスバー self.myStatusBar = QStatusBar() self.setStatusBar(self.myStatusBar) self.myStatusBar.showMessage('Ready', 1000) # :: プログラスバー self.progressBar = QProgressBar() self.myStatusBar.addPermanentWidget(self.progressBar) self.progressBar.reset() self.progressBar.setVisible(False) self.progressBar.setValue(0) # :: MainWidgetに追加 # self.workspace.tile() self.setCentralWidget(self.workspace) self.setCSS() # ==================================== # シグナルスロットのコネクト # ==================================== # lite_listview self.lite_listview.fileDropped.connect(self.set_filelist) self.lite_listview.clicked.connect(self.file_selected) # Analysisボタンで解析実行 self.btn_ana.clicked.connect(self.run_analysis) self.btn_plot.clicked.connect(self.run_plot) # ***************************************************** # ファイルインプット用スロット # ***************************************************** @Slot() def file_selected(self, index): """listviewがクリックされたときの動作""" selected_stritem = index.data(Qt.DisplayRole) s = "Clicked[%d] : %r" % (index.row(), selected_stritem) self.flush(s) @Slot() def set_filelist(self, file_list): self.filelist = file_list self.flush("Load File List") # ***************************************************** # Window2: インパクト音&自由振動音解析用 # ***************************************************** @Slot() def run_FIH_analysis(self): """解析データの受け渡し用中間スロット""" self.flush("> (QThread) run analysis") self.p2 = thread_analysis_imp_and_hrm() self.p2.set_option(self.filelist) self.p2.progress.connect(self.progress) self.p2.start() @Slot() def run_FIH_plot(self): res = self.p2.get_result() self.fig_impandharm.plot(resuls=res) pass # ***************************************************** # Window1: 全データ統計解析用 # ***************************************************** @Slot() def run_analysis(self): """特徴量算出アルゴリズム実行""" self.flush("> (QThread) run analysis") self.p = thProcess() self.p.set_option(self.filelist) self.p.progress.connect(self.progress) self.p.start() @Slot() def run_plot(self): """特徴量マップの表示""" # ; データ取得 # res = array(self.result) res = array(self.p.get_result()) # : canvas = BubleChartCanvas() self.workspace.addWindow(canvas) canvas.show() # グラフプロット names = [os.path.basename(p) for p in self.filelist] canvas.bubbleplot(xdata=res[:, 0], data=res[:, 1], names=names) canvas.set_xlabel("Katasa").set_ylabel("Matomari").canvas_update() # ***************************************************** # 共通関数 # ***************************************************** def flush(self, s, ms=1): maxlen = 50 if len(s) > maxlen: s = s[:10] + "..." + s[-maxlen:] self.myStatusBar.showMessage(s, ms * 1000) def progress(self, value=None): if value < 0: self.progressBar.reset() self.progressBar.setVisible(False) if value >= 0: self.progressBar.setVisible(True) self.progressBar.setValue(value) def setCSS(self): """cssを読みこんでセット """ with open(CSS_PATH, "r") as f: self.setStyleSheet("".join(f.readlines()))
class OtpOperations(object): def __init__(self): self.verbose = True self.address_increment_disable_reg = REGISTERS_BY_OFFSET_DICT[ADDRESS_AUTO_INCREMENT_ADDR] self.supervisor_disable_reg = REGISTERS_BY_OFFSET_DICT[SUPERVISOR_DISABLE_ADDR] self.supervisor_state_reg = REGISTERS_BY_OFFSET_DICT[SUPERVISOR_STATE_ADDR] self.regulator_poc_reg = REGISTERS_BY_OFFSET_DICT[REGULATOR_POC_ADDR] self.otp_addr_reg = REGISTERS_BY_OFFSET_DICT[OTP_A_ADDR] self.otp_d_reg = REGISTERS_BY_OFFSET_DICT[OTP_D_ADDR] self.otp_q_reg = REGISTERS_BY_OFFSET_DICT[OTP_Q_ADDR] self.otp_ctl_reg = REGISTERS_BY_OFFSET_DICT[OTP_CTL_ADDR] self.vg_ctl_reg = REGISTERS_BY_OFFSET_DICT[VG_CTL_ADDR] self.vg_mpp_reg = REGISTERS_BY_OFFSET_DICT[VG_MPP_ADDR] self.vg_mrr_h_reg = REGISTERS_BY_OFFSET_DICT[VG_MRR_H_ADDR] self.vg_mrr_l_reg = REGISTERS_BY_OFFSET_DICT[VG_MRR_L_ADDR] self.OTP_bytes=[] self.regulator_trim_reg = REGISTERS_BY_OFFSET_DICT[BYTE003] def loadWindow(self,wind): self.window=QMainWindow() self.window=wind self.progressBar=QProgressBar(self.window) self.progressBar.setGeometry(600, 660, 150, 15) def otp_disable(self): self.vg_ctl_reg.set_and_upload(0x00) self.otp_ctl_reg.set_and_upload(0x00) return def otp_operations_preps_are_complete(self, forcing=False): # first, check that the supervisor is disabled success, readback, log_string, log_color = self.supervisor_disable_reg.download_and_overwrite() if (readback & SUPERVISOR_DISABLE) == 0x00: UI.log('supervisor is not disabled', Qt.red) if not forcing: UI.log('....aborting!', Qt.red) return False else: UI.log('....override is ON', Qt.red) UI.log('....continuing!', Qt.red) # then, get the supervisor state, REG1 POC, and REG3 POC success, readback, log_string, log_color = self.supervisor_state_reg.download_and_overwrite() if (readback & SUPERVISOR_STATE) != 0x00: UI.log('supervisor is ACTIVE!', Qt.red) if not forcing: UI.log('....aborting!', Qt.red) return False else: UI.log('....override is ON', Qt.red) UI.log('....continuing!', Qt.red) # then, get the regulator POC bits success, readback, log_string, log_color = self.regulator_poc_reg.download_and_overwrite() if (readback & REGULATOR_POC) != 0x00: UI.log('at least one regulator is POWERED-DOWN', Qt.red) if not forcing: UI.log('....aborting!', Qt.red) return False else: UI.log('....override is ON', Qt.red) UI.log('....continuing!', Qt.red) # finally, set the regulator voltage if required self.regulator_trim_reg.set_and_upload(VREG_SETUP) return True def otp_read_setup(self, vg_mrr): self.vg_mrr_h_reg.set_and_upload(0x00) self.vg_mrr_l_reg.set_and_upload(vg_mrr & 0xFF) self.vg_ctl_reg.set_and_upload(VG_DBEN | VG_VRREN) self.otp_ctl_reg.set_and_upload(CK_ONESHOT_EN | OTP_TEST_EN | OTP_SEL) return def otp_write_setup(self): self.vg_mpp_reg.set_and_upload(0x00) self.vg_mrr_h_reg.set_and_upload(0x00) self.vg_mrr_l_reg.set_and_upload(VRR0 & 0xFF) self.vg_ctl_reg.set_and_upload(VG_VRREN | VG_VPPEN) # note read voltage must be enabled even for write self.otp_ctl_reg.set_and_upload(OTP_VCC_EXT_EN | OTP_TEST_EN | OTP_SEL) self.otp_ctl_reg.set_and_upload(OTP_VCC_EXT_EN | OTP_TEST_EN | OTP_WE | OTP_SEL) return def otp_write_clk_180(self): # print "write_180" data_otp_ck_high = (OTP_VCC_EXT_EN | OTP_TEST_EN | OTP_WE | OTP_SEL | OTP_CK) data_otp_ck_low = (OTP_VCC_EXT_EN | OTP_TEST_EN | OTP_WE | OTP_SEL) databytes = [data_otp_ck_high, data_otp_ck_low, ] UI.process_events() # time.sleep(2) SERIAL_CHANNELS.current_channel.smbus_block_write(OTP_CTL_ADDR, databytes) return def otp_write_clk_2000(self): # print "write_2000" data_otp_ck_high = (OTP_VCC_EXT_EN | OTP_TEST_EN | OTP_WE | OTP_SEL | OTP_CK) data_otp_ck_low = (OTP_VCC_EXT_EN | OTP_TEST_EN | OTP_WE | OTP_SEL) databytes = [] for i in range(10): databytes.append(data_otp_ck_high) databytes.append(data_otp_ck_low) UI.process_events() # time.sleep(2) SERIAL_CHANNELS.current_channel.smbus_block_write(OTP_CTL_ADDR, databytes) return def otp_read_atom(self, offset): """ otp_setup_for_read must be first called with the correct VG_MRR voltage """ self.otp_addr_reg.set_and_upload(offset & 0x7F) self.otp_ctl_reg.set_and_upload(CK_ONESHOT_EN | OTP_TEST_EN | OTP_SEL | OTP_CK) self.otp_ctl_reg.set_and_upload(CK_ONESHOT_EN | OTP_TEST_EN | OTP_SEL) success, readback, log_strng, log_color = self.otp_q_reg.download_and_overwrite() return success, readback, log_strng, log_color def otp_read_range(self, read_range=None, forcing=False, overwrite_queue=False): """ check the supervisor and regulator states, then if they are OK, iterate on a read of all OTP registers of the device """ UI.process_events() self.OTP_bytes[:]=[] if not self.otp_operations_preps_are_complete(forcing=forcing): return # setup the OTP for reading UI.log('enabling OTP for read') self.otp_read_setup(VRR0) # use "normal" read voltage UI.progressBar.setVisible(True) UI.progressBar.setMinimum(0) UI.progressBar.setMaximum(len(OTPBYTES_BY_OFFSET_DICT)) count = 0 UI.progressBar.setValue(count) self.progressBar.setVisible(True) self.progressBar.setMinimum(0) self.progressBar.setMaximum(len(OTPBYTES_BY_OFFSET_DICT)) count = 0 self.progressBar.setValue(count) UI.process_events() # loop over the range of registers, reading both "banks" or versions UI.log('reading device OTP') if read_range is None: working_read_range = range(0x00, 0x80) else: working_read_range = read_range for offset in working_read_range: otp_reg = OTPBYTES_BY_OFFSET_DICT[offset] count += 1 if (count % 5) == 0: UI.progressBar.setValue(count) self.progressBar.setValue(count) UI.process_events() success, readback, log_strng, log_color = self.otp_read_atom(offset) if success: otp_reg.current_active_val = readback readback_string = number_to_hex_string(readback, 2) otp_reg.active_hex_item.setText(readback_string) if overwrite_queue: otp_reg.update_bits_from_readback(readback) string = "offset=" + number_to_hex_string(offset, 2) + " / data=" + number_to_hex_string(readback, 2) self.OTP_bytes.append(number_to_hex_string(readback, 2)) UI.log(string) else: UI.log(log_strng, log_color) self.otp_disable() UI.log('OTP read finished') UI.progressBar.setVisible(False) self.progressBar.setVisible(False) return def otp_write_one_byte_from_queue_atom(self, offset, bit_position_list): bits_programmed = [] # offset should already be in this register, but just to be sure self.otp_addr_reg.set_and_upload(offset) for bit_pos in bit_position_list: # set the data bit at the correct position (all others 0) # and program the bit for 180 us self.otp_d_reg.set_and_upload(2**bit_pos & 0xFF) # DATA = 8-bit one hot value self.otp_write_setup() self.otp_write_clk_180() count = 1 bit_programmed = False while count < 10: # read the byte using VRR1, and check the bit which was just programmed self.otp_read_setup(VRR1) success, readback, log_strng, log_color = self.otp_read_atom(offset) if readback & 2**bit_pos != 0: read_passed = True else: read_passed = False if read_passed and count > 1: bit_programmed = True break # program the bit for 2000 us self.otp_write_setup() self.otp_write_clk_2000() count += 1 # read the byte using VRR2, and check the bit which was just programmed self.otp_read_setup(VRR2) success, readback, log_strng, log_color = self.otp_read_atom(offset) if readback & 2**bit_pos != 0: bit_programmed = True break bits_programmed.append(bit_programmed) UI.log("count="+str(count)) self.otp_disable() return bits_programmed def otp_write_range(self, write_rng, forcing=False): """ check the supervisor and regulator states, then if they are OK, iterate on a write of all OTP registers in the bank chosen """ errorFlag=False if not self.otp_operations_preps_are_complete(forcing=forcing): return # for OTP write, we need to make sure that the auto-increment bit is DISABLED success, readback, log_string, log_color = self.address_increment_disable_reg.download_and_overwrite() if (readback & ADDRESS_AUTO_INCREMENT_DISABLE) == 0x00: UI.log("address auto-increment bit is not set....setting it") self.address_increment_disable_reg.set_and_upload(readback | ADDRESS_AUTO_INCREMENT_DISABLE) if (readback & ADDRESS_AUTO_INCREMENT_DISABLE) == 0x00: UI.log('address auto-increment bit is not disabled', Qt.red) UI.log('....aborting!', Qt.red) return UI.progressBar.setVisible(True) UI.progressBar.setMinimum(0) UI.progressBar.setMaximum(len(OTPBYTES_BY_OFFSET_DICT)) count = 0 UI.progressBar.setValue(count) UI.process_events() progress_count = 0 self.progressBar.setVisible(True) self.progressBar.setMinimum(0) self.progressBar.setMaximum(len(OTPBYTES_BY_OFFSET_DICT)) count = 0 self.progressBar.setValue(count) for offset in write_rng: # get the data to be written # get the write data otp_reg = OTPBYTES_BY_OFFSET_DICT[offset] write_data = otp_reg.current_queue_val # get the current OTP contents, reading the OTP with vrr0 (normal) self.otp_read_setup(VRR0) success, readback, log_strng, log_color = self.otp_read_atom(offset) # put that readback into the OTP register table (or not) if success: otp_reg.current_active_val = readback readback_string = number_to_hex_string(readback, 2) otp_reg.active_hex_item.setText(readback_string) else: UI.log(log_strng, log_color) break # make a list of the bits that have to be written # OTP starts out as a zero, so we don't have to program 0's, # and we write only 1's where the OTP is not already a 1 failed = False bit_position_list = [] for i in range(8): if (write_data & 2**i) != 0 and (readback & 2**i) == 0: bit_position_list.append(i) if (write_data & 2**i) == 0 and (readback & 2**i) != 0: UI.log("OTP bit #"+str(i)+"cannot be UNset", Qt.red) failed = True break if failed: string = "OTP write halted" UI.log(string, Qt.red) errorFlag=True break string = "writing offset=" + str(offset) + ", bits=[" for bit_position in bit_position_list: string += str(bit_position) + "," string += "]" UI.log(string) bits_programmed = self.otp_write_one_byte_from_queue_atom(offset, bit_position_list) if not all(bits_programmed): string = "OTP write failed" errorFlag=True UI.log(string, Qt.red) break progress_count += 1 if (progress_count % 5) == 0: UI.progressBar.setValue(progress_count) self.progressBar.setValue(progress_count) UI.process_events() UI.log('disabling OTP write mode') self.otp_disable() UI.log('OTP write finished') UI.progressBar.setVisible(False) self.progressBar.setVisible(False) if errorFlag==True: return 0 return 1