def __init__(self): """ Create a new USB context. """ context_p = libusb1.libusb_context_p() result = libusb1.libusb_init(byref(context_p)) if result: raise libusb1.USBError(result) self.__context_p = context_p
def open_cp2130(): context = libusb1.libusb_context_p() deviceList = libusb1.libusb_device_p_p() deviceCount = 0 deviceDescriptor = libusb1.libusb_device_descriptor() device = libusb1.libusb_device_p() cp2130Handle = libusb1.libusb_device_handle_p() kernelAttached = 0 if libusb1.libusb_init(byref(context)) != 0: print('Could not initialize libusb!') exit_cp2130() deviceCount = libusb1.libusb_get_device_list(context, byref(deviceList)) if deviceCount <= 0: print('No devices found!') exit_cp2130() for i in range(0, deviceCount): if libusb1.libusb_get_device_descriptor(deviceList[i], byref(deviceDescriptor)) == 0: if (deviceDescriptor.idVendor == 0x10C4) and (deviceDescriptor.idProduct == 0x87A0): device = deviceList[i] break if device == None: print('CP2130 device not found!') exit_cp2130() if libusb1.libusb_open(device, byref(cp2130Handle)) != 0: print('Could not open device!') exit_cp2130() if libusb1.libusb_kernel_driver_active(cp2130Handle, 0) != 0: libusb1.libusb_detach_kernel_driver(cp2130Handle, 0) kernelAttached = 1 if libusb1.libusb_claim_interface(cp2130Handle, 0) != 0: print('Could not claim interface!') exit_cp2130() if cp2130_libusb_set_usb_config(cp2130Handle) == False: exit_cp2130() if cp2130_libusb_set_spi_word(cp2130Handle) == False: exit_cp2130() print('Successfully opened CP2130!') return cp2130Handle, kernelAttached, deviceList, context
class CMWorker(QThread): connStateChanged = pyqtSignal(bool) boardsChanged = pyqtSignal(list) # initializing libusb and device things context = libusb1.libusb_context_p() deviceList = libusb1.libusb_device_p_p() deviceCount = 0 deviceDescriptor = libusb1.libusb_device_descriptor() device = libusb1.libusb_device_p() cp2130Handle = libusb1.libusb_device_handle_p() kernelAttached = 0 if libusb1.libusb_init(byref(context)) != 0: print('Could not initialize libusb!') def __init__(self, parent=None): super().__init__(parent) def __del__(self): # wait for the thread to finish before destroying object self.wait() def _flushRadio(self): cp2130_libusb_write(CMWorker.cp2130Handle, [0xAA, *struct.pack('>I', 0x00)]) def _regWr(self, reg, value): cp2130_libusb_write(CMWorker.cp2130Handle, [reg.value, *struct.pack('>I', value)]) def exit_cp2130(self): if self.cp2130Handle: libusb1.libusb_release_interface(self.cp2130Handle, 0) if self.kernelAttached: libusb1.libusb_attach_kernel_driver(self.cp2130Handle, 0) if self.cp2130Handle: libusb1.libusb_close(self.cp2130Handle) if self.deviceList: libusb1.libusb_free_device_list(self.deviceList, 1) if self.context: libusb1.libusb_exit(self.context) @pyqtSlot() def refreshBoards(self): dev_list = [] deviceCount = libusb1.libusb_get_device_list(self.context, byref(self.deviceList)) if deviceCount <= 0: print('No devices found!') for i in range(0, deviceCount): if libusb1.libusb_get_device_descriptor( self.deviceList[i], byref(self.deviceDescriptor)) == 0: if (self.deviceDescriptor.idVendor == 0x10C4) and (self.deviceDescriptor.idProduct == 0x87A0): dev_list.append(self.deviceList[i]) self.device = self.deviceList[i] # TODO: how to get device desciptor from libusb1? if dev_list: self.boardsChanged.emit(["cp2130"]) else: self.boardsChanged.emit([]) @pyqtSlot(str) def connectToBoard(self, board): # open device if libusb1.libusb_open(self.device, byref(self.cp2130Handle)) != 0: print('Could not open device!') return # See if a kernel driver is active already, if so detach it and store a flag so we can reattach when we are done if libusb1.libusb_kernel_driver_active(self.cp2130Handle, 0) != 0: libusb1.libusb_detach_kernel_driver(self.cp2130Handle, 0) self.kernelAttached = 1 # claim the device if libusb1.libusb_claim_interface(self.cp2130Handle, 0) != 0: print('Could not claim interface!') return print("Connected to {}".format(board)) cp2130_libusb_set_spi_word(self.cp2130Handle) cp2130_libusb_set_usb_config(self.cp2130Handle) self.connStateChanged.emit(True) @pyqtSlot(str) def disconnectBoard(self, board): self.exit_cp2130() print("Disconnected from {}".format(board)) self.connStateChanged.emit(False) self.refreshBoards() def startStream(self): if not self.cp2130Handle: return self._regWr(Reg.req, 0x0020) def stopStream(self): if not self.cp2130Handle: return self._regWr(Reg.req, 0x0010) def regOp(self, addr, data, write): buf = c_ubyte * 200 d = buf() count = 0 self._regWr(Reg.n0d1, 1 if write else 0) self._regWr(Reg.n0d2, addr << 16 | data) self._regWr(Reg.ctrl, 0x1000) if not write: self._flushRadio() self._regWr(Reg.req, 0x0100) time.sleep(0.05) while d[1] != 4 and count < 20: d = cp2130_libusb_read(CMWorker.cp2130Handle) count = count + 1 time.sleep(0.0008) success = (d[1] == 4) add = d[2] + 256 * d[3] val = d[4] + 256 * d[5] return [success, add, val] def readRegister(self, addr): if not self.cp2130Handle: return ret = [False, 0, 0] tries = 0 while (tries < 10) and not (ret[0] and addr == ret[1]): ret = self.regOp(addr, 0, False) tries = tries + 1 if tries >= 10: ret[0] = False return ret def writeRegister(self, addr, value): if not self.cp2130Handle: return tries = 0 while tries < 5: self.regOp(addr, value, True) ret = self.readRegister(addr) if ret[0] and (ret[2] == value): break tries = tries + 1 if tries == 5: return False else: return True def wideDisable(self): if not self.cp2130Handle: return # print('Wide Input Disable:') ret = self.readRegister(0x0C) if not ret[0]: print('Failed to connect to FlexEMG board.') return False else: value = ret[2] # print("Register Value: {:04x}".format(value)) if not (value % 2): # print('Wide In already disabled!') print('FlexEMG board connected and ready.') return True else: print('Wide In is enabled -- Disabling... ') value = value - 1 tries = 0 success = self.writeRegister(0x0C, value) if success: print('Wide In successfully disabled!') print('FlexEMG board connected and ready.') return True else: # print('Unable to disable Wide In!') print('Unable to configure FlexEMG board.') return False
class CMWorker(QThread): connStateChanged = pyqtSignal(bool) boardsChanged = pyqtSignal(list) regReadData = pyqtSignal(int, int, int) saveRegs = pyqtSignal(str, int) # ser = Device(lazy_open=True) # initializing libusb and device things context = libusb1.libusb_context_p() deviceList = libusb1.libusb_device_p_p() deviceCount = 0 deviceDescriptor = libusb1.libusb_device_descriptor() device = libusb1.libusb_device_p() cp2130Handle = libusb1.libusb_device_handle_p() kernelAttached = 0 regReadFailed = False if libusb1.libusb_init(byref(context)) != 0: print('Could not initialize libusb!') def __init__(self, parent=None): super().__init__(parent) self.regReadFailed = False def __del__(self): # wait for the thread to finish before destroying object self.wait() def _flushRadio(self): cp2130_libusb_write(CMWorker.cp2130Handle, [0xAA, *struct.pack('>I', 0x00)]) def _regWr(self, reg, value): cp2130_libusb_write(CMWorker.cp2130Handle, [reg.value, *struct.pack('>I', value)]) def _sendCmd(self, nm, cmd): print('Send Command') if nm == 0: self._regWr(Reg.n0d2, 1 << 10 | (cmd & 0x3FF)) self._regWr(Reg.ctrl, 0x1010) if nm == 1: self._regWr(Reg.n1d2, 1 << 10 | (cmd & 0x3FF)) self._regWr(Reg.ctrl, 0x2020) def _regOp(self, nm, addr, data, write): buf = c_ubyte * 200 d = buf() count = 0 if nm == 0: self._regWr(Reg.n0d1, 1 if write else 0) self._regWr(Reg.n0d2, addr << 16 | data) self._regWr(Reg.ctrl, 0x1000) if not write: self._flushRadio() self._regWr(Reg.req, 0x0100) time.sleep(0.05) while d[1] != 4 and count < 20: d = cp2130_libusb_read(CMWorker.cp2130Handle) count = count + 1 time.sleep(0.0008) success = (d[1] == 4) add = d[2] + 256 * d[3] val = d[4] + 256 * d[5] return [success, add, val] if nm == 1: self._regWr(Reg.n1d1, 1 if write else 0) self._regWr(Reg.n1d2, addr << 16 | data) self._regWr(Reg.ctrl, 0x2000) if not write: self._flushRadio() self._regWr(Reg.req, 0x0200) time.sleep(0.05) while d[1] != 4 and count < 150: d = cp2130_libusb_read(CMWorker.cp2130Handle) count = count + 1 time.sleep(0.0008) success = (d[1] == 4) add = d[2] + 256 * d[3] val = d[4] + 256 * d[5] return [success, add, val] @pyqtSlot(str) def regFile(self, fn): self.saveRegs.emit(fn, 0) def exit_cp2130(self): if self.cp2130Handle: libusb1.libusb_release_interface(self.cp2130Handle, 0) if self.kernelAttached: libusb1.libusb_attach_kernel_driver(self.cp2130Handle, 0) if self.cp2130Handle: libusb1.libusb_close(self.cp2130Handle) if self.deviceList: libusb1.libusb_free_device_list(self.deviceList, 1) if self.context: libusb1.libusb_exit(self.context) @pyqtSlot() def refreshBoards(self): dev_list = [] deviceCount = libusb1.libusb_get_device_list(self.context, byref(self.deviceList)) if deviceCount <= 0: print('No devices found!') for i in range(0, deviceCount): if libusb1.libusb_get_device_descriptor( self.deviceList[i], byref(self.deviceDescriptor)) == 0: if (self.deviceDescriptor.idVendor == 0x10C4) and (self.deviceDescriptor.idProduct == 0x87A0): dev_list.append(self.deviceList[i]) self.device = self.deviceList[i] # TODO: how to get device desciptor from libusb1? if dev_list: self.boardsChanged.emit(["cp2130"]) else: self.boardsChanged.emit([]) @pyqtSlot(str) def connectToBoard(self, board): # open device if libusb1.libusb_open(self.device, byref(self.cp2130Handle)) != 0: print('Could not open device!') return # See if a kernel driver is active already, if so detach it and store a flag so we can reattach when we are done if libusb1.libusb_kernel_driver_active(self.cp2130Handle, 0) != 0: libusb1.libusb_detach_kernel_driver(self.cp2130Handle, 0) self.kernelAttached = 1 # claim the device if libusb1.libusb_claim_interface(self.cp2130Handle, 0) != 0: print('Could not claim interface!') return print("Connected to {}".format(board)) cp2130_libusb_set_spi_word(self.cp2130Handle) cp2130_libusb_set_usb_config(self.cp2130Handle) self.connStateChanged.emit(True) @pyqtSlot(str) def disconnectBoard(self, board): self.exit_cp2130() print("Disconnected from {}".format(board)) self.connStateChanged.emit(False) self.refreshBoards() @pyqtSlot(int, int) def nmicCommand(self, nm, cmd): if not self.cp2130Handle: return self._sendCmd(nm, cmd) @pyqtSlot(int, int, int) def writeReg(self, nm, addr, value): if not self.cp2130Handle: return tries = 0 if addr > 0x0F: self._regOp(nm, addr, value, True) return True while tries < 5: self._regOp(nm, addr, value, True) ret = self.readReg(nm, addr) if ret[0] and (ret[2] == value): break tries = tries + 1 if tries == 5: success = False else: success = True self.regReadData.emit(nm, addr, value) return success @pyqtSlot(int, int) def readReg(self, nm, addr): if not self.cp2130Handle: return if (addr != 0) and self.regReadFailed: return ret = [False, 0, 0] tries = 0 while (tries < 10) and not (ret[0] and addr == ret[1]): ret = self._regOp(nm, addr, 0, False) tries = tries + 1 if tries < 10: self.regReadFailed = False print("Read register from NM {}: {:04x} {:04x}".format( nm, addr, ret[2])) self.regReadData.emit(nm, addr, ret[2]) else: print("Failed to read register{:04x}".format(addr)) self.regReadFailed = True return ret # @pyqtSlot() def enableInterpolate(self): if not self.cp2130Handle: return self._regWr(Reg.req, 0x8000) # @pyqtSlot() def disableInterpolate(self): if not self.cp2130Handle: return self._regWr(Reg.req, 0x4000) def startStream(self): if not self.cp2130Handle: return self._regWr(Reg.req, 0x0020) def stopStream(self): if not self.cp2130Handle: return self._regWr(Reg.req, 0x0010) @pyqtSlot(int, bool) def setWideIn(self, nm, enable): if not self.cp2130Handle: return self.regReadFailed = False r = self.readReg(nm, 0x0C) if not r: print('Failed to read wide input register') return False if not r[0]: print('Failed to read wide input register') return False else: value = r[2] print("Register Value: {:04x}".format(value)) value = value & 0xFFFE if enable: value = value + 1 print('Writing wide input mode') tries = 0 success = self.writeReg(nm, 0x0C, value) if success: if enable: print('Wide input enabled!') else: print('Wide input disabled!') return True else: print('Unable to configure wide input mode.') return False @pyqtSlot(int) def enableHV(self, nm): if not self.cp2130Handle: return regval = self.readReg(nm, 0x02) if not regval[0]: print('Failed to read power config register!') return False else: newval = (regval[2] & 0xFFFE) # clear lv_ratio newval = (newval | 0x0E20 ) # set hvclock and first step of charge pump if self.writeReg(nm, 0x02, newval): print('Successfully set LV_RATIO and HV Clk') print('Successfully set to 6V') else: print('Failed to set LV_RATIO and HV Clk') return False print('Stepping to 6V...') self._sendCmd(nm, 0x03) self._sendCmd(nm, 0x03) time.sleep(1) newval = (newval & 0xFF9F) newval = (newval | 0x0040) if self.writeReg(nm, 0x02, newval): print('Successfully set to 9V') else: print('Failed to set to 9V') return False print('Stepping to 9V...') self._sendCmd(nm, 0x03) self._sendCmd(nm, 0x03) time.sleep(1) newval = (newval | 0x0060) if self.writeReg(nm, 0x02, newval): print('Successfully set to 12V') else: print('Failed to set to 12V') return False print('Stepping to 12V...') self._sendCmd(nm, 0x03) self._sendCmd(nm, 0x03) time.sleep(1) @pyqtSlot(int, int, int) def setZmeasure(self, nm, mag, cycles): print("Set z-measure {} mag, {} cycles".format(mag, cycles)) if not self.cp2130Handle: return magbits = ((2**mag) - 1) << 4 regval = self.readReg(nm, 0x0C) if not regval[0]: print('Failed to read z-measure magnitude register!') return False else: newval = (regval[2] & 0xFF8F) + magbits if self.writeReg(nm, 0x0C, newval): print('Successfully set impedance measurement magnitude') else: print('Failed to set impedance measurement magnitude') return False cycles = (cycles - 1) << 4 regval = self.readReg(nm, 0x0D) if not regval[0]: print('Failed to read register!') return False else: newval = (regval[2] & 0xFF0F) + cycles if self.writeReg(nm, 0x0D, newval): print('Successfully set impedance measurement cycles') return True print('Failed to set impedance measurement cycles') return False
def __init__(self): context_p = libusb1.libusb_context_p() result = libusb1.libusb_init(byref(context_p)) if result: raise libusb1.USBError, result self.context_p = context_p