[aravis/wip/emmanuel/usb3vision] wip: usb3vision memory write support



commit 19e67c46694d628cc3185df6c81b26ca5bbcdd67
Author: Emmanuel Pacaud <emmanuel gnome org>
Date:   Wed May 18 18:10:33 2016 +0200

    wip: usb3vision memory write support

 docs/reference/aravis/aravis-docs.xml     |    1 +
 docs/reference/aravis/aravis-sections.txt |   80 +++++++++
 src/arvuvcp.c                             |   35 +++-
 src/arvuvcp.h                             |   28 +++-
 src/arvuvdevice.c                         |  256 ++++++++++++++++++-----------
 5 files changed, 294 insertions(+), 106 deletions(-)
---
diff --git a/docs/reference/aravis/aravis-docs.xml b/docs/reference/aravis/aravis-docs.xml
index 14074c0..1a5399a 100644
--- a/docs/reference/aravis/aravis-docs.xml
+++ b/docs/reference/aravis/aravis-docs.xml
@@ -89,6 +89,7 @@
                        <xi:include href="xml/arvuvinterface.xml"/>
                        <xi:include href="xml/arvuvdevice.xml"/>
                        <xi:include href="xml/arvuvstream.xml"/>
+                       <xi:include href="xml/arvuvcp.xml"/>
                </chapter>
 
                <chapter>
diff --git a/docs/reference/aravis/aravis-sections.txt b/docs/reference/aravis/aravis-sections.txt
index 0d2b810..60b1d76 100644
--- a/docs/reference/aravis/aravis-sections.txt
+++ b/docs/reference/aravis/aravis-sections.txt
@@ -1319,6 +1319,86 @@ ARAVIS_PACKED_STRUCTURE
 </SECTION>
 
 <SECTION>
+<FILE>arvuvcp</FILE>
+<TITLE>ArvUvcp</TITLE>
+ArvUvcpCommand
+ArvUvcpPacket
+ArvUvcpPacketType
+arv_uvcp_next_packet_id
+arv_uvcp_packet_debug
+arv_uvcp_packet_free
+arv_uvcp_packet_get_command
+arv_uvcp_packet_get_packet_id
+arv_uvcp_packet_get_packet_type
+arv_uvcp_packet_get_read_memory_ack_data
+arv_uvcp_packet_get_read_memory_ack_size
+arv_uvcp_packet_get_write_memory_ack_size
+arv_uvcp_packet_get_write_memory_cmd_data
+arv_uvcp_packet_new_read_memory_cmd
+arv_uvcp_packet_new_write_memory_cmd
+arv_uvcp_packet_set_packet_id
+arv_uvcp_packet_to_string
+<SUBSECTION Standard>
+<SUBSECTION Private>
+ArvUvcpHeader
+ArvUvcpManifestEntry
+ArvUvcpReadMemoryCmd
+ArvUvcpReadMemoryCmdInfos
+ArvUvcpWriteMemoryAck
+ArvUvcpWriteMemoryAckInfos
+ArvUvcpWriteMemoryCmd
+ArvUvcpWriteMemoryCmdInfos
+ARV_ABRM_ACCESS_PRIVILEGE
+ARV_ABRM_DEVICE_CAPABILITY
+ARV_ABRM_DEVICE_CONFIGURATION
+ARV_ABRM_DEVICE_VERSION
+ARV_ABRM_FAMILY_NAME
+ARV_ABRM_GENCP_VERSION
+ARV_ABRM_HEARTBEAT_TIMEOUT
+ARV_ABRM_IMPLEMENTATION_ENDIANESS
+ARV_ABRM_MANIFEST_TABLE_ADDRESS
+ARV_ABRM_MANUFACTURER_INFO
+ARV_ABRM_MANUFACTURER_NAME
+ARV_ABRM_MAX_DEVICE_RESPONSE_TIME
+ARV_ABRM_MESSAGE_CHANNEL_ID
+ARV_ABRM_MODEL_NAME
+ARV_ABRM_PROTOCOL_ENDIANESS
+ARV_ABRM_RESERVED
+ARV_ABRM_SBRM_ADDRESS
+ARV_ABRM_SERIAL_NUMBER
+ARV_ABRM_TIMESTAMP
+ARV_ABRM_TIMESTAMP_INCREMENT
+ARV_ABRM_TIMESTAMP_LATCH
+ARV_ABRM_USER_DEFINED_NAME
+ARV_SBRM_CURRENT_SPEED
+ARV_SBRM_EIRM_ADDRESS
+ARV_SBRM_EIRM_LENGTH
+ARV_SBRM_IIDC2_ADDRESS
+ARV_SBRM_MAX_ACK_TRANSFER
+ARV_SBRM_MAX_CMD_TRANSFER
+ARV_SBRM_NUM_STREAM_CHANNELS
+ARV_SBRM_RESERVED
+ARV_SBRM_SIRM_ADDRESS
+ARV_SBRM_SIRM_LENGTH
+ARV_SBRM_U3VCP_CAPABILITY
+ARV_SBRM_U3VCP_CONFIGURATION
+ARV_SBRM_U3V_VERSION
+ARV_SI_CONTROL
+ARV_SI_INFO
+ARV_SI_INFO_ALIGNMENT_MASK
+ARV_SI_INFO_ALIGNMENT_SHIFT
+ARV_SI_MAX_LEADER_SIZE
+ARV_SI_MAX_TRAILER_SIZE
+ARV_SI_PAYLOAD_COUNT
+ARV_SI_PAYLOAD_SIZE
+ARV_SI_REQ_LEADER_SIZE
+ARV_SI_REQ_PAYLOAD_SIZE
+ARV_SI_REQ_TRAILER_SIZE
+ARV_SI_TRANSFER1_SIZE
+ARV_SI_TRANSFER2_SIZE
+</SECTION>
+
+<SECTION>
 <FILE>arvdomtext</FILE>
 <TITLE>ArvDomText</TITLE>
 arv_dom_text_new
