The bootloaderhost utility is now working under Linux.
[SCSI2SD-V6.git] / software / bootloaderhost / main.c
1 //      Copyright (C) 2013 Michael McMaster <michael@codesrc.com>
2 //
3 //      This file is part of SCSI2SD.
4 //
5 //      SCSI2SD is free software: you can redistribute it and/or modify
6 //      it under the terms of the GNU General Public License as published by
7 //      the Free Software Foundation, either version 3 of the License, or
8 //      (at your option) any later version.
9 //
10 //      SCSI2SD is distributed in the hope that it will be useful,
11 //      but WITHOUT ANY WARRANTY; without even the implied warranty of
12 //      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 //      GNU General Public License for more details.
14 //
15 //      You should have received a copy of the GNU General Public License
16 //      along with SCSI2SD.  If not, see <http://www.gnu.org/licenses/>.
17
18 #include <stdint.h>
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <unistd.h>
23
24
25 #include "hidapi.h"
26 #include "cybtldr_api.h"
27 #include "cybtldr_api2.h"
28
29 hid_device *handle = NULL;
30
31 static int OpenConnection(void)
32 {
33         return 0;
34 }
35
36 static int CloseConnection(void)
37 {
38         return 0;
39 }
40
41 static int ReadData(unsigned char* data, int count)
42 {
43         unsigned char buf[65];
44         buf[0] = 0; // Report ID
45
46         int result = hid_read(handle, buf, count);
47
48         if (result < 0)
49         {
50                 fprintf(stderr, "USB HID Read Failure: %ls\n", hid_error(handle));
51         }
52
53         memcpy(data, buf, count);
54
55         return (result >= 0) ? 0 : -1;
56 }
57
58 static int WriteData(unsigned char* data, int count)
59 {
60         unsigned char buf[65];
61         buf[0] = 0; // report ID
62         int i;
63         for (i = 0; i < count; ++i)
64         {
65                 buf[i+1] = data[i];
66         }
67         int result = hid_write(handle, buf, count + 1);
68
69         if (result < 0)
70         {
71                 fprintf(stderr, "USB HID Write Failure: %ls\n", hid_error(handle));
72         }
73
74         return (result >= 0) ? 0 : -1;
75 }
76
77
78 static void ProgressUpdate(unsigned char arrayId, unsigned short rowNum)
79 {
80         printf("Programmed flash array %d, row %d\n", arrayId, rowNum);
81 }
82
83 static void usage()
84 {
85         printf("Usage: bootloaderhost [-v UsbVendorId] [-p UsbProductId] /path/to/firmware.cyacd\n");
86         printf("\n\n");
87 }
88
89 int main(int argc, char* argv[])
90 {
91         CyBtldr_CommunicationsData cyComms =
92         {
93                 &OpenConnection,
94                 &CloseConnection,
95                 &ReadData,
96                 &WriteData,
97                 64
98         };
99
100         printf("PSoC 3/5LP USB HID Bootloader Host\n");
101         printf("Copyright (C) 2013 Michael McMaster <michael@codesrc.com>\n\n");
102
103         uint16_t vendorId = 0x04B4; // Cypress
104         uint16_t productId = 0xB71D; // Default PSoC3/5LP Bootloader
105
106         opterr = 0;
107         int c;
108         while ((c = getopt(argc, argv, "v:p:")) != -1)
109         {
110                 switch (c)
111                 {
112                 case 'v':
113                         sscanf(optarg, "%x", &vendorId);
114                         break;
115                 case 'p':
116                         sscanf(optarg, "%x", &productId);
117                         break;
118                 case '?':
119                         usage();
120                         exit(1);
121                 }
122         }
123
124         const char* filename;
125         if (optind < argc)
126         {
127                 filename = argv[optind];
128         }
129         else
130         {
131                 usage();
132                 exit(1);
133         }
134
135         printf(
136                 "USB device parameters\n\tVendor ID:\t0x%04X\n\tProduct ID:\t0x%04X\n",
137                 vendorId,
138                 productId);
139
140         // Enumerate and print the HID devices on the system
141         struct hid_device_info *dev = hid_enumerate(vendorId, productId);
142
143         if (!dev)
144         {
145                 printf("Waiting for device connection\n");
146                 printf("Connect USB cable to the bus-powered device now, or otherwise reset the device.\n");
147         }
148
149         while (!dev)
150         {
151                 dev = hid_enumerate(vendorId, productId);
152                 usleep(10000); // 10ms
153         }
154
155         printf("Device Found\n  type: %04hx %04hx\n  path: %s\n  serial_number: %ls",
156                 dev->vendor_id, dev->product_id, dev->path, dev->serial_number);
157         printf("\n");
158         printf("  Manufacturer: %ls\n", dev->manufacturer_string);
159         printf("  Product:      %ls\n", dev->product_string);
160         printf("\n");
161         //hid_free_enumeration(devs);
162
163         // Open the device using the VID, PID,
164         // and optionally the Serial number.
165         handle = hid_open(vendorId, productId, NULL);
166         if (!handle)
167         {
168                 fprintf(
169                         stderr,
170                         "Could not open device %s. Check permissions.\n", dev->path
171                         );
172                 exit(1);
173         }
174
175
176         printf("Starting firmware upload: %s\n", filename);
177         int result = CyBtldr_Program(
178                 filename,
179                 &cyComms,
180                 &ProgressUpdate);
181         if (result == 0)
182         {
183                 printf("Firmware update complete\n");
184         }
185         else
186         {
187                 printf("Firmware update failed\n");
188         }
189
190         return 0;
191 }
192