jtag/cmsis_dap: switch to command 'adapter serial'
[fw/openocd] / src / jtag / drivers / cmsis_dap_usb_hid.c
index 681aef171266b9b2d782e0a118382a7ef6fe52fc..912ba3972fa9cf4117403450bee3df2c89b48f22 100644 (file)
 #include "config.h"
 #endif
 
+#include <string.h>
 #include <hidapi.h>
 #include <helper/log.h>
 
 #include "cmsis_dap.h"
 
-#define PACKET_SIZE       (64 + 1)     /* 64 bytes plus report id */
-
 struct cmsis_dap_backend_data {
        hid_device *dev_handle;
 };
 
-static int cmsis_dap_hid_open(struct cmsis_dap *dap, uint16_t vids[], uint16_t pids[], char *serial)
+static void cmsis_dap_hid_close(struct cmsis_dap *dap);
+static int cmsis_dap_hid_alloc(struct cmsis_dap *dap, unsigned int pkt_sz);
+
+static int cmsis_dap_hid_open(struct cmsis_dap *dap, uint16_t vids[], uint16_t pids[], const char *serial)
 {
        hid_device *dev = NULL;
        int i;
@@ -68,11 +70,11 @@ static int cmsis_dap_hid_open(struct cmsis_dap *dap, uint16_t vids[], uint16_t p
         */
        devs = hid_enumerate(0x0, 0x0);
        cur_dev = devs;
-       while (NULL != cur_dev) {
+       while (cur_dev) {
                bool found = false;
 
-               if (0 == vids[0]) {
-                       if (NULL == cur_dev->product_string) {
+               if (vids[0] == 0) {
+                       if (!cur_dev->product_string) {
                                LOG_DEBUG("Cannot read product string of device 0x%x:0x%x",
                                          cur_dev->vendor_id, cur_dev->product_id);
                        } else if (wcsstr(cur_dev->product_string, L"CMSIS-DAP")) {
@@ -95,10 +97,10 @@ static int cmsis_dap_hid_open(struct cmsis_dap *dap, uint16_t vids[], uint16_t p
 
                if (found) {
                        /* check serial number matches if given */
-                       if (serial == NULL)
+                       if (!serial)
                                break;
 
-                       if (cur_dev->serial_number != NULL) {
+                       if (cur_dev->serial_number) {
                                size_t len = (strlen(serial) + 1) * sizeof(wchar_t);
                                wchar_t *wserial = malloc(len);
                                mbstowcs(wserial, serial, len);
@@ -116,7 +118,7 @@ static int cmsis_dap_hid_open(struct cmsis_dap *dap, uint16_t vids[], uint16_t p
                cur_dev = cur_dev->next;
        }
 
-       if (NULL != cur_dev) {
+       if (cur_dev) {
                target_vid = cur_dev->vendor_id;
                target_pid = cur_dev->product_id;
        }
@@ -127,7 +129,7 @@ static int cmsis_dap_hid_open(struct cmsis_dap *dap, uint16_t vids[], uint16_t p
        }
 
        dap->bdata = malloc(sizeof(struct cmsis_dap_backend_data));
-       if (dap->bdata == NULL) {
+       if (!dap->bdata) {
                LOG_ERROR("unable to allocate memory");
                return ERROR_FAIL;
        }
@@ -135,7 +137,7 @@ static int cmsis_dap_hid_open(struct cmsis_dap *dap, uint16_t vids[], uint16_t p
        dev = hid_open_path(cur_dev->path);
        hid_free_enumeration(devs);
 
-       if (dev == NULL) {
+       if (!dev) {
                LOG_ERROR("unable to open CMSIS-DAP device 0x%x:0x%x", target_vid, target_pid);
                return ERROR_FAIL;
        }
@@ -145,7 +147,7 @@ static int cmsis_dap_hid_open(struct cmsis_dap *dap, uint16_t vids[], uint16_t p
         * without this info we cannot communicate with the adapter.
         * For the moment we have to hard code the packet size */
 
-       dap->packet_size = PACKET_SIZE;
+       unsigned int packet_size = 64;
 
        /* atmel cmsis-dap uses 512 byte reports */
        /* except when it doesn't e.g. with mEDBG on SAMD10 Xplained
@@ -153,10 +155,18 @@ static int cmsis_dap_hid_open(struct cmsis_dap *dap, uint16_t vids[], uint16_t p
        /* TODO: HID report descriptor should be parsed instead of
         * hardcoding a match by VID */
        if (target_vid == 0x03eb && target_pid != 0x2145 && target_pid != 0x2175)
-               dap->packet_size = 512 + 1;
+               packet_size = 512;
 
        dap->bdata->dev_handle = dev;
 
+       int retval = cmsis_dap_hid_alloc(dap, packet_size);
+       if (retval != ERROR_OK) {
+               cmsis_dap_hid_close(dap);
+               return ERROR_FAIL;
+       }
+
+       dap->command = dap->packet_buffer + REPORT_ID_SIZE;
+       dap->response = dap->packet_buffer;
        return ERROR_OK;
 }
 
@@ -166,11 +176,13 @@ static void cmsis_dap_hid_close(struct cmsis_dap *dap)
        hid_exit();
        free(dap->bdata);
        dap->bdata = NULL;
+       free(dap->packet_buffer);
+       dap->packet_buffer = NULL;
 }
 
 static int cmsis_dap_hid_read(struct cmsis_dap *dap, int timeout_ms)
 {
-       int retval = hid_read_timeout(dap->bdata->dev_handle, dap->packet_buffer, dap->packet_size, timeout_ms);
+       int retval = hid_read_timeout(dap->bdata->dev_handle, dap->packet_buffer, dap->packet_buffer_size, timeout_ms);
 
        if (retval == 0) {
                return ERROR_TIMEOUT_REACHED;
@@ -186,11 +198,13 @@ static int cmsis_dap_hid_write(struct cmsis_dap *dap, int txlen, int timeout_ms)
 {
        (void) timeout_ms;
 
+       dap->packet_buffer[0] = 0; /* HID report number */
+
        /* Pad the rest of the TX buffer with 0's */
-       memset(dap->packet_buffer + txlen, 0, dap->packet_size - txlen);
+       memset(dap->command + txlen, 0, dap->packet_size - txlen);
 
        /* write data to device */
-       int retval = hid_write(dap->bdata->dev_handle, dap->packet_buffer, dap->packet_size);
+       int retval = hid_write(dap->bdata->dev_handle, dap->packet_buffer, dap->packet_buffer_size);
        if (retval == -1) {
                LOG_ERROR("error writing data: %ls", hid_error(dap->bdata->dev_handle));
                return ERROR_FAIL;
@@ -199,10 +213,30 @@ static int cmsis_dap_hid_write(struct cmsis_dap *dap, int txlen, int timeout_ms)
        return retval;
 }
 
+static int cmsis_dap_hid_alloc(struct cmsis_dap *dap, unsigned int pkt_sz)
+{
+       unsigned int packet_buffer_size = pkt_sz + REPORT_ID_SIZE;
+       uint8_t *buf = malloc(packet_buffer_size);
+       if (!buf) {
+               LOG_ERROR("unable to allocate CMSIS-DAP packet buffer");
+               return ERROR_FAIL;
+       }
+
+       dap->packet_buffer = buf;
+       dap->packet_size = pkt_sz;
+       dap->packet_buffer_size = packet_buffer_size;
+
+       dap->command = dap->packet_buffer + REPORT_ID_SIZE;
+       dap->response = dap->packet_buffer;
+
+       return ERROR_OK;
+}
+
 const struct cmsis_dap_backend cmsis_dap_hid_backend = {
        .name = "hid",
        .open = cmsis_dap_hid_open,
        .close = cmsis_dap_hid_close,
        .read = cmsis_dap_hid_read,
        .write = cmsis_dap_hid_write,
+       .packet_buffer_alloc = cmsis_dap_hid_alloc,
 };