diff --git a/src/arvuvcp.c b/src/arvuvcp.c
index f87a52c..b2fe9db 100644
--- a/src/arvuvcp.c
+++ b/src/arvuvcp.c
@@ -86,23 +86,22 @@ arv_uvcp_packet_new_read_memory_cmd (guint32 address, guint32 size, guint16 pack
 ArvUvcpPacket *
 arv_uvcp_packet_new_write_memory_cmd (guint32 address, guint32 size, guint16 packet_id, size_t *packet_size)
 {
-       ArvUvcpPacket *packet;
-       guint32 n_address = g_htonl (address);
+       ArvUvcpWriteMemoryCmd *packet;
 
        g_return_val_if_fail (packet_size != NULL, NULL);
 
-       *packet_size = sizeof (ArvUvcpHeader) + sizeof (guint32) + size;
+       *packet_size = sizeof (ArvUvcpWriteMemoryCmd) + size;
 
        packet = g_malloc (*packet_size);
 
-       packet->header.packet_type = g_htons (ARV_UVCP_PACKET_TYPE_CMD);
-       packet->header.command = g_htons (ARV_UVCP_COMMAND_WRITE_MEMORY_CMD);
-       packet->header.size = g_htons (sizeof (guint32) + size);
-       packet->header.id = g_htons (packet_id);
-
-       memcpy (&packet->data, &n_address, sizeof (guint32));
+       packet->header.magic = GUINT32_TO_LE (ARV_UVCP_MAGIC);
+       packet->header.packet_type = GUINT16_TO_LE (ARV_UVCP_PACKET_TYPE_CMD);
+       packet->header.command = GUINT16_TO_LE (ARV_UVCP_COMMAND_WRITE_MEMORY_CMD);
+       packet->header.size = GUINT16_TO_LE (sizeof (ArvUvcpWriteMemoryCmdInfos) + size);
+       packet->header.id = GUINT16_TO_LE (packet_id);
+       packet->infos.address = GUINT64_TO_LE (address);
 
-       return packet;
+       return (ArvUvcpPacket *) packet;
 }
 
 static const char *
@@ -181,6 +180,22 @@ arv_uvcp_packet_to_string (const ArvUvcpPacket *packet)
                        {
                                break;
                        }
+               case ARV_UVCP_COMMAND_WRITE_MEMORY_CMD:
+                       {
+                               ArvUvcpWriteMemoryCmd *cmd_packet = (void *) packet;
+
+                               value = GUINT64_FROM_LE (cmd_packet->infos.address);
+                               g_string_append_printf (string, "address      = %10u (0x%08x)\n",
+                                                       value, value);
+                       }
+               case ARV_UVCP_COMMAND_WRITE_MEMORY_ACK:
+                       {
+                               ArvUvcpWriteMemoryAck *cmd_packet = (void *) packet;
+
+                               value = GUINT64_FROM_LE (cmd_packet->infos.bytes_written);
+                               g_string_append_printf (string, "written      = %10u (0x%08x)\n",
+                                                       value, value);
+                       }
        }
 
        packet_size = sizeof (ArvUvcpHeader) + GUINT16_FROM_LE (packet->header.size);
