libsigrok
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines
ezusb.c
Go to the documentation of this file.
00001 /*
00002  * This file is part of the sigrok project.
00003  *
00004  * Copyright (C) 2010-2012 Bert Vermeulen <bert@biot.com>
00005  *
00006  * This program is free software: you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation, either version 3 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00018  */
00019 
00020 /*
00021  * Helper functions for the Cypress EZ-USB / FX2 series chips.
00022  */
00023 
00024 #include <libusb.h>
00025 #include <glib.h>
00026 #include <glib/gstdio.h>
00027 #include <stdio.h>
00028 #include <errno.h>
00029 #include <string.h>
00030 #include "sigrok.h"
00031 #include "sigrok-internal.h"
00032 
00033 SR_PRIV int ezusb_reset(struct libusb_device_handle *hdl, int set_clear)
00034 {
00035         int ret;
00036         unsigned char buf[1];
00037 
00038         sr_info("ezusb: setting CPU reset mode %s...",
00039                 set_clear ? "on" : "off");
00040         buf[0] = set_clear ? 1 : 0;
00041         ret = libusb_control_transfer(hdl, LIBUSB_REQUEST_TYPE_VENDOR, 0xa0,
00042                                       0xe600, 0x0000, buf, 1, 100);
00043         if (ret < 0)
00044                 sr_err("ezusb: Unable to send control request: %d", ret);
00045 
00046         return ret;
00047 }
00048 
00049 SR_PRIV int ezusb_install_firmware(libusb_device_handle *hdl,
00050                                    const char *filename)
00051 {
00052         FILE *fw;
00053         int offset, chunksize, ret, result;
00054         unsigned char buf[4096];
00055 
00056         sr_info("ezusb: Uploading firmware at %s", filename);
00057         if ((fw = g_fopen(filename, "rb")) == NULL) {
00058                 sr_err("ezusb: Unable to open firmware file %s for reading: %s",
00059                        filename, strerror(errno));
00060                 return SR_ERR;
00061         }
00062 
00063         result = SR_OK;
00064         offset = 0;
00065         while (1) {
00066                 chunksize = fread(buf, 1, 4096, fw);
00067                 if (chunksize == 0)
00068                         break;
00069                 ret = libusb_control_transfer(hdl, LIBUSB_REQUEST_TYPE_VENDOR |
00070                                               LIBUSB_ENDPOINT_OUT, 0xa0, offset,
00071                                               0x0000, buf, chunksize, 100);
00072                 if (ret < 0) {
00073                         sr_err("ezusb: Unable to send firmware to device: %d",
00074                                ret);
00075                         result = SR_ERR;
00076                         break;
00077                 }
00078                 sr_info("ezusb: Uploaded %d bytes", chunksize);
00079                 offset += chunksize;
00080         }
00081         fclose(fw);
00082         sr_info("ezusb: Firmware upload done");
00083 
00084         return result;
00085 }
00086 
00087 SR_PRIV int ezusb_upload_firmware(libusb_device *dev, int configuration,
00088                                   const char *filename)
00089 {
00090         struct libusb_device_handle *hdl;
00091         int ret;
00092 
00093         sr_info("ezusb: uploading firmware to device on %d.%d",
00094                 libusb_get_bus_number(dev), libusb_get_device_address(dev));
00095 
00096         if ((ret = libusb_open(dev, &hdl)) < 0) {
00097                 sr_err("ezusb: failed to open device: %d", ret);
00098                 return SR_ERR;
00099         }
00100 
00101 /* Neither Windows/MinGW nor Darwin/Mac support these libusb-1.0 calls. */
00102 #if !defined(_WIN32) && !defined(__APPLE__)
00103         if (libusb_kernel_driver_active(hdl, 0)) {
00104                 if ((ret = libusb_detach_kernel_driver(hdl, 0)) < 0) {
00105                         sr_err("ezusb: failed to detach kernel driver: %d", ret);
00106                         return SR_ERR;
00107                 }
00108         }
00109 #endif
00110 
00111         if ((ret = libusb_set_configuration(hdl, configuration)) < 0) {
00112                 sr_err("ezusb: Unable to set configuration: %d", ret);
00113                 return SR_ERR;
00114         }
00115 
00116         if ((ezusb_reset(hdl, 1)) < 0)
00117                 return SR_ERR;
00118 
00119         if (ezusb_install_firmware(hdl, filename) < 0)
00120                 return SR_ERR;
00121 
00122         if ((ezusb_reset(hdl, 0)) < 0)
00123                 return SR_ERR;
00124 
00125         libusb_close(hdl);
00126 
00127         return SR_OK;
00128 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines