This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

USB2ANY: When trying to output the serial number of the device, it outputs a negative number

Part Number: USB2ANY

Tool/software:

I am attempting to learn how to use the device so we can use it for future projects. Currently, I am just trying out the basic functions that are listed in the documentation. While it seems that the device is recognized, the output for the serial number is -49 or -2, usually being -49. When I refer to the documentation, negative numbers are supposed to be error codes, -49 being a write timeout. What am I doing wrong? The only other info I can offer that may be worthwhile is that it is also stuck on a "BLINK BLINK BLINK BLINK pause" pattern with the LED on the front.

Code snippit

  • Use ctypes.c_buffer() or ctypes.create_string_buffer(), instead of a ctypes.c_long() reference, to get the serial number.

    Excerpt below is from an internal library (U2A_ERRWrapper uses __getattr__ to apply a wrapper function that checks for negative status code from API calls, and raises readable errors):

    class USB2ANY:
        u2adll = U2A_ERRWrapper(ctypes.WinDLL(_DLL_PATH))
        
        @classmethod
        def _FindControllers(cls) -> int:
            '''
            Scan the USB, and return the total number of USB2ANY found.
            '''
            return cls.u2adll.u2aFindControllers()
    
        @classmethod
        def _GetSerialNumber(cls, index: int) -> ctypes.c_buffer:
            '''
            Returns a ctypes.c_buffer containing the ascii bytes corresponding to 
            the serial number of a USB2ANY at the given index, with respect to 
            the ordering determined by _FindControllers function.
            '''
            buf = ctypes.c_buffer(40) # `40` is from SERNUM_LEN in USB2ANY_SDK.h
            status = cls.u2adll.u2aGetSerialNumber(index, buf)
            return buf
    
        @classmethod
        def Controllers(cls) -> List[ctypes.c_buffer]:
            '''
            Returns a list of ctypes.c_buffers containing the serial numbers of 
            all detected USB2ANY.
            '''
            return [cls._GetSerialNumber(i)
                    for i in range(cls._FindControllers())]
    
        def Open(self, controller: Optional[ctypes.c_buffer] = None) -> None:
            '''
            Acquires a handle to the controller specified by the serial number. 
            If controller argument is omitted, the handle will be acquired for 
            the first USB2ANY enumerated.
        
            On failure, the handle is not assigned, and an exception is raised.
            '''
            if controller is None: # use an empty buffer to select first U2A
                controller = ctypes.c_buffer(0)
            self._handle = self.u2adll.u2aOpen(controller)

    There's a lot of I2C functions, and the explanations in the API manual aren't great. A more thorough explanation of the transaction functions can be found here: https://e2e.ti.com/support/amplifiers-group/amplifiers/f/amplifiers-forum/1389829/usb2any-multibyte-i2c-transactions

    Note that if your application doesn't have pull-up resistors on the I2C bus, you may need to enable the USB2ANY's on-board pull-ups, which requires enabling the 3.3V power supply (u2aPower_Enable(HANDLE, 1, 2, 2)).