diff --git a/src/arvuvcp.h b/src/arvuvcp.h
index cb84b85..9d98f19 100644
--- a/src/arvuvcp.h
+++ b/src/arvuvcp.h
@@ -81,6 +81,7 @@ G_BEGIN_DECLS
 
 /**
  * ArvUvcpPacketType:
+ * @ARV_UVCP_PACKET_TYPE_ERROR: error packet
  * @ARV_UVCP_PACKET_TYPE_ACK: acknowledge packet
  * @ARV_UVCP_PACKET_TYPE_CMD: command packet
  */
@@ -135,6 +136,25 @@ typedef struct ARAVIS_PACKED_STRUCTURE {
        ArvUvcpReadMemoryCmdInfos infos;
 } ArvUvcpReadMemoryCmd;
 
+typedef struct ARAVIS_PACKED_STRUCTURE {
+       guint64 address;
+} ArvUvcpWriteMemoryCmdInfos;
+
+typedef struct ARAVIS_PACKED_STRUCTURE {
+       ArvUvcpHeader header;
+       ArvUvcpWriteMemoryCmdInfos infos;
+} ArvUvcpWriteMemoryCmd;
+
+typedef struct ARAVIS_PACKED_STRUCTURE {
+       guint16 unknown;
+       guint16 bytes_written;
+} ArvUvcpWriteMemoryAckInfos;
+
+typedef struct ARAVIS_PACKED_STRUCTURE {
+       ArvUvcpHeader header;
+       ArvUvcpWriteMemoryAckInfos infos;
+} ArvUvcpWriteMemoryAck;
+
 /**
  * ArvUvcpPacket:
  * @header: packet header
@@ -232,7 +252,13 @@ arv_uvcp_packet_get_read_memory_ack_size (size_t data_size)
 static inline void *
 arv_uvcp_packet_get_write_memory_cmd_data (const ArvUvcpPacket *packet)
 {
-       return (char *) packet + sizeof (ArvUvcpPacket);
+       return (char *) packet + sizeof (ArvUvcpWriteMemoryCmd);
+}
+
+static inline size_t
+arv_uvcp_packet_get_write_memory_ack_size (void)
+{
+       return sizeof (ArvUvcpWriteMemoryAck);
 }
 
 static inline guint16
diff --git a/src/arvuvdevice.c b/src/arvuvdevice.c
index 03edb1a..414932b 100644
--- a/src/arvuvdevice.c
+++ b/src/arvuvdevice.c
@@ -70,6 +70,167 @@ arv_uv_device_create_stream (ArvDevice *device, ArvStreamCallback callback, void
        return stream;
 }
 
+static gboolean
+_read_memory (ArvUvDevice *uv_device, guint32 address, guint32 size, void *buffer, GError **error)
+{
+       ArvUvcpPacket *packet;
+       size_t packet_size;
+       size_t answer_size;
+       gboolean success = FALSE;
+
+       answer_size = arv_uvcp_packet_get_read_memory_ack_size (size);
+
+       g_return_val_if_fail (answer_size <= 1024, FALSE);
+
+       packet = arv_uvcp_packet_new_read_memory_cmd (address, size, 0, &packet_size);
+
+       do {
+               int transferred;
+               void *read_packet;
+               size_t read_packet_size;
+
+               read_packet_size = arv_uvcp_packet_get_read_memory_ack_size (size);
+               read_packet = g_malloc0 (read_packet_size);
+
+               uv_device->priv->packet_id = arv_uvcp_next_packet_id (uv_device->priv->packet_id);
+               arv_uvcp_packet_set_packet_id (packet, uv_device->priv->packet_id);
+
+               arv_uvcp_packet_debug (packet, ARV_DEBUG_LEVEL_LOG);
+
+               g_assert (libusb_claim_interface (uv_device->priv->usb_device, 0) >= 0);
+               g_assert (libusb_bulk_transfer (uv_device->priv->usb_device, (0x04 | LIBUSB_ENDPOINT_OUT),
+                                               (guchar *) packet, packet_size, &transferred, 0) >= 0);
+               g_assert (libusb_bulk_transfer (uv_device->priv->usb_device, (0x84 | LIBUSB_ENDPOINT_IN),
+                                               (guchar *) read_packet, read_packet_size, &transferred, 0) >= 
0);
+               g_assert (libusb_release_interface (uv_device->priv->usb_device, 0) >= 0);
+               success = TRUE;
+
+               memcpy (buffer, arv_uvcp_packet_get_read_memory_ack_data (read_packet), size);
+
+               arv_uvcp_packet_debug (read_packet, ARV_DEBUG_LEVEL_LOG);
+
+               g_free (read_packet);
+
+       } while (!success);
+
+       arv_uvcp_packet_free (packet);
+
+       if (!success) {
+               if (error != NULL && *error == NULL)
+                       *error = g_error_new (ARV_DEVICE_ERROR, ARV_DEVICE_STATUS_TIMEOUT,
+                                             "[ArvDevice::read_memory] Timeout");
+       }
+
+       return success;
+}
+
+static gboolean
+arv_uv_device_read_memory (ArvDevice *device, guint32 address, guint32 size, void *buffer, GError **error)
+{
+       ArvUvDevice *uv_device = ARV_UV_DEVICE (device);
+       int i;
+       gint32 block_size;
+       guint data_size_max;
+
+       data_size_max = uv_device->priv->data_size_max;
+
+       for (i = 0; i < (size + data_size_max - 1) / data_size_max; i++) {
+               block_size = MIN (data_size_max, size - i * data_size_max);
+               if (!_read_memory (uv_device,
+                                  address + i * data_size_max,
+                                  block_size, ((char *) buffer) + i * data_size_max, error))
+                       return FALSE;
+       }
+
+       return TRUE;
+}
+
+static gboolean
+_write_memory (ArvUvDevice *uv_device, guint32 address, guint32 size, void *buffer, GError **error)
+{
+       ArvUvcpPacket *packet;
+       size_t packet_size;
+       size_t answer_size;
+       gboolean success = FALSE;
+
+       answer_size = arv_uvcp_packet_get_write_memory_ack_size ();
+
+       g_return_val_if_fail (answer_size <= 1024, FALSE);
+
+       packet = arv_uvcp_packet_new_write_memory_cmd (address, size, 0, &packet_size);
+       memcpy (arv_uvcp_packet_get_write_memory_cmd_data (packet), buffer, size);
+
+       do {
+               int transferred;
+               void *read_packet;
+               size_t read_packet_size;
+
+               read_packet_size = arv_uvcp_packet_get_read_memory_ack_size (size);
+               read_packet = g_malloc0 (read_packet_size);
+
+               uv_device->priv->packet_id = arv_uvcp_next_packet_id (uv_device->priv->packet_id);
+               arv_uvcp_packet_set_packet_id (packet, uv_device->priv->packet_id);
+
+               arv_uvcp_packet_debug (packet, ARV_DEBUG_LEVEL_LOG);
+
+               g_assert (libusb_claim_interface (uv_device->priv->usb_device, 0) >= 0);
+               g_assert (libusb_bulk_transfer (uv_device->priv->usb_device, (0x04 | LIBUSB_ENDPOINT_OUT),
+                                               (guchar *) packet, packet_size, &transferred, 0) >= 0);
+               g_assert (libusb_bulk_transfer (uv_device->priv->usb_device, (0x84 | LIBUSB_ENDPOINT_IN),
+                                               (guchar *) read_packet, read_packet_size, &transferred, 0) >= 
0);
+               g_assert (libusb_release_interface (uv_device->priv->usb_device, 0) >= 0);
+               success = TRUE;
+
+               arv_uvcp_packet_debug (read_packet, ARV_DEBUG_LEVEL_LOG);
+
+               g_free (read_packet);
+
+       } while (!success);
+
+       arv_uvcp_packet_free (packet);
+
+       if (!success) {
+               if (error != NULL && *error == NULL)
+                       *error = g_error_new (ARV_DEVICE_ERROR, ARV_DEVICE_STATUS_TIMEOUT,
+                                             "[ArvDevice::write_memory] Timeout");
+       }
+
+       return success;
+}
+
+static gboolean
+arv_uv_device_write_memory (ArvDevice *device, guint32 address, guint32 size, void *buffer, GError **error)
+{
+       ArvUvDevice *uv_device = ARV_UV_DEVICE (device);
+       int i;
+       gint32 block_size;
+       guint data_size_max;
+
+       data_size_max = uv_device->priv->data_size_max;
+
+       for (i = 0; i < (size + data_size_max - 1) / data_size_max; i++) {
+               block_size = MIN (data_size_max, size - i * data_size_max);
+               if (!_write_memory (uv_device,
+                                  address + i * data_size_max,
+                                  block_size, ((char *) buffer) + i * data_size_max, error))
+                       return FALSE;
+       }
+
+       return TRUE;
+}
+
+static gboolean
+arv_uv_device_read_register (ArvDevice *device, guint32 address, guint32 *value, GError **error)
+{
+       return arv_uv_device_read_memory (device, address, sizeof (guint32), value, error);
+}
+
+static gboolean
+arv_uv_device_write_register (ArvDevice *device, guint32 address, guint32 value, GError **error)
+{
+       return arv_uv_device_write_memory (device, address, sizeof (guint32), &value, error);
+}
+
 static void 
 _bootstrap (ArvUvDevice *uv_device)
 {
@@ -189,61 +350,6 @@ arv_uv_device_get_genicam (ArvDevice *device)
        return uv_device->priv->genicam;
 }
 
-static gboolean
-_read_memory (ArvUvDevice *uv_device, guint32 address, guint32 size, void *buffer, GError **error)
-{
-       ArvUvcpPacket *packet;
-       size_t packet_size;
-       size_t answer_size;
-       gboolean success = FALSE;
-
-       answer_size = arv_uvcp_packet_get_read_memory_ack_size (size);
-
-       g_return_val_if_fail (answer_size <= 1024, FALSE);
-
-       packet = arv_uvcp_packet_new_read_memory_cmd (address, size, 0, &packet_size);
-
-       do {
-               int transferred;
-               void *read_packet;
-               size_t read_packet_size;
-
-/*                read_packet_size = arv_uvcp_packet_get_read_memory_ack_size (size);*/
-/*                read_packet = g_malloc0 (read_packet_size);*/
-
-               read_packet_size = 1024;
-               read_packet = g_malloc0 (read_packet_size);
-
-               uv_device->priv->packet_id = arv_uvcp_next_packet_id (uv_device->priv->packet_id);
-               arv_uvcp_packet_set_packet_id (packet, uv_device->priv->packet_id);
-
-               arv_uvcp_packet_debug (packet, ARV_DEBUG_LEVEL_LOG);
-
-               g_assert (libusb_claim_interface (uv_device->priv->usb_device, 0) >= 0);
-               g_assert (libusb_bulk_transfer (uv_device->priv->usb_device, (0x04 | LIBUSB_ENDPOINT_OUT),
-                                               (guchar *) packet, packet_size, &transferred, 0) >= 0);
-               g_assert (libusb_bulk_transfer (uv_device->priv->usb_device, (0x84 | LIBUSB_ENDPOINT_IN),
-                                               (guchar *) read_packet, read_packet_size, &transferred, 0) >= 
0);
-               g_assert (libusb_release_interface (uv_device->priv->usb_device, 0) >= 0);
-               success = TRUE;
-
-               memcpy (buffer, arv_uvcp_packet_get_read_memory_ack_data (read_packet), size);
-
-               g_free (read_packet);
-
-       } while (!success);
-
-       arv_uvcp_packet_free (packet);
-
-       if (!success) {
-               if (error != NULL && *error == NULL)
-                       *error = g_error_new (ARV_DEVICE_ERROR, ARV_DEVICE_STATUS_TIMEOUT,
-                                             "[ArvDevice::read_memory] Timeout");
-       }
-
-       return success;
-}
-
 static const char *
 arv_uv_device_get_genicam_xml (ArvDevice *device, size_t *size)
 {
@@ -255,46 +361,6 @@ arv_uv_device_get_genicam_xml (ArvDevice *device, size_t *size)
        return uv_device->priv->genicam_xml;
 }
 
