7 #include "include/hidsdi.h"
8 #include "include/hidpi.h"
13 #define OUR_VID 0x9ac4
14 #define OUR_PID 0x4b8f
19 static void ShowError(void)
22 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
, NULL
, GetLastError(), 0,
23 buf
, sizeof(buf
), NULL
);
24 printf("ERROR: %s", buf
);
27 static BOOL
UsbConnect(void)
29 typedef void (__stdcall
*GetGuidProc
)(GUID
*);
30 typedef BOOLEAN (__stdcall
*GetAttrProc
)(HANDLE
, HIDD_ATTRIBUTES
*);
31 typedef BOOLEAN (__stdcall
*GetPreparsedProc
)(HANDLE
,
32 PHIDP_PREPARSED_DATA
*);
33 typedef NTSTATUS (__stdcall
*GetCapsProc
)(PHIDP_PREPARSED_DATA
, PHIDP_CAPS
);
36 GetPreparsedProc getPreparsed
;
39 HMODULE h
= LoadLibrary("hid.dll");
40 getGuid
= (GetGuidProc
)GetProcAddress(h
, "HidD_GetHidGuid");
41 getAttr
= (GetAttrProc
)GetProcAddress(h
, "HidD_GetAttributes");
42 getPreparsed
= (GetPreparsedProc
)GetProcAddress(h
, "HidD_GetPreparsedData");
43 getCaps
= (GetCapsProc
)GetProcAddress(h
, "HidP_GetCaps");
49 devInfo
= SetupDiGetClassDevs(&hidGuid
, NULL
, NULL
,
50 DIGCF_PRESENT
| DIGCF_INTERFACEDEVICE
);
52 SP_DEVICE_INTERFACE_DATA devInfoData
;
53 devInfoData
.cbSize
= sizeof(devInfoData
);
57 if(!SetupDiEnumDeviceInterfaces(devInfo
, 0, &hidGuid
, i
, &devInfoData
))
59 if(GetLastError() != ERROR_NO_MORE_ITEMS
) {
60 // printf("SetupDiEnumDeviceInterfaces failed\n");
62 // printf("done list\n");
63 SetupDiDestroyDeviceInfoList(devInfo
);
67 // printf("item %d:\n", i);
70 if(!SetupDiGetDeviceInterfaceDetail(devInfo
, &devInfoData
,
71 NULL
, 0, &sizeReqd
, NULL
))
73 if(GetLastError() != ERROR_INSUFFICIENT_BUFFER
) {
74 // printf("SetupDiGetDeviceInterfaceDetail (0) failed\n");
79 SP_DEVICE_INTERFACE_DETAIL_DATA
*devInfoDetailData
=
80 (SP_DEVICE_INTERFACE_DETAIL_DATA
*)malloc(sizeReqd
);
81 devInfoDetailData
->cbSize
= sizeof(*devInfoDetailData
);
83 if(!SetupDiGetDeviceInterfaceDetail(devInfo
, &devInfoData
,
84 devInfoDetailData
, 87, NULL
, NULL
))
86 // printf("SetupDiGetDeviceInterfaceDetail (1) failed\n");
90 char *path
= devInfoDetailData
->DevicePath
;
92 UsbHandle
= CreateFile(path
, /*GENERIC_READ |*/ GENERIC_WRITE
,
93 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
,
94 FILE_FLAG_OVERLAPPED
, NULL
);
96 if(UsbHandle
== INVALID_HANDLE_VALUE
) {
98 // printf("CreateFile failed: for '%s'\n", path);
102 HIDD_ATTRIBUTES attr
;
103 attr
.Size
= sizeof(attr
);
104 if(!getAttr(UsbHandle
, &attr
)) {
106 // printf("HidD_GetAttributes failed\n");
110 // printf("VID: %04x PID %04x\n", attr.VendorID, attr.ProductID);
112 if(attr
.VendorID
!= OUR_VID
|| attr
.ProductID
!= OUR_PID
) {
113 CloseHandle(UsbHandle
);
114 // printf(" nope, not us\n");
118 // printf ("got it!\n");
119 CloseHandle(UsbHandle
);
121 UsbHandle
= CreateFile(path
, GENERIC_READ
| GENERIC_WRITE
,
122 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
,
123 FILE_FLAG_OVERLAPPED
, NULL
);
125 if(UsbHandle
== INVALID_HANDLE_VALUE
) {
127 // printf("Error, couldn't open our own handle as desired.\n");
131 PHIDP_PREPARSED_DATA pp
;
132 getPreparsed(UsbHandle
, &pp
);
135 if(getCaps(pp
, &caps
) != HIDP_STATUS_SUCCESS
) {
136 // printf("getcaps failed\n");
140 // printf("input/out report %d/%d\n", caps.InputReportByteLength,
141 // caps.OutputReportByteLength);
149 BOOL
ReceiveCommandPoll(UsbCommand
*c
)
151 static BOOL ReadInProgress
= FALSE
;
152 static OVERLAPPED Ov
;
154 static DWORD HaveRead
;
156 if(!ReadInProgress
) {
157 memset(&Ov
, 0, sizeof(Ov
));
158 ReadFile(UsbHandle
, Buf
, 65, &HaveRead
, &Ov
);
159 if(GetLastError() != ERROR_IO_PENDING
) {
163 ReadInProgress
= TRUE
;
166 if(HasOverlappedIoCompleted(&Ov
)) {
167 ReadInProgress
= FALSE
;
169 if(!GetOverlappedResult(UsbHandle
, &Ov
, &HaveRead
, FALSE
)) {
174 memcpy(c
, Buf
+1, 64);
182 void ReceiveCommand(UsbCommand
*c
)
184 while(!ReceiveCommandPoll(c
)) {
189 void SendCommand(UsbCommand
*c
, BOOL wantAck
)
193 memcpy(buf
+1, c
, 64);
198 memset(&ov
, 0, sizeof(ov
));
199 WriteFile(UsbHandle
, buf
, 65, &written
, &ov
);
200 if(GetLastError() != ERROR_IO_PENDING
) {
205 while(!HasOverlappedIoCompleted(&ov
)) {
209 if(!GetOverlappedResult(UsbHandle
, &ov
, &written
, FALSE
)) {
216 ReceiveCommand(&ack
);
217 if(ack
.cmd
!= CMD_ACK
) {
224 static DWORD ExpectedAddr
;
225 static BYTE QueuedToSend
[256];
226 static BOOL AllWritten
;
228 static void FlushPrevious(void)
231 memset(&c
, 0, sizeof(c
));
234 for(i
= 0; i
< 240; i
+= 48) {
235 c
.cmd
= CMD_SETUP_WRITE
;
236 memcpy(c
.d
.asBytes
, QueuedToSend
+i
, 48);
238 SendCommand(&c
, TRUE
);
241 c
.cmd
= CMD_FINISH_WRITE
;
242 c
.ext1
= (ExpectedAddr
-1) & (~255);
243 printf("Flashing address: %08x\r", c
.ext1
);
244 memcpy(c
.d
.asBytes
, QueuedToSend
+240, 16);
245 SendCommand(&c
, TRUE
);
250 static void GotByte(DWORD where
, BYTE which
)
254 if(where
!= ExpectedAddr
) {
255 printf("bad: got at %08x, expected at %08x\n", where
, ExpectedAddr
);
258 QueuedToSend
[where
& 255] = which
;
261 if((where
& 255) == 255) {
262 // we have completed a full page
267 static int HexVal(int c
)
270 if(c
>= '0' && c
<= '9') {
272 } else if(c
>= 'a' && c
<= 'f') {
273 return (c
- 'a') + 10;
275 printf("bad hex digit '%c'\n", c
);
280 static BYTE
HexByte(char *s
)
282 return (HexVal(s
[0]) << 4) | HexVal(s
[1]);
285 static void LoadFlashFromSRecords(char *file
, int addr
)
289 FILE *f
= fopen(file
, "r");
291 printf("couldn't open file\n");
296 while(fgets(line
, sizeof(line
), f
)) {
297 if(memcmp(line
, "S3", 2)==0) {
299 int len
= HexByte(s
) - 5;
303 memcpy(addrStr
, s
, 8);
306 sscanf(addrStr
, "%x", &addr
);
310 for(i
= 0; i
< len
; i
++) {
311 while((addr
+i
) > ExpectedAddr
) {
312 GotByte(ExpectedAddr
, 0xff);
314 GotByte(addr
+i
, HexByte(s
));
320 if(!AllWritten
) FlushPrevious();
326 int main(int argc
, char **argv
)
331 printf("Usage: %s bootrom file.s19\n", argv
[0]);
332 printf(" %s load osimage.s19\n", argv
[0]);
333 printf(" %s fpga fpgaimg.s19\n", argv
[0]);
334 printf(" %s gui\n", argv
[0]);
335 printf(" %s offline\n", argv
[0]);
339 // Only do this if NOT in offline mode
340 if (strcmp(argv
[1], "offline"))
347 printf("...no device connected, polling for it now\n");
350 printf("Could not connect to USB device; exiting.\n");
358 if(strcmp(argv
[1], "bootrom")==0 || strcmp(argv
[1], "load")==0 || strcmp(argv
[1], "fpga")==0) {
360 printf("Need filename.\n");
363 if(strcmp(argv
[1], "bootrom")==0) {
364 LoadFlashFromSRecords(argv
[2], 0);
365 } else if(strcmp(argv
[1], "fpga")==0) {
366 LoadFlashFromSRecords(argv
[2], 0x2000);
368 LoadFlashFromSRecords(argv
[2], 0x10000);
370 } else if(strcmp(argv
[1], "gui")==0) {
372 } else if(strcmp(argv
[1], "offline")==0) {
375 } else if(strcmp(argv
[1], "cmd")==0) {
377 printf("Need command.\n");
382 printf("Command '%s' not recognized.\n", argv
[1]);