7 #include "include/hidsdi.h"
8 #include "include/hidpi.h"
13 #define OUR_VID 0x9ac4
14 #define OUR_PID 0x4b8f
18 static void ShowError(void)
21 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
, NULL
, GetLastError(), 0,
22 buf
, sizeof(buf
), NULL
);
23 printf("ERROR: %s", buf
);
26 static BOOL
UsbConnect(void)
28 typedef void (__stdcall
*GetGuidProc
)(GUID
*);
29 typedef BOOLEAN (__stdcall
*GetAttrProc
)(HANDLE
, HIDD_ATTRIBUTES
*);
30 typedef BOOLEAN (__stdcall
*GetPreparsedProc
)(HANDLE
,
31 PHIDP_PREPARSED_DATA
*);
32 typedef NTSTATUS (__stdcall
*GetCapsProc
)(PHIDP_PREPARSED_DATA
, PHIDP_CAPS
);
35 GetPreparsedProc getPreparsed
;
38 HMODULE h
= LoadLibrary("hid.dll");
39 getGuid
= (GetGuidProc
)GetProcAddress(h
, "HidD_GetHidGuid");
40 getAttr
= (GetAttrProc
)GetProcAddress(h
, "HidD_GetAttributes");
41 getPreparsed
= (GetPreparsedProc
)GetProcAddress(h
, "HidD_GetPreparsedData");
42 getCaps
= (GetCapsProc
)GetProcAddress(h
, "HidP_GetCaps");
48 devInfo
= SetupDiGetClassDevs(&hidGuid
, NULL
, NULL
,
49 DIGCF_PRESENT
| DIGCF_INTERFACEDEVICE
);
51 SP_DEVICE_INTERFACE_DATA devInfoData
;
52 devInfoData
.cbSize
= sizeof(devInfoData
);
56 if(!SetupDiEnumDeviceInterfaces(devInfo
, 0, &hidGuid
, i
, &devInfoData
))
58 if(GetLastError() != ERROR_NO_MORE_ITEMS
) {
59 // printf("SetupDiEnumDeviceInterfaces failed\n");
61 // printf("done list\n");
62 SetupDiDestroyDeviceInfoList(devInfo
);
66 // printf("item %d:\n", i);
69 if(!SetupDiGetDeviceInterfaceDetail(devInfo
, &devInfoData
,
70 NULL
, 0, &sizeReqd
, NULL
))
72 if(GetLastError() != ERROR_INSUFFICIENT_BUFFER
) {
73 // printf("SetupDiGetDeviceInterfaceDetail (0) failed\n");
78 SP_DEVICE_INTERFACE_DETAIL_DATA
*devInfoDetailData
=
79 (SP_DEVICE_INTERFACE_DETAIL_DATA
*)malloc(sizeReqd
);
80 devInfoDetailData
->cbSize
= sizeof(*devInfoDetailData
);
82 if(!SetupDiGetDeviceInterfaceDetail(devInfo
, &devInfoData
,
83 devInfoDetailData
, 87, NULL
, NULL
))
85 // printf("SetupDiGetDeviceInterfaceDetail (1) failed\n");
89 char *path
= devInfoDetailData
->DevicePath
;
91 UsbHandle
= CreateFile(path
, /*GENERIC_READ |*/ GENERIC_WRITE
,
92 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
,
93 FILE_FLAG_OVERLAPPED
, NULL
);
95 if(UsbHandle
== INVALID_HANDLE_VALUE
) {
97 // printf("CreateFile failed: for '%s'\n", path);
101 HIDD_ATTRIBUTES attr
;
102 attr
.Size
= sizeof(attr
);
103 if(!getAttr(UsbHandle
, &attr
)) {
105 // printf("HidD_GetAttributes failed\n");
109 // printf("VID: %04x PID %04x\n", attr.VendorID, attr.ProductID);
111 if(attr
.VendorID
!= OUR_VID
|| attr
.ProductID
!= OUR_PID
) {
112 CloseHandle(UsbHandle
);
113 // printf(" nope, not us\n");
117 // printf ("got it!\n");
118 CloseHandle(UsbHandle
);
120 UsbHandle
= CreateFile(path
, GENERIC_READ
| GENERIC_WRITE
,
121 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
,
122 FILE_FLAG_OVERLAPPED
, NULL
);
124 if(UsbHandle
== INVALID_HANDLE_VALUE
) {
126 // printf("Error, couldn't open our own handle as desired.\n");
130 PHIDP_PREPARSED_DATA pp
;
131 getPreparsed(UsbHandle
, &pp
);
134 if(getCaps(pp
, &caps
) != HIDP_STATUS_SUCCESS
) {
135 // printf("getcaps failed\n");
139 // printf("input/out report %d/%d\n", caps.InputReportByteLength,
140 // caps.OutputReportByteLength);
148 BOOL
ReceiveCommandPoll(UsbCommand
*c
)
150 static BOOL ReadInProgress
= FALSE
;
151 static OVERLAPPED Ov
;
153 static DWORD HaveRead
;
155 if(!ReadInProgress
) {
156 memset(&Ov
, 0, sizeof(Ov
));
157 ReadFile(UsbHandle
, Buf
, 65, &HaveRead
, &Ov
);
158 if(GetLastError() != ERROR_IO_PENDING
) {
162 ReadInProgress
= TRUE
;
165 if(HasOverlappedIoCompleted(&Ov
)) {
166 ReadInProgress
= FALSE
;
168 if(!GetOverlappedResult(UsbHandle
, &Ov
, &HaveRead
, FALSE
)) {
173 memcpy(c
, Buf
+1, 64);
181 void ReceiveCommand(UsbCommand
*c
)
183 while(!ReceiveCommandPoll(c
)) {
188 void SendCommand(UsbCommand
*c
, BOOL wantAck
)
192 memcpy(buf
+1, c
, 64);
196 memset(&ov
, 0, sizeof(ov
));
197 WriteFile(UsbHandle
, buf
, 65, &written
, &ov
);
198 if(GetLastError() != ERROR_IO_PENDING
) {
203 while(!HasOverlappedIoCompleted(&ov
)) {
207 if(!GetOverlappedResult(UsbHandle
, &ov
, &written
, FALSE
)) {
214 ReceiveCommand(&ack
);
215 if(ack
.cmd
!= CMD_ACK
) {
222 static DWORD ExpectedAddr
;
223 static BYTE QueuedToSend
[256];
224 static BOOL AllWritten
;
226 static void FlushPrevious(void)
229 memset(&c
, 0, sizeof(c
));
231 printf("expected = %08x flush, ", ExpectedAddr
);
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("c.ext1 = %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]);
343 printf("...no device connected, polling for it now\n");
346 printf("Could not connect to USB device; exiting.\n");
353 if(strcmp(argv
[1], "bootrom")==0 || strcmp(argv
[1], "load")==0 || strcmp(argv
[1], "fpga")==0) {
355 printf("Need filename.\n");
358 if(strcmp(argv
[1], "bootrom")==0) {
359 LoadFlashFromSRecords(argv
[2], 0);
360 } else if(strcmp(argv
[1], "fpga")==0) {
361 LoadFlashFromSRecords(argv
[2], 0x2000);
363 LoadFlashFromSRecords(argv
[2], 0x10000);
365 } else if(strcmp(argv
[1], "gui")==0) {
367 } else if(strcmp(argv
[1], "cmd")==0) {
369 printf("Need command.\n");
374 printf("Command '%s' not recognized.\n", argv
[1]);