Commit ded22e93 authored by Richard Hughes's avatar Richard Hughes

trivial: Add some initial colormunki support to gcm-parse-beagle

parent 7a4deeb5
......@@ -26,6 +26,7 @@
#include <libcolor-glib.h>
#include "gcm-sensor-huey-private.h"
#include "gcm-sensor-colormunki-private.h"
typedef enum {
GCM_PARSE_SECTION_LEVEL,
......@@ -52,6 +53,7 @@ typedef struct {
const gchar *summary_pretty;
gint dev;
gint ep;
const gchar *ep_description;
GcmParseEntryDirection direction;
} GcmParseEntry;
......@@ -68,6 +70,8 @@ gcm_parse_beagle_process_entry_huey (GcmParseEntry *entry)
const gchar *command_as_text;
GString *output;
entry->ep_description = "default";
/* only know how to parse 8 bytes */
tok = g_strsplit (entry->summary, " ", -1);
if (g_strv_length (tok) != 8) {
......@@ -117,6 +121,80 @@ out:
g_strfreev (tok);
}
/**
* gcm_parse_beagle_process_entry_colormunki:
**/
static void
gcm_parse_beagle_process_entry_colormunki (GcmParseEntry *entry)
{
gchar **tok;
guint j;
guchar cmd;
guint tok_len;
GString *output;
/* set ep description */
entry->ep_description = gcm_sensor_colormunki_endpoint_to_string (entry->ep);
output = g_string_new ("");
/* only know how to parse 8 bytes */
tok = g_strsplit (entry->summary, " ", -1);
tok_len = g_strv_length (tok);
/* status */
if (entry->ep == GCM_SENSOR_COLORMUNKI_EP_CONTROL &&
entry->direction == GCM_PARSE_ENTRY_DIRECTION_REPLY &&
tok_len == 2) {
/* dial position */
cmd = g_ascii_strtoll (tok[0], NULL, 16);
g_string_append_printf (output, "%s(dial-position-%s) ",
tok[0],
gcm_sensor_colormunki_dial_position_to_string (cmd));
/* button value */
cmd = g_ascii_strtoll (tok[1], NULL, 16);
g_string_append_printf (output, "%s(button-state-%s)",
tok[1],
gcm_sensor_colormunki_button_state_to_string (cmd));
goto out;
}
/* event */
if (entry->ep == GCM_SENSOR_COLORMUNKI_EP_EVENT &&
entry->direction == GCM_PARSE_ENTRY_DIRECTION_REPLY &&
tok_len == 8) {
g_print ("process 8: %s\n", entry->summary);
/* cmd */
cmd = g_ascii_strtoll (tok[0], NULL, 16);
g_string_append_printf (output, "%s(%s) ",
tok[0],
gcm_sensor_colormunki_command_value_to_string (cmd));
for (j=1; j<8; j++) {
cmd = g_ascii_strtoll (tok[j], NULL, 16);
g_string_append_printf (output, "%02x ", cmd);
}
if (output->len > 1)
g_string_set_size (output, output->len - 1);
goto out;
}
/* unknown command */
for (j=0; j<tok_len; j++) {
cmd = g_ascii_strtoll (tok[j], NULL, 16);
g_string_append_printf (output, "%02x ", cmd);
}
if (output->len > 1)
g_string_set_size (output, output->len - 1);
out:
if (output != NULL)
entry->summary_pretty = g_string_free (output, FALSE);
g_strfreev (tok);
}
/**
* gcm_parse_beagle_process_entry:
**/
......@@ -127,7 +205,7 @@ gcm_parse_beagle_process_entry (GcmSensorKind kind, GcmParseEntry *entry)
const gchar *direction = "??";
/* timeout */
if (g_strcmp0 (entry->record, "[250 IN-NAK]") == 0)
if (g_str_has_suffix (entry->record, "IN-NAK]"))
goto out;
/* device closed */
......@@ -137,10 +215,20 @@ gcm_parse_beagle_process_entry (GcmSensorKind kind, GcmParseEntry *entry)
/* usb error */
if (g_strcmp0 (entry->record, "[53 SYNC ERRORS]") == 0)
goto out;
if (g_strcmp0 (entry->record, "[240 IN-NAK]") == 0)
goto out;
/* other event to ignore */
if (g_strcmp0 (entry->record, "Bus event") == 0)
goto out;
if (g_strcmp0 (entry->record, "Get Configuration Descriptor") == 0)
goto out;
if (g_strcmp0 (entry->record, "Set Configuration") == 0)
goto out;
/* not sure what these are */
if (g_str_has_suffix (entry->record, " SOF]"))
goto out;
if (g_strcmp0 (entry->record, "Clear Endpoint Feature") == 0)
goto out;
/* start or end of file */
if (g_str_has_prefix (entry->record, "Capture started"))
......@@ -163,8 +251,12 @@ gcm_parse_beagle_process_entry (GcmSensorKind kind, GcmParseEntry *entry)
/* sexify the output */
if (kind == GCM_SENSOR_KIND_HUEY)
gcm_parse_beagle_process_entry_huey (entry);
retval = g_strdup_printf ("dev%02i ep%02i\t%s\t%s\n",
entry->dev, entry->ep, direction,
else if (kind == GCM_SENSOR_KIND_COLOR_MUNKI)
gcm_parse_beagle_process_entry_colormunki (entry);
retval = g_strdup_printf ("dev%02i ep%02i(%s)\t%s\t%s\n",
entry->dev, entry->ep,
entry->ep_description,
direction,
entry->summary_pretty != NULL ? entry->summary_pretty : entry->summary);
out:
return retval;
......@@ -219,6 +311,8 @@ main (gint argc, gchar *argv[])
split[i][0] == '\0')
continue;
g_print ("@@%i:%s\n", i, split[i]);
/* populate a GcmParseEntry */
sections = g_strsplit (split[i], ",", -1);
entry.record = sections[GCM_PARSE_SECTION_RECORD];
......@@ -227,6 +321,7 @@ main (gint argc, gchar *argv[])
entry.ep = atoi (sections[GCM_PARSE_SECTION_EP]);
entry.direction = GCM_PARSE_ENTRY_DIRECTION_UNKNOWN;
entry.summary_pretty = NULL;
entry.ep_description = NULL;
part = gcm_parse_beagle_process_entry (kind, &entry);
if (part != NULL) {
g_string_append (output, part);
......
......@@ -69,3 +69,18 @@ gcm_sensor_colormunki_dial_position_to_string (guchar value)
return "ambient";
return NULL;
}
/**
* gcm_sensor_colormunki_endpoint_to_string:
**/
const gchar *
gcm_sensor_colormunki_endpoint_to_string (guint value)
{
if (value == GCM_SENSOR_COLORMUNKI_EP_CONTROL)
return "control";
if (value == GCM_SENSOR_COLORMUNKI_EP_DATA)
return "data";
if (value == GCM_SENSOR_COLORMUNKI_EP_EVENT)
return "event";
return NULL;
}
......@@ -46,11 +46,85 @@ G_BEGIN_DECLS
#define GCM_SENSOR_COLORMUNKI_DIAL_POSITION_AMBIENT 0x03
#define GCM_SENSOR_COLORMUNKI_DIAL_POSITION_UNKNOWN 0xff
#define COLORMUNKI_EEPROM_OFFSET_SERIAL_NUMBER 0x0018
/*
* Triggers a request for a bulk transfer of EEPROM
* Length: 8 bytes
*
* address length (LE)
* ____|____ ____|____
* / \ / \
* 04 00 00 00 04 00 00 00
*/
#define GCM_SENSOR_COLORMUNKI_REQUEST_EEPROM_DATA 0x81
/*
* Gets the next hardware event
* Length: 8 bytes
*
* This blocks until the hardware sends an event, and must either be
* run in a mainloop or thread to avoid blocking.
*
* subcmd ----\ /------------ 32 bit event time
* cmd ----|\ || || || || ||
* Returns: 02 00 00 00 ac 62 07 00
* always zero ---||-||
*
* cmd is:
* 00 dial rotate
* 01 button pressed
* 02 button released
*
* subcmd is:
* 00 button event
* 01 dial rotate
*/
#define GCM_SENSOR_COLORMUNKI_REQUEST_INTERRUPT 0x83
/*
* Returns the major and minor version numbers
* Length: 24 bytes
*/
#define GCM_SENSOR_COLORMUNKI_REQUEST_VERSION_STRING 0x85
/*
* Returns the chip id
* Length: 8 bytes
*/
#define GCM_SENSOR_COLORMUNKI_REQUEST_FIRMWARE_PARAMS 0x86
/*
* Gets the device status
* Length: 2 bytes
*
* Returns: 00 00
* |/ ||
* dial pos -/ \--- button value
* - 00 = projector
* - 01 = surface
* - 02 = calibration
* - 03 = ambient
*/
#define GCM_SENSOR_COLORMUNKI_REQUEST_GET_STATUS 0x87
/*
* Returns the version string
* Length: 36 bytes
*/
#define GCM_SENSOR_COLORMUNKI_REQUEST_CHIP_ID 0x8A
/* USB endpoints in use */
#define GCM_SENSOR_COLORMUNKI_EP_CONTROL 0x00
#define GCM_SENSOR_COLORMUNKI_EP_DATA 0x01
#define GCM_SENSOR_COLORMUNKI_EP_EVENT 0x03
/* EEPROM is massive */
#define COLORMUNKI_EEPROM_OFFSET_SERIAL_NUMBER 0x0018 /* 10 bytes */
const gchar *gcm_sensor_colormunki_button_state_to_string (guchar value);
const gchar *gcm_sensor_colormunki_dial_position_to_string (guchar value);
const gchar *gcm_sensor_colormunki_command_value_to_string (guchar value);
const gchar *gcm_sensor_colormunki_endpoint_to_string (guint value);
G_END_DECLS
......
......@@ -107,40 +107,11 @@ gcm_sensor_colormunki_refresh_state_transfer_cb (struct libusb_transfer *transfe
goto out;
}
/*
* Returns: 00 00
* |/ ||
* dial pos -/ \--- button value
* - 00 = projector
* - 01 = surface
* - 02 = calibration
* - 03 = ambient
*/
if (reply[0] == GCM_SENSOR_COLORMUNKI_DIAL_POSITION_PROJECTOR) {
egg_debug ("now projector");
priv->dial_position = GCM_SENSOR_COLORMUNKI_DIAL_POSITION_PROJECTOR;
} else if (reply[0] == GCM_SENSOR_COLORMUNKI_DIAL_POSITION_SURFACE) {
egg_debug ("now surface");
priv->dial_position = GCM_SENSOR_COLORMUNKI_DIAL_POSITION_SURFACE;
} else if (reply[0] == GCM_SENSOR_COLORMUNKI_DIAL_POSITION_CALIBRATION) {
egg_debug ("now calibration");
priv->dial_position = GCM_SENSOR_COLORMUNKI_DIAL_POSITION_CALIBRATION;
} else if (reply[0] == GCM_SENSOR_COLORMUNKI_DIAL_POSITION_AMBIENT) {
egg_debug ("now ambient");
priv->dial_position = GCM_SENSOR_COLORMUNKI_DIAL_POSITION_AMBIENT;
} else {
egg_warning ("dial position unknown: 0x%02x", reply[0]);
priv->dial_position = GCM_SENSOR_COLORMUNKI_DIAL_POSITION_UNKNOWN;
}
/* button state */
if (reply[1] == GCM_SENSOR_COLORMUNKI_BUTTON_STATE_RELEASED) {
egg_debug ("button released");
} else if (reply[1] == GCM_SENSOR_COLORMUNKI_BUTTON_STATE_PRESSED) {
egg_debug ("button pressed");
} else {
egg_warning ("switch state unknown: 0x%02x", reply[1]);
}
/* sensor position and button state */
priv->dial_position = reply[0];
egg_debug ("dial now %s, button now %s",
gcm_sensor_colormunki_dial_position_to_string (priv->dial_position),
gcm_sensor_colormunki_button_state_to_string (reply[1]));
gcm_sensor_colormunki_print_data ("reply", transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE, transfer->actual_length);
out:
......@@ -164,8 +135,13 @@ gcm_sensor_colormunki_refresh_state (GcmSensorColormunki *sensor_colormunki, GEr
/* request new button state */
request = g_new0 (guchar, LIBUSB_CONTROL_SETUP_SIZE + 2);
libusb_fill_control_setup (request, LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE, 0x87, 0x00, 0, 2);
libusb_fill_control_transfer (priv->transfer_state, handle, request, &gcm_sensor_colormunki_refresh_state_transfer_cb, sensor_colormunki, 2000);
libusb_fill_control_setup (request,
LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,
GCM_SENSOR_COLORMUNKI_REQUEST_GET_STATUS,
0x00, 0, 2);
libusb_fill_control_transfer (priv->transfer_state, handle, request,
&gcm_sensor_colormunki_refresh_state_transfer_cb,
sensor_colormunki, 2000);
/* submit transfer */
retval = libusb_submit_transfer (priv->transfer_state);
......@@ -195,21 +171,6 @@ gcm_sensor_colormunki_transfer_cb (struct libusb_transfer *transfer)
return;
}
/*
* subcmd ----\ /------------ 32 bit event time
* cmd ----|\ || || || || ||
* Returns: 02 00 00 00 ac 62 07 00
* always zero ---||-||
*
* cmd is:
* 00 dial rotate
* 01 button pressed
* 02 button released
*
* subcmd is:
* 00 button event
* 01 dial rotate
*/
gcm_sensor_colormunki_print_data ("reply", transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE, transfer->actual_length);
timestamp = (reply[7] << 24) + (reply[6] << 16) + (reply[5] << 8) + (reply[4] << 0);
/* we only care when the button is pressed */
......@@ -247,8 +208,9 @@ gcm_sensor_colormunki_submit_transfer (GcmSensorColormunki *sensor_colormunki)
reply = g_new0 (guchar, 8);
handle = gcm_usb_get_device_handle (priv->usb);
libusb_fill_interrupt_transfer (priv->transfer_interrupt,
handle, 0x83, reply, 8,
libusb_fill_interrupt_transfer (priv->transfer_interrupt, handle,
GCM_SENSOR_COLORMUNKI_REQUEST_INTERRUPT,
reply, 8,
gcm_sensor_colormunki_transfer_cb,
sensor_colormunki, -1);
......@@ -273,13 +235,7 @@ gcm_sensor_colormunki_get_eeprom_data (GcmSensorColormunki *sensor_colormunki,
gboolean ret = FALSE;
GcmSensorColormunkiPrivate *priv = sensor_colormunki->priv;
/* do EEPROM request
*
* address length (LE)
* ____|____ ____|____
* / \ / \
* 04 00 00 00 04 00 00 00
*/
/* do EEPROM request */
egg_debug ("get EEPROM at 0x%04x for %i", address, size);
gcm_buffer_write_uint32_le (request, address);
gcm_buffer_write_uint32_le (request + 4, size);
......@@ -287,7 +243,8 @@ gcm_sensor_colormunki_get_eeprom_data (GcmSensorColormunki *sensor_colormunki,
handle = gcm_usb_get_device_handle (priv->usb);
retval = libusb_control_transfer (handle,
LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,
0x81, 0, 0, request, 8, 2000);
GCM_SENSOR_COLORMUNKI_REQUEST_EEPROM_DATA,
0, 0, request, 8, 2000);
if (retval < 0) {
g_set_error (error, GCM_SENSOR_ERROR,
GCM_SENSOR_ERROR_NO_SUPPORT,
......@@ -297,7 +254,8 @@ gcm_sensor_colormunki_get_eeprom_data (GcmSensorColormunki *sensor_colormunki,
}
/* read EEPROM */
retval = libusb_bulk_transfer (handle, 0x81,
retval = libusb_bulk_transfer (handle,
GCM_SENSOR_COLORMUNKI_REQUEST_EEPROM_DATA,
data, (gint) size, (gint*)&reply_read,
5000);
if (retval < 0) {
......@@ -374,7 +332,8 @@ gcm_sensor_colormunki_startup (GcmSensor *sensor, GError **error)
handle = gcm_usb_get_device_handle (priv->usb);
retval = libusb_control_transfer (handle,
LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,
0x86, 0, 0, buffer, 24, 2000);
GCM_SENSOR_COLORMUNKI_REQUEST_FIRMWARE_PARAMS,
0, 0, buffer, 24, 2000);
if (retval < 0) {
g_set_error (error, GCM_SENSOR_ERROR,
GCM_SENSOR_ERROR_NO_SUPPORT,
......@@ -393,7 +352,8 @@ gcm_sensor_colormunki_startup (GcmSensor *sensor, GError **error)
/* get chip ID */
retval = libusb_control_transfer (handle,
LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,
0x8A, 0, 0, buffer, 8, 2000);
GCM_SENSOR_COLORMUNKI_REQUEST_CHIP_ID,
0, 0, buffer, 8, 2000);
if (retval < 0) {
g_set_error (error, GCM_SENSOR_ERROR,
GCM_SENSOR_ERROR_NO_SUPPORT,
......@@ -409,7 +369,8 @@ gcm_sensor_colormunki_startup (GcmSensor *sensor, GError **error)
priv->version_string = g_new0 (gchar, 36);
retval = libusb_control_transfer (handle,
LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,
0x85, 0, 0, (guchar*) priv->version_string, 36, 2000);
GCM_SENSOR_COLORMUNKI_REQUEST_VERSION_STRING,
0, 0, (guchar*) priv->version_string, 36, 2000);
if (retval < 0) {
g_set_error (error, GCM_SENSOR_ERROR,
GCM_SENSOR_ERROR_NO_SUPPORT,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment