Click here to Skip to main content
15,867,308 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I use a USB Device, a Press-Button with RGB-LED from ultimarc:

Its connected to a linux device and I want to set the color of it and query the pressed state.

Link: USB Button :: USBButton[^]

For this device there is a existing windows API for accessing the Button, like
-set-color (USBButtonConfigureColor)
-get-state (USBButtonGetState)

http://www.ultimarc.com/PacDriveSDK.zip


There is also a linux api project, but it does not have the full functions like the windows API. It does have the set-color functionality (updateBoardUSBButtonColor), but not the get-state functionality.

Link[^]

As the maintainer of the project did not responded, my goal is to extend the linux api project myself with the functionality to read the pressed-state of the USB-button. As there is a functional windows implementation that has the needed functionality, it must be possible to port it to the linux project..

I learned that the linux api project of the button uses libusb-1.0, and that I should probably use libusb_control_transfer to read from the device.

What I have tried:

I build the library and coded a small c-programm that uses the set-color functionality (updateBoardUSBButtonColor), that worked very well.

To get also the info about the button (is pressed or not) I tried to extend the linux library, by adding a new function,
but the reading does not seems to be correct, it always returns empty results.
I guess the parameters of libusb_control_transfer might be the problem, but I dont know how to find the correct settings for my device....

Thanks in advance for help or suggestions :-)

C++
bool readUSBButton(unsigned char* barray, int autoconnect, bool transfer, unsigned int size)
{
 
  #define BUTTON_READ 0x02
  libusb_context *ctx = NULL;
  struct libusb_device_handle *handle = NULL;
  // USBBTN_MESG_LENGTH = 4 
  unsigned char mesg[USBBTN_MESG_LENGTH] = {0,0,0,0};

  bool result = true;

  int pos = 0;
  int ret = 0;

  if (transfer)
  {
    handle = openUSB(ctx, USBBTN_VENDOR, USBBTN_PRODUCT, USBBTN_INTERFACE, autoconnect);

    if (!handle)
    {
      result = false;
      goto error;
    }
  }

  while (pos < size)
  {

    debug ("reading (%i): %x, %x, %x, %x", pos, mesg[0], mesg[1], mesg[2], mesg[3]);
    if (transfer)
    {

ret = libusb_control_transfer(handle, 0xa1, 0x01, 0x3000, 0x0000, mesg , USBBTN_MESG_LENGTH, UM_TIMEOUT) ;

      printf(" read: %x %x %x %x  | ret= %i", mesg[0], mesg[1], mesg[2], mesg[3], ret); 
      debug ("read result: %i", ret);
    }
    pos+=USBBTN_MESG_LENGTH;
  }

exit:
  if (transfer)
  {
    closeUSB(ctx, handle, USBBTN_INTERFACE);
  }
  else
  {
    log_info ("board array was not read !!!");
  }
  return result;

error:
  return result;

}
Posted
Updated 17-May-21 11:32am
v2

1 solution

I don't own the part, but I think it should be possible to rewrite the function known to Windows for Linux. The USB command should be the same.

C
typedef struct {
	UCHAR ReportID;
	UCHAR ReportBuffer[96];
} REPORT_BUF, *PREPORT_BUF;

PACDRIVE_API BOOL __stdcall USBButtonGetState(INT id, PBOOL state)
{
	if(m_hidDeviceData[id].Type != DEVICETYPE_USBBUTTON)
		FALSE;

	REPORT_BUF reportBuffer;
	BOOL retVal = FALSE;

	reportBuffer.ReportID = 0;
	reportBuffer.ReportBuffer[0] = 0x02;
	reportBuffer.ReportBuffer[1] = 0x00;
	reportBuffer.ReportBuffer[2] = 0x00;
	reportBuffer.ReportBuffer[3] = 0x00;

	retVal = UsbWrite(&m_hidDeviceData[id], &reportBuffer);

	if(!retVal)
		return retVal;

	memset(&reportBuffer, 0, sizeof(REPORT_BUF));

	retVal = UsbRead(&m_hidDeviceData[id], &reportBuffer);

	if(!retVal)
		return retVal;

	*state = reportBuffer.ReportBuffer[0];

	return retVal;
}


Looks like sending 4 Bytes, clearing the buffer, read and return the first byte.

In the sources you find this hint:
C
// For more info use FillDeviceInfo
// https://xp-dev.com/sc/36636/44/%2Ftrunk%2FProjects%2Fusb-device-hid-transfer-project-at91sam7x-ek%2Fusb-device-hid-transfer-project%2FHIDTest%2Fpnp.c

Looks like you find more Infos about USB HID or at91sam7x with google.

Perhaps you look at this too:
How to Communicate with its USB Devices using HID Protocol[^]
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900