-static gboolean
-arv_uv_device_read_memory (ArvDevice *device, guint32 address, guint32 size, void *buffer, GError **error)
-{
-       ArvUvDevice *uv_device = ARV_UV_DEVICE (device);
-       int i;
-       gint32 block_size;
-       guint data_size_max;
-
-       data_size_max = uv_device->priv->data_size_max;
-
-       for (i = 0; i < (size + data_size_max - 1) / data_size_max; i++) {
-               block_size = MIN (data_size_max, size - i * data_size_max);
-               if (!_read_memory (uv_device,
-                                  address + i * data_size_max,
-                                  block_size, ((char *) buffer) + i * data_size_max, error))
-                       return FALSE;
-       }
-
-       return TRUE;
-}
-
-static gboolean
-arv_uv_device_write_memory (ArvDevice *device, guint32 address, guint32 size, void *buffer, GError **error)
-{
-       g_assert_not_reached ();
-       return FALSE;
-}
-
-static gboolean
-arv_uv_device_read_register (ArvDevice *device, guint32 address, guint32 *value, GError **error)
-{
-       return arv_uv_device_read_memory (device, address, sizeof (guint32), value, error);
-}
-
-static gboolean
-arv_uv_device_write_register (ArvDevice *device, guint32 address, guint32 value, GError **error)
-{
-       return arv_uv_device_write_memory (device, address, sizeof (guint32), &value, error);
-}
-
 static void
 _open_usb_device (ArvUvDevice *uv_device)
 {